Refactoring: Body.
This commit is contained in:
parent
87779e88ab
commit
5f374f0657
2 changed files with 126 additions and 122 deletions
|
@ -1,4 +1,4 @@
|
||||||
import type {valuableBody} from '../@types/edsmResponses';
|
import type { valuableBody } from '../@types/edsmResponses';
|
||||||
import type {
|
import type {
|
||||||
asteroidScan,
|
asteroidScan,
|
||||||
autoScan,
|
autoScan,
|
||||||
|
@ -7,17 +7,19 @@ import type {
|
||||||
starScan,
|
starScan,
|
||||||
} from '../@types/journalLines';
|
} 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 {
|
export class Body {
|
||||||
DSSDone: boolean;
|
DSSDone: boolean;
|
||||||
mappedValue: number;
|
mappedValue: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
journalLine: autoScan | detailedScan | valuableBody | null = null,
|
journalLine: autoScan|detailedScan|valuableBody|null = null,
|
||||||
DSS: boolean = false,
|
DSS: boolean = false,
|
||||||
) {
|
) {
|
||||||
this.DSSDone = DSS;
|
this.DSSDone = DSS;
|
||||||
|
|
||||||
|
@ -28,25 +30,25 @@ export class Body {
|
||||||
this.mappedValue = this.#getValue();
|
this.mappedValue = this.#getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- isAsteroid ---- */
|
/* ---------------------------------------------------------------------------- isAsteroid ---- */
|
||||||
|
|
||||||
isAsteroid(): boolean {
|
isAsteroid(): boolean {
|
||||||
return this.BodyName?.includes('Belt');
|
return this.BodyName?.includes('Belt');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- isPlanet ---- */
|
/* ------------------------------------------------------------------------------ isPlanet ---- */
|
||||||
|
|
||||||
isPlanet(): boolean {
|
isPlanet(): boolean {
|
||||||
return !!this.PlanetClass;
|
return !!this.PlanetClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------ isStar ---- */
|
/* -------------------------------------------------------------------------------- isStar ---- */
|
||||||
|
|
||||||
isStar(): boolean {
|
isStar(): boolean {
|
||||||
return !!this.StarType;
|
return !!this.StarType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- nameIcon ---- */
|
/* ------------------------------------------------------------------------------ nameIcon ---- */
|
||||||
|
|
||||||
nameIcon(): string {
|
nameIcon(): string {
|
||||||
let nameIcon: string = '';
|
let nameIcon: string = '';
|
||||||
|
@ -62,13 +64,13 @@ export class Body {
|
||||||
return nameIcon;
|
return nameIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- simpleName ---- */
|
/* ---------------------------------------------------------------------------- simpleName ---- */
|
||||||
|
|
||||||
simpleName(): string {
|
simpleName(): string {
|
||||||
return this.BodyName.replace(this.StarSystem, '');
|
return this.BodyName.replace(this.StarSystem, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- typeIcon ---- */
|
/* ------------------------------------------------------------------------------ typeIcon ---- */
|
||||||
|
|
||||||
typeIcon(): string {
|
typeIcon(): string {
|
||||||
let typeIcon: string = '';
|
let typeIcon: string = '';
|
||||||
|
@ -96,51 +98,58 @@ export class Body {
|
||||||
return typeIcon;
|
return typeIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------- getValue ---- */
|
/* ------------------------------------------------------------------------------ getValue ---- */
|
||||||
|
|
||||||
// https://forums.frontier.co.uk/threads/exploration-value-formulae.232000/
|
// https://forums.frontier.co.uk/threads/exploration-value-formulae.232000/
|
||||||
// https://github.com/EDSM-NET/Component/blob/master/Body/Value.php
|
// https://github.com/EDSM-NET/Component/blob/master/Body/Value.php
|
||||||
|
|
||||||
#getValue(): number {
|
#getValue(): number {
|
||||||
let bodyType: number | undefined = undefined; // Asteroids.
|
const bodyType = this.#getNumericalBodyType();
|
||||||
|
const mass = 'MassEM' in this ? this.MassEM : 1;
|
||||||
|
|
||||||
if (this.isStar()) {
|
let terraformState = this.#getNumericalTerraformState();
|
||||||
// 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()) {
|
if (this.isStar()) {
|
||||||
return this.#appraiseStar(bodyType, mass);
|
return this.#appraiseStar(bodyType, mass);
|
||||||
|
|
||||||
} else if (this.isPlanet() || this.isAsteroid()) {
|
} else if (this.isPlanet() || this.isAsteroid()) {
|
||||||
// Asteroids are treated as planets for the purpose of value calculation.
|
return this.#appraisePlanet(bodyType, mass, terraformState);
|
||||||
return this.#appraisePlanet(bodyType, mass, terraformState, firstDiscover, firstMap);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
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;
|
let value: number = 1200;
|
||||||
|
|
||||||
if (bodyType) {
|
if (bodyType) {
|
||||||
|
@ -154,108 +163,104 @@ export class Body {
|
||||||
value = 22628;
|
value = 22628;
|
||||||
|
|
||||||
} else if (BodyCodes.superMassiveBlackHole.includes(bodyType)) {
|
} else if (BodyCodes.superMassiveBlackHole.includes(bodyType)) {
|
||||||
value = 33.5678; // Not confirmed in game.
|
value = 33.5678;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.round(value + (
|
return Math.round(value + (mass * value / 66.25));
|
||||||
mass * value / 66.25
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- #appraisePlanet ---- */
|
/* ----------------------------------------------------------------------- #appraisePlanet ---- */
|
||||||
|
|
||||||
#appraisePlanet(
|
#appraisePlanet(
|
||||||
bodyType: number | undefined,
|
bodyType: number|undefined,
|
||||||
mass: number,
|
mass: number,
|
||||||
terraformState: number | undefined,
|
terraformState: number|undefined,
|
||||||
firstDiscover: boolean,
|
|
||||||
firstMap: boolean,
|
|
||||||
): number {
|
): number {
|
||||||
|
let value: number = this.#calculatePlanetBaseValue(bodyType);
|
||||||
// Base value & terraform bonus calculation.
|
let terraformBonus: number = this.#calculateTerraformBonus(bodyType, terraformState);
|
||||||
let value: number = 300;
|
let mapMultiplier: number = this.#calculateMapMultiplier();
|
||||||
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.
|
// Final calculation.
|
||||||
const q = 0.56591828;
|
const q = 0.56591828;
|
||||||
value += terraformBonus;
|
value += terraformBonus;
|
||||||
|
|
||||||
let finalValue = Math.max((
|
let finalValue = Math.max((value + (value * Math.pow(mass, 0.2) * q)) * mapMultiplier, 500);
|
||||||
value + (
|
|
||||||
value * Math.pow(mass, 0.2) * q
|
|
||||||
)
|
|
||||||
) * mapMultiplier, 500);
|
|
||||||
|
|
||||||
// First discovery bonus.
|
// First discovery bonus.
|
||||||
if (firstDiscover) {
|
if (!this.WasDiscovered) {
|
||||||
finalValue *= 2.6;
|
finalValue *= 2.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.round(finalValue);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ const {statSync, writeFileSync, readFileSync} = require('fs');
|
||||||
const ini = require('ini');
|
const ini = require('ini');
|
||||||
const os = require('node:os');
|
const os = require('node:os');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const {setTimeout} = require('node:timers/promises');
|
|
||||||
const xmlJS = require('xml-js');
|
const xmlJS = require('xml-js');
|
||||||
|
|
||||||
import {Log} from './Log';
|
import {Log} from './Log';
|
||||||
|
|
Loading…
Reference in a new issue