diff --git a/sim/dex-abilities.ts b/sim/dex-abilities.ts index 882ec3ee71d7..c038d7c4b866 100644 --- a/sim/dex-abilities.ts +++ b/sim/dex-abilities.ts @@ -1,5 +1,5 @@ import type {PokemonEventMethods, ConditionData} from './dex-conditions'; -import {BasicEffect, toID} from './dex-data'; +import {assignMissingFields, BasicEffect, toID} from './dex-data'; import {Utils} from '../lib'; interface AbilityEventMethods { @@ -64,6 +64,7 @@ export class Ability extends BasicEffect implements Readonly { this.gen = 3; } } + assignMissingFields(this, data); } } diff --git a/sim/dex-conditions.ts b/sim/dex-conditions.ts index 9e95c69bd1fe..c7bd4be888d0 100644 --- a/sim/dex-conditions.ts +++ b/sim/dex-conditions.ts @@ -1,5 +1,5 @@ import {Utils} from '../lib'; -import {BasicEffect, toID} from './dex-data'; +import {assignMissingFields, BasicEffect, toID} from './dex-data'; import type {SecondaryEffect, MoveEventMethods} from './dex-moves'; export interface EventMethods { @@ -628,9 +628,8 @@ export class Condition extends BasicEffect implements constructor(data: AnyObject) { super(data); - // eslint-disable-next-line @typescript-eslint/no-this-alias - data = this; this.effectType = (['Weather', 'Status'].includes(data.effectType) ? data.effectType : 'Condition'); + assignMissingFields(this, data); } } diff --git a/sim/dex-data.ts b/sim/dex-data.ts index e6eea3d3496f..c52b0e90d3b8 100644 --- a/sim/dex-data.ts +++ b/sim/dex-data.ts @@ -34,7 +34,19 @@ export function toID(text: any): ID { /* eslint-enable @typescript-eslint/prefer-optional-chain */ } -export class BasicEffect implements EffectData { +/** + * Like Object.assign but only assigns fields missing from self. + * Facilitates consistent field ordering in constructors. + * Modifies self in-place. + */ +export function assignMissingFields(self: AnyObject, data: AnyObject) { + for (const k in data) { + if (k in self) continue; + self[k] = data[k]; + } +} + +export abstract class BasicEffect implements EffectData { /** * ID. This will be a lowercase version of the name with all the * non-alphanumeric characters removed. So, for instance, "Mr. Mime" @@ -102,14 +114,11 @@ export class BasicEffect implements EffectData { sourceEffect: string; constructor(data: AnyObject) { - this.exists = true; - Object.assign(this, data); - this.name = Utils.getString(data.name).trim(); this.id = data.realMove ? toID(data.realMove) : toID(this.name); // Hidden Power hack this.fullname = Utils.getString(data.fullname) || this.name; this.effectType = Utils.getString(data.effectType) as EffectType || 'Condition'; - this.exists = !!(this.exists && this.id); + this.exists = data.exists ?? !!this.id; this.num = data.num || 0; this.gen = data.gen || 0; this.shortDesc = data.shortDesc || ''; @@ -134,14 +143,12 @@ export class Nature extends BasicEffect implements Readonly { readonly HPdvs: SparseStatsTable; constructor(data: AnyObject) { - this.exists = true; - Object.assign(this, data); - this.name = data.name; this.id = data.id; this.effectType = Utils.getString(data.effectType) as TypeInfoEffectType || 'Type'; - this.exists = !!(this.exists && this.id); + this.exists = data.exists ?? !!this.id; this.gen = data.gen || 0; this.isNonstandard = data.isNonstandard || null; this.damageTaken = data.damageTaken || {}; this.HPivs = data.HPivs || {}; this.HPdvs = data.HPdvs || {}; + assignMissingFields(this, data); } toString() { diff --git a/sim/dex-formats.ts b/sim/dex-formats.ts index a70619fa877b..2e160117f2c4 100644 --- a/sim/dex-formats.ts +++ b/sim/dex-formats.ts @@ -1,5 +1,5 @@ import {Utils} from '../lib'; -import {toID, BasicEffect} from './dex-data'; +import {assignMissingFields, toID, BasicEffect} from './dex-data'; import {EventMethods} from './dex-conditions'; import {SpeciesData} from './dex-species'; import {Tags} from '../data/tags'; @@ -478,8 +478,6 @@ export class Format extends BasicEffect implements Readonly { constructor(data: AnyObject) { super(data); - // eslint-disable-next-line @typescript-eslint/no-this-alias - data = this; this.mod = Utils.getString(data.mod) || 'gen9'; this.effectType = Utils.getString(data.effectType) as FormatEffectType || 'Format'; @@ -496,6 +494,7 @@ export class Format extends BasicEffect implements Readonly { this.onBegin = data.onBegin || undefined; this.noLog = !!data.noLog; this.playerCount = (this.gameType === 'multi' || this.gameType === 'freeforall' ? 4 : 2); + assignMissingFields(this, data); } } diff --git a/sim/dex-items.ts b/sim/dex-items.ts index 828a44f4f8d3..9c175d72fde8 100644 --- a/sim/dex-items.ts +++ b/sim/dex-items.ts @@ -1,5 +1,5 @@ import type {PokemonEventMethods, ConditionData} from './dex-conditions'; -import {BasicEffect, toID} from './dex-data'; +import {assignMissingFields, BasicEffect, toID} from './dex-data'; import {Utils} from '../lib'; interface FlingData { @@ -107,8 +107,6 @@ export class Item extends BasicEffect implements Readonly { constructor(data: AnyObject) { super(data); - // eslint-disable-next-line @typescript-eslint/no-this-alias - data = this; this.fullname = `item: ${this.name}`; this.effectType = 'Item'; @@ -152,6 +150,8 @@ export class Item extends BasicEffect implements Readonly { if (this.onDrive) this.fling = {basePower: 70}; if (this.megaStone) this.fling = {basePower: 80}; if (this.onMemory) this.fling = {basePower: 50}; + + assignMissingFields(this, data); } } diff --git a/sim/dex-moves.ts b/sim/dex-moves.ts index dcd66b11039a..7853c5e2135d 100644 --- a/sim/dex-moves.ts +++ b/sim/dex-moves.ts @@ -1,6 +1,6 @@ import {Utils} from '../lib'; import type {ConditionData} from './dex-conditions'; -import {BasicEffect, toID} from './dex-data'; +import {assignMissingFields, BasicEffect, toID} from './dex-data'; /** * Describes the acceptable target(s) of a move. @@ -481,8 +481,6 @@ export class DataMove extends BasicEffect implements Readonly= 140) { @@ -611,6 +609,7 @@ export class DataMove extends BasicEffect implements Readonly= 1) { if (this.num >= 906 || this.forme.includes('Paldea')) { @@ -353,6 +351,7 @@ export class Species extends BasicEffect implements Readonly