diff --git a/src/models/Body.ts b/src/models/Body.ts index c61e89d..c419d0c 100755 --- a/src/models/Body.ts +++ b/src/models/Body.ts @@ -1,4 +1,4 @@ -import type {valuableBody} from '../@types/edsmResponses'; +import type { valuableBody } from '../@types/edsmResponses'; import type { asteroidScan, autoScan, @@ -7,17 +7,19 @@ import type { starScan, } from '../@types/journalLines'; -import {BodyCodes} from '../data/BodyCodes'; +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 { DSSDone: boolean; mappedValue: number; constructor( - journalLine: autoScan | detailedScan | valuableBody | null = null, - DSS: boolean = false, + journalLine: autoScan|detailedScan|valuableBody|null = null, + DSS: boolean = false, ) { this.DSSDone = DSS; @@ -28,25 +30,25 @@ export class Body { this.mappedValue = this.#getValue(); } - /* -------------------------------------------------------------------------- isAsteroid ---- */ + /* ---------------------------------------------------------------------------- isAsteroid ---- */ isAsteroid(): boolean { return this.BodyName?.includes('Belt'); } - /* ---------------------------------------------------------------------------- isPlanet ---- */ + /* ------------------------------------------------------------------------------ isPlanet ---- */ isPlanet(): boolean { return !!this.PlanetClass; } - /* ------------------------------------------------------------------------------ isStar ---- */ + /* -------------------------------------------------------------------------------- isStar ---- */ isStar(): boolean { return !!this.StarType; } - /* ---------------------------------------------------------------------------- nameIcon ---- */ + /* ------------------------------------------------------------------------------ nameIcon ---- */ nameIcon(): string { let nameIcon: string = ''; @@ -62,13 +64,13 @@ export class Body { return nameIcon; } - /* -------------------------------------------------------------------------- simpleName ---- */ + /* ---------------------------------------------------------------------------- simpleName ---- */ simpleName(): string { return this.BodyName.replace(this.StarSystem, ''); } - /* ---------------------------------------------------------------------------- typeIcon ---- */ + /* ------------------------------------------------------------------------------ typeIcon ---- */ typeIcon(): string { let typeIcon: string = ''; @@ -96,51 +98,58 @@ export class Body { return typeIcon; } - /* ---------------------------------------------------------------------------- getValue ---- */ + /* ------------------------------------------------------------------------------ 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. + const bodyType = this.#getNumericalBodyType(); + const mass = 'MassEM' in this ? this.MassEM : 1; - 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; + let terraformState = this.#getNumericalTerraformState(); 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); + return this.#appraisePlanet(bodyType, mass, terraformState); } else { return 0; } } - /* ----------------------------------------------------------------------- #appraiseStar ---- */ + /* ----------------------------------------------------------------- #getNumericalBodyType ---- */ - #appraiseStar(bodyType: number | undefined, mass: number): number { + #getNumericalBodyType(): number|undefined { + let code: number|undefined; + + if (this.isStar()) { + // Typescript feels so stupid sometimes. + code = BodyCodes.starTypes[this.StarType as keyof typeof BodyCodes.starTypes]; + } else if (this.isPlanet()) { + code = BodyCodes.planetTypes[this.PlanetClass as keyof typeof BodyCodes.planetTypes]; + } + + return code; + } + + /* ----------------------------------------------------------- #getNumericalTerraformState ---- */ + + #getNumericalTerraformState(): number|undefined { + let terraformState: number|undefined; + + if ('TerraformState' in this) { + terraformState = + BodyCodes.terraformStates[this.TerraformState as keyof typeof BodyCodes.terraformStates]; + } + return terraformState; + } + + /* ------------------------------------------------------------------------- #appraiseStar ---- */ + + #appraiseStar(bodyType: number|undefined, mass: number): number { let value: number = 1200; if (bodyType) { @@ -154,108 +163,104 @@ export class Body { value = 22628; } else if (BodyCodes.superMassiveBlackHole.includes(bodyType)) { - value = 33.5678; // Not confirmed in game. + value = 33.5678; } } - return Math.round(value + ( - mass * value / 66.25 - )); + return Math.round(value + (mass * value / 66.25)); } - /* --------------------------------------------------------------------- #appraisePlanet ---- */ + /* ----------------------------------------------------------------------- #appraisePlanet ---- */ #appraisePlanet( - bodyType: number | undefined, + bodyType: number|undefined, mass: number, - terraformState: number | undefined, - firstDiscover: boolean, - firstMap: boolean, + terraformState: number|undefined, ): 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; + let value: number = this.#calculatePlanetBaseValue(bodyType); + let terraformBonus: number = this.#calculateTerraformBonus(bodyType, terraformState); + let mapMultiplier: number = this.#calculateMapMultiplier(); // Final calculation. const q = 0.56591828; value += terraformBonus; - let finalValue = Math.max(( - value + ( - value * Math.pow(mass, 0.2) * q - ) - ) * mapMultiplier, 500); + let finalValue = Math.max((value + (value * Math.pow(mass, 0.2) * q)) * mapMultiplier, 500); // First discovery bonus. - if (firstDiscover) { + if (!this.WasDiscovered) { finalValue *= 2.6; } return Math.round(finalValue); } + + /* ------------------------------------------------------------- #calculatePlanetBaseValue ---- */ + + #calculatePlanetBaseValue(bodyType: number|undefined): number { + let value: number = 300; + + if (bodyType) { + if (BodyCodes.metalRich.includes(bodyType)) { + value = 21790; + } else if (BodyCodes.ammonia.includes(bodyType)) { + value = 96932; + } else if (BodyCodes.classIGiant.includes(bodyType)) { + value = 1656; + } else if ( + BodyCodes.highMetalContent.includes(bodyType) + || BodyCodes.classIIGiant.includes(bodyType) + ) { + value = 9654; + } else if (BodyCodes.earthLike.includes(bodyType) || BodyCodes.water.includes(bodyType)) { + value = 64831; + } + } + + return value; + } + + /* -------------------------------------------------------------- #calculateTerraformBonus ---- */ + + #calculateTerraformBonus(bodyType: number|undefined, terraformState: number|undefined): number { + let bonus: number = 0; + + if (terraformState && terraformState > 0) { + bonus = 93328; + } + + if (bodyType && (terraformState && terraformState > 0)) { + if (BodyCodes.metalRich.includes(bodyType)) { + bonus = 65631; + } else if ( + BodyCodes.highMetalContent.includes(bodyType) + || BodyCodes.classIIGiant.includes(bodyType) + ) { + bonus = 100677; + } else if (BodyCodes.water.includes(bodyType)) { + bonus = 116295; + } + } else if (bodyType && BodyCodes.earthLike.includes(bodyType)) { + bonus = 116295; + } + + return bonus; + } + + /* --------------------------------------------------------------- #calculateMapMultiplier ---- */ + + #calculateMapMultiplier(): number { + let multiplier: number = 3.3333333333; + + if (!this.WasDiscovered && !this.WasMapped) { + multiplier = 3.699622554; + + } else if (this.WasDiscovered && !this.WasMapped) { + multiplier = 8.0956; + } + + // Efficiency bonus. + multiplier *= 1.25; + return multiplier; + } } diff --git a/src/models/Settings.ts b/src/models/Settings.ts index 51421c2..6deb71b 100644 --- a/src/models/Settings.ts +++ b/src/models/Settings.ts @@ -8,7 +8,6 @@ const {statSync, writeFileSync, readFileSync} = require('fs'); const ini = require('ini'); const os = require('node:os'); const path = require('node:path'); -const {setTimeout} = require('node:timers/promises'); const xmlJS = require('xml-js'); import {Log} from './Log';