diff --git a/src/battle-scene.ts b/src/battle-scene.ts index f117615e5db..39fd4d6577a 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -17,7 +17,7 @@ import { TextStyle, addTextObject } from './ui/text'; import { Moves } from "./data/enums/moves"; import { allMoves } from "./data/move"; import { initMoves } from './data/move'; -import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue } from './modifier/modifier-type'; +import { ModifierPoolType, getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getLuckString, getLuckTextTint, getModifierPoolForType, getPartyLuckValue, modifierTypes, getModifierType } from './modifier/modifier-type'; import AbilityBar from './ui/ability-bar'; import { BlockItemTheftAbAttr, DoubleBattleChanceAbAttr, IncrementMovePriorityAbAttr, applyAbAttrs, initAbilities } from './data/ability'; import { Abilities } from "./data/enums/abilities"; @@ -59,7 +59,7 @@ import { SceneBase } from './scene-base'; import CandyBar from './ui/candy-bar'; import { Variant, variantData } from './data/variant'; import { Localizable } from './plugins/i18n'; -import { STARTING_WAVE_OVERRIDE, OPP_SPECIES_OVERRIDE, SEED_OVERRIDE, STARTING_BIOME_OVERRIDE, DOUBLE_BATTLE_OVERRIDE } from './overrides'; +import { STARTING_WAVE_OVERRIDE, OPP_SPECIES_OVERRIDE, SEED_OVERRIDE, STARTING_BIOME_OVERRIDE, DOUBLE_BATTLE_OVERRIDE, OPP_MODIFIER_OVERRIDE, OPP_MODIFIER_QTY_OVERRIDE } from './overrides'; import {InputsController} from "./inputs-controller"; import {UiInputs} from "./ui-inputs"; @@ -615,6 +615,16 @@ export default class BattleScene extends SceneBase { if (OPP_SPECIES_OVERRIDE) species = getPokemonSpecies(OPP_SPECIES_OVERRIDE); const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource); + // we get the modifiers override for the opponent + const modifiersOverride = this.getEnemyModifiersOverride(); + // if we have some modifiers override, apply them to the opponent + if (modifiersOverride?.length) { + // we delete all previous modifiers to avoid stack of override + this.enemyModifiers = []; + for (const m of modifiersOverride) { + this.addEnemyModifier(getModifierType(modifierTypes[m]).newModifier(pokemon) as PersistentModifier, true, true); + } + } if (boss && !dataSource) { const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295)); @@ -1723,6 +1733,24 @@ export default class BattleScene extends SceneBase { }); } + getEnemyModifiersOverride(): Array { + // if no override, do nothing + const ret = []; + if (!OPP_MODIFIER_OVERRIDE || OPP_MODIFIER_OVERRIDE.length === 0) return ret; + // we loop through all the modifier name given in the override file + for (const [index, modifierName] of OPP_MODIFIER_OVERRIDE.entries()) { + // if the modifier does not exist, we skip it + if (!modifierTypes.hasOwnProperty(modifierName)) continue; + // We get how many modifiers, if none given, default to 1 + const qty = OPP_MODIFIER_QTY_OVERRIDE[index] || 1 + // for example, if qty is 2, we create an array of size 2 with the modifier on each slot + for (const i of [...Array(qty).keys()]) { + ret.push(modifierName); + } + } + return ret; + } + generateEnemyModifiers(): Promise { return new Promise(resolve => { if (this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS) diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index c5ebb950c54..82757e080d6 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -19,7 +19,7 @@ import { VoucherType } from '../system/voucher'; import { FormChangeItem, SpeciesFormChangeItemTrigger } from '../data/pokemon-forms'; import { Nature } from '#app/data/nature'; import { BattlerTagType } from '#app/data/enums/battler-tag-type'; -import { OPP_HELD_ITEMS_OVERRIDE, STARTING_HELD_ITEMS_OVERRIDE } from "../overrides"; +import { STARTING_MODIFIER_OVERRIDE, STARTING_MODIFIER_QTY_OVERRIDE, OPP_HELD_ITEMS_OVERRIDE, STARTING_HELD_ITEMS_OVERRIDE } from "../overrides"; import { modifierTypes } from "./modifier-type"; type ModifierType = ModifierTypes.ModifierType; @@ -2179,6 +2179,25 @@ export class EnemyFusionChanceModifier extends EnemyPersistentModifier { } } +export function getModifierOverride(): Modifier[] { + // if no override, do nothing + const modifiers: Modifier[] = new Array(); + if (!STARTING_MODIFIER_OVERRIDE || STARTING_MODIFIER_OVERRIDE.length === 0) return modifiers; + // we loop through all the modifier name given in the override file + for (const [index, modifierName] of STARTING_MODIFIER_OVERRIDE.entries()) { + // if the modifier does not exist, we skip it + if (!modifierTypes.hasOwnProperty(modifierName)) continue; + const modifierType = modifierTypes[modifierName](); + // We get how many modifiers, if none given, default to 1 + const qty = STARTING_MODIFIER_QTY_OVERRIDE[index] || 1 + for (const i of [...Array(qty).keys()]) { + // for example, if qty is 2, we create an array of size 2 with the modifier on each slot + modifiers.push(modifierType.withIdFromFunc(modifierTypes[modifierName]).newModifier()); + } + } + return modifiers; +} + export function startingItemHeldsOverride(pokemon: Pokemon): Modifier[] { const ret: Modifier[] = new Array(); // if no override, do nothing diff --git a/src/overrides.ts b/src/overrides.ts index 97ad8518c58..d4557fa33e9 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -11,6 +11,8 @@ export const STARTING_LEVEL_OVERRIDE = 0; export const STARTING_WAVE_OVERRIDE = 0; export const STARTING_BIOME_OVERRIDE = Biome.TOWN; export const STARTING_MONEY_OVERRIDE = 0; +export const STARTING_MODIFIER_OVERRIDE = []; // ['EXP_SHARE', 'GOLDEN_EXP_CHARM'] +export const STARTING_MODIFIER_QTY_OVERRIDE = []; // [5, 10]; export const WEATHER_OVERRIDE = WeatherType.NONE; export const DOUBLE_BATTLE_OVERRIDE = false; export const STARTING_HELD_ITEMS_OVERRIDE = ['REVIVER_SEED']; @@ -25,6 +27,8 @@ export const OPP_PASSIVE_ABILITY_OVERRIDE = Abilities.NONE; export const OPP_MOVE_OVERRIDE = Moves.NONE; export const OPP_MOVE_OVERRIDE_2 = Moves.NONE; export const OPP_HELD_ITEMS_OVERRIDE = ['LUCKY_EGG']; +export const OPP_MODIFIER_OVERRIDE = []; // ['ENEMY_DAMAGE_REDUCTION', 'ENEMY_ATTACK_POISON_CHANCE'] +export const OPP_MODIFIER_QTY_OVERRIDE = []; // [1, 1]; export const OPP_SHINY_OVERRIDE = false; export const OPP_VARIANT_OVERRIDE = 0; diff --git a/src/phases.ts b/src/phases.ts index a03d66ff720..5682f0a24d9 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -6,7 +6,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov import { Mode } from './ui/ui'; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./data/pokemon-stat"; -import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier, startingItemHeldsOverride, opponentItemHeldsOverride } from "./modifier/modifier"; +import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, PokemonMoveAccuracyBoosterModifier, getModifierOverride, startingItemHeldsOverride, opponentItemHeldsOverride } from "./modifier/modifier"; import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball"; import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims"; @@ -516,6 +516,15 @@ export class SelectStarterPhase extends Phase { this.scene.addModifier(itemHeldOverride, true, false, false, true); } } + // we get the modifiers override + const modifiersOverride = getModifierOverride(); + // if we have some modifiers override, apply them to the player + if (modifiersOverride?.length) { + for (const m of modifiersOverride) { + this.scene.addModifier(m, true, false, false, true); + } + this.scene.updateModifiers(true, true); + } Promise.all(loadPokemonAssets).then(() => { SoundFade.fadeOut(this.scene, this.scene.sound.get('menu'), 500, true); this.scene.time.delayedCall(500, () => this.scene.playBgm());