Body value calculations written and displayed!
This commit is contained in:
parent
0bf9cb2c69
commit
5bdeec7857
3 changed files with 317 additions and 1 deletions
156
src/data/BodyCodes.ts
Normal file
156
src/data/BodyCodes.ts
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
export const BodyCodes = {
|
||||||
|
// https://github.com/EDSM-NET/Alias/blob/master/Body/Star/Type.php
|
||||||
|
starTypes: {
|
||||||
|
// Main sequence
|
||||||
|
'O': 1,
|
||||||
|
|
||||||
|
'B': 2,
|
||||||
|
'B_BlueSuperGiant': 201,
|
||||||
|
|
||||||
|
'A': 3,
|
||||||
|
'A_BlueWhiteSuperGiant': 301,
|
||||||
|
|
||||||
|
'F': 4,
|
||||||
|
'F_WhiteSuperGiant': 401,
|
||||||
|
|
||||||
|
'G': 5,
|
||||||
|
'G_WhiteSuperGiant': 5001,
|
||||||
|
|
||||||
|
'K': 6,
|
||||||
|
'K_OrangeGiant': 601,
|
||||||
|
|
||||||
|
'M': 7,
|
||||||
|
'M_RedGiant': 701,
|
||||||
|
'M_RedSuperGiant': 702,
|
||||||
|
|
||||||
|
'L': 8,
|
||||||
|
'T': 9,
|
||||||
|
'Y': 10,
|
||||||
|
|
||||||
|
// Proto stars
|
||||||
|
'TTS': 11,
|
||||||
|
'AeBe': 12,
|
||||||
|
|
||||||
|
// Wolf-Rayet
|
||||||
|
'W': 21,
|
||||||
|
'WN': 22,
|
||||||
|
'WNC': 23,
|
||||||
|
'WC': 24,
|
||||||
|
'WO': 25,
|
||||||
|
|
||||||
|
// Carbon stars
|
||||||
|
'CS': 31,
|
||||||
|
'C': 32,
|
||||||
|
'CN': 33,
|
||||||
|
'CJ': 34,
|
||||||
|
'CH': 35,
|
||||||
|
'CHd': 36,
|
||||||
|
|
||||||
|
'MS': 41,
|
||||||
|
'S': 42,
|
||||||
|
|
||||||
|
// White dwarfs
|
||||||
|
'D': 51,
|
||||||
|
'DA': 501,
|
||||||
|
'DAB': 502,
|
||||||
|
'DAO': 503,
|
||||||
|
'DAZ': 504,
|
||||||
|
'DAV': 505,
|
||||||
|
'DB': 506,
|
||||||
|
'DBZ': 507,
|
||||||
|
'DBV': 508,
|
||||||
|
'DO': 509,
|
||||||
|
'DOV': 510,
|
||||||
|
'DQ': 511,
|
||||||
|
'DC': 512,
|
||||||
|
'DCV': 513,
|
||||||
|
'DX': 514,
|
||||||
|
|
||||||
|
'N': 91,
|
||||||
|
'H': 92,
|
||||||
|
'SuperMassiveBlackHole': 93,
|
||||||
|
|
||||||
|
'X': 94,
|
||||||
|
|
||||||
|
'RoguePlanet': 111,
|
||||||
|
'Nebula': 112,
|
||||||
|
'StellarRemnantNebula': 113,
|
||||||
|
},
|
||||||
|
|
||||||
|
// https://github.com/EDSM-NET/Alias/blob/master/Body/Planet/Type.php
|
||||||
|
planetTypes: {
|
||||||
|
'Metal-rich body': 1,
|
||||||
|
'Metal rich body': 1,
|
||||||
|
|
||||||
|
'High metal content world': 2,
|
||||||
|
'High metal content body': 2,
|
||||||
|
|
||||||
|
'Rocky body': 11,
|
||||||
|
|
||||||
|
'Rocky Ice world': 12,
|
||||||
|
'Rocky ice body': 12,
|
||||||
|
|
||||||
|
'Icy body': 21,
|
||||||
|
|
||||||
|
'Earth-like world': 31,
|
||||||
|
'Earthlike body': 31,
|
||||||
|
|
||||||
|
'Water world': 41,
|
||||||
|
|
||||||
|
'Water giant': 42,
|
||||||
|
'Water giant with life': 43,
|
||||||
|
|
||||||
|
'Ammonia world': 51,
|
||||||
|
|
||||||
|
'Gas giant with water-based life': 61,
|
||||||
|
'Gas giant with water based life': 61,
|
||||||
|
|
||||||
|
'Gas giant with ammonia-based life': 62,
|
||||||
|
'Gas giant with ammonia based life': 62,
|
||||||
|
|
||||||
|
'Class I gas giant': 71,
|
||||||
|
'Class II gas giant': 72,
|
||||||
|
'Class III gas giant': 73,
|
||||||
|
'Class IV gas giant': 74,
|
||||||
|
'Class V gas giant': 75,
|
||||||
|
|
||||||
|
'Sudarsky class I gas giant': 71,
|
||||||
|
'Sudarsky class II gas giant': 72,
|
||||||
|
'Sudarsky class III gas giant': 73,
|
||||||
|
'Sudarsky class IV gas giant': 74,
|
||||||
|
'Sudarsky class V gas giant': 75,
|
||||||
|
|
||||||
|
'Helium-rich gas giant': 81,
|
||||||
|
'Helium rich gas giant': 81,
|
||||||
|
'Helium gas giant': 82,
|
||||||
|
},
|
||||||
|
|
||||||
|
// https://github.com/EDSM-NET/Alias/blob/master/Body/Planet/TerraformState.php
|
||||||
|
terraformStates: {
|
||||||
|
'Not terraformable': 0,
|
||||||
|
|
||||||
|
'Candidate for terraforming': 1,
|
||||||
|
'Terraformable': 1,
|
||||||
|
|
||||||
|
'Terraforming completed': 2,
|
||||||
|
'Terraformed': 2,
|
||||||
|
|
||||||
|
'Being terraformed': 3,
|
||||||
|
'Terraforming': 3,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Star categories
|
||||||
|
whiteDwarf: [51, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514],
|
||||||
|
neutronStar: [91],
|
||||||
|
blackHole: [92],
|
||||||
|
superMassiveBlackHole: [93],
|
||||||
|
|
||||||
|
// Planet categories
|
||||||
|
metalRich: [1],
|
||||||
|
ammonia: [51],
|
||||||
|
classIGiant: [71],
|
||||||
|
highMetalContent: [2],
|
||||||
|
classIIGiant: [72],
|
||||||
|
earthLike: [31],
|
||||||
|
water: [41],
|
||||||
|
}
|
|
@ -1,9 +1,12 @@
|
||||||
import type { valuableBody } from "../@types/edsmResponses"
|
import type { valuableBody } from "../@types/edsmResponses"
|
||||||
import type { asteroidScan, autoScan, detailedScan, planetScan, starScan } from "../@types/journalLines"
|
import type { asteroidScan, autoScan, detailedScan, planetScan, starScan } from "../@types/journalLines"
|
||||||
|
|
||||||
|
import { BodyCodes } from "../data/BodyCodes"
|
||||||
|
|
||||||
export interface Body extends starScan<'AutoScan'|'DetailedScan'>, asteroidScan<'AutoScan'|'DetailedScan'>, planetScan<'AutoScan'|'DetailedScan'> {}
|
export interface Body extends starScan<'AutoScan'|'DetailedScan'>, asteroidScan<'AutoScan'|'DetailedScan'>, planetScan<'AutoScan'|'DetailedScan'> {}
|
||||||
export class Body {
|
export class Body {
|
||||||
DSSDone: boolean
|
DSSDone: boolean
|
||||||
|
mappedValue: number
|
||||||
|
|
||||||
constructor(journalLine: autoScan|detailedScan|valuableBody|null = null, DSS: boolean = false) {
|
constructor(journalLine: autoScan|detailedScan|valuableBody|null = null, DSS: boolean = false) {
|
||||||
this.DSSDone = DSS
|
this.DSSDone = DSS
|
||||||
|
@ -11,6 +14,8 @@ export class Body {
|
||||||
if (journalLine !== null) {
|
if (journalLine !== null) {
|
||||||
Object.assign(this, journalLine)
|
Object.assign(this, journalLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.mappedValue = this.#getValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- isAsteroid ---- */
|
/* -------------------------------------------------------------------------- isAsteroid ---- */
|
||||||
|
@ -80,4 +85,159 @@ export class Body {
|
||||||
|
|
||||||
return typeIcon
|
return typeIcon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------- getValue ---- */
|
||||||
|
|
||||||
|
// https://forums.frontier.co.uk/threads/exploration-value-formulae.232000/
|
||||||
|
// https://github.com/EDSM-NET/Component/blob/master/Body/Value.php
|
||||||
|
|
||||||
|
#getValue(): number {
|
||||||
|
let bodyType: number|undefined = undefined // Asteroids.
|
||||||
|
|
||||||
|
if (this.isStar()) {
|
||||||
|
// Typescript feels so stupid sometimes.
|
||||||
|
bodyType = BodyCodes.starTypes[this.StarType as keyof typeof BodyCodes.starTypes]
|
||||||
|
} else if (this.isPlanet()) {
|
||||||
|
bodyType = BodyCodes.planetTypes[this.PlanetClass as keyof typeof BodyCodes.planetTypes]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asteroids don't have mass.
|
||||||
|
const mass = ('MassEM' in this) ? this.MassEM : 1
|
||||||
|
|
||||||
|
let terraformState: number|undefined = undefined // Asteroids & Stars.
|
||||||
|
|
||||||
|
if ('TerraformState' in this) {
|
||||||
|
terraformState =
|
||||||
|
BodyCodes.terraformStates[this.TerraformState as keyof typeof BodyCodes.terraformStates]
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstDiscover = !this.WasDiscovered
|
||||||
|
const firstMap = !this.WasMapped
|
||||||
|
|
||||||
|
if (this.isStar()) {
|
||||||
|
return this.#appraiseStar(bodyType, mass)
|
||||||
|
|
||||||
|
} else if (this.isPlanet() || this.isAsteroid()) {
|
||||||
|
// Asteroids are treated as planets for the purpose of value calculation.
|
||||||
|
return this.#appraisePlanet(bodyType, mass, terraformState, firstDiscover, firstMap)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- #appraiseStar ---- */
|
||||||
|
|
||||||
|
#appraiseStar(bodyType: number|undefined, mass: number): number {
|
||||||
|
let value: number = 1200
|
||||||
|
|
||||||
|
if (bodyType) {
|
||||||
|
if (BodyCodes.whiteDwarf.includes(bodyType)) {
|
||||||
|
value = 14057
|
||||||
|
|
||||||
|
} else if (
|
||||||
|
BodyCodes.neutronStar.includes(bodyType)
|
||||||
|
|| BodyCodes.blackHole.includes(bodyType)
|
||||||
|
) {
|
||||||
|
value = 22628
|
||||||
|
|
||||||
|
} else if (BodyCodes.superMassiveBlackHole.includes(bodyType)) {
|
||||||
|
value = 33.5678 // Not confirmed in game.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(value + (mass * value / 66.25))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- #appraisePlanet ---- */
|
||||||
|
|
||||||
|
#appraisePlanet(
|
||||||
|
bodyType: number|undefined,
|
||||||
|
mass: number,
|
||||||
|
terraformState: number|undefined,
|
||||||
|
firstDiscover: boolean,
|
||||||
|
firstMap: boolean
|
||||||
|
): number {
|
||||||
|
|
||||||
|
// Base value & terraform bonus calculation.
|
||||||
|
let value: number = 300
|
||||||
|
let terraformBonus: number = 0
|
||||||
|
|
||||||
|
// Base terraform bonus.
|
||||||
|
if (terraformState && terraformState > 0) {
|
||||||
|
terraformBonus = 93328
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bodyType) {
|
||||||
|
// Metal-rich body.
|
||||||
|
if (BodyCodes.metalRich.includes(bodyType)) {
|
||||||
|
value = 21790
|
||||||
|
|
||||||
|
if (terraformState && terraformState > 0) {
|
||||||
|
terraformBonus = 65631
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ammonia world.
|
||||||
|
} else if (BodyCodes.ammonia.includes(bodyType)) {
|
||||||
|
value = 96932
|
||||||
|
|
||||||
|
// Class I gas giant.
|
||||||
|
} else if (BodyCodes.classIGiant.includes(bodyType)) {
|
||||||
|
value = 1656
|
||||||
|
|
||||||
|
// High metal content & Class II gas giant.
|
||||||
|
} else if (
|
||||||
|
BodyCodes.highMetalContent.includes(bodyType)
|
||||||
|
|| BodyCodes.classIIGiant.includes(bodyType)
|
||||||
|
) {
|
||||||
|
value = 9654
|
||||||
|
|
||||||
|
if (terraformState && terraformState > 0) {
|
||||||
|
terraformBonus = 100677
|
||||||
|
}
|
||||||
|
|
||||||
|
// Earth-like world & water world.
|
||||||
|
} else if (
|
||||||
|
BodyCodes.earthLike.includes(bodyType)
|
||||||
|
|| BodyCodes.water.includes(bodyType)
|
||||||
|
) {
|
||||||
|
value = 64831
|
||||||
|
|
||||||
|
if (terraformState && terraformState > 0) {
|
||||||
|
terraformBonus = 116295
|
||||||
|
}
|
||||||
|
|
||||||
|
// Earth-like always gets a bonus.
|
||||||
|
if (BodyCodes.earthLike.includes(bodyType)) {
|
||||||
|
terraformBonus = 116295
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mapping multiplier.
|
||||||
|
let mapMultiplier: number = 3.3333333333
|
||||||
|
|
||||||
|
if (firstDiscover && firstMap) {
|
||||||
|
mapMultiplier = 3.699622554
|
||||||
|
|
||||||
|
} else if (!firstDiscover && firstMap) {
|
||||||
|
mapMultiplier = 8.0956
|
||||||
|
}
|
||||||
|
|
||||||
|
// Efficiency bonus.
|
||||||
|
mapMultiplier *= 1.25
|
||||||
|
|
||||||
|
// Final calculation.
|
||||||
|
const q = 0.56591828
|
||||||
|
value += terraformBonus
|
||||||
|
|
||||||
|
let finalValue = Math.max((value + (value * Math.pow(mass, 0.2) * q)) * mapMultiplier, 500)
|
||||||
|
|
||||||
|
// First discovery bonus.
|
||||||
|
if (firstDiscover) {
|
||||||
|
finalValue *= 2.6
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(finalValue)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -133,8 +133,8 @@ export class UI {
|
||||||
row.appendChild(info)
|
row.appendChild(info)
|
||||||
|
|
||||||
// mapped value
|
// mapped value
|
||||||
// TODO APPRAISAL DATA
|
|
||||||
const value = $('<div>').addClass(`col-2 text-end system ${chartedStyle}`)
|
const value = $('<div>').addClass(`col-2 text-end system ${chartedStyle}`)
|
||||||
|
value.text(UI.#formatNumber(body.mappedValue))
|
||||||
row.appendChild(value)
|
row.appendChild(value)
|
||||||
|
|
||||||
return row
|
return row
|
||||||
|
|
Loading…
Reference in a new issue