From a3b36910845ed0b41489dac335e8974e7c556e0e Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 04:37:48 -0400 Subject: [PATCH 1/7] Implemented Repels --- .env.development | 2 +- package-lock.json | 38 --------- src/battle-scene.ts | 129 +++++++++++++++--------------- src/modifier/modifier-type.ts | 143 +++++++++++++++++++--------------- src/modifier/modifier.ts | 26 +++++++ 5 files changed, 174 insertions(+), 164 deletions(-) diff --git a/.env.development b/.env.development index 88dcdce61..4ce9e53b2 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,2 @@ VITE_BYPASS_LOGIN=1 -VITE_BYPASS_TUTORIAL=0 \ No newline at end of file +VITE_BYPASS_TUTORIAL=1 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7db944a45..565eac97e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2565,33 +2565,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/happy-dom": { - "version": "14.3.9", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.3.9.tgz", - "integrity": "sha512-0kPQchwthekcYpYN8CvCiq+/z5bqFYDLbTxZ+yDLwT8AFRVJDFadShHRxp3VAZRy7a5isOZ1j/LzsU1dtAIZMQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "entities": "^4.5.0", - "webidl-conversions": "^7.0.0", - "whatwg-mimetype": "^3.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/happy-dom/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5802,17 +5775,6 @@ "node": ">=0.10.0" } }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - } - }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", diff --git a/src/battle-scene.ts b/src/battle-scene.ts index cbf363f68..a8a9bf59d 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -4,7 +4,7 @@ import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePh import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon'; import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies, initSpecies, speciesStarters } from './data/pokemon-species'; import * as Utils from './utils'; -import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier } from './modifier/modifier'; +import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, DoubleBattleChancePreventerModifier } from './modifier/modifier'; import { PokeballType } from './data/pokeball'; import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from './data/battle-anims'; import { Phase } from './phase'; @@ -124,7 +124,7 @@ export default class BattleScene extends SceneBase { public gamepadSupport: boolean = true; public enableTouchControls: boolean = false; public enableVibration: boolean = false; - + public disableMenu: boolean = false; public gameData: GameData; @@ -189,14 +189,14 @@ export default class BattleScene extends SceneBase { private bgmResumeTimer: Phaser.Time.TimerEvent; private bgmCache: Set = new Set(); private playTimeTimer: Phaser.Time.TimerEvent; - + private buttonKeys: Phaser.Input.Keyboard.Key[][]; private lastProcessedButtonPressTimes: Map = new Map(); // movementButtonLock ensures only a single movement key is firing repeated inputs // (i.e. by holding down a button) at a time private movementButtonLock: Button; - // using a dualshock controller as a map + // using a dualshock controller as a map private gamepadKeyConfig = { [Button.UP]: 12, // up [Button.DOWN]: 13, // down @@ -228,7 +228,7 @@ export default class BattleScene extends SceneBase { initSpecies(); initMoves(); initAbilities(); - + this.phaseQueue = []; this.phaseQueuePrepend = []; this.phaseQueuePrependSpliceIndex = -1; @@ -243,7 +243,7 @@ export default class BattleScene extends SceneBase { experimental = this.hasExpSprite(key); if (variant) atlasPath = atlasPath.replace('variant/', ''); - this.load.atlas(key, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.png`, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.json`); + this.load.atlas(key, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.png`, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.json`); } async preload() { @@ -251,8 +251,8 @@ export default class BattleScene extends SceneBase { const scene = this; const originalRealInRange = Phaser.Math.RND.realInRange; Phaser.Math.RND.realInRange = function (min: number, max: number): number { - const ret = originalRealInRange.apply(this, [ min, max ]); - const args = [ 'RNG', ++scene.rngCounter, ret / (max - min), `min: ${min} / max: ${max}` ]; + const ret = originalRealInRange.apply(this, [min, max]); + const args = ['RNG', ++scene.rngCounter, ret / (max - min), `min: ${min} / max: ${max}`]; args.push(`seed: ${scene.rngSeedOverride || scene.waveSeed || scene.seed}`); if (scene.rngOffset) args.push(`offset: ${scene.rngOffset}`); @@ -260,7 +260,7 @@ export default class BattleScene extends SceneBase { return ret; }; } - + populateAnims(); await this.initVariantData(); @@ -295,7 +295,7 @@ export default class BattleScene extends SceneBase { this.arenaBg = this.add.sprite(0, 0, 'plains_bg'); this.arenaBgTransition = this.add.sprite(0, 0, 'plains_bg'); - [ this.arenaBgTransition, this.arenaBg ].forEach(a => { + [this.arenaBgTransition, this.arenaBg].forEach(a => { a.setPipeline(this.fieldSpritePipeline); a.setScale(6); a.setOrigin(0); @@ -427,7 +427,7 @@ export default class BattleScene extends SceneBase { this.arenaPlayerTransition.setVisible(false); this.arenaNextEnemy.setVisible(false); - [ this.arenaPlayer, this.arenaPlayerTransition, this.arenaEnemy, this.arenaNextEnemy ].forEach(a => { + [this.arenaPlayer, this.arenaPlayerTransition, this.arenaEnemy, this.arenaNextEnemy].forEach(a => { if (a instanceof Phaser.GameObjects.Sprite) a.setOrigin(0, 0); field.add(a); @@ -466,12 +466,12 @@ export default class BattleScene extends SceneBase { ui.setup(); - const defaultMoves = [ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ]; + const defaultMoves = [Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE]; Promise.all([ Promise.all(loadPokemonAssets), initCommonAnims(this).then(() => loadCommonAnimAssets(this, true)), - Promise.all([ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ].map(m => initMoveAnim(this, m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)), + Promise.all([Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE].map(m => initMoveAnim(this, m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)), this.initStarterColors() ]).then(() => { this.pushPhase(new LoginPhase(this)); @@ -491,7 +491,7 @@ export default class BattleScene extends SceneBase { this.playTimeTimer = this.time.addEvent({ delay: Utils.fixedInt(1000), repeat: -1, - callback: () => { + callback: () => { if (this.gameData) this.gameData.gameStats.playTime++; if (this.sessionPlayTime !== null) @@ -529,14 +529,14 @@ export default class BattleScene extends SceneBase { variantTree = variantTree[k]; expTree = expTree[k]; } else if (variantTree.hasOwnProperty(k) && expTree.hasOwnProperty(k)) { - if ([ 'back', 'female' ].includes(k)) + if (['back', 'female'].includes(k)) traverseVariantData(keys.concat(k)); else variantTree[k] = expTree[k]; } }); }; - Object.keys(expVariantData).forEach(ek => traverseVariantData([ ek ])); + Object.keys(expVariantData).forEach(ek => traverseVariantData([ek])); } Promise.resolve(); }); @@ -710,9 +710,9 @@ export default class BattleScene extends SceneBase { addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container { const container = this.add.container(x, y); - + const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride)); - icon.setFrame(pokemon.getIconId(true)); + icon.setFrame(pokemon.getIconId(true)); icon.setOrigin(0.5, 0); container.add(icon); @@ -727,7 +727,7 @@ export default class BattleScene extends SceneBase { const originalFrame = icon.frame; const iconHeight = (icon.frame.cutHeight <= fusionIcon.frame.cutHeight ? Math.ceil : Math.floor)((icon.frame.cutHeight + fusionIcon.frame.cutHeight) / 4); - + // Inefficient, but for some reason didn't work with only the unique properties as part of the name const iconFrameId = `${icon.frame.name}f${fusionIcon.frame.name}`; @@ -785,7 +785,7 @@ export default class BattleScene extends SceneBase { this.gameData = new GameData(this); this.gameMode = gameModes[GameModes.CLASSIC]; - + this.setSeed(SEED_OVERRIDE || Utils.randomString(24)); console.log('Seed:', this.seed); @@ -796,7 +796,7 @@ export default class BattleScene extends SceneBase { this.lockModifierTiers = false; - this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ])); + this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [t, 0])); this.pokeballCounts[PokeballType.POKEBALL] += 5; this.modifiers = []; @@ -809,7 +809,7 @@ export default class BattleScene extends SceneBase { this.party = []; for (let p of this.getEnemyParty()) p.destroy(); - + this.currentBattle = null; this.waveCountText.setText(startingWave.toString()); @@ -821,14 +821,14 @@ export default class BattleScene extends SceneBase { this.updateScoreText(); this.scoreText.setVisible(false); - [ this.luckLabelText, this.luckText ].map(t => t.setVisible(false)); + [this.luckLabelText, this.luckText].map(t => t.setVisible(false)); this.newArena(STARTING_BIOME_OVERRIDE || Biome.TOWN); this.arenaBgTransition.setPosition(0, 0); this.arenaPlayer.setPosition(300, 0); this.arenaPlayerTransition.setPosition(0, 0); - [ this.arenaEnemy, this.arenaNextEnemy ].forEach(a => a.setPosition(-280, 0)); + [this.arenaEnemy, this.arenaNextEnemy].forEach(a => a.setPosition(-280, 0)); this.arenaNextEnemy.setVisible(false); this.arena.init(); @@ -854,7 +854,7 @@ export default class BattleScene extends SceneBase { this.fadeOutBgm(250, false); this.tweens.add({ - targets: [ this.uiContainer ], + targets: [this.uiContainer], alpha: 0, duration: 250, ease: 'Sine.easeInOut', @@ -870,6 +870,9 @@ export default class BattleScene extends SceneBase { } newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean): Battle { + if (this.getModifiers(DoubleBattleChancePreventerModifier) != null) { + double = false; + } let newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1); let newDouble: boolean; let newBattleType: BattleType; @@ -880,7 +883,7 @@ export default class BattleScene extends SceneBase { this.resetSeed(newWaveIndex); const playerField = this.getPlayerField(); - + if (this.gameMode.hasFixedBattles && fixedBattles.hasOwnProperty(newWaveIndex) && trainerData === undefined) { battleConfig = fixedBattles[newWaveIndex]; newDouble = battleConfig.double; @@ -988,7 +991,7 @@ export default class BattleScene extends SceneBase { this.pushPhase(new LevelCapPhase(this)); } } - + return this.currentBattle; } @@ -1070,7 +1073,7 @@ export default class BattleScene extends SceneBase { case Species.OINKOLOGNE: return gender === Gender.FEMALE ? 1 : 0; case Species.TOXTRICITY: - const lowkeyNatures = [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ]; + const lowkeyNatures = [Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL]; if (nature !== undefined && lowkeyNatures.indexOf(nature) > -1) return 1; return 0; @@ -1147,7 +1150,7 @@ export default class BattleScene extends SceneBase { party.forEach((pokemon, p) => { if (!pokemon.pokerus || infectedIndexes.indexOf(p) > -1) return; - + this.executeWithSeedOffset(() => { if (p) spread(p, -1); @@ -1160,7 +1163,7 @@ export default class BattleScene extends SceneBase { resetSeed(waveIndex?: integer): void { const wave = waveIndex || this.currentBattle?.waveIndex || 0; this.waveSeed = Utils.shiftCharCodes(this.seed, wave); - Phaser.Math.RND.sow([ this.waveSeed ]); + Phaser.Math.RND.sow([this.waveSeed]); console.log('Wave Seed:', this.waveSeed, wave); this.rngCounter = 0; } @@ -1172,7 +1175,7 @@ export default class BattleScene extends SceneBase { const tempRngOffset = this.rngOffset; const tempRngSeedOverride = this.rngSeedOverride; const state = Phaser.Math.RND.state(); - Phaser.Math.RND.sow([ Utils.shiftCharCodes(seedOverride || this.seed, offset) ]); + Phaser.Math.RND.sow([Utils.shiftCharCodes(seedOverride || this.seed, offset)]); this.rngCounter = 0; this.rngOffset = offset; this.rngSeedOverride = seedOverride || ''; @@ -1199,7 +1202,7 @@ export default class BattleScene extends SceneBase { } initPokemonSprite(sprite: Phaser.GameObjects.Sprite, pokemon?: Pokemon, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite { - sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined }); + sprite.setPipeline(this.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined }); this.spriteSparkleHandler.add(sprite); return sprite; } @@ -1247,7 +1250,7 @@ export default class BattleScene extends SceneBase { } updateAndShowLuckText(duration: integer): void { - const labels = [ this.luckLabelText, this.luckText ]; + const labels = [this.luckLabelText, this.luckText]; labels.map(t => { t.setAlpha(0); t.setVisible(true); @@ -1267,7 +1270,7 @@ export default class BattleScene extends SceneBase { } hideLuckText(duration: integer): void { - const labels = [ this.luckLabelText, this.luckText ]; + const labels = [this.luckLabelText, this.luckText]; this.tweens.add({ targets: labels, duration: duration, @@ -1283,7 +1286,7 @@ export default class BattleScene extends SceneBase { this.waveCountText.setY(-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0)); this.moneyText.setY(this.waveCountText.y + 10); this.scoreText.setY(this.moneyText.y + 10); - [ this.luckLabelText, this.luckText ].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10)); + [this.luckLabelText, this.luckText].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10)); const offsetY = (this.scoreText.visible ? this.scoreText : this.moneyText).y + 15; this.partyExpBar.setY(offsetY); this.candyBar.setY(offsetY + 15); @@ -1368,7 +1371,7 @@ export default class BattleScene extends SceneBase { } else if (this.buttonJustPressed(Button.ACTION) || this.repeatInputDurationJustPassed(Button.ACTION)) { inputSuccess = this.ui.processInput(Button.ACTION); this.setLastProcessedMovementTime(Button.ACTION); - } else if (this.buttonJustPressed(Button.CANCEL)|| this.repeatInputDurationJustPassed(Button.CANCEL)) { + } else if (this.buttonJustPressed(Button.CANCEL) || this.repeatInputDurationJustPassed(Button.CANCEL)) { inputSuccess = this.ui.processInput(Button.CANCEL); this.setLastProcessedMovementTime(Button.CANCEL); } else if (this.buttonJustPressed(Button.MENU)) { @@ -1405,25 +1408,25 @@ export default class BattleScene extends SceneBase { } else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) { if (this.buttonJustPressed(Button.CYCLE_SHINY)) { inputSuccess = this.ui.processInput(Button.CYCLE_SHINY); - this.setLastProcessedMovementTime(Button.CYCLE_SHINY); + this.setLastProcessedMovementTime(Button.CYCLE_SHINY); } else if (this.buttonJustPressed(Button.CYCLE_FORM)) { inputSuccess = this.ui.processInput(Button.CYCLE_FORM); - this.setLastProcessedMovementTime(Button.CYCLE_FORM); + this.setLastProcessedMovementTime(Button.CYCLE_FORM); } else if (this.buttonJustPressed(Button.CYCLE_GENDER)) { inputSuccess = this.ui.processInput(Button.CYCLE_GENDER); - this.setLastProcessedMovementTime(Button.CYCLE_GENDER); + this.setLastProcessedMovementTime(Button.CYCLE_GENDER); } else if (this.buttonJustPressed(Button.CYCLE_ABILITY)) { inputSuccess = this.ui.processInput(Button.CYCLE_ABILITY); - this.setLastProcessedMovementTime(Button.CYCLE_ABILITY); + this.setLastProcessedMovementTime(Button.CYCLE_ABILITY); } else if (this.buttonJustPressed(Button.CYCLE_NATURE)) { inputSuccess = this.ui.processInput(Button.CYCLE_NATURE); - this.setLastProcessedMovementTime(Button.CYCLE_NATURE); + this.setLastProcessedMovementTime(Button.CYCLE_NATURE); } else if (this.buttonJustPressed(Button.CYCLE_VARIANT)) { inputSuccess = this.ui.processInput(Button.CYCLE_VARIANT); this.setLastProcessedMovementTime(Button.CYCLE_VARIANT); } else return; - } else if (this.buttonJustPressed(Button.SPEED_UP)) { + } else if (this.buttonJustPressed(Button.SPEED_UP)) { if (this.gameSpeed < 5) { this.gameData.saveSetting(Setting.Game_Speed, settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) + 1); if (this.ui?.getMode() === Mode.SETTINGS) @@ -1446,14 +1449,14 @@ export default class BattleScene extends SceneBase { return; } if (inputSuccess && this.enableVibration && typeof navigator.vibrate !== 'undefined') - navigator.vibrate(vibrationLength || 10); + navigator.vibrate(vibrationLength || 10); } - /** - * gamepadButtonJustDown returns true if @param button has just been pressed down - * or not. It will only return true once, until the key is released and pressed down - * again. - */ + /** + * gamepadButtonJustDown returns true if @param button has just been pressed down + * or not. It will only return true once, until the key is released and pressed down + * again. + */ gamepadButtonJustDown(button: Phaser.Input.Gamepad.Button): boolean { if (!button || !this.gamepadSupport) return false; @@ -1467,7 +1470,7 @@ export default class BattleScene extends SceneBase { this.gamepadButtonStates[button.index] = false; return ret; - } + } buttonJustPressed(button: Button): boolean { const gamepad = this.input.gamepad?.gamepads[0]; @@ -1484,7 +1487,7 @@ export default class BattleScene extends SceneBase { return false; return !this.gamepadButtonStates[button.index]; - } + } buttonJustReleased(button: Button): boolean { const gamepad = this.input.gamepad?.gamepads[0]; @@ -1596,7 +1599,7 @@ export default class BattleScene extends SceneBase { fadeOutBgm(duration: integer = 500, destroy: boolean = true): boolean { if (!this.bgm) return false; - const bgm = this.sound.getAllPlaying().find(bgm => bgm.key === this.bgm.key); + const bgm = this.sound.getAllPlaying().find(bgm => bgm.key === this.bgm.key); if (bgm) { SoundFade.fadeOut(this, this.bgm, duration, destroy); return true; @@ -1753,7 +1756,7 @@ export default class BattleScene extends SceneBase { this.currentPhase = this.phaseQueue.shift(); this.currentPhase.start(); } - + overridePhase(phase: Phase): boolean { if (this.standbyPhase) return false; @@ -1838,7 +1841,7 @@ export default class BattleScene extends SceneBase { modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId))); if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) { if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - success = modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); + success = modifier.apply([this.getPokemonById(modifier.pokemonId), true]); if (playSound && !this.sound.get(soundName)) this.playSound(soundName); } else if (!virtual) { @@ -1846,7 +1849,7 @@ export default class BattleScene extends SceneBase { this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true); return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound, false, instant).then(success => resolve(success)); } - + for (let rm of modifiersToRemove) this.removeModifier(rm); @@ -1860,7 +1863,7 @@ export default class BattleScene extends SceneBase { for (let p in this.party) { const pokemon = this.party[p]; - const args: any[] = [ pokemon ]; + const args: any[] = [pokemon]; if (modifier instanceof PokemonHpRestoreModifier) { if (!(modifier as PokemonHpRestoreModifier).fainted) { const hpRestoreMultiplier = new Utils.IntegerHolder(1); @@ -1870,7 +1873,7 @@ export default class BattleScene extends SceneBase { args.push(1); } else if (modifier instanceof FusePokemonModifier) args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon); - + if (modifier.shouldApply(args)) { const result = modifier.apply(args); if (result instanceof Promise) @@ -1879,10 +1882,10 @@ export default class BattleScene extends SceneBase { success ||= result; } } - + return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success)); } else { - const args = [ this ]; + const args = [this]; if (modifier.shouldApply(args)) { const result = modifier.apply(args); if (result instanceof Promise) { @@ -1901,10 +1904,10 @@ export default class BattleScene extends SceneBase { return new Promise(resolve => { const modifiersToRemove: PersistentModifier[] = []; if (modifier instanceof TerastallizeModifier) - modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false))); + modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false))); if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) { if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); + modifier.apply([this.getPokemonById(modifier.pokemonId), true]); for (let rm of modifiersToRemove) this.removeModifier(rm, true); } @@ -2006,7 +2009,7 @@ export default class BattleScene extends SceneBase { } if (isBoss) count = Math.max(count, Math.floor(chances / 2)); - getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance) + getEnemyModifierTypesForWave(difficultyWaveIndex, count, [enemyPokemon], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance) .map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this)); }); @@ -2022,7 +2025,7 @@ export default class BattleScene extends SceneBase { } setModifiersVisible(visible: boolean) { - [ this.modifierBar, this.enemyModifierBar ].map(m => m.setVisible(visible)); + [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); } updateModifiers(player?: boolean, instant?: boolean): Promise { @@ -2071,7 +2074,7 @@ export default class BattleScene extends SceneBase { if (modifierIndex > -1) { modifiers.splice(modifierIndex, 1); if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]); + modifier.apply([this.getPokemonById(modifier.pokemonId), false]); return true; } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 4229b8be3..3adbcf4be 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -73,16 +73,16 @@ export class ModifierType { let poolTypes: ModifierPoolType[]; switch (poolType) { case ModifierPoolType.PLAYER: - poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ]; + poolTypes = [poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD]; break; case ModifierPoolType.WILD: - poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER ]; + poolTypes = [poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER]; break; case ModifierPoolType.TRAINER: - poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD ]; + poolTypes = [poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD]; break; default: - poolTypes = [ poolType ]; + poolTypes = [poolType]; break; } // Try multiple pool types in case of stolen items @@ -111,7 +111,7 @@ export class ModifierType { type ModifierTypeGeneratorFunc = (party: Pokemon[], pregenArgs?: any[]) => ModifierType; export class ModifierTypeGenerator extends ModifierType { - private genTypeFunc: ModifierTypeGeneratorFunc; + private genTypeFunc: ModifierTypeGeneratorFunc; constructor(genTypeFunc: ModifierTypeGeneratorFunc) { super(null, null, null, null); @@ -193,11 +193,11 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType { constructor(name: string, restorePoints: integer, restorePercent: integer, healStatus: boolean = false, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, iconImage?: string, group?: string) { super(name, restorePoints ? `Restores ${restorePoints} HP or ${restorePercent}% HP for one Pokémon, whichever is higher` : `Fully restores HP for one Pokémon${healStatus ? ' and heals any status ailment' : ''}`, newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)), - selectFilter || ((pokemon: PlayerPokemon) => { - if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || !pokemon.status))) - return PartyUiHandler.NoEffectMessage; - return null; - }), iconImage, group || 'potion'); + selectFilter || ((pokemon: PlayerPokemon) => { + if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || !pokemon.status))) + return PartyUiHandler.NoEffectMessage; + return null; + }), iconImage, group || 'potion'); this.restorePoints = restorePoints; this.restorePercent = restorePercent; @@ -252,12 +252,12 @@ export class PokemonPpRestoreModifierType extends PokemonMoveModifierType { constructor(name: string, restorePoints: integer, iconImage?: string) { super(name, `Restores ${restorePoints > -1 ? restorePoints : 'all'} PP for one Pokémon move`, (_type, args) => new Modifiers.PokemonPpRestoreModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.restorePoints), (_pokemon: PlayerPokemon) => { - return null; - }, (pokemonMove: PokemonMove) => { - if (!pokemonMove.ppUsed) - return PartyUiHandler.NoEffectMessage; - return null; - }, iconImage, 'ether'); + return null; + }, (pokemonMove: PokemonMove) => { + if (!pokemonMove.ppUsed) + return PartyUiHandler.NoEffectMessage; + return null; + }, iconImage, 'ether'); this.restorePoints = restorePoints; } @@ -284,12 +284,12 @@ export class PokemonPpUpModifierType extends PokemonMoveModifierType { constructor(name: string, upPoints: integer, iconImage?: string) { super(name, `Permanently increases PP for one Pokémon move by ${upPoints} for every 5 maximum PP (maximum 3)`, (_type, args) => new Modifiers.PokemonPpUpModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.upPoints), (_pokemon: PlayerPokemon) => { - return null; - }, (pokemonMove: PokemonMove) => { - if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3) - return PartyUiHandler.NoEffectMessage; - return null; - }, iconImage, 'ppUp'); + return null; + }, (pokemonMove: PokemonMove) => { + if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3) + return PartyUiHandler.NoEffectMessage; + return null; + }, iconImage, 'ppUp'); this.upPoints = upPoints; } @@ -304,7 +304,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType { if (pokemon.getNature() === this.nature) return PartyUiHandler.NoEffectMessage; return null; - }), `mint_${Utils.getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || 'neutral' }`, 'mint'); + }), `mint_${Utils.getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || 'neutral'}`, 'mint'); this.nature = nature; } @@ -332,6 +332,17 @@ export class DoubleBattleChanceBoosterModifierType extends ModifierType { } } +export class DoubleBattleChancePreventerModifierType extends ModifierType { + public battleCount: integer; + + constructor(name: string, battleCount: integer) { + super(name, `Prevents the chance of an encounter being a double battle for ${battleCount} battles`, (_type, _args) => new Modifiers.DoubleBattleChancePreventerModifier(this, this.battleCount), + null, 'repel'); + + this.battleCount = battleCount; + } +} + export class TempBattleStatBoosterModifierType extends ModifierType implements GeneratedPersistentModifierType { public tempBattleStat: TempBattleStat; @@ -345,7 +356,7 @@ export class TempBattleStatBoosterModifierType extends ModifierType implements G } getPregenArgs(): any[] { - return [ this.tempBattleStat ]; + return [this.tempBattleStat]; } } @@ -356,12 +367,12 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge super(getBerryName(berryType), getBerryEffectDescription(berryType), (type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, berryType), null, 'berry'); - + this.berryType = berryType; } getPregenArgs(): any[] { - return [ this.berryType ]; + return [this.berryType]; } } @@ -420,7 +431,7 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType i } getPregenArgs(): any[] { - return [ this.moveType ]; + return [this.moveType]; } } @@ -464,7 +475,7 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT } getPregenArgs(): any[] { - return [ this.stat ]; + return [this.stat]; } } @@ -509,7 +520,7 @@ export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType { export class PokemonFriendshipBoosterModifierType extends PokemonHeldItemModifierType { constructor(name: string, iconImage?: string) { - super(name,'Increases friendship gain per victory by 50%', (_type, args) => new Modifiers.PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id), iconImage); + super(name, 'Increases friendship gain per victory by 50%', (_type, args) => new Modifiers.PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id), iconImage); } } @@ -545,22 +556,22 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge constructor(evolutionItem: EvolutionItem) { super(Utils.toReadableString(EvolutionItem[evolutionItem]), `Causes certain Pokémon to evolve`, (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id), - (pokemon: PlayerPokemon) => { - if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem - && (!e.condition || e.condition.predicate(pokemon))).length) - return null; - else if (pokemon.isFusion() && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem - && (!e.condition || e.condition.predicate(pokemon))).length) - return null; + (pokemon: PlayerPokemon) => { + if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem + && (!e.condition || e.condition.predicate(pokemon))).length) + return null; + else if (pokemon.isFusion() && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem + && (!e.condition || e.condition.predicate(pokemon))).length) + return null; - return PartyUiHandler.NoEffectMessage; - }, EvolutionItem[evolutionItem].toLowerCase()); + return PartyUiHandler.NoEffectMessage; + }, EvolutionItem[evolutionItem].toLowerCase()); this.evolutionItem = evolutionItem; } getPregenArgs(): any[] { - return [ this.evolutionItem ]; + return [this.evolutionItem]; } } @@ -569,19 +580,19 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G constructor(formChangeItem: FormChangeItem) { super(Utils.toReadableString(FormChangeItem[formChangeItem]), `Causes certain Pokémon to change form`, (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true), - (pokemon: PlayerPokemon) => { - if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) && !!pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) - && (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem)) - return null; + (pokemon: PlayerPokemon) => { + if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) && !!pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) + && (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem)) + return null; - return PartyUiHandler.NoEffectMessage; - }, FormChangeItem[formChangeItem].toLowerCase()); + return PartyUiHandler.NoEffectMessage; + }, FormChangeItem[formChangeItem].toLowerCase()); this.formChangeItem = formChangeItem; } getPregenArgs(): any[] { - return [ this.formChangeItem ]; + return [this.formChangeItem]; } } @@ -623,7 +634,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { return null; let type: Type; - + const randInt = Utils.randSeedInt(totalWeight); let weight = 0; @@ -635,7 +646,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { } weight += typeWeight; } - + return new AttackTypeBoosterModifierType(type, 20); }); } @@ -711,7 +722,7 @@ export class TerastallizeModifierType extends PokemonHeldItemModifierType implem } getPregenArgs(): any[] { - return [ this.teraType ]; + return [this.teraType]; } } @@ -784,7 +795,7 @@ export const modifierTypes = { HYPER_POTION: () => new PokemonHpRestoreModifierType('Hyper Potion', 200, 50), MAX_POTION: () => new PokemonHpRestoreModifierType('Max Potion', 0, 100), FULL_RESTORE: () => new PokemonHpRestoreModifierType('Full Restore', 0, 100, true), - + REVIVE: () => new PokemonReviveModifierType('Revive', 50), MAX_REVIVE: () => new PokemonReviveModifierType('Max Revive', 100), @@ -804,9 +815,9 @@ export const modifierTypes = { PP_UP: () => new PokemonPpUpModifierType('PP Up', 1), PP_MAX: () => new PokemonPpUpModifierType('PP Max', 3), - /*REPEL: () => new DoubleBattleChanceBoosterModifierType('Repel', 5), - SUPER_REPEL: () => new DoubleBattleChanceBoosterModifierType('Super Repel', 10), - MAX_REPEL: () => new DoubleBattleChanceBoosterModifierType('Max Repel', 25),*/ + REPEL: () => new DoubleBattleChancePreventerModifierType('Repel', 5), + SUPER_REPEL: () => new DoubleBattleChancePreventerModifierType('Super Repel', 10), + MAX_REPEL: () => new DoubleBattleChancePreventerModifierType('Max Repel', 25), LURE: () => new DoubleBattleChanceBoosterModifierType('Lure', 5), SUPER_LURE: () => new DoubleBattleChanceBoosterModifierType('Super Lure', 10), @@ -937,7 +948,7 @@ export const modifierTypes = { DNA_SPLICERS: () => new FusePokemonModifierType('DNA Splicers'), MINI_BLACK_HOLE: () => new TurnHeldItemTransferModifierType('Mini Black Hole'), - + VOUCHER: () => new AddVoucherModifierType(VoucherType.REGULAR, 1), VOUCHER_PLUS: () => new AddVoucherModifierType(VoucherType.PLUS, 1), VOUCHER_PREMIUM: () => new AddVoucherModifierType(VoucherType.PREMIUM, 1), @@ -983,7 +994,14 @@ const modifierPool: ModifierPool = { const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3); return thresholdPartyMemberCount; }, 3), - new WeightedModifierType(modifierTypes.LURE, 2), + new WeightedModifierType(modifierTypes.REPEL, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 2; + }), + new WeightedModifierType(modifierTypes.LURE, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 2; + }), new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4), new WeightedModifierType(modifierTypes.BERRY, 2), new WeightedModifierType(modifierTypes.TM_COMMON, 1), @@ -1169,8 +1187,8 @@ const enemyBuffModifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5), new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 300) ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), - [ModifierTier.ROGUE]: [ ].map(m => { m.setTier(ModifierTier.ROGUE); return m; }), - [ModifierTier.MASTER]: [ ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) + [ModifierTier.ROGUE]: [].map(m => { m.setTier(ModifierTier.ROGUE); return m; }), + [ModifierTier.MASTER]: [].map(m => { m.setTier(ModifierTier.MASTER); return m; }) }; const dailyStarterModifierPool: ModifierPool = { @@ -1240,11 +1258,11 @@ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool return pool; } -const tierWeights = [ 769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ]; +const tierWeights = [769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024]; export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount: integer = 0) { const pool = getModifierPoolForType(poolType); - + const ignoredIndexes = {}; const modifierTableData = {}; const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => { @@ -1256,6 +1274,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod pool[t].reduce((total: integer, modifierType: WeightedModifierType) => { const weightedModifierType = modifierType as WeightedModifierType; const existingModifiers = party[0].scene.findModifiers(m => (m.type.generatorId || m.type.id) === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER); + existingModifiers.forEach(m => console.log(m.type.name)) const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator ? weightedModifierType.modifierType.generateType(party) : weightedModifierType.modifierType; @@ -1285,7 +1304,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod }, 0); for (let id of tierModifierIds) modifierTableData[id].tierPercent = Math.floor((modifierTableData[id].weight / tierMaxWeight) * 10000) / 100; - return [ t, Object.fromEntries(thresholds) ]; + return [t, Object.fromEntries(thresholds)]; }))); for (let id of Object.keys(modifierTableData)) { modifierTableData[id].totalPercent = Math.floor(modifierTableData[id].tierPercent * tierWeights[modifierTableData[id].tier] * 100) / 100; @@ -1480,7 +1499,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (index === undefined) return null; - + if (player) console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier]) let modifierType: ModifierType = (pool[tier][index]).modifierType; @@ -1523,7 +1542,7 @@ export function getPartyLuckValue(party: Pokemon[]): integer { } export function getLuckString(luckValue: integer): string { - return [ 'D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS' ][luckValue]; + return ['D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS'][luckValue]; } export function getLuckTextTint(luckValue: integer): integer { diff --git a/src/modifier/modifier.ts b/src/modifier/modifier.ts index 88b009d3a..294f53358 100644 --- a/src/modifier/modifier.ts +++ b/src/modifier/modifier.ts @@ -310,6 +310,32 @@ export class DoubleBattleChanceBoosterModifier extends LapsingPersistentModifier } } +export class DoubleBattleChancePreventerModifier extends LapsingPersistentModifier { + constructor(type: ModifierTypes.DoubleBattleChancePreventerModifierType, battlesLeft: integer, stackCount?: integer) { + super(type, battlesLeft, stackCount); + } + + match(modifier: Modifier): boolean { + if (modifier instanceof DoubleBattleChancePreventerModifier) + return (modifier as DoubleBattleChancePreventerModifier).battlesLeft === this.battlesLeft; + return false; + } + + clone(): DoubleBattleChancePreventerModifier { + return new DoubleBattleChancePreventerModifier(this.type as ModifierTypes.DoubleBattleChancePreventerModifierType, this.battlesLeft, this.stackCount); + } + + getArgs(): any[] { + return [ this.battlesLeft ]; + } + + apply(args: any[]): boolean { + const doubleBattleChance = args[0] as Utils.NumberHolder; + doubleBattleChance.value = 0; + return true; + } +} + export class TempBattleStatBoosterModifier extends LapsingPersistentModifier { private tempBattleStat: TempBattleStat; From 37571e50cc0714171035fa11c080f5305818f58f Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 04:53:06 -0400 Subject: [PATCH 2/7] Implemented Repels --- .env.development | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.development b/.env.development index 4ce9e53b2..88dcdce61 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,2 @@ VITE_BYPASS_LOGIN=1 -VITE_BYPASS_TUTORIAL=1 \ No newline at end of file +VITE_BYPASS_TUTORIAL=0 \ No newline at end of file From 4225e0fa47b163e4cb1464cd42b29bcd38ef0822 Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 05:04:42 -0400 Subject: [PATCH 3/7] Added all types of Repel and Lure (Regular, Super, Max) to the appropriate pools and matched the weightings of repels to lures --- src/modifier/modifier-type.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 3adbcf4be..beb247dce 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -1045,7 +1045,14 @@ const modifierPool: ModifierPool = { return thresholdPartyMemberCount; }, 3), new WeightedModifierType(modifierTypes.DIRE_HIT, 4), - new WeightedModifierType(modifierTypes.SUPER_LURE, 4), + new WeightedModifierType(modifierTypes.SUPER_REPEL, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 4; + }), + new WeightedModifierType(modifierTypes.SUPER_LURE, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 4; + }), new WeightedModifierType(modifierTypes.NUGGET, 5), new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, (party: Pokemon[]) => { return Math.min(Math.ceil(party[0].scene.currentBattle.waveIndex / 15), 8); @@ -1064,7 +1071,14 @@ const modifierPool: ModifierPool = { ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), [ModifierTier.ULTRA]: [ new WeightedModifierType(modifierTypes.ULTRA_BALL, 24), - new WeightedModifierType(modifierTypes.MAX_LURE, 4), + new WeightedModifierType(modifierTypes.MAX_REPEL, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 4; + }), + new WeightedModifierType(modifierTypes.MAX_LURE, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 4; + }), new WeightedModifierType(modifierTypes.BIG_NUGGET, 12), new WeightedModifierType(modifierTypes.PP_UP, 9), new WeightedModifierType(modifierTypes.PP_MAX, 3), From 1d41aa7173252189260c3d3049871f1d46eff4ca Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 05:43:47 -0400 Subject: [PATCH 4/7] Fixed the check (I realized that getModifiers actually returns [] if the item isn't obtained, not null) --- src/battle-scene.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index a8a9bf59d..6ef8ee121 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -870,7 +870,7 @@ export default class BattleScene extends SceneBase { } newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean): Battle { - if (this.getModifiers(DoubleBattleChancePreventerModifier) != null) { + if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) { double = false; } let newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1); From 38078a34880334fb97449f1e44da62953cc0af77 Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 13:49:27 -0400 Subject: [PATCH 5/7] Undid VSC autoformatter and changed the repel logic to just override the result of a double battle chance calculation (battle-scene:823 and battle-scene:836) --- src/battle-scene.ts | 536 ++++++++++++++-------------------- src/modifier/modifier-type.ts | 237 +++++++++------ src/overrides.ts | 2 +- 3 files changed, 375 insertions(+), 400 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 6ef8ee121..05fffb90d 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1,4 +1,4 @@ -import Phaser, { Time } from 'phaser'; +import Phaser from 'phaser'; import UI, { Mode } from './ui/ui'; import { NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, MessagePhase, TurnInitPhase, ReturnPhase, LevelCapPhase, ShowTrainerPhase, LoginPhase, MovePhase, TitlePhase, SwitchPhase } from './phases'; import Pokemon, { PlayerPokemon, EnemyPokemon } from './field/pokemon'; @@ -54,13 +54,14 @@ import CharSprite from './ui/char-sprite'; import DamageNumberHandler from './field/damage-number-handler'; import PokemonInfoContainer from './ui/pokemon-info-container'; import { biomeDepths } from './data/biomes'; -import { initTouchControls } from './touch-controls'; import { UiTheme } from './enums/ui-theme'; 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 } from './overrides'; +import {InputsController} from "./inputs-controller"; +import {UiInputs} from "./ui-inputs"; export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1"; @@ -69,33 +70,12 @@ const DEBUG_RNG = false; export const startingWave = STARTING_WAVE_OVERRIDE || 1; const expSpriteKeys: string[] = []; -const repeatInputDelayMillis = 250; export let starterColors: StarterColors; interface StarterColors { [key: string]: [string, string] } -export enum Button { - UP, - DOWN, - LEFT, - RIGHT, - SUBMIT, - ACTION, - CANCEL, - MENU, - STATS, - CYCLE_SHINY, - CYCLE_FORM, - CYCLE_GENDER, - CYCLE_ABILITY, - CYCLE_NATURE, - CYCLE_VARIANT, - SPEED_UP, - SLOW_DOWN -} - export interface PokeballCounts { [pb: string]: integer; } @@ -104,6 +84,8 @@ export type AnySound = Phaser.Sound.WebAudioSound | Phaser.Sound.HTML5AudioSound export default class BattleScene extends SceneBase { public rexUI: UIPlugin; + public inputController: InputsController; + public uiInputs: UiInputs; public sessionPlayTime: integer = null; public masterVolume: number = 0.5; @@ -124,6 +106,7 @@ export default class BattleScene extends SceneBase { public gamepadSupport: boolean = true; public enableTouchControls: boolean = false; public enableVibration: boolean = false; + public abSwapped: boolean = false; public disableMenu: boolean = false; @@ -190,34 +173,6 @@ export default class BattleScene extends SceneBase { private bgmCache: Set = new Set(); private playTimeTimer: Phaser.Time.TimerEvent; - private buttonKeys: Phaser.Input.Keyboard.Key[][]; - private lastProcessedButtonPressTimes: Map = new Map(); - // movementButtonLock ensures only a single movement key is firing repeated inputs - // (i.e. by holding down a button) at a time - private movementButtonLock: Button; - - // using a dualshock controller as a map - private gamepadKeyConfig = { - [Button.UP]: 12, // up - [Button.DOWN]: 13, // down - [Button.LEFT]: 14, // left - [Button.RIGHT]: 15, // right - [Button.SUBMIT]: 17, // touchpad - [Button.ACTION]: 0, // X - [Button.CANCEL]: 1, // O - [Button.MENU]: 9, // options - [Button.STATS]: 8, // share - [Button.CYCLE_SHINY]: 5, // RB - [Button.CYCLE_FORM]: 4, // LB - [Button.CYCLE_GENDER]: 6, // LT - [Button.CYCLE_ABILITY]: 7, // RT - [Button.CYCLE_NATURE]: 2, // square - [Button.CYCLE_VARIANT]: 3, // triangle - [Button.SPEED_UP]: 10, // L3 - [Button.SLOW_DOWN]: 11 // R3 - }; - public gamepadButtonStates: boolean[] = new Array(17).fill(false); - public rngCounter: integer = 0; public rngSeedOverride: string = ''; public rngOffset: integer = 0; @@ -228,7 +183,7 @@ export default class BattleScene extends SceneBase { initSpecies(); initMoves(); initAbilities(); - + this.phaseQueue = []; this.phaseQueuePrepend = []; this.phaseQueuePrependSpliceIndex = -1; @@ -243,7 +198,7 @@ export default class BattleScene extends SceneBase { experimental = this.hasExpSprite(key); if (variant) atlasPath = atlasPath.replace('variant/', ''); - this.load.atlas(key, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.png`, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.json`); + this.load.atlas(key, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.png`, `images/pokemon/${variant ? 'variant/' : ''}${experimental ? 'exp/' : ''}${atlasPath}.json`); } async preload() { @@ -251,8 +206,8 @@ export default class BattleScene extends SceneBase { const scene = this; const originalRealInRange = Phaser.Math.RND.realInRange; Phaser.Math.RND.realInRange = function (min: number, max: number): number { - const ret = originalRealInRange.apply(this, [min, max]); - const args = ['RNG', ++scene.rngCounter, ret / (max - min), `min: ${min} / max: ${max}`]; + const ret = originalRealInRange.apply(this, [ min, max ]); + const args = [ 'RNG', ++scene.rngCounter, ret / (max - min), `min: ${min} / max: ${max}` ]; args.push(`seed: ${scene.rngSeedOverride || scene.waveSeed || scene.seed}`); if (scene.rngOffset) args.push(`offset: ${scene.rngOffset}`); @@ -268,13 +223,13 @@ export default class BattleScene extends SceneBase { create() { initGameSpeed.apply(this); + this.inputController = new InputsController(this); + this.uiInputs = new UiInputs(this, this.inputController); this.gameData = new GameData(this); addUiThemeOverrides(this); - this.setupControls(); - this.load.setBaseURL(); this.spritePipeline = new SpritePipeline(this.game); @@ -287,7 +242,7 @@ export default class BattleScene extends SceneBase { } update() { - this.checkInput(); + this.inputController.update(); this.ui?.update(); } @@ -295,7 +250,7 @@ export default class BattleScene extends SceneBase { this.arenaBg = this.add.sprite(0, 0, 'plains_bg'); this.arenaBgTransition = this.add.sprite(0, 0, 'plains_bg'); - [this.arenaBgTransition, this.arenaBg].forEach(a => { + [ this.arenaBgTransition, this.arenaBg ].forEach(a => { a.setPipeline(this.fieldSpritePipeline); a.setScale(6); a.setOrigin(0); @@ -427,7 +382,7 @@ export default class BattleScene extends SceneBase { this.arenaPlayerTransition.setVisible(false); this.arenaNextEnemy.setVisible(false); - [this.arenaPlayer, this.arenaPlayerTransition, this.arenaEnemy, this.arenaNextEnemy].forEach(a => { + [ this.arenaPlayer, this.arenaPlayerTransition, this.arenaEnemy, this.arenaNextEnemy ].forEach(a => { if (a instanceof Phaser.GameObjects.Sprite) a.setOrigin(0, 0); field.add(a); @@ -466,12 +421,12 @@ export default class BattleScene extends SceneBase { ui.setup(); - const defaultMoves = [Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE]; + const defaultMoves = [ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ]; Promise.all([ Promise.all(loadPokemonAssets), initCommonAnims(this).then(() => loadCommonAnimAssets(this, true)), - Promise.all([Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE].map(m => initMoveAnim(this, m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)), + Promise.all([ Moves.TACKLE, Moves.TAIL_WHIP, Moves.FOCUS_ENERGY, Moves.STRUGGLE ].map(m => initMoveAnim(this, m))).then(() => loadMoveAnimAssets(this, defaultMoves, true)), this.initStarterColors() ]).then(() => { this.pushPhase(new LoginPhase(this)); @@ -491,7 +446,7 @@ export default class BattleScene extends SceneBase { this.playTimeTimer = this.time.addEvent({ delay: Utils.fixedInt(1000), repeat: -1, - callback: () => { + callback: () => { if (this.gameData) this.gameData.gameStats.playTime++; if (this.sessionPlayTime !== null) @@ -529,14 +484,14 @@ export default class BattleScene extends SceneBase { variantTree = variantTree[k]; expTree = expTree[k]; } else if (variantTree.hasOwnProperty(k) && expTree.hasOwnProperty(k)) { - if (['back', 'female'].includes(k)) + if ([ 'back', 'female' ].includes(k)) traverseVariantData(keys.concat(k)); else variantTree[k] = expTree[k]; } }); }; - Object.keys(expVariantData).forEach(ek => traverseVariantData([ek])); + Object.keys(expVariantData).forEach(ek => traverseVariantData([ ek ])); } Promise.resolve(); }); @@ -606,42 +561,6 @@ export default class BattleScene extends SceneBase { return true; } - setupControls() { - const keyCodes = Phaser.Input.Keyboard.KeyCodes; - const keyConfig = { - [Button.UP]: [keyCodes.UP, keyCodes.W], - [Button.DOWN]: [keyCodes.DOWN, keyCodes.S], - [Button.LEFT]: [keyCodes.LEFT, keyCodes.A], - [Button.RIGHT]: [keyCodes.RIGHT, keyCodes.D], - [Button.SUBMIT]: [keyCodes.ENTER], - [Button.ACTION]: [keyCodes.SPACE, keyCodes.ENTER, keyCodes.Z], - [Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.X], - [Button.MENU]: [keyCodes.ESC, keyCodes.M], - [Button.STATS]: [keyCodes.SHIFT, keyCodes.C], - [Button.CYCLE_SHINY]: [keyCodes.R], - [Button.CYCLE_FORM]: [keyCodes.F], - [Button.CYCLE_GENDER]: [keyCodes.G], - [Button.CYCLE_ABILITY]: [keyCodes.E], - [Button.CYCLE_NATURE]: [keyCodes.N], - [Button.CYCLE_VARIANT]: [keyCodes.V], - [Button.SPEED_UP]: [keyCodes.PLUS], - [Button.SLOW_DOWN]: [keyCodes.MINUS] - }; - const mobileKeyConfig = {}; - this.buttonKeys = []; - for (let b of Utils.getEnumValues(Button)) { - const keys: Phaser.Input.Keyboard.Key[] = []; - if (keyConfig.hasOwnProperty(b)) { - for (let k of keyConfig[b]) - keys.push(this.input.keyboard.addKey(k, false)); - mobileKeyConfig[Button[b]] = keys[0]; - } - this.buttonKeys[b] = keys; - } - - initTouchControls(mobileKeyConfig); - } - getParty(): PlayerPokemon[] { return this.party; } @@ -710,9 +629,9 @@ export default class BattleScene extends SceneBase { addPokemonIcon(pokemon: Pokemon, x: number, y: number, originX: number = 0.5, originY: number = 0.5, ignoreOverride: boolean = false): Phaser.GameObjects.Container { const container = this.add.container(x, y); - + const icon = this.add.sprite(0, 0, pokemon.getIconAtlasKey(ignoreOverride)); - icon.setFrame(pokemon.getIconId(true)); + icon.setFrame(pokemon.getIconId(true)); icon.setOrigin(0.5, 0); container.add(icon); @@ -727,7 +646,7 @@ export default class BattleScene extends SceneBase { const originalFrame = icon.frame; const iconHeight = (icon.frame.cutHeight <= fusionIcon.frame.cutHeight ? Math.ceil : Math.floor)((icon.frame.cutHeight + fusionIcon.frame.cutHeight) / 4); - + // Inefficient, but for some reason didn't work with only the unique properties as part of the name const iconFrameId = `${icon.frame.name}f${fusionIcon.frame.name}`; @@ -785,7 +704,7 @@ export default class BattleScene extends SceneBase { this.gameData = new GameData(this); this.gameMode = gameModes[GameModes.CLASSIC]; - + this.setSeed(SEED_OVERRIDE || Utils.randomString(24)); console.log('Seed:', this.seed); @@ -796,7 +715,7 @@ export default class BattleScene extends SceneBase { this.lockModifierTiers = false; - this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [t, 0])); + this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ])); this.pokeballCounts[PokeballType.POKEBALL] += 5; this.modifiers = []; @@ -809,7 +728,7 @@ export default class BattleScene extends SceneBase { this.party = []; for (let p of this.getEnemyParty()) p.destroy(); - + this.currentBattle = null; this.waveCountText.setText(startingWave.toString()); @@ -821,14 +740,14 @@ export default class BattleScene extends SceneBase { this.updateScoreText(); this.scoreText.setVisible(false); - [this.luckLabelText, this.luckText].map(t => t.setVisible(false)); + [ this.luckLabelText, this.luckText ].map(t => t.setVisible(false)); this.newArena(STARTING_BIOME_OVERRIDE || Biome.TOWN); this.arenaBgTransition.setPosition(0, 0); this.arenaPlayer.setPosition(300, 0); this.arenaPlayerTransition.setPosition(0, 0); - [this.arenaEnemy, this.arenaNextEnemy].forEach(a => a.setPosition(-280, 0)); + [ this.arenaEnemy, this.arenaNextEnemy ].forEach(a => a.setPosition(-280, 0)); this.arenaNextEnemy.setVisible(false); this.arena.init(); @@ -854,7 +773,7 @@ export default class BattleScene extends SceneBase { this.fadeOutBgm(250, false); this.tweens.add({ - targets: [this.uiContainer], + targets: [ this.uiContainer ], alpha: 0, duration: 250, ease: 'Sine.easeInOut', @@ -870,9 +789,6 @@ export default class BattleScene extends SceneBase { } newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean): Battle { - if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) { - double = false; - } let newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (startingWave - 1)) + 1); let newDouble: boolean; let newBattleType: BattleType; @@ -883,7 +799,7 @@ export default class BattleScene extends SceneBase { this.resetSeed(newWaveIndex); const playerField = this.getPlayerField(); - + if (this.gameMode.hasFixedBattles && fixedBattles.hasOwnProperty(newWaveIndex) && trainerData === undefined) { battleConfig = fixedBattles[newWaveIndex]; newDouble = battleConfig.double; @@ -905,10 +821,11 @@ export default class BattleScene extends SceneBase { if (trainerConfigs[trainerType].doubleOnly) doubleTrainer = true; else if (trainerConfigs[trainerType].hasDouble) { - const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); + let doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, doubleChance)); doubleTrainer = !Utils.randSeedInt(doubleChance.value); + if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) doubleTrainer = false; } newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, doubleTrainer ? TrainerVariant.DOUBLE : Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT); this.field.add(newTrainer); @@ -917,10 +834,11 @@ export default class BattleScene extends SceneBase { if (double === undefined && newWaveIndex > 1) { if (newBattleType === BattleType.WILD && !this.gameMode.isWaveFinal(newWaveIndex)) { - const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); + let doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, doubleChance)); newDouble = !Utils.randSeedInt(doubleChance.value); + if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) newDouble = false; } else if (newBattleType === BattleType.TRAINER) newDouble = newTrainer.variant === TrainerVariant.DOUBLE; } else if (!battleConfig) @@ -991,7 +909,7 @@ export default class BattleScene extends SceneBase { this.pushPhase(new LevelCapPhase(this)); } } - + return this.currentBattle; } @@ -1073,7 +991,7 @@ export default class BattleScene extends SceneBase { case Species.OINKOLOGNE: return gender === Gender.FEMALE ? 1 : 0; case Species.TOXTRICITY: - const lowkeyNatures = [Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL]; + const lowkeyNatures = [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ]; if (nature !== undefined && lowkeyNatures.indexOf(nature) > -1) return 1; return 0; @@ -1114,7 +1032,7 @@ export default class BattleScene extends SceneBase { return 5; let isBoss: boolean; - if (forceBoss || (species && (species.pseudoLegendary || species.legendary || species.mythical))) + if (forceBoss || (species && (species.subLegendary || species.legendary || species.mythical))) isBoss = true; else { this.executeWithSeedOffset(() => { @@ -1150,7 +1068,7 @@ export default class BattleScene extends SceneBase { party.forEach((pokemon, p) => { if (!pokemon.pokerus || infectedIndexes.indexOf(p) > -1) return; - + this.executeWithSeedOffset(() => { if (p) spread(p, -1); @@ -1163,7 +1081,7 @@ export default class BattleScene extends SceneBase { resetSeed(waveIndex?: integer): void { const wave = waveIndex || this.currentBattle?.waveIndex || 0; this.waveSeed = Utils.shiftCharCodes(this.seed, wave); - Phaser.Math.RND.sow([this.waveSeed]); + Phaser.Math.RND.sow([ this.waveSeed ]); console.log('Wave Seed:', this.waveSeed, wave); this.rngCounter = 0; } @@ -1175,7 +1093,7 @@ export default class BattleScene extends SceneBase { const tempRngOffset = this.rngOffset; const tempRngSeedOverride = this.rngSeedOverride; const state = Phaser.Math.RND.state(); - Phaser.Math.RND.sow([Utils.shiftCharCodes(seedOverride || this.seed, offset)]); + Phaser.Math.RND.sow([ Utils.shiftCharCodes(seedOverride || this.seed, offset) ]); this.rngCounter = 0; this.rngOffset = offset; this.rngSeedOverride = seedOverride || ''; @@ -1202,7 +1120,7 @@ export default class BattleScene extends SceneBase { } initPokemonSprite(sprite: Phaser.GameObjects.Sprite, pokemon?: Pokemon, hasShadow: boolean = false, ignoreOverride: boolean = false): Phaser.GameObjects.Sprite { - sprite.setPipeline(this.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined }); + sprite.setPipeline(this.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: hasShadow, ignoreOverride: ignoreOverride, teraColor: pokemon ? getTypeRgb(pokemon.getTeraType()) : undefined }); this.spriteSparkleHandler.add(sprite); return sprite; } @@ -1250,7 +1168,7 @@ export default class BattleScene extends SceneBase { } updateAndShowLuckText(duration: integer): void { - const labels = [this.luckLabelText, this.luckText]; + const labels = [ this.luckLabelText, this.luckText ]; labels.map(t => { t.setAlpha(0); t.setVisible(true); @@ -1270,7 +1188,7 @@ export default class BattleScene extends SceneBase { } hideLuckText(duration: integer): void { - const labels = [this.luckLabelText, this.luckText]; + const labels = [ this.luckLabelText, this.luckText ]; this.tweens.add({ targets: labels, duration: duration, @@ -1286,7 +1204,7 @@ export default class BattleScene extends SceneBase { this.waveCountText.setY(-(this.game.canvas.height / 6) + (enemyModifierCount ? enemyModifierCount <= 12 ? 15 : 24 : 0)); this.moneyText.setY(this.waveCountText.y + 10); this.scoreText.setY(this.moneyText.y + 10); - [this.luckLabelText, this.luckText].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10)); + [ this.luckLabelText, this.luckText ].map(l => l.setY((this.scoreText.visible ? this.scoreText : this.moneyText).y + 10)); const offsetY = (this.scoreText.visible ? this.scoreText : this.moneyText).y + 15; this.partyExpBar.setY(offsetY); this.candyBar.setY(offsetY + 15); @@ -1346,177 +1264,6 @@ export default class BattleScene extends SceneBase { return biomes[Utils.randSeedInt(biomes.length)]; } - checkInput(): boolean { - let inputSuccess = false; - let vibrationLength = 0; - if (this.buttonJustPressed(Button.UP) || this.repeatInputDurationJustPassed(Button.UP)) { - inputSuccess = this.ui.processInput(Button.UP); - vibrationLength = 5; - this.setLastProcessedMovementTime(Button.UP) - } else if (this.buttonJustPressed(Button.DOWN) || this.repeatInputDurationJustPassed(Button.DOWN)) { - inputSuccess = this.ui.processInput(Button.DOWN); - vibrationLength = 5; - this.setLastProcessedMovementTime(Button.DOWN) - } else if (this.buttonJustPressed(Button.LEFT) || this.repeatInputDurationJustPassed(Button.LEFT)) { - inputSuccess = this.ui.processInput(Button.LEFT); - vibrationLength = 5; - this.setLastProcessedMovementTime(Button.LEFT) - } else if (this.buttonJustPressed(Button.RIGHT) || this.repeatInputDurationJustPassed(Button.RIGHT)) { - inputSuccess = this.ui.processInput(Button.RIGHT); - vibrationLength = 5; - this.setLastProcessedMovementTime(Button.RIGHT) - } else if (this.buttonJustPressed(Button.SUBMIT) || this.repeatInputDurationJustPassed(Button.SUBMIT)) { - inputSuccess = this.ui.processInput(Button.SUBMIT) || this.ui.processInput(Button.ACTION); - this.setLastProcessedMovementTime(Button.SUBMIT); - } else if (this.buttonJustPressed(Button.ACTION) || this.repeatInputDurationJustPassed(Button.ACTION)) { - inputSuccess = this.ui.processInput(Button.ACTION); - this.setLastProcessedMovementTime(Button.ACTION); - } else if (this.buttonJustPressed(Button.CANCEL) || this.repeatInputDurationJustPassed(Button.CANCEL)) { - inputSuccess = this.ui.processInput(Button.CANCEL); - this.setLastProcessedMovementTime(Button.CANCEL); - } else if (this.buttonJustPressed(Button.MENU)) { - if (this.disableMenu) - return; - switch (this.ui?.getMode()) { - case Mode.MESSAGE: - if (!(this.ui.getHandler() as MessageUiHandler).pendingPrompt) - return; - case Mode.TITLE: - case Mode.COMMAND: - case Mode.FIGHT: - case Mode.BALL: - case Mode.TARGET_SELECT: - case Mode.SAVE_SLOT: - case Mode.PARTY: - case Mode.SUMMARY: - case Mode.STARTER_SELECT: - case Mode.CONFIRM: - case Mode.OPTION_SELECT: - this.ui.setOverlayMode(Mode.MENU); - inputSuccess = true; - break; - case Mode.MENU: - case Mode.SETTINGS: - case Mode.ACHIEVEMENTS: - this.ui.revertMode(); - this.playSound('select'); - inputSuccess = true; - break; - default: - return; - } - } else if (this.ui?.getHandler() instanceof StarterSelectUiHandler) { - if (this.buttonJustPressed(Button.CYCLE_SHINY)) { - inputSuccess = this.ui.processInput(Button.CYCLE_SHINY); - this.setLastProcessedMovementTime(Button.CYCLE_SHINY); - } else if (this.buttonJustPressed(Button.CYCLE_FORM)) { - inputSuccess = this.ui.processInput(Button.CYCLE_FORM); - this.setLastProcessedMovementTime(Button.CYCLE_FORM); - } else if (this.buttonJustPressed(Button.CYCLE_GENDER)) { - inputSuccess = this.ui.processInput(Button.CYCLE_GENDER); - this.setLastProcessedMovementTime(Button.CYCLE_GENDER); - } else if (this.buttonJustPressed(Button.CYCLE_ABILITY)) { - inputSuccess = this.ui.processInput(Button.CYCLE_ABILITY); - this.setLastProcessedMovementTime(Button.CYCLE_ABILITY); - } else if (this.buttonJustPressed(Button.CYCLE_NATURE)) { - inputSuccess = this.ui.processInput(Button.CYCLE_NATURE); - this.setLastProcessedMovementTime(Button.CYCLE_NATURE); - } else if (this.buttonJustPressed(Button.CYCLE_VARIANT)) { - inputSuccess = this.ui.processInput(Button.CYCLE_VARIANT); - this.setLastProcessedMovementTime(Button.CYCLE_VARIANT); - } else - return; - } else if (this.buttonJustPressed(Button.SPEED_UP)) { - if (this.gameSpeed < 5) { - this.gameData.saveSetting(Setting.Game_Speed, settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) + 1); - if (this.ui?.getMode() === Mode.SETTINGS) - (this.ui.getHandler() as SettingsUiHandler).show([]); - } - } else if (this.buttonJustPressed(Button.SLOW_DOWN)) { - if (this.gameSpeed > 1) { - this.gameData.saveSetting(Setting.Game_Speed, Math.max(settingOptions[Setting.Game_Speed].indexOf(`${this.gameSpeed}x`) - 1, 0)); - if (this.ui?.getMode() === Mode.SETTINGS) - (this.ui.getHandler() as SettingsUiHandler).show([]); - } - } else { - let pressed = false; - if (this.ui && (this.buttonJustReleased(Button.STATS) || (pressed = this.buttonJustPressed(Button.STATS)))) { - for (let p of this.getField().filter(p => p?.isActive(true))) - p.toggleStats(pressed); - if (pressed) - this.setLastProcessedMovementTime(Button.STATS); - } else - return; - } - if (inputSuccess && this.enableVibration && typeof navigator.vibrate !== 'undefined') - navigator.vibrate(vibrationLength || 10); - } - - /** - * gamepadButtonJustDown returns true if @param button has just been pressed down - * or not. It will only return true once, until the key is released and pressed down - * again. - */ - gamepadButtonJustDown(button: Phaser.Input.Gamepad.Button): boolean { - if (!button || !this.gamepadSupport) - return false; - - let ret = false; - if (button.pressed) { - if (!this.gamepadButtonStates[button.index]) - ret = true; - this.gamepadButtonStates[button.index] = true; - } else - this.gamepadButtonStates[button.index] = false; - - return ret; - } - - buttonJustPressed(button: Button): boolean { - const gamepad = this.input.gamepad?.gamepads[0]; - return this.buttonKeys[button].some(k => Phaser.Input.Keyboard.JustDown(k)) || this.gamepadButtonJustDown(gamepad?.buttons[this.gamepadKeyConfig[button]]); - } - - /** - * gamepadButtonJustUp returns true if @param button has just been released - * or not. It will only return true once, until the key is released and pressed down - * again. - */ - gamepadButtonJustUp(button: Phaser.Input.Gamepad.Button): boolean { - if (!button || !this.gamepadSupport) - return false; - - return !this.gamepadButtonStates[button.index]; - } - - buttonJustReleased(button: Button): boolean { - const gamepad = this.input.gamepad?.gamepads[0]; - return this.buttonKeys[button].some(k => Phaser.Input.Keyboard.JustUp(k)) || this.gamepadButtonJustUp(gamepad?.buttons[this.gamepadKeyConfig[button]]); - } - - /** - * repeatInputDurationJustPassed returns true if @param button has been held down long - * enough to fire a repeated input. A button must claim the movementButtonLock before - * firing a repeated input - this is to prevent multiple buttons from firing repeatedly. - */ - repeatInputDurationJustPassed(button: Button): boolean { - if (this.movementButtonLock !== null && this.movementButtonLock !== button) { - return false; - } - if (this.buttonKeys[button].every(k => k.isUp) && this.gamepadButtonStates.every(b => b == false)) { - this.movementButtonLock = null; - return false; - } - if (this.time.now - this.lastProcessedButtonPressTimes.get(button) >= repeatInputDelayMillis) { - return true; - } - } - - setLastProcessedMovementTime(button: Button) { - this.lastProcessedButtonPressTimes.set(button, this.time.now); - this.movementButtonLock = button; - } - isBgmPlaying(): boolean { return this.bgm && this.bgm.isPlaying; } @@ -1599,7 +1346,7 @@ export default class BattleScene extends SceneBase { fadeOutBgm(duration: integer = 500, destroy: boolean = true): boolean { if (!this.bgm) return false; - const bgm = this.sound.getAllPlaying().find(bgm => bgm.key === this.bgm.key); + const bgm = this.sound.getAllPlaying().find(bgm => bgm.key === this.bgm.key); if (bgm) { SoundFade.fadeOut(this, this.bgm, duration, destroy); return true; @@ -1674,11 +1421,13 @@ export default class BattleScene extends SceneBase { return 13.122; case 'battle_unova_gym': return 19.145; - case 'battle_legendary': + case 'battle_legendary_regis': //B2W2 Legendary Titan Battle + return 49.500; + case 'battle_legendary_unova': //BW Unova Legendary Battle return 13.855; - case 'battle_legendary_k': + case 'battle_legendary_kyurem': //BW Kyurem Battle return 18.314; - case 'battle_legendary_rz': + case 'battle_legendary_res_zek': //BW Reshiram & Zekrom Battle return 18.329; case 'battle_rival': return 13.689; @@ -1756,7 +1505,7 @@ export default class BattleScene extends SceneBase { this.currentPhase = this.phaseQueue.shift(); this.currentPhase.start(); } - + overridePhase(phase: Phase): boolean { if (this.standbyPhase) return false; @@ -1841,7 +1590,7 @@ export default class BattleScene extends SceneBase { modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId))); if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) { if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - success = modifier.apply([this.getPokemonById(modifier.pokemonId), true]); + success = modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); if (playSound && !this.sound.get(soundName)) this.playSound(soundName); } else if (!virtual) { @@ -1849,7 +1598,7 @@ export default class BattleScene extends SceneBase { this.queueMessage(`The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true); return this.addModifier(defaultModifierType.newModifier(), ignoreUpdate, playSound, false, instant).then(success => resolve(success)); } - + for (let rm of modifiersToRemove) this.removeModifier(rm); @@ -1863,7 +1612,7 @@ export default class BattleScene extends SceneBase { for (let p in this.party) { const pokemon = this.party[p]; - const args: any[] = [pokemon]; + const args: any[] = [ pokemon ]; if (modifier instanceof PokemonHpRestoreModifier) { if (!(modifier as PokemonHpRestoreModifier).fainted) { const hpRestoreMultiplier = new Utils.IntegerHolder(1); @@ -1873,7 +1622,7 @@ export default class BattleScene extends SceneBase { args.push(1); } else if (modifier instanceof FusePokemonModifier) args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon); - + if (modifier.shouldApply(args)) { const result = modifier.apply(args); if (result instanceof Promise) @@ -1882,10 +1631,10 @@ export default class BattleScene extends SceneBase { success ||= result; } } - + return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success)); } else { - const args = [this]; + const args = [ this ]; if (modifier.shouldApply(args)) { const result = modifier.apply(args); if (result instanceof Promise) { @@ -1904,10 +1653,10 @@ export default class BattleScene extends SceneBase { return new Promise(resolve => { const modifiersToRemove: PersistentModifier[] = []; if (modifier instanceof TerastallizeModifier) - modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false))); + modifiersToRemove.push(...(this.findModifiers(m => m instanceof TerastallizeModifier && m.pokemonId === modifier.pokemonId, false))); if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) { if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - modifier.apply([this.getPokemonById(modifier.pokemonId), true]); + modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]); for (let rm of modifiersToRemove) this.removeModifier(rm, true); } @@ -2009,7 +1758,7 @@ export default class BattleScene extends SceneBase { } if (isBoss) count = Math.max(count, Math.floor(chances / 2)); - getEnemyModifierTypesForWave(difficultyWaveIndex, count, [enemyPokemon], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance) + getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance) .map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this)); }); @@ -2024,6 +1773,171 @@ export default class BattleScene extends SceneBase { this.updateModifiers(false).then(() => this.updateUIPositions()); } + setModifiersVisible(visible: boolean) { + [ this.modifierBar, this.enemyModifierBar ].map(m => m.setVisible(visible)); + } + + updateModifiers(player?: boolean, instant?: boolean): Promise { + if (player === undefined) + player = true; + return new Promise(resolve => { + const modifiers = player ? this.modifiers : this.enemyModifiers as PersistentModifier[]; + for (let m = 0; m < modifiers.length; m++) { + const modifier = modifiers[m]; + if (modifier instanceof PokemonHeldItemModifier && !this.getPokemonById((modifier as PokemonHeldItemModifier).pokemonId)) + modifiers.splice(m--, 1); + } + for (let modifier of modifiers) { + if (modifier instanceof PersistentModifier) + (modifier as PersistentModifier).virtualStackCount = 0; + } + + const modifiersClone = modifiers.slice(0); + for (let modifier of modifiersClone) { + if (!modifier.getStackCount()) + modifiers.splice(modifiers.indexOf(modifier), 1); + } + + this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => { + (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); + if (!player) + this.updateUIPositions(); + resolve(); + }); + }); + } + + updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise { + return new Promise(resolve => { + Promise.allSettled(party.map(p => { + if (p.scene) + p.calculateStats(); + return p.updateInfo(instant); + })).then(() => resolve()); + }); + } + + removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { + const modifiers = !enemy ? this.modifiers : this.enemyModifiers; + const modifierIndex = modifiers.indexOf(modifier); + if (modifierIndex > -1) { + modifiers.splice(modifierIndex, 1); + if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) + modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]); +his.enemyModifiers.indexOf(m), 1); + this.updateModifiers(false).then(() => this.updateUIPositions()); + } + + setModifiersVisible(visible: boolean) { + [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); + } + + updateModifiers(player?: boolean, instant?: boolean): Promise { + if (player === undefined) + player = true; + return new Promise(resolve => { + const modifiers = player ? this.modifiers : this.enemyModifiers as PersistentModifier[]; + for (let m = 0; m < modifiers.length; m++) { + const modifier = modifiers[m]; + if (modifier instanceof PokemonHeldItemModifier && !this.getPokemonById((modifier as PokemonHeldItemModifier).pokemonId)) + modifiers.splice(m--, 1); + } + for (let modifier of modifiers) { + if (modifier instanceof PersistentModifier) + (modifier as PersistentModifier).virtualStackCount = 0; + } + + const modifiersClone = modifiers.slice(0); + for (let modifier of modifiersClone) { + if (!modifier.getStackCount()) + modifiers.splice(modifiers.indexOf(modifier), 1); + } + + this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => { + (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); + if (!player) + this.updateUIPositions(); + resolve(); + }); + }); + } + + updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise { + return new Promise(resolve => { + Promise.allSettled(party.map(p => { + if (p.scene) + p.calculateStats(); + return p.updateInfo(instant); + })).then(() => resolve()); + }); + } + + removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { + const modifiers = !enemy ? this.modifiers : this.enemyModifiers; + const modifierIndex = modifiers.indexOf(modifier); + if (modifierIndex > -1) { + modifiers.splice(modifierIndex, 1); + if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) + modifier.apply([this.getPokemonById(modifier.pokemonId), false]); +his.enemyModifiers.indexOf(m), 1); + this.updateModifiers(false).then(() => this.updateUIPositions()); + } + + setModifiersVisible(visible: boolean) { + [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); + } + + updateModifiers(player?: boolean, instant?: boolean): Promise { + if (player === undefined) + player = true; + return new Promise(resolve => { + const modifiers = player ? this.modifiers : this.enemyModifiers as PersistentModifier[]; + for (let m = 0; m < modifiers.length; m++) { + const modifier = modifiers[m]; + if (modifier instanceof PokemonHeldItemModifier && !this.getPokemonById((modifier as PokemonHeldItemModifier).pokemonId)) + modifiers.splice(m--, 1); + } + for (let modifier of modifiers) { + if (modifier instanceof PersistentModifier) + (modifier as PersistentModifier).virtualStackCount = 0; + } + + const modifiersClone = modifiers.slice(0); + for (let modifier of modifiersClone) { + if (!modifier.getStackCount()) + modifiers.splice(modifiers.indexOf(modifier), 1); + } + + this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => { + (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); + if (!player) + this.updateUIPositions(); + resolve(); + }); + }); + } + + updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise { + return new Promise(resolve => { + Promise.allSettled(party.map(p => { + if (p.scene) + p.calculateStats(); + return p.updateInfo(instant); + })).then(() => resolve()); + }); + } + + removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { + const modifiers = !enemy ? this.modifiers : this.enemyModifiers; + const modifierIndex = modifiers.indexOf(modifier); + if (modifierIndex > -1) { + modifiers.splice(modifierIndex, 1); + if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) + modifier.apply([this.getPokemonById(modifier.pokemonId), false]); +his.enemyModifiers.indexOf(m), 1); + this.updateModifiers(false).then(() => this.updateUIPositions()); + } + setModifiersVisible(visible: boolean) { [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index beb247dce..869c2a448 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -70,19 +70,16 @@ export class ModifierType { return this.tier; if (!this.id) return null; - let poolTypes: ModifierPoolType[]; - switch (poolType) { - case ModifierPoolType.PLAYER: - poolTypes = [poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD]; + let poolTypes: Modifier poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ]; break; case ModifierPoolType.WILD: - poolTypes = [poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER]; + poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER ]; break; case ModifierPoolType.TRAINER: - poolTypes = [poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD]; + poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.WILD ]; break; default: - poolTypes = [poolType]; + poolTypes = [ poolType ]; break; } // Try multiple pool types in case of stolen items @@ -111,7 +108,7 @@ export class ModifierType { type ModifierTypeGeneratorFunc = (party: Pokemon[], pregenArgs?: any[]) => ModifierType; export class ModifierTypeGenerator extends ModifierType { - private genTypeFunc: ModifierTypeGeneratorFunc; + private genTypeFunc: ModifierTypeGeneratorFunc; constructor(genTypeFunc: ModifierTypeGeneratorFunc) { super(null, null, null, null); @@ -193,11 +190,11 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType { constructor(name: string, restorePoints: integer, restorePercent: integer, healStatus: boolean = false, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, iconImage?: string, group?: string) { super(name, restorePoints ? `Restores ${restorePoints} HP or ${restorePercent}% HP for one Pokémon, whichever is higher` : `Fully restores HP for one Pokémon${healStatus ? ' and heals any status ailment' : ''}`, newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)), - selectFilter || ((pokemon: PlayerPokemon) => { - if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || !pokemon.status))) - return PartyUiHandler.NoEffectMessage; - return null; - }), iconImage, group || 'potion'); + selectFilter || ((pokemon: PlayerPokemon) => { + if (!pokemon.hp || (pokemon.hp >= pokemon.getMaxHp() && (!this.healStatus || !pokemon.status))) + return PartyUiHandler.NoEffectMessage; + return null; + }), iconImage, group || 'potion'); this.restorePoints = restorePoints; this.restorePercent = restorePercent; @@ -252,12 +249,12 @@ export class PokemonPpRestoreModifierType extends PokemonMoveModifierType { constructor(name: string, restorePoints: integer, iconImage?: string) { super(name, `Restores ${restorePoints > -1 ? restorePoints : 'all'} PP for one Pokémon move`, (_type, args) => new Modifiers.PokemonPpRestoreModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.restorePoints), (_pokemon: PlayerPokemon) => { - return null; - }, (pokemonMove: PokemonMove) => { - if (!pokemonMove.ppUsed) - return PartyUiHandler.NoEffectMessage; - return null; - }, iconImage, 'ether'); + return null; + }, (pokemonMove: PokemonMove) => { + if (!pokemonMove.ppUsed) + return PartyUiHandler.NoEffectMessage; + return null; + }, iconImage, 'ether'); this.restorePoints = restorePoints; } @@ -284,12 +281,12 @@ export class PokemonPpUpModifierType extends PokemonMoveModifierType { constructor(name: string, upPoints: integer, iconImage?: string) { super(name, `Permanently increases PP for one Pokémon move by ${upPoints} for every 5 maximum PP (maximum 3)`, (_type, args) => new Modifiers.PokemonPpUpModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.upPoints), (_pokemon: PlayerPokemon) => { - return null; - }, (pokemonMove: PokemonMove) => { - if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3) - return PartyUiHandler.NoEffectMessage; - return null; - }, iconImage, 'ppUp'); + return null; + }, (pokemonMove: PokemonMove) => { + if (pokemonMove.getMove().pp < 5 || pokemonMove.ppUp >= 3) + return PartyUiHandler.NoEffectMessage; + return null; + }, iconImage, 'ppUp'); this.upPoints = upPoints; } @@ -304,7 +301,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType { if (pokemon.getNature() === this.nature) return PartyUiHandler.NoEffectMessage; return null; - }), `mint_${Utils.getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || 'neutral'}`, 'mint'); + }), `mint_${Utils.getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || 'neutral' }`, 'mint'); this.nature = nature; } @@ -356,7 +353,7 @@ export class TempBattleStatBoosterModifierType extends ModifierType implements G } getPregenArgs(): any[] { - return [this.tempBattleStat]; + return [ this.tempBattleStat ]; } } @@ -367,12 +364,12 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge super(getBerryName(berryType), getBerryEffectDescription(berryType), (type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, berryType), null, 'berry'); - + this.berryType = berryType; } getPregenArgs(): any[] { - return [this.berryType]; + return [ this.berryType ]; } } @@ -431,7 +428,7 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType i } getPregenArgs(): any[] { - return [this.moveType]; + return [ this.moveType ]; } } @@ -475,7 +472,7 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT } getPregenArgs(): any[] { - return [this.stat]; + return [ this.stat ]; } } @@ -520,7 +517,7 @@ export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType { export class PokemonFriendshipBoosterModifierType extends PokemonHeldItemModifierType { constructor(name: string, iconImage?: string) { - super(name, 'Increases friendship gain per victory by 50%', (_type, args) => new Modifiers.PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id), iconImage); + super(name,'Increases friendship gain per victory by 50%', (_type, args) => new Modifiers.PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id), iconImage); } } @@ -556,22 +553,22 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge constructor(evolutionItem: EvolutionItem) { super(Utils.toReadableString(EvolutionItem[evolutionItem]), `Causes certain Pokémon to evolve`, (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id), - (pokemon: PlayerPokemon) => { - if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem - && (!e.condition || e.condition.predicate(pokemon))).length) - return null; - else if (pokemon.isFusion() && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem - && (!e.condition || e.condition.predicate(pokemon))).length) - return null; + (pokemon: PlayerPokemon) => { + if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem + && (!e.condition || e.condition.predicate(pokemon))).length) + return null; + else if (pokemon.isFusion() && pokemonEvolutions.hasOwnProperty(pokemon.fusionSpecies.speciesId) && pokemonEvolutions[pokemon.fusionSpecies.speciesId].filter(e => e.item === this.evolutionItem + && (!e.condition || e.condition.predicate(pokemon))).length) + return null; - return PartyUiHandler.NoEffectMessage; - }, EvolutionItem[evolutionItem].toLowerCase()); + return PartyUiHandler.NoEffectMessage; + }, EvolutionItem[evolutionItem].toLowerCase()); this.evolutionItem = evolutionItem; } getPregenArgs(): any[] { - return [this.evolutionItem]; + return [ this.evolutionItem ]; } } @@ -580,19 +577,19 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G constructor(formChangeItem: FormChangeItem) { super(Utils.toReadableString(FormChangeItem[formChangeItem]), `Causes certain Pokémon to change form`, (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true), - (pokemon: PlayerPokemon) => { - if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) && !!pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) - && (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem)) - return null; + (pokemon: PlayerPokemon) => { + if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId) && !!pokemonFormChanges[pokemon.species.speciesId].find(fc => fc.trigger.hasTriggerType(SpeciesFormChangeItemTrigger) + && (fc.trigger as SpeciesFormChangeItemTrigger).item === this.formChangeItem)) + return null; - return PartyUiHandler.NoEffectMessage; - }, FormChangeItem[formChangeItem].toLowerCase()); + return PartyUiHandler.NoEffectMessage; + }, FormChangeItem[formChangeItem].toLowerCase()); this.formChangeItem = formChangeItem; } getPregenArgs(): any[] { - return [this.formChangeItem]; + return [ this.formChangeItem ]; } } @@ -634,7 +631,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { return null; let type: Type; - + const randInt = Utils.randSeedInt(totalWeight); let weight = 0; @@ -646,7 +643,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator { } weight += typeWeight; } - + return new AttackTypeBoosterModifierType(type, 20); }); } @@ -722,7 +719,7 @@ export class TerastallizeModifierType extends PokemonHeldItemModifierType implem } getPregenArgs(): any[] { - return [this.teraType]; + return [ this.teraType ]; } } @@ -795,7 +792,7 @@ export const modifierTypes = { HYPER_POTION: () => new PokemonHpRestoreModifierType('Hyper Potion', 200, 50), MAX_POTION: () => new PokemonHpRestoreModifierType('Max Potion', 0, 100), FULL_RESTORE: () => new PokemonHpRestoreModifierType('Full Restore', 0, 100, true), - + REVIVE: () => new PokemonReviveModifierType('Revive', 50), MAX_REVIVE: () => new PokemonReviveModifierType('Max Revive', 100), @@ -815,9 +812,9 @@ export const modifierTypes = { PP_UP: () => new PokemonPpUpModifierType('PP Up', 1), PP_MAX: () => new PokemonPpUpModifierType('PP Max', 3), - REPEL: () => new DoubleBattleChancePreventerModifierType('Repel', 5), - SUPER_REPEL: () => new DoubleBattleChancePreventerModifierType('Super Repel', 10), - MAX_REPEL: () => new DoubleBattleChancePreventerModifierType('Max Repel', 25), + REPEL: () => new DoubleBattleChanceBoosterModifierType('Repel', 5), + SUPER_REPEL: () => new DoubleBattleChanceBoosterModifierType('Super Repel', 10), + MAX_REPEL: () => new DoubleBattleChanceBoosterModifierType('Max Repel', 25), LURE: () => new DoubleBattleChanceBoosterModifierType('Lure', 5), SUPER_LURE: () => new DoubleBattleChanceBoosterModifierType('Super Lure', 10), @@ -948,7 +945,7 @@ export const modifierTypes = { DNA_SPLICERS: () => new FusePokemonModifierType('DNA Splicers'), MINI_BLACK_HOLE: () => new TurnHeldItemTransferModifierType('Mini Black Hole'), - + VOUCHER: () => new AddVoucherModifierType(VoucherType.REGULAR, 1), VOUCHER_PLUS: () => new AddVoucherModifierType(VoucherType.PLUS, 1), VOUCHER_PREMIUM: () => new AddVoucherModifierType(VoucherType.PREMIUM, 1), @@ -994,14 +991,7 @@ const modifierPool: ModifierPool = { const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3); return thresholdPartyMemberCount; }, 3), - new WeightedModifierType(modifierTypes.REPEL, (party: Pokemon[]) => { - const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); - return existingItem ? 0 : 2; - }), - new WeightedModifierType(modifierTypes.LURE, (party: Pokemon[]) => { - const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); - return existingItem ? 0 : 2; - }), + new WeightedModifierType(modifierTypes.LURE, 2), new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4), new WeightedModifierType(modifierTypes.BERRY, 2), new WeightedModifierType(modifierTypes.TM_COMMON, 1), @@ -1050,7 +1040,7 @@ const modifierPool: ModifierPool = { return existingItem ? 0 : 4; }), new WeightedModifierType(modifierTypes.SUPER_LURE, (party: Pokemon[]) => { - const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChanceBoosterModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); return existingItem ? 0 : 4; }), new WeightedModifierType(modifierTypes.NUGGET, 5), @@ -1071,14 +1061,7 @@ const modifierPool: ModifierPool = { ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), [ModifierTier.ULTRA]: [ new WeightedModifierType(modifierTypes.ULTRA_BALL, 24), - new WeightedModifierType(modifierTypes.MAX_REPEL, (party: Pokemon[]) => { - const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); - return existingItem ? 0 : 4; - }), - new WeightedModifierType(modifierTypes.MAX_LURE, (party: Pokemon[]) => { - const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); - return existingItem ? 0 : 4; - }), + new WeightedModifierType(modifierTypes.MAX_LURE, 4), new WeightedModifierType(modifierTypes.BIG_NUGGET, 12), new WeightedModifierType(modifierTypes.PP_UP, 9), new WeightedModifierType(modifierTypes.PP_MAX, 3), @@ -1183,7 +1166,7 @@ const enemyBuffModifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.ENEMY_ATTACK_FREEZE_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_ATTACK_BURN_CHANCE, 2), new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10), - new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 10000), + new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5), new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1) ].map(m => { m.setTier(ModifierTier.COMMON); return m; }), [ModifierTier.GREAT]: [ @@ -1194,15 +1177,15 @@ const enemyBuffModifierPool: ModifierPool = { new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 1) ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), [ModifierTier.ULTRA]: [ - new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 5), - new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 5), - new WeightedModifierType(modifierTypes.ENEMY_HEAL, 5), - new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 5), - new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 5), - new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 300) + new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 10), + new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 10), + new WeightedModifierType(modifierTypes.ENEMY_HEAL, 10), + new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 10), + new WeightedModifierType(modifierTypes.ENEMY_ENDURE_CHANCE, 10), + new WeightedModifierType(modifierTypes.ENEMY_FUSED_CHANCE, 5) ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), - [ModifierTier.ROGUE]: [].map(m => { m.setTier(ModifierTier.ROGUE); return m; }), - [ModifierTier.MASTER]: [].map(m => { m.setTier(ModifierTier.MASTER); return m; }) + [ModifierTier.ROGUE]: [ ].map(m => { m.setTier(ModifierTier.ROGUE); return m; }), + [ModifierTier.MASTER]: [ ].map(m => { m.setTier(ModifierTier.MASTER); return m; }) }; const dailyStarterModifierPool: ModifierPool = { @@ -1272,11 +1255,11 @@ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool return pool; } -const tierWeights = [769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024]; +const tierWeights = [ 769 / 1024, 192 / 1024, 48 / 1024, 12 / 1024, 1 / 1024 ]; export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount: integer = 0) { const pool = getModifierPoolForType(poolType); - + const ignoredIndexes = {}; const modifierTableData = {}; const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => { @@ -1288,7 +1271,6 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod pool[t].reduce((total: integer, modifierType: WeightedModifierType) => { const weightedModifierType = modifierType as WeightedModifierType; const existingModifiers = party[0].scene.findModifiers(m => (m.type.generatorId || m.type.id) === weightedModifierType.modifierType.id, poolType === ModifierPoolType.PLAYER); - existingModifiers.forEach(m => console.log(m.type.name)) const itemModifierType = weightedModifierType.modifierType instanceof ModifierTypeGenerator ? weightedModifierType.modifierType.generateType(party) : weightedModifierType.modifierType; @@ -1318,7 +1300,7 @@ export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: Mod }, 0); for (let id of tierModifierIds) modifierTableData[id].tierPercent = Math.floor((modifierTableData[id].weight / tierMaxWeight) * 10000) / 100; - return [t, Object.fromEntries(thresholds)]; + return [ t, Object.fromEntries(thresholds) ]; }))); for (let id of Object.keys(modifierTableData)) { modifierTableData[id].totalPercent = Math.floor(modifierTableData[id].tierPercent * tierWeights[modifierTableData[id].tier] * 100) / 100; @@ -1513,7 +1495,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, if (index === undefined) return null; - + if (player) console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier]) let modifierType: ModifierType = (pool[tier][index]).modifierType; @@ -1555,6 +1537,85 @@ export function getPartyLuckValue(party: Pokemon[]): integer { .reduce((total: integer, value: integer) => total += value, 0), 0, 14); } +export function getLuckString(luckValue: integer): string { + return [ 'D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS' ][luckValue]; + (modifierType instanceof ModifierTypeGenerator) { + modifierType = (modifierType as ModifierTypeGenerator).generateType(party); + if (modifierType === null) { + if (player) + console.log(ModifierTier[tier], upgradeCount); + return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount); + } + } + + console.log(modifierType, !player ? '(enemy)' : ''); + + return new ModifierTypeOption(modifierType as ModifierType, upgradeCount); +} + +export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType { + let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][0]; + if (modifierType instanceof WeightedModifierType) + modifierType = (modifierType as WeightedModifierType).modifierType; + return modifierType; +} + +export class ModifierTypeOption { + public type: ModifierType; + public upgradeCount: integer; + public cost: integer; + + constructor(type: ModifierType, upgradeCount: integer, cost: number = 0) { + this.type = type; + this.upgradeCount = upgradeCount; + this.cost = Math.min(Math.round(cost), Number.MAX_SAFE_INTEGER); + } +} + +export function getPartyLuckValue(party: Pokemon[]): integer { + return Phaser.Math.Clamp(party.map(p => p.isFainted() ? 0 : p.getLuck()) + .reduce((total: integer, value: integer) => total += value, 0), 0, 14); +} + +export function getLuckString(luckValue: integer): string { + return ['D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS'][luckValue]; + (modifierType as ModifierTypeGenerator).generateType(party); + if (modifierType === null) { + if (player) + console.log(ModifierTier[tier], upgradeCount); + return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount); + } + } + + console.log(modifierType, !player ? '(enemy)' : ''); + + return new ModifierTypeOption(modifierType as ModifierType, upgradeCount); +} + +export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType { + let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][0]; + if (modifierType instanceof WeightedModifierType) + modifierType = (modifierType as WeightedModifierType).modifierType; + return modifierType; +} + +export class ModifierTypeOption { + public type: ModifierType; + public upgradeCount: integer; + public cost: integer; + + constructor(type: ModifierType, upgradeCount: integer, cost: number = 0) { + this.type = type; + this.upgradeCount = upgradeCount; + this.cost = Math.min(Math.round(cost), Number.MAX_SAFE_INTEGER); + } +} + +export function getPartyLuckValue(party: Pokemon[]): integer { + return Phaser.Math.Clamp(party.map(p => p.isFainted() ? 0 : p.getLuck()) + .reduce((total: integer, value: integer) => total += value, 0), 0, 14); +} + export function getLuckString(luckValue: integer): string { return ['D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS'][luckValue]; } diff --git a/src/overrides.ts b/src/overrides.ts index 732b1a5a4..e29dc6579 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -4,7 +4,7 @@ import { Biome } from "./data/enums/biome"; import { Moves } from "./data/enums/moves"; import { WeatherType } from "./data/weather"; -export const SEED_OVERRIDE = ''; +export const SEED_OVERRIDE = 'b3DoubDG5i4izShAO06Z2V2y'; export const STARTER_SPECIES_OVERRIDE = 0; export const STARTER_FORM_OVERRIDE = 0; export const STARTING_LEVEL_OVERRIDE = 0; From 29138ebef7a633edbd7739779cab43e15ef706eb Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 14:34:45 -0400 Subject: [PATCH 6/7] Adjusted the repel logic; now whenever doubleChance is used in a calculation in a randSeedInt call, the result is overriden by setting whatever it was written to as false --- src/battle-scene.ts | 165 ---------------------------------- src/modifier/modifier-type.ts | 111 ++++++----------------- 2 files changed, 25 insertions(+), 251 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 05fffb90d..9db0cd967 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1824,171 +1824,6 @@ export default class BattleScene extends SceneBase { modifiers.splice(modifierIndex, 1); if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]); -his.enemyModifiers.indexOf(m), 1); - this.updateModifiers(false).then(() => this.updateUIPositions()); - } - - setModifiersVisible(visible: boolean) { - [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); - } - - updateModifiers(player?: boolean, instant?: boolean): Promise { - if (player === undefined) - player = true; - return new Promise(resolve => { - const modifiers = player ? this.modifiers : this.enemyModifiers as PersistentModifier[]; - for (let m = 0; m < modifiers.length; m++) { - const modifier = modifiers[m]; - if (modifier instanceof PokemonHeldItemModifier && !this.getPokemonById((modifier as PokemonHeldItemModifier).pokemonId)) - modifiers.splice(m--, 1); - } - for (let modifier of modifiers) { - if (modifier instanceof PersistentModifier) - (modifier as PersistentModifier).virtualStackCount = 0; - } - - const modifiersClone = modifiers.slice(0); - for (let modifier of modifiersClone) { - if (!modifier.getStackCount()) - modifiers.splice(modifiers.indexOf(modifier), 1); - } - - this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => { - (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); - if (!player) - this.updateUIPositions(); - resolve(); - }); - }); - } - - updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise { - return new Promise(resolve => { - Promise.allSettled(party.map(p => { - if (p.scene) - p.calculateStats(); - return p.updateInfo(instant); - })).then(() => resolve()); - }); - } - - removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { - const modifiers = !enemy ? this.modifiers : this.enemyModifiers; - const modifierIndex = modifiers.indexOf(modifier); - if (modifierIndex > -1) { - modifiers.splice(modifierIndex, 1); - if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - modifier.apply([this.getPokemonById(modifier.pokemonId), false]); -his.enemyModifiers.indexOf(m), 1); - this.updateModifiers(false).then(() => this.updateUIPositions()); - } - - setModifiersVisible(visible: boolean) { - [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); - } - - updateModifiers(player?: boolean, instant?: boolean): Promise { - if (player === undefined) - player = true; - return new Promise(resolve => { - const modifiers = player ? this.modifiers : this.enemyModifiers as PersistentModifier[]; - for (let m = 0; m < modifiers.length; m++) { - const modifier = modifiers[m]; - if (modifier instanceof PokemonHeldItemModifier && !this.getPokemonById((modifier as PokemonHeldItemModifier).pokemonId)) - modifiers.splice(m--, 1); - } - for (let modifier of modifiers) { - if (modifier instanceof PersistentModifier) - (modifier as PersistentModifier).virtualStackCount = 0; - } - - const modifiersClone = modifiers.slice(0); - for (let modifier of modifiersClone) { - if (!modifier.getStackCount()) - modifiers.splice(modifiers.indexOf(modifier), 1); - } - - this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => { - (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); - if (!player) - this.updateUIPositions(); - resolve(); - }); - }); - } - - updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise { - return new Promise(resolve => { - Promise.allSettled(party.map(p => { - if (p.scene) - p.calculateStats(); - return p.updateInfo(instant); - })).then(() => resolve()); - }); - } - - removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { - const modifiers = !enemy ? this.modifiers : this.enemyModifiers; - const modifierIndex = modifiers.indexOf(modifier); - if (modifierIndex > -1) { - modifiers.splice(modifierIndex, 1); - if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - modifier.apply([this.getPokemonById(modifier.pokemonId), false]); -his.enemyModifiers.indexOf(m), 1); - this.updateModifiers(false).then(() => this.updateUIPositions()); - } - - setModifiersVisible(visible: boolean) { - [this.modifierBar, this.enemyModifierBar].map(m => m.setVisible(visible)); - } - - updateModifiers(player?: boolean, instant?: boolean): Promise { - if (player === undefined) - player = true; - return new Promise(resolve => { - const modifiers = player ? this.modifiers : this.enemyModifiers as PersistentModifier[]; - for (let m = 0; m < modifiers.length; m++) { - const modifier = modifiers[m]; - if (modifier instanceof PokemonHeldItemModifier && !this.getPokemonById((modifier as PokemonHeldItemModifier).pokemonId)) - modifiers.splice(m--, 1); - } - for (let modifier of modifiers) { - if (modifier instanceof PersistentModifier) - (modifier as PersistentModifier).virtualStackCount = 0; - } - - const modifiersClone = modifiers.slice(0); - for (let modifier of modifiersClone) { - if (!modifier.getStackCount()) - modifiers.splice(modifiers.indexOf(modifier), 1); - } - - this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty(), instant).then(() => { - (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); - if (!player) - this.updateUIPositions(); - resolve(); - }); - }); - } - - updatePartyForModifiers(party: Pokemon[], instant?: boolean): Promise { - return new Promise(resolve => { - Promise.allSettled(party.map(p => { - if (p.scene) - p.calculateStats(); - return p.updateInfo(instant); - })).then(() => resolve()); - }); - } - - removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean { - const modifiers = !enemy ? this.modifiers : this.enemyModifiers; - const modifierIndex = modifiers.indexOf(modifier); - if (modifierIndex > -1) { - modifiers.splice(modifierIndex, 1); - if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) - modifier.apply([this.getPokemonById(modifier.pokemonId), false]); return true; } diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 869c2a448..0639e2f0c 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -70,7 +70,10 @@ export class ModifierType { return this.tier; if (!this.id) return null; - let poolTypes: Modifier poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ]; + let poolTypes: ModifierPoolType[]; + switch (poolType) { + case ModifierPoolType.PLAYER: + poolTypes = [ poolType, ModifierPoolType.TRAINER, ModifierPoolType.WILD ]; break; case ModifierPoolType.WILD: poolTypes = [ poolType, ModifierPoolType.PLAYER, ModifierPoolType.TRAINER ]; @@ -812,9 +815,9 @@ export const modifierTypes = { PP_UP: () => new PokemonPpUpModifierType('PP Up', 1), PP_MAX: () => new PokemonPpUpModifierType('PP Max', 3), - REPEL: () => new DoubleBattleChanceBoosterModifierType('Repel', 5), - SUPER_REPEL: () => new DoubleBattleChanceBoosterModifierType('Super Repel', 10), - MAX_REPEL: () => new DoubleBattleChanceBoosterModifierType('Max Repel', 25), + REPEL: () => new DoubleBattleChancePreventerModifierType('Repel', 5), + SUPER_REPEL: () => new DoubleBattleChancePreventerModifierType('Super Repel', 10), + MAX_REPEL: () => new DoubleBattleChancePreventerModifierType('Max Repel', 25), LURE: () => new DoubleBattleChanceBoosterModifierType('Lure', 5), SUPER_LURE: () => new DoubleBattleChanceBoosterModifierType('Super Lure', 10), @@ -991,7 +994,15 @@ const modifierPool: ModifierPool = { const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && p.getMoveset().filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length, 3); return thresholdPartyMemberCount; }, 3), - new WeightedModifierType(modifierTypes.LURE, 2), + new WeightedModifierType(modifierTypes.REPEL, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + //return existingItem ? 0 : 2; + return 10000 + }), + new WeightedModifierType(modifierTypes.LURE, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 2; + }), new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4), new WeightedModifierType(modifierTypes.BERRY, 2), new WeightedModifierType(modifierTypes.TM_COMMON, 1), @@ -1040,7 +1051,7 @@ const modifierPool: ModifierPool = { return existingItem ? 0 : 4; }), new WeightedModifierType(modifierTypes.SUPER_LURE, (party: Pokemon[]) => { - const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChanceBoosterModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); return existingItem ? 0 : 4; }), new WeightedModifierType(modifierTypes.NUGGET, 5), @@ -1061,7 +1072,14 @@ const modifierPool: ModifierPool = { ].map(m => { m.setTier(ModifierTier.GREAT); return m; }), [ModifierTier.ULTRA]: [ new WeightedModifierType(modifierTypes.ULTRA_BALL, 24), - new WeightedModifierType(modifierTypes.MAX_LURE, 4), + new WeightedModifierType(modifierTypes.MAX_REPEL, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 4; + }), + new WeightedModifierType(modifierTypes.MAX_LURE, (party: Pokemon[]) => { + const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); + return existingItem ? 0 : 4; + }), new WeightedModifierType(modifierTypes.BIG_NUGGET, 12), new WeightedModifierType(modifierTypes.PP_UP, 9), new WeightedModifierType(modifierTypes.PP_MAX, 3), @@ -1539,85 +1557,6 @@ export function getPartyLuckValue(party: Pokemon[]): integer { export function getLuckString(luckValue: integer): string { return [ 'D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS' ][luckValue]; - (modifierType instanceof ModifierTypeGenerator) { - modifierType = (modifierType as ModifierTypeGenerator).generateType(party); - if (modifierType === null) { - if (player) - console.log(ModifierTier[tier], upgradeCount); - return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount); - } - } - - console.log(modifierType, !player ? '(enemy)' : ''); - - return new ModifierTypeOption(modifierType as ModifierType, upgradeCount); -} - -export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType { - let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][0]; - if (modifierType instanceof WeightedModifierType) - modifierType = (modifierType as WeightedModifierType).modifierType; - return modifierType; -} - -export class ModifierTypeOption { - public type: ModifierType; - public upgradeCount: integer; - public cost: integer; - - constructor(type: ModifierType, upgradeCount: integer, cost: number = 0) { - this.type = type; - this.upgradeCount = upgradeCount; - this.cost = Math.min(Math.round(cost), Number.MAX_SAFE_INTEGER); - } -} - -export function getPartyLuckValue(party: Pokemon[]): integer { - return Phaser.Math.Clamp(party.map(p => p.isFainted() ? 0 : p.getLuck()) - .reduce((total: integer, value: integer) => total += value, 0), 0, 14); -} - -export function getLuckString(luckValue: integer): string { - return ['D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS'][luckValue]; - (modifierType as ModifierTypeGenerator).generateType(party); - if (modifierType === null) { - if (player) - console.log(ModifierTier[tier], upgradeCount); - return getNewModifierTypeOption(party, poolType, tier, upgradeCount, ++retryCount); - } - } - - console.log(modifierType, !player ? '(enemy)' : ''); - - return new ModifierTypeOption(modifierType as ModifierType, upgradeCount); -} - -export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType { - let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][0]; - if (modifierType instanceof WeightedModifierType) - modifierType = (modifierType as WeightedModifierType).modifierType; - return modifierType; -} - -export class ModifierTypeOption { - public type: ModifierType; - public upgradeCount: integer; - public cost: integer; - - constructor(type: ModifierType, upgradeCount: integer, cost: number = 0) { - this.type = type; - this.upgradeCount = upgradeCount; - this.cost = Math.min(Math.round(cost), Number.MAX_SAFE_INTEGER); - } -} - -export function getPartyLuckValue(party: Pokemon[]): integer { - return Phaser.Math.Clamp(party.map(p => p.isFainted() ? 0 : p.getLuck()) - .reduce((total: integer, value: integer) => total += value, 0), 0, 14); -} - -export function getLuckString(luckValue: integer): string { - return ['D', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'A++', 'S', 'S+', 'SS', 'SS+', 'SSS'][luckValue]; } export function getLuckTextTint(luckValue: integer): integer { From cc51ae411b0da1cec5fd1b5a119f10357f6d7842 Mon Sep 17 00:00:00 2001 From: Sophie Kujo Date: Mon, 6 May 2024 14:41:42 -0400 Subject: [PATCH 7/7] Removed debug code and reverted const -> let changes in battle-scene.ts --- src/battle-scene.ts | 10 ++++++---- src/modifier/modifier-type.ts | 5 ++--- src/overrides.ts | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 9db0cd967..2db56e18c 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -821,11 +821,12 @@ export default class BattleScene extends SceneBase { if (trainerConfigs[trainerType].doubleOnly) doubleTrainer = true; else if (trainerConfigs[trainerType].hasDouble) { - let doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); + const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, doubleChance)); doubleTrainer = !Utils.randSeedInt(doubleChance.value); - if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) doubleTrainer = false; + if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) + doubleTrainer = false; } newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, doubleTrainer ? TrainerVariant.DOUBLE : Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT); this.field.add(newTrainer); @@ -834,11 +835,12 @@ export default class BattleScene extends SceneBase { if (double === undefined && newWaveIndex > 1) { if (newBattleType === BattleType.WILD && !this.gameMode.isWaveFinal(newWaveIndex)) { - let doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); + const doubleChance = new Utils.IntegerHolder(newWaveIndex % 10 === 0 ? 32 : 8); this.applyModifiers(DoubleBattleChanceBoosterModifier, true, doubleChance); playerField.forEach(p => applyAbAttrs(DoubleBattleChanceAbAttr, p, null, doubleChance)); newDouble = !Utils.randSeedInt(doubleChance.value); - if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) newDouble = false; + if (this.getModifiers(DoubleBattleChancePreventerModifier).length != 0) + newDouble = false; } else if (newBattleType === BattleType.TRAINER) newDouble = newTrainer.variant === TrainerVariant.DOUBLE; } else if (!battleConfig) diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 0639e2f0c..b13a3961e 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -336,7 +336,7 @@ export class DoubleBattleChancePreventerModifierType extends ModifierType { public battleCount: integer; constructor(name: string, battleCount: integer) { - super(name, `Prevents the chance of an encounter being a double battle for ${battleCount} battles`, (_type, _args) => new Modifiers.DoubleBattleChancePreventerModifier(this, this.battleCount), + super(name, `Prevents double battles for ${battleCount} battles`, (_type, _args) => new Modifiers.DoubleBattleChancePreventerModifier(this, this.battleCount), null, 'repel'); this.battleCount = battleCount; @@ -996,8 +996,7 @@ const modifierPool: ModifierPool = { }, 3), new WeightedModifierType(modifierTypes.REPEL, (party: Pokemon[]) => { const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); - //return existingItem ? 0 : 2; - return 10000 + return existingItem ? 0 : 2; }), new WeightedModifierType(modifierTypes.LURE, (party: Pokemon[]) => { const existingItem = party[0].scene.findModifier(m => m.type instanceof DoubleBattleChancePreventerModifierType || m.type instanceof DoubleBattleChanceBoosterModifierType); diff --git a/src/overrides.ts b/src/overrides.ts index 731a095c8..4b9bcaa0b 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -4,7 +4,7 @@ import { Biome } from "./data/enums/biome"; import { Moves } from "./data/enums/moves"; import { WeatherType } from "./data/weather"; -export const SEED_OVERRIDE = 'b3DoubDG5i4izShAO06Z2V2y'; +export const SEED_OVERRIDE = ''; export const STARTER_SPECIES_OVERRIDE = 0; export const STARTER_FORM_OVERRIDE = 0; export const STARTING_LEVEL_OVERRIDE = 0;