mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-06-21 00:52:47 +02:00
* Refactor evo conditions and descriptions * Fix test * Fix Shedinja * Simplify Gimmighoul evolution * Primeape and Stantler evolve by using their move 10 times * Basculin white stripe evolves by taking 294 recoil damage * Primeape and Stantler use modifiers for tracking * Basculin uses modifier too * Remove evo count from pokemon data * No more evo counter data, Gallade/Froslass * Fix allmoves import * Clamperl * Struggle shouldn't count for Basc recoil * Change to nicer type * Apply Benjie's suggestions Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> * Address formatting * Undo new evolution changes * Remove unused imports * Fix speciesid * Fixed up descriptions a little * Change a key name * Fix Gimmighoul * Apply Biome * Apply Biome unsafe fixes * Review suggestions - Convert `EvoCondKey` enum to `const` object - Use early returns in `SpeciesEvolutionCondition#description` and `SpeciesFormEvolution#description` - Replace `!!x.find` with `x.some` and `y.indexOf() > -1` with `y.includes()` - Implement `coerceArray` - Fix Shelmet evolution condition checking for Shelmet and not Karrablast - Remove unnecessary type casting in `battle-scene.ts` * Remove leftover enforce func loop * Fix circular imports issue - `getPokemonSpecies` moved to `src/utils/pokemon-utils.ts` - `allSpecies` moved to `src/data/data-lists.ts` --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
210 lines
7.9 KiB
TypeScript
210 lines
7.9 KiB
TypeScript
import { SettingKeys } from "#app/system/settings/settings";
|
|
import type { SystemSaveData, SessionSaveData } from "#app/system/game-data";
|
|
import { defaultStarterSpecies } from "#app/constants";
|
|
import { AbilityAttr } from "#enums/ability-attr";
|
|
import { DexAttr } from "#enums/dex-attr";
|
|
import { allSpecies } from "#app/data/data-lists";
|
|
import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
|
import { isNullOrUndefined } from "#app/utils/common";
|
|
import type { SystemSaveMigrator } from "#app/@types/SystemSaveMigrator";
|
|
import type { SettingsSaveMigrator } from "#app/@types/SettingsSaveMigrator";
|
|
import type { SessionSaveMigrator } from "#app/@types/SessionSaveMigrator";
|
|
|
|
/**
|
|
* Migrate ability starter data if empty for caught species.
|
|
* @param data - {@linkcode SystemSaveData}
|
|
*/
|
|
const migrateAbilityData: SystemSaveMigrator = {
|
|
version: "1.0.4",
|
|
migrate: (data: SystemSaveData): void => {
|
|
if (data.starterData && data.dexData) {
|
|
Object.keys(data.starterData).forEach(sd => {
|
|
if (data.dexData[sd]?.caughtAttr && data.starterData[sd] && !data.starterData[sd].abilityAttr) {
|
|
data.starterData[sd].abilityAttr = 1;
|
|
}
|
|
});
|
|
}
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Populate legendary Pokémon statistics if they are missing.
|
|
* @param data - {@linkcode SystemSaveData}
|
|
*/
|
|
const fixLegendaryStats: SystemSaveMigrator = {
|
|
version: "1.0.4",
|
|
migrate: (data: SystemSaveData): void => {
|
|
if (
|
|
data.gameStats &&
|
|
data.gameStats.legendaryPokemonCaught !== undefined &&
|
|
data.gameStats.subLegendaryPokemonCaught === undefined
|
|
) {
|
|
data.gameStats.subLegendaryPokemonSeen = 0;
|
|
data.gameStats.subLegendaryPokemonCaught = 0;
|
|
data.gameStats.subLegendaryPokemonHatched = 0;
|
|
allSpecies
|
|
.filter(s => s.subLegendary)
|
|
.forEach(s => {
|
|
const dexEntry = data.dexData[s.speciesId];
|
|
data.gameStats.subLegendaryPokemonSeen += dexEntry.seenCount;
|
|
data.gameStats.legendaryPokemonSeen = Math.max(data.gameStats.legendaryPokemonSeen - dexEntry.seenCount, 0);
|
|
data.gameStats.subLegendaryPokemonCaught += dexEntry.caughtCount;
|
|
data.gameStats.legendaryPokemonCaught = Math.max(
|
|
data.gameStats.legendaryPokemonCaught - dexEntry.caughtCount,
|
|
0,
|
|
);
|
|
data.gameStats.subLegendaryPokemonHatched += dexEntry.hatchedCount;
|
|
data.gameStats.legendaryPokemonHatched = Math.max(
|
|
data.gameStats.legendaryPokemonHatched - dexEntry.hatchedCount,
|
|
0,
|
|
);
|
|
});
|
|
data.gameStats.subLegendaryPokemonSeen = Math.max(
|
|
data.gameStats.subLegendaryPokemonSeen,
|
|
data.gameStats.subLegendaryPokemonCaught,
|
|
);
|
|
data.gameStats.legendaryPokemonSeen = Math.max(
|
|
data.gameStats.legendaryPokemonSeen,
|
|
data.gameStats.legendaryPokemonCaught,
|
|
);
|
|
data.gameStats.mythicalPokemonSeen = Math.max(
|
|
data.gameStats.mythicalPokemonSeen,
|
|
data.gameStats.mythicalPokemonCaught,
|
|
);
|
|
}
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Unlock all starters' first ability and female gender option.
|
|
* @param data - {@linkcode SystemSaveData}
|
|
*/
|
|
const fixStarterData: SystemSaveMigrator = {
|
|
version: "1.0.4",
|
|
migrate: (data: SystemSaveData): void => {
|
|
if (!isNullOrUndefined(data.starterData)) {
|
|
for (const starterId of defaultStarterSpecies) {
|
|
if (data.starterData[starterId]?.abilityAttr) {
|
|
data.starterData[starterId].abilityAttr |= AbilityAttr.ABILITY_1;
|
|
}
|
|
if (data.dexData[starterId]?.caughtAttr) {
|
|
data.dexData[starterId].caughtAttr |= DexAttr.FEMALE;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
export const systemMigrators: Readonly<SystemSaveMigrator[]> = [
|
|
migrateAbilityData,
|
|
fixLegendaryStats,
|
|
fixStarterData,
|
|
] as const;
|
|
|
|
/**
|
|
* Migrate from `REROLL_TARGET` property to {@linkcode SettingKeys.Shop_Cursor_Target}
|
|
* @param data - The `settings` object
|
|
*/
|
|
const fixRerollTarget: SettingsSaveMigrator = {
|
|
version: "1.0.4",
|
|
// biome-ignore lint/complexity/noBannedTypes: TODO - refactor settings
|
|
migrate: (data: Object): void => {
|
|
if (data.hasOwnProperty("REROLL_TARGET") && !data.hasOwnProperty(SettingKeys.Shop_Cursor_Target)) {
|
|
data[SettingKeys.Shop_Cursor_Target] = data["REROLL_TARGET"];
|
|
// biome-ignore lint/performance/noDelete: intentional
|
|
delete data["REROLL_TARGET"];
|
|
localStorage.setItem("settings", JSON.stringify(data));
|
|
}
|
|
},
|
|
};
|
|
|
|
export const settingsMigrators: Readonly<SettingsSaveMigrator[]> = [fixRerollTarget] as const;
|
|
|
|
/**
|
|
* Converts old lapsing modifiers (battle items, lures, and Dire Hit) and
|
|
* other miscellaneous modifiers (vitamins, White Herb) to any new class
|
|
* names and/or change in reload arguments.
|
|
* @param data - {@linkcode SessionSaveData}
|
|
*/
|
|
const migrateModifiers: SessionSaveMigrator = {
|
|
version: "1.0.4",
|
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: necessary?
|
|
migrate: (data: SessionSaveData): void => {
|
|
for (const m of data.modifiers) {
|
|
if (m.className === "PokemonBaseStatModifier") {
|
|
m.className = "BaseStatModifier";
|
|
} else if (m.className === "PokemonResetNegativeStatStageModifier") {
|
|
m.className = "ResetNegativeStatStageModifier";
|
|
} else if (m.className === "TempBattleStatBoosterModifier") {
|
|
const maxBattles = 5;
|
|
// Dire Hit no longer a part of the TempBattleStatBoosterModifierTypeGenerator
|
|
if (m.typeId !== "DIRE_HIT") {
|
|
m.className = "TempStatStageBoosterModifier";
|
|
m.typeId = "TEMP_STAT_STAGE_BOOSTER";
|
|
|
|
// Migration from TempBattleStat to Stat
|
|
const newStat = m.typePregenArgs[0] + 1;
|
|
m.typePregenArgs[0] = newStat;
|
|
|
|
// From [ stat, battlesLeft ] to [ stat, maxBattles, battleCount ]
|
|
m.args = [newStat, maxBattles, Math.min(m.args[1], maxBattles)];
|
|
} else {
|
|
m.className = "TempCritBoosterModifier";
|
|
m.typePregenArgs = [];
|
|
|
|
// From [ stat, battlesLeft ] to [ maxBattles, battleCount ]
|
|
m.args = [maxBattles, Math.min(m.args[1], maxBattles)];
|
|
}
|
|
} else if (m.className === "DoubleBattleChanceBoosterModifier" && m.args.length === 1) {
|
|
let maxBattles: number;
|
|
switch (m.typeId) {
|
|
case "MAX_LURE":
|
|
maxBattles = 30;
|
|
break;
|
|
case "SUPER_LURE":
|
|
maxBattles = 15;
|
|
break;
|
|
default:
|
|
maxBattles = 10;
|
|
break;
|
|
}
|
|
|
|
// From [ battlesLeft ] to [ maxBattles, battleCount ]
|
|
m.args = [maxBattles, Math.min(m.args[0], maxBattles)];
|
|
}
|
|
}
|
|
|
|
for (const m of data.enemyModifiers) {
|
|
if (m.className === "PokemonBaseStatModifier") {
|
|
m.className = "BaseStatModifier";
|
|
} else if (m.className === "PokemonResetNegativeStatStageModifier") {
|
|
m.className = "ResetNegativeStatStageModifier";
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
const migrateCustomPokemonData: SessionSaveMigrator = {
|
|
version: "1.0.4",
|
|
migrate: (data: SessionSaveData): void => {
|
|
// Fix Pokemon nature overrides and custom data migration
|
|
for (const pokemon of data.party) {
|
|
if (pokemon["mysteryEncounterPokemonData"]) {
|
|
pokemon.customPokemonData = new CustomPokemonData(pokemon["mysteryEncounterPokemonData"]);
|
|
pokemon["mysteryEncounterPokemonData"] = null;
|
|
}
|
|
if (pokemon["fusionMysteryEncounterPokemonData"]) {
|
|
pokemon.fusionCustomPokemonData = new CustomPokemonData(pokemon["fusionMysteryEncounterPokemonData"]);
|
|
pokemon["fusionMysteryEncounterPokemonData"] = null;
|
|
}
|
|
pokemon.customPokemonData = pokemon.customPokemonData ?? new CustomPokemonData();
|
|
if (!isNullOrUndefined(pokemon["natureOverride"]) && pokemon["natureOverride"] >= 0) {
|
|
pokemon.customPokemonData.nature = pokemon["natureOverride"];
|
|
pokemon["natureOverride"] = -1;
|
|
}
|
|
}
|
|
},
|
|
};
|
|
|
|
export const sessionMigrators: Readonly<SessionSaveMigrator[]> = [migrateModifiers, migrateCustomPokemonData] as const;
|