Add enemy modifiers functionality
parent
3546f3b5a7
commit
60ac4e096c
|
@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, ConditionalMoveA
|
|||
import { Mode } from './ui/ui';
|
||||
import { Command } from "./ui/command-ui-handler";
|
||||
import { Stat } from "./data/pokemon-stat";
|
||||
import { BerryModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, HealingBoosterModifier, HitHealModifier, PokemonExpBoosterModifier, TempBattleStatBoosterModifier } from "./modifier/modifier";
|
||||
import { BerryModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, HealingBoosterModifier, HitHealModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, TempBattleStatBoosterModifier } from "./modifier/modifier";
|
||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
||||
import { CommonAnim, CommonBattleAnim, MoveAnim, initMoveAnim, loadMoveAnimAssets } from "./data/battle-anims";
|
||||
|
@ -16,7 +16,7 @@ import { EvolutionPhase } from "./evolution-phase";
|
|||
import { BattlePhase } from "./battle-phase";
|
||||
import { BattleStat, getBattleStatLevelChangeDescription, getBattleStatName } from "./data/battle-stat";
|
||||
import { Biome, biomeLinks } from "./data/biome";
|
||||
import { ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, getModifierTypeOptionsForWave, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
|
||||
import { ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, getPlayerModifierTypeOptionsForWave, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
|
||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||
import { BattleTagLapseType, BattleTagType, HideSpriteTag as HiddenTag } from "./data/battle-tag";
|
||||
import { getPokemonMessage } from "./messages";
|
||||
|
@ -67,7 +67,7 @@ export class EncounterPhase extends BattlePhase {
|
|||
start() {
|
||||
super.start();
|
||||
|
||||
this.scene.updateWaveText();
|
||||
this.scene.updateWaveCountText();
|
||||
|
||||
const battle = this.scene.currentBattle;
|
||||
const enemySpecies = this.scene.arena.randomSpecies(battle.waveIndex, battle.enemyLevel);
|
||||
|
@ -85,6 +85,9 @@ export class EncounterPhase extends BattlePhase {
|
|||
this.scene.field.moveBelow(enemyPokemon, this.scene.getPlayerPokemon());
|
||||
enemyPokemon.tint(0, 0.5);
|
||||
|
||||
regenerateModifierPoolThresholds(this.scene.getEnemyParty(), false);
|
||||
this.scene.generateEnemyModifiers();
|
||||
|
||||
this.scene.ui.setMode(Mode.MESSAGE).then(() => this.doEncounter());
|
||||
});
|
||||
}
|
||||
|
@ -92,7 +95,7 @@ export class EncounterPhase extends BattlePhase {
|
|||
doEncounter() {
|
||||
if (startingWave > 10) {
|
||||
for (let m = 0; m < Math.floor(startingWave / 10); m++)
|
||||
this.scene.addModifier(getModifierTypeOptionsForWave((m + 1) * 10, 1, this.scene.getParty())[0].type.newModifier());
|
||||
this.scene.addModifier(getPlayerModifierTypeOptionsForWave((m + 1) * 10, 1, this.scene.getParty())[0].type.newModifier());
|
||||
}
|
||||
|
||||
this.scene.arena.trySetWeather(getRandomWeatherType(this.scene.arena.biomeType), false);
|
||||
|
@ -594,7 +597,7 @@ export class TurnEndPhase extends BattlePhase {
|
|||
this.scene.pushPhase(new MessagePhase(this.scene, `${dm.getName()} is disabled\nno more!`));
|
||||
}
|
||||
|
||||
const hasUsableBerry = pokemon.isPlayer() && !!this.scene.findModifier(m => m instanceof BerryModifier && m.shouldApply([ pokemon ]));
|
||||
const hasUsableBerry = !!this.scene.findModifier(m => m instanceof BerryModifier && m.shouldApply([ pokemon ]), pokemon.isPlayer());
|
||||
if (hasUsableBerry)
|
||||
this.scene.pushPhase(new BerryPhase(this.scene, pokemon.isPlayer()));
|
||||
|
||||
|
@ -627,6 +630,8 @@ export class BattleEndPhase extends BattlePhase {
|
|||
start() {
|
||||
super.start();
|
||||
|
||||
this.scene.clearEnemyModifiers();
|
||||
|
||||
const tempBattleStatBoosterModifiers = this.scene.getModifiers(TempBattleStatBoosterModifier) as TempBattleStatBoosterModifier[];
|
||||
for (let m of tempBattleStatBoosterModifiers) {
|
||||
if (!m.lapse())
|
||||
|
@ -675,7 +680,7 @@ export class CommonAnimPhase extends PokemonPhase {
|
|||
}
|
||||
|
||||
start() {
|
||||
new CommonBattleAnim(this.anim, this.getPokemon(), this.getPokemon().isPlayer() ? this.scene.getEnemyPokemon() : this.scene.getPlayerPokemon()).play(this.scene, () => {
|
||||
new CommonBattleAnim(this.anim, this.getPokemon(), this.player ? this.scene.getEnemyPokemon() : this.scene.getPlayerPokemon()).play(this.scene, () => {
|
||||
this.end();
|
||||
});
|
||||
}
|
||||
|
@ -881,8 +886,7 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
|||
else {
|
||||
if (user.turnData.hitsTotal > 1)
|
||||
this.scene.unshiftPhase(new MessagePhase(this.scene, `Hit ${user.turnData.hitCount} time(s)!`));
|
||||
if (this.player)
|
||||
this.scene.applyModifiers(HitHealModifier, user);
|
||||
this.scene.applyModifiers(HitHealModifier, this.player, user);
|
||||
}
|
||||
|
||||
super.end();
|
||||
|
@ -907,8 +911,7 @@ abstract class MoveEffectPhase extends PokemonPhase {
|
|||
if (this.move.getMove().category !== MoveCategory.STATUS) {
|
||||
const userAccuracyLevel = new Utils.IntegerHolder(this.getUserPokemon().summonData.battleStats[BattleStat.ACC]);
|
||||
const targetEvasionLevel = new Utils.IntegerHolder(this.getTargetPokemon().summonData.battleStats[BattleStat.EVA]);
|
||||
if (this.getUserPokemon().isPlayer())
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, TempBattleStat.ACC, userAccuracyLevel);
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.player, TempBattleStat.ACC, userAccuracyLevel);
|
||||
const rand = Utils.randInt(100, 1);
|
||||
let accuracyMultiplier = 1;
|
||||
if (userAccuracyLevel.value !== targetEvasionLevel.value) {
|
||||
|
@ -1324,7 +1327,7 @@ export class VictoryPhase extends PokemonPhase {
|
|||
if (expShareModifier)
|
||||
expMultiplier += expShareModifier.stackCount * 0.1;
|
||||
const pokemonExp = new Utils.NumberHolder(expValue * expMultiplier);
|
||||
this.scene.applyModifiers(PokemonExpBoosterModifier, partyMember, pokemonExp);
|
||||
this.scene.applyModifiers(PokemonExpBoosterModifier, true, partyMember, pokemonExp);
|
||||
partyMemberExp.push(Math.floor(pokemonExp.value));
|
||||
}
|
||||
|
||||
|
@ -1404,7 +1407,7 @@ export class ExpPhase extends PartyMemberPokemonPhase {
|
|||
|
||||
const pokemon = this.getPokemon();
|
||||
let exp = new Utils.NumberHolder(this.expValue);
|
||||
this.scene.applyModifiers(ExpBoosterModifier, exp);
|
||||
this.scene.applyModifiers(ExpBoosterModifier, true, exp);
|
||||
exp.value = Math.floor(exp.value);
|
||||
this.scene.ui.showText(`${pokemon.name} gained\n${exp.value} EXP. Points!`, null, () => {
|
||||
const lastLevel = pokemon.level;
|
||||
|
@ -1549,18 +1552,16 @@ export class BerryPhase extends CommonAnimPhase {
|
|||
start() {
|
||||
let berryModifier: BerryModifier;
|
||||
|
||||
if (this.player) {
|
||||
if ((berryModifier = this.scene.applyModifier(BerryModifier, this.getPokemon()) as BerryModifier)) {
|
||||
if (berryModifier.consumed) {
|
||||
if (!--berryModifier.stackCount)
|
||||
this.scene.removeModifier(berryModifier);
|
||||
else
|
||||
berryModifier.consumed = false;
|
||||
this.scene.updateModifiers();
|
||||
}
|
||||
super.start();
|
||||
return;
|
||||
if ((berryModifier = this.scene.applyModifier(BerryModifier, this.player, this.getPokemon()) as BerryModifier)) {
|
||||
if (berryModifier.consumed) {
|
||||
if (!--berryModifier.stackCount)
|
||||
this.scene.removeModifier(berryModifier);
|
||||
else
|
||||
berryModifier.consumed = false;
|
||||
this.scene.updateModifiers(this.player);
|
||||
}
|
||||
super.start();
|
||||
return;
|
||||
}
|
||||
|
||||
this.end();
|
||||
|
@ -1596,8 +1597,7 @@ export class PokemonHealPhase extends CommonAnimPhase {
|
|||
|
||||
if (!fullHp) {
|
||||
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
||||
if (this.player)
|
||||
this.scene.applyModifiers(HealingBoosterModifier, hpRestoreMultiplier);
|
||||
this.scene.applyModifiers(HealingBoosterModifier, this.player, hpRestoreMultiplier);
|
||||
pokemon.hp = Math.min(pokemon.hp + this.hpHealed * hpRestoreMultiplier.value, pokemon.getMaxHp());
|
||||
pokemon.updateInfo().then(() => super.end());
|
||||
} else if (this.showFullHpMessage)
|
||||
|
@ -1699,9 +1699,7 @@ export class AttemptCapturePhase extends BattlePhase {
|
|||
} else
|
||||
this.scene.sound.play('pb_lock')
|
||||
},
|
||||
onComplete: () => {
|
||||
this.catch();
|
||||
}
|
||||
onComplete: () => this.catch()
|
||||
});
|
||||
} : () => this.catch();
|
||||
|
||||
|
@ -1747,12 +1745,16 @@ export class AttemptCapturePhase extends BattlePhase {
|
|||
};
|
||||
const addToParty = () => {
|
||||
const newPokemon = pokemon.addToParty();
|
||||
pokemon.hp = 0;
|
||||
this.scene.field.remove(pokemon, true);
|
||||
if (newPokemon)
|
||||
newPokemon.loadAssets().then(end);
|
||||
else
|
||||
end();
|
||||
const modifiers = this.scene.findModifiers(m => m instanceof PokemonHeldItemModifier, false);
|
||||
Promise.all(modifiers.map(m => this.scene.addModifier(m))).then(() => {
|
||||
pokemon.hp = 0;
|
||||
this.scene.clearEnemyModifiers();
|
||||
this.scene.field.remove(pokemon, true);
|
||||
if (newPokemon)
|
||||
newPokemon.loadAssets().then(end);
|
||||
else
|
||||
end();
|
||||
});
|
||||
};
|
||||
Promise.all([ pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
|
||||
if (this.scene.getParty().length === 6) {
|
||||
|
@ -1804,8 +1806,8 @@ export class SelectModifierPhase extends BattlePhase {
|
|||
const party = this.scene.getParty();
|
||||
regenerateModifierPoolThresholds(party);
|
||||
const modifierCount = new Utils.IntegerHolder(3);
|
||||
this.scene.applyModifiers(ExtraModifierModifier, modifierCount);
|
||||
const typeOptions: Array<ModifierTypeOption> = getModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex - 1, modifierCount.value, party);
|
||||
this.scene.applyModifiers(ExtraModifierModifier, true, modifierCount);
|
||||
const typeOptions: Array<ModifierTypeOption> = getPlayerModifierTypeOptionsForWave(this.scene.currentBattle.waveIndex - 1, modifierCount.value, party);
|
||||
|
||||
const modifierSelectCallback = (cursor: integer) => {
|
||||
if (cursor < 0) {
|
||||
|
@ -1825,14 +1827,14 @@ export class SelectModifierPhase extends BattlePhase {
|
|||
const modifier = !isMoveModifier
|
||||
? modifierType.newModifier(party[slotIndex])
|
||||
: modifierType.newModifier(party[slotIndex], option - PartyOption.MOVE_1);
|
||||
this.scene.addModifier(modifier).then(() => super.end());
|
||||
this.scene.addModifier(modifier, true).then(() => super.end());
|
||||
this.scene.ui.clearText();
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
} else
|
||||
this.scene.ui.setMode(Mode.MODIFIER_SELECT, typeOptions, modifierSelectCallback);
|
||||
}, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined);
|
||||
} else {
|
||||
this.scene.addModifier(typeOptions[cursor].type.newModifier()).then(() => super.end());
|
||||
this.scene.addModifier(typeOptions[cursor].type.newModifier(), true).then(() => super.end());
|
||||
this.scene.ui.clearText();
|
||||
this.scene.ui.setMode(Mode.MESSAGE);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import Phaser from 'phaser';
|
|||
import { Biome } from './data/biome';
|
||||
import UI from './ui/ui';
|
||||
import { EncounterPhase, SummonPhase, CommandPhase, NextEncounterPhase, NewBiomeEncounterPhase, SelectBiomePhase, SelectStarterPhase, MessagePhase } from './battle-phases';
|
||||
import { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from './pokemon';
|
||||
import PokemonSpecies, { allSpecies, getPokemonSpecies } from './data/pokemon-species';
|
||||
import * as Utils from './utils';
|
||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PartyShareModifier, PokemonHpRestoreModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ConsumablePokemonMoveModifier, ModifierPredicate } from './modifier/modifier';
|
||||
|
@ -18,7 +18,7 @@ import { GameData } from './system/game-data';
|
|||
import StarterSelectUiHandler from './ui/starter-select-ui-handler';
|
||||
import { TextStyle, addTextObject } from './ui/text';
|
||||
import { Moves } from './data/move';
|
||||
import { getDefaultModifierTypeForTier } from './modifier/modifier-type';
|
||||
import { getDefaultModifierTypeForTier, getEnemyModifierTypesForWave, getPlayerModifierTypeOptionsForWave } from './modifier/modifier-type';
|
||||
|
||||
const enableAuto = true;
|
||||
export const startingLevel = 5;
|
||||
|
@ -45,7 +45,7 @@ export enum Button {
|
|||
export default class BattleScene extends Phaser.Scene {
|
||||
public auto: boolean;
|
||||
public gameSpeed: integer = 1;
|
||||
public quickStart: boolean;
|
||||
public quickStart: boolean = true;
|
||||
|
||||
public gameData: GameData;
|
||||
|
||||
|
@ -68,7 +68,9 @@ export default class BattleScene extends Phaser.Scene {
|
|||
private party: PlayerPokemon[];
|
||||
private waveCountText: Phaser.GameObjects.Text;
|
||||
private modifierBar: ModifierBar;
|
||||
private enemyModifierBar: ModifierBar;
|
||||
private modifiers: PersistentModifier[];
|
||||
private enemyModifiers: PokemonHeldItemModifier[];
|
||||
public uiContainer: Phaser.GameObjects.Container;
|
||||
public ui: UI;
|
||||
|
||||
|
@ -285,13 +287,19 @@ export default class BattleScene extends Phaser.Scene {
|
|||
this.uiContainer = uiContainer;
|
||||
|
||||
this.modifiers = [];
|
||||
this.enemyModifiers = [];
|
||||
|
||||
this.modifierBar = new ModifierBar(this);
|
||||
this.add.existing(this.modifierBar);
|
||||
uiContainer.add(this.modifierBar);
|
||||
|
||||
this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, -(this.game.canvas.height / 6), '1', TextStyle.BATTLE_INFO);
|
||||
this.enemyModifierBar = new ModifierBar(this, true);
|
||||
this.add.existing(this.enemyModifierBar);
|
||||
uiContainer.add(this.enemyModifierBar);
|
||||
|
||||
this.waveCountText = addTextObject(this, (this.game.canvas.width / 6) - 2, 0, '1', TextStyle.BATTLE_INFO);
|
||||
this.waveCountText.setOrigin(1, 0);
|
||||
this.updateWaveCountPosition();
|
||||
this.fieldUI.add(this.waveCountText);
|
||||
|
||||
this.party = [];
|
||||
|
@ -414,6 +422,10 @@ export default class BattleScene extends Phaser.Scene {
|
|||
return this.party;
|
||||
}
|
||||
|
||||
getEnemyParty(): EnemyPokemon[] {
|
||||
return this.getEnemyPokemon() ? [ this.getEnemyPokemon() ] : [];
|
||||
}
|
||||
|
||||
getPlayerPokemon(): PlayerPokemon {
|
||||
return this.getParty()[0];
|
||||
}
|
||||
|
@ -451,13 +463,17 @@ export default class BattleScene extends Phaser.Scene {
|
|||
return this.arena;
|
||||
}
|
||||
|
||||
updateWaveText(): void {
|
||||
updateWaveCountText(): void {
|
||||
const isBoss = !(this.currentBattle.waveIndex % 10);
|
||||
this.waveCountText.setText(this.currentBattle.waveIndex.toString());
|
||||
this.waveCountText.setColor(!isBoss ? '#404040' : '#f89890');
|
||||
this.waveCountText.setShadowColor(!isBoss ? '#ded6b5' : '#984038');
|
||||
}
|
||||
|
||||
updateWaveCountPosition(): void {
|
||||
this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.length ? 15 : 0));
|
||||
}
|
||||
|
||||
randomSpecies(waveIndex: integer, level: integer, fromArenaPool?: boolean): PokemonSpecies {
|
||||
return fromArenaPool
|
||||
? this.arena.randomSpecies(waveIndex, level)
|
||||
|
@ -591,16 +607,16 @@ export default class BattleScene extends Phaser.Scene {
|
|||
this.phaseQueue.push(new CommandPhase(this));
|
||||
}
|
||||
|
||||
addModifier(modifier: Modifier, virtual?: boolean): Promise<void> {
|
||||
addModifier(modifier: Modifier, playSound?: boolean, virtual?: boolean): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
const soundName = modifier.type.soundName;
|
||||
if (modifier instanceof PersistentModifier) {
|
||||
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual)) {
|
||||
if (!virtual && !this.sound.get(soundName))
|
||||
if (playSound && !this.sound.get(soundName))
|
||||
this.sound.play(soundName);
|
||||
} else if (!virtual) {
|
||||
const defaultModifierType = getDefaultModifierTypeForTier(modifier.type.tier);
|
||||
this.addModifier(defaultModifierType.newModifier()).then(() => resolve());
|
||||
this.addModifier(defaultModifierType.newModifier(), playSound).then(() => resolve());
|
||||
this.unshiftPhase(new MessagePhase(this, `The stack for this item is full.\n You will receive ${defaultModifierType.name} instead.`, null, true));
|
||||
return;
|
||||
}
|
||||
|
@ -608,7 +624,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
if (!virtual)
|
||||
this.updateModifiers().then(() => resolve());
|
||||
} else if (modifier instanceof ConsumableModifier) {
|
||||
if (!this.sound.get(soundName))
|
||||
if (playSound && !this.sound.get(soundName))
|
||||
this.sound.play(soundName);
|
||||
|
||||
if (modifier instanceof ConsumablePokemonModifier) {
|
||||
|
@ -619,7 +635,7 @@ export default class BattleScene extends Phaser.Scene {
|
|||
if (modifier instanceof PokemonHpRestoreModifier) {
|
||||
if (!(modifier as PokemonHpRestoreModifier).fainted) {
|
||||
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
|
||||
this.applyModifiers(HealingBoosterModifier, hpRestoreMultiplier);
|
||||
this.applyModifiers(HealingBoosterModifier, true, hpRestoreMultiplier);
|
||||
args.push(hpRestoreMultiplier.value);
|
||||
} else
|
||||
args.push(1);
|
||||
|
@ -651,68 +667,114 @@ export default class BattleScene extends Phaser.Scene {
|
|||
});
|
||||
}
|
||||
|
||||
updateModifiers(): Promise<void> {
|
||||
generateEnemyModifiers(): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
for (let modifier of this.modifiers) {
|
||||
const waveIndex = this.currentBattle.waveIndex;
|
||||
const chances = Math.ceil(waveIndex / 20);
|
||||
const isBoss = waveIndex >= 100 || !(waveIndex % 10);
|
||||
let count = 0;
|
||||
for (let c = 0; c < chances; c++) {
|
||||
if (!Utils.randInt(!isBoss ? 8 : 2))
|
||||
count++;
|
||||
if (count === 12)
|
||||
break;
|
||||
}
|
||||
if (isBoss)
|
||||
count = Math.max(count, Math.ceil(chances / 2));
|
||||
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyParty()).map(mt => mt.newModifier(this.getEnemyPokemon()).add(this.enemyModifiers, false));
|
||||
|
||||
this.updateModifiers(false).then(() => resolve());
|
||||
});
|
||||
}
|
||||
|
||||
clearEnemyModifiers(): void {
|
||||
this.enemyModifiers.splice(0, this.enemyModifiers.length);
|
||||
this.updateModifiers(false).then(() => this.updateWaveCountPosition());
|
||||
}
|
||||
|
||||
updateModifiers(player?: boolean): Promise<void> {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return new Promise(resolve => {
|
||||
const modifiers = player ? this.modifiers : this.enemyModifiers;
|
||||
for (let modifier of modifiers) {
|
||||
if (modifier instanceof PersistentModifier)
|
||||
(modifier as PersistentModifier).virtualStackCount = 0;
|
||||
}
|
||||
|
||||
this.applyModifiers(PartyShareModifier, this, this.modifiers);
|
||||
if (player)
|
||||
this.applyModifiers(PartyShareModifier, true, this, modifiers);
|
||||
|
||||
const modifiers = this.modifiers.slice(0);
|
||||
for (let modifier of modifiers) {
|
||||
const modifiersClone = modifiers.slice(0);
|
||||
for (let modifier of modifiersClone) {
|
||||
if (!modifier.getStackCount())
|
||||
this.modifiers.splice(this.modifiers.indexOf(modifier), 1);
|
||||
modifiers.splice(modifiers.indexOf(modifier), 1);
|
||||
}
|
||||
|
||||
this.updatePartyForModifiers().then(() => {
|
||||
this.modifierBar.updateModifiers(this.modifiers);
|
||||
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty()).then(() => {
|
||||
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
|
||||
if (!player)
|
||||
this.updateWaveCountPosition();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
updatePartyForModifiers(): Promise<void> {
|
||||
updatePartyForModifiers(party: Pokemon[]): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
Promise.allSettled(this.party.map(p => {
|
||||
Promise.allSettled(party.map(p => {
|
||||
p.calculateStats();
|
||||
return p.updateInfo();
|
||||
})).then(() => resolve());
|
||||
});
|
||||
}
|
||||
|
||||
removeModifier(modifier: PersistentModifier): boolean {
|
||||
const modifierIndex = this.modifiers.indexOf(modifier);
|
||||
removeModifier(modifier: PersistentModifier, enemy?: boolean): boolean {
|
||||
const modifiers = !enemy ? this.modifiers : this.enemyModifiers;
|
||||
const modifierIndex = modifiers.indexOf(modifier);
|
||||
if (modifierIndex > -1) {
|
||||
this.modifiers.splice(modifierIndex, 1);
|
||||
modifiers.splice(modifierIndex, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getModifiers(modifierType: { new(...args: any[]): Modifier }): Modifier[] {
|
||||
return this.modifiers.filter(m => m instanceof modifierType);
|
||||
getModifiers(modifierType: { new(...args: any[]): Modifier }, player?: boolean): Modifier[] {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType);
|
||||
}
|
||||
|
||||
findModifier(modifierFilter: ModifierPredicate): Modifier {
|
||||
return this.modifiers.find(m => (modifierFilter as ModifierPredicate)(m));
|
||||
findModifiers(modifierFilter: ModifierPredicate, player?: boolean): Modifier[] {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m));
|
||||
}
|
||||
|
||||
applyModifiers(modifierType: { new(...args: any[]): Modifier }, ...args: any[]): void {
|
||||
const modifiers = this.modifiers.filter(m => m instanceof modifierType && m.shouldApply(args));
|
||||
findModifier(modifierFilter: ModifierPredicate, player?: boolean): Modifier {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m));
|
||||
}
|
||||
|
||||
applyModifiers(modifierType: { new(...args: any[]): Modifier }, player?: boolean, ...args: any[]): void {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
||||
for (let modifier of modifiers) {
|
||||
if (modifier.apply(args))
|
||||
console.log('Applied', modifier.type.name);
|
||||
console.log('Applied', modifier.type.name, !player ? '(enemy)' : '');
|
||||
}
|
||||
}
|
||||
|
||||
applyModifier(modifierType: { new(...args: any[]): Modifier }, ...args: any[]): PersistentModifier {
|
||||
const modifiers = this.modifiers.filter(m => m instanceof modifierType && m.shouldApply(args));
|
||||
applyModifier(modifierType: { new(...args: any[]): Modifier }, player?: boolean, ...args: any[]): PersistentModifier {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
|
||||
for (let modifier of modifiers) {
|
||||
if (modifier.apply(args)) {
|
||||
console.log('Applied', modifier.type.name);
|
||||
console.log('Applied', modifier.type.name, !player ? '(enemy)' : '');
|
||||
return modifier;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
|||
switch (berryType) {
|
||||
case BerryType.SITRUS:
|
||||
return (pokemon: Pokemon) => {
|
||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, true, Math.floor(pokemon.getMaxHp() / 4), getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
|
||||
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.isPlayer(), Math.floor(pokemon.getMaxHp() / 4), getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
|
||||
};
|
||||
case BerryType.LUM:
|
||||
return (pokemon: Pokemon) => {
|
||||
|
|
|
@ -87,7 +87,7 @@ export function getStatusEffectOverlapText(statusEffect: StatusEffect): string {
|
|||
return '';
|
||||
}
|
||||
|
||||
export function getStatusEffectHealText(statusEffect: StatusEffect) {
|
||||
export function getStatusEffectHealText(statusEffect: StatusEffect): string {
|
||||
switch (statusEffect) {
|
||||
case StatusEffect.POISON:
|
||||
case StatusEffect.TOXIC:
|
||||
|
@ -105,7 +105,7 @@ export function getStatusEffectHealText(statusEffect: StatusEffect) {
|
|||
return '';
|
||||
}
|
||||
|
||||
export function getStatusEffectDescriptor(statusEffect: StatusEffect) {
|
||||
export function getStatusEffectDescriptor(statusEffect: StatusEffect): string {
|
||||
switch (statusEffect) {
|
||||
case StatusEffect.POISON:
|
||||
case StatusEffect.TOXIC:
|
||||
|
@ -121,7 +121,7 @@ export function getStatusEffectDescriptor(statusEffect: StatusEffect) {
|
|||
}
|
||||
}
|
||||
|
||||
export function getStatusEffectCatchRateMultiplier(statusEffect: StatusEffect) {
|
||||
export function getStatusEffectCatchRateMultiplier(statusEffect: StatusEffect): number {
|
||||
switch (statusEffect) {
|
||||
case StatusEffect.POISON:
|
||||
case StatusEffect.TOXIC:
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { BattleStat, getBattleStatName } from '../data/battle-stat';
|
||||
import * as Modifiers from './modifier';
|
||||
import { AttackMove, Moves, allMoves } from '../data/move';
|
||||
import { PokeballType, getPokeballName } from '../data/pokeball';
|
||||
import { PlayerPokemon, PokemonMove } from '../pokemon';
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from '../pokemon';
|
||||
import { EvolutionItem, pokemonEvolutions } from '../data/pokemon-evolutions';
|
||||
import { Stat, getStatName } from '../data/pokemon-stat';
|
||||
import { tmSpecies } from '../data/tms';
|
||||
|
@ -31,7 +30,7 @@ export class ModifierType {
|
|||
public group: string;
|
||||
public soundName: string;
|
||||
public tier: ModifierTier;
|
||||
private newModifierFunc: NewModifierFunc;
|
||||
protected newModifierFunc: NewModifierFunc;
|
||||
|
||||
constructor(name: string, description: string, newModifierFunc: NewModifierFunc, iconImage?: string, group?: string, soundName?: string) {
|
||||
this.name = name;
|
||||
|
@ -42,11 +41,11 @@ export class ModifierType {
|
|||
this.newModifierFunc = newModifierFunc;
|
||||
}
|
||||
|
||||
setTier(tier: ModifierTier) {
|
||||
setTier(tier: ModifierTier): void {
|
||||
this.tier = tier;
|
||||
}
|
||||
|
||||
newModifier(...args: any[]) {
|
||||
newModifier(...args: any[]): Modifier {
|
||||
return this.newModifierFunc(this, args);
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +68,12 @@ export class PokemonModifierType extends ModifierType {
|
|||
}
|
||||
|
||||
export class PokemonHeldItemModifierType extends PokemonModifierType {
|
||||
constructor(name: string, description: string, newModifierFunc: NewModifierFunc, selectFilter?: PokemonSelectFilter, iconImage?: string, group?: string, soundName?: string) {
|
||||
super(name, description, newModifierFunc, selectFilter, iconImage, group, soundName);
|
||||
constructor(name: string, description: string, newModifierFunc: NewModifierFunc, iconImage?: string, group?: string, soundName?: string) {
|
||||
super(name, description, newModifierFunc, undefined, iconImage, group, soundName);
|
||||
}
|
||||
|
||||
newModifier(...args: any[]): Modifiers.PokemonHeldItemModifier {
|
||||
return super.newModifier(...args) as Modifiers.PokemonHeldItemModifier;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,8 +228,8 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType {
|
|||
|
||||
constructor(moveType: Type, boostPercent: integer) {
|
||||
super(Utils.toPokemonUpperCase(getAttackTypeBoosterItemName(moveType)), `Inceases the power of a POKéMON's ${Type[moveType]}-type moves by 20%`,
|
||||
(_type, args) => new Modifiers.AttackTypeBoosterModifier(this, (args[0] as PlayerPokemon).id, moveType, boostPercent),
|
||||
null, `${getAttackTypeBoosterItemName(moveType).replace(/[ \-]/g, '_').toLowerCase()}`);
|
||||
(_type, args) => new Modifiers.AttackTypeBoosterModifier(this, (args[0] as Pokemon).id, moveType, boostPercent),
|
||||
`${getAttackTypeBoosterItemName(moveType).replace(/[ \-]/g, '_').toLowerCase()}`);
|
||||
|
||||
this.moveType = moveType;
|
||||
this.boostPercent = boostPercent;
|
||||
|
@ -261,7 +264,7 @@ export class PokemonBaseStatBoosterModifierType extends PokemonHeldItemModifierT
|
|||
private stat: Stat;
|
||||
|
||||
constructor(name: string, stat: Stat, _iconImage?: string) {
|
||||
super(name, `Increases the holder's base ${getStatName(stat)} by 20%` , (_type, args) => new Modifiers.PokemonBaseStatModifier(this, (args[0] as PlayerPokemon).id, this.stat));
|
||||
super(name, `Increases the holder's base ${getStatName(stat)} by 20%`, (_type, args) => new Modifiers.PokemonBaseStatModifier(this, (args[0] as Pokemon).id, this.stat));
|
||||
|
||||
this.stat = stat;
|
||||
}
|
||||
|
@ -287,8 +290,8 @@ export class ExpBoosterModifierType extends ModifierType {
|
|||
|
||||
export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType {
|
||||
constructor(name: string, boostPercent: integer, iconImage?: string) {
|
||||
super(name, `Increases the holder's gain of EXP. Points by ${boostPercent}%`, (_type, args) => new Modifiers.PokemonExpBoosterModifier(this, (args[0] as PlayerPokemon).id, boostPercent),
|
||||
(_pokemon: PlayerPokemon) => null, iconImage);
|
||||
super(name, `Increases the holder's gain of EXP. Points by ${boostPercent}%`, (_type, args) => new Modifiers.PokemonExpBoosterModifier(this, (args[0] as Pokemon).id, boostPercent),
|
||||
iconImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +362,7 @@ class ModifierTypeGenerator extends ModifierType {
|
|||
this.genTypeFunc = genTypeFunc;
|
||||
}
|
||||
|
||||
generateType(party: PlayerPokemon[]) {
|
||||
generateType(party: Pokemon[]) {
|
||||
const ret = this.genTypeFunc(party);
|
||||
if (ret)
|
||||
ret.setTier(this.tier);
|
||||
|
@ -369,7 +372,7 @@ class ModifierTypeGenerator extends ModifierType {
|
|||
|
||||
class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
constructor() {
|
||||
super((party: PlayerPokemon[]) => {
|
||||
super((party: Pokemon[]) => {
|
||||
const attackMoveTypes = party.map(p => p.moveset.map(m => m.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat();
|
||||
const attackMoveTypeWeights = new Map<Type, integer>();
|
||||
let totalWeight = 0;
|
||||
|
@ -408,7 +411,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||
|
||||
class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
|
||||
constructor() {
|
||||
super((party: PlayerPokemon[]) => {
|
||||
super((party: Pokemon[]) => {
|
||||
const evolutionItemPool = party.filter(p => pokemonEvolutions.hasOwnProperty(p.species.speciesId)).map(p => {
|
||||
const evolutions = pokemonEvolutions[p.species.speciesId]
|
||||
return evolutions.filter(e => e.item !== EvolutionItem.NONE && (!e.condition || e.condition.predicate(p)));
|
||||
|
@ -436,119 +439,205 @@ class WeightedModifierType {
|
|||
}
|
||||
}
|
||||
|
||||
const modifierTypes = {
|
||||
POKEBALL: new AddPokeballModifierType(PokeballType.POKEBALL, 5, 'pb'),
|
||||
GREAT_BALL: new AddPokeballModifierType(PokeballType.GREAT_BALL, 5, 'gb'),
|
||||
ULTRA_BALL: new AddPokeballModifierType(PokeballType.ULTRA_BALL, 5, 'ub'),
|
||||
MASTER_BALL: new AddPokeballModifierType(PokeballType.MASTER_BALL, 1, 'mb'),
|
||||
|
||||
RARE_CANDY: new PokemonLevelIncrementModifierType('RARE CANDY'),
|
||||
|
||||
EVOLUTION_ITEM: new EvolutionItemModifierTypeGenerator(),
|
||||
|
||||
POTION: new PokemonHpRestoreModifierType('POTION', 20),
|
||||
SUPER_POTION: new PokemonHpRestoreModifierType('SUPER POTION', 50),
|
||||
HYPER_POTION: new PokemonHpRestoreModifierType('HYPER POTION', 200),
|
||||
MAX_POTION: new PokemonHpRestoreModifierType('MAX POTION', 100, true),
|
||||
|
||||
REVIVE: new PokemonReviveModifierType('REVIVE', 50),
|
||||
MAX_REVIVE: new PokemonReviveModifierType('MAX REVIVE', 100),
|
||||
|
||||
FULL_HEAL: new PokemonStatusHealModifierType('FULL HEAL'),
|
||||
|
||||
SACRED_ASH: new AllPokemonFullReviveModifierType('SACRED ASH'),
|
||||
|
||||
ETHER: new PokemonPpRestoreModifierType('ETHER', 10),
|
||||
MAX_ETHER: new PokemonPpRestoreModifierType('MAX ETHER', -1),
|
||||
|
||||
ELIXIR: new PokemonAllMovePpRestoreModifierType('ELIXIR', 10),
|
||||
MAX_ELIXIR: new PokemonAllMovePpRestoreModifierType('MAX ELIXIR', -1),
|
||||
|
||||
TEMP_STAT_BOOSTER: new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
const randTempBattleStat = Utils.randInt(7) as TempBattleStat;
|
||||
return new TempBattleStatBoosterModifierType(randTempBattleStat);
|
||||
}),
|
||||
|
||||
BASE_STAT_BOOSTER: new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
const randStat = Utils.randInt(6) as Stat;
|
||||
return new PokemonBaseStatBoosterModifierType(getBaseStatBoosterItemName(randStat), randStat);
|
||||
}),
|
||||
|
||||
ATTACK_TYPE_BOOSTER: new AttackTypeBoosterModifierTypeGenerator(),
|
||||
|
||||
BERRY: new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
const berryTypes = Utils.getEnumValues(BerryType);
|
||||
const randBerryType = berryTypes[Utils.randInt(berryTypes.length)];
|
||||
return new PokemonHeldItemModifierType(getBerryName(randBerryType), getBerryEffectDescription(randBerryType),
|
||||
(type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, randBerryType),
|
||||
null, 'berry');
|
||||
}),
|
||||
|
||||
TM: new ModifierTypeGenerator((party: Pokemon[]) => {
|
||||
const partyMemberCompatibleTms = party.map(p => (p as PlayerPokemon).compatibleTms);
|
||||
const uniqueCompatibleTms = partyMemberCompatibleTms.flat().filter((tm, i, array) => array.indexOf(tm) === i);
|
||||
if (!uniqueCompatibleTms.length)
|
||||
return null;
|
||||
const randTmIndex = Utils.randInt(uniqueCompatibleTms.length);
|
||||
return new TmModifierType(uniqueCompatibleTms[randTmIndex]);
|
||||
}),
|
||||
|
||||
EXP_SHARE: new ModifierType('EXP. SHARE', 'All POKéMON in your party gain an additional 10% of a battle\'s EXP. Points',
|
||||
(type, _args) => new Modifiers.ExpShareModifier(type), 'exp_share'),
|
||||
EXP_BALANCE: new ModifierType('EXP. BALANCE', 'All EXP. Points received from battles is split among the lower leveled party members',
|
||||
(type, _args) => new Modifiers.ExpBalanceModifier(type), 'exp_balance'),
|
||||
|
||||
EXP_CHARM: new ExpBoosterModifierType('EXP CHARM', 25),
|
||||
GOLDEN_EXP_CHARM: new ExpBoosterModifierType('GOLDEN EXP CHARM', 100),
|
||||
|
||||
LUCKY_EGG: new PokemonExpBoosterModifierType('LUCKY EGG', 50),
|
||||
|
||||
HEALING_CHARM: new ModifierType('HEALING CHARM', 'Doubles the effectiveness of HP restoring moves and items (excludes revives)',
|
||||
(type, _args) => new Modifiers.HealingBoosterModifier(type, 2), 'healing_charm'),
|
||||
|
||||
OVAL_CHARM: new ModifierType('OVAL CHARM', 'For every X (no. of party members) items in a POKéMON\'s held item stack, give one to each other party member',
|
||||
(type, _args) => new Modifiers.PartyShareModifier(type), 'oval_charm'),
|
||||
|
||||
BERRY_POUCH: new ModifierType('BERRY POUCH', 'Adds a 25% chance that a used berry will not be consumed',
|
||||
(type, _args) => new Modifiers.PreserveBerryModifier(type)),
|
||||
|
||||
SHELL_BELL: new PokemonHeldItemModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s dealt damage',
|
||||
(type, args) => new Modifiers.HitHealModifier(type, (args[0] as Pokemon).id)),
|
||||
|
||||
SHINY_CHARM: new ModifierType('SHINY CHARM', 'Dramatically increases the chance of a wild POKéMON being shiny', (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
|
||||
|
||||
GOLDEN_POKEBALL: new ModifierType(`GOLDEN ${getPokeballName(PokeballType.POKEBALL)}`, 'Adds 1 extra item option at the end of every battle',
|
||||
(type, _args) => new Modifiers.ExtraModifierModifier(type), 'pb_gold', null, 'pb_bounce_1'),
|
||||
};
|
||||
|
||||
const modifierPool = {
|
||||
[ModifierTier.COMMON]: [
|
||||
new WeightedModifierType(new AddPokeballModifierType(PokeballType.POKEBALL, 5, 'pb'), 6),
|
||||
new WeightedModifierType(new PokemonLevelIncrementModifierType('RARE CANDY'), 2),
|
||||
new WeightedModifierType(new PokemonHpRestoreModifierType('POTION', 20), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.POKEBALL, 6),
|
||||
new WeightedModifierType(modifierTypes.RARE_CANDY, 2),
|
||||
new WeightedModifierType(modifierTypes.POTION, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 10 || p.getHpRatio() <= 0.875).length;
|
||||
return thresholdPartyMemberCount * 3;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonHpRestoreModifierType('SUPER POTION', 50), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.SUPER_POTION, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 25 || p.getHpRatio() <= 0.75).length;
|
||||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonPpRestoreModifierType('ETHER', 10), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.ETHER, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
|
||||
return thresholdPartyMemberCount * 3;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonPpRestoreModifierType('MAX ETHER', -1), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.MAX_ETHER, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
|
||||
return thresholdPartyMemberCount;
|
||||
}),
|
||||
new WeightedModifierType(new ModifierTypeGenerator((party: PlayerPokemon[]) => {
|
||||
const randTempBattleStat = Utils.randInt(7) as TempBattleStat;
|
||||
return new TempBattleStatBoosterModifierType(randTempBattleStat);
|
||||
}), 4),
|
||||
new WeightedModifierType(new ModifierTypeGenerator((party: PlayerPokemon[]) => {
|
||||
const berryTypes = Utils.getEnumValues(BerryType);
|
||||
const randBerryType = berryTypes[Utils.randInt(berryTypes.length)];
|
||||
return new PokemonHeldItemModifierType(getBerryName(randBerryType), getBerryEffectDescription(randBerryType),
|
||||
(type, args) => new Modifiers.BerryModifier(type, (args[0] as PlayerPokemon).id, randBerryType),
|
||||
() => null, null, 'berry');
|
||||
}), 2)
|
||||
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
|
||||
new WeightedModifierType(modifierTypes.BERRY, 2)
|
||||
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
|
||||
[ModifierTier.GREAT]: [
|
||||
new WeightedModifierType(new AddPokeballModifierType(PokeballType.GREAT_BALL, 5, 'gb'), 12),
|
||||
new WeightedModifierType(new PokemonStatusHealModifierType('FULL HEAL'), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.GREAT_BALL, 12),
|
||||
new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => {
|
||||
const statusEffectPartyMemberCount = party.filter(p => p.hp && !!p.status).length;
|
||||
return statusEffectPartyMemberCount * 8;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonReviveModifierType('REVIVE', 50), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.REVIVE, (party: Pokemon[]) => {
|
||||
const faintedPartyMemberCount = party.filter(p => !p.hp).length;
|
||||
return faintedPartyMemberCount * 6;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonReviveModifierType('MAX REVIVE', 100), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.MAX_REVIVE, (party: Pokemon[]) => {
|
||||
const faintedPartyMemberCount = party.filter(p => !p.hp).length;
|
||||
return faintedPartyMemberCount * 2;
|
||||
}),
|
||||
new WeightedModifierType(new AllPokemonFullReviveModifierType('SACRED ASH'), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.SACRED_ASH, (party: Pokemon[]) => {
|
||||
return party.filter(p => !p.hp).length >= Math.ceil(party.length / 2) ? 1 : 0;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonHpRestoreModifierType('HYPER POTION', 200), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.HYPER_POTION, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 100 || p.getHpRatio() <= 0.625).length;
|
||||
return thresholdPartyMemberCount * 2;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonHpRestoreModifierType('MAX POTION', 100, true), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.MAX_POTION, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.getInverseHp() >= 150 || p.getHpRatio() <= 0.5).length;
|
||||
return Math.ceil(thresholdPartyMemberCount / 1.5);
|
||||
}),
|
||||
new WeightedModifierType(new PokemonAllMovePpRestoreModifierType('ELIXIR', 10), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
|
||||
return thresholdPartyMemberCount * 2;
|
||||
}),
|
||||
new WeightedModifierType(new PokemonAllMovePpRestoreModifierType('MAX ELIXIR', -1), (party: PlayerPokemon[]) => {
|
||||
new WeightedModifierType(modifierTypes.MAX_ELIXIR, (party: Pokemon[]) => {
|
||||
const thresholdPartyMemberCount = party.filter(p => p.hp && p.moveset.filter(m => (m.getMove().pp - m.ppUsed) <= 5).length).length;
|
||||
return Math.ceil(thresholdPartyMemberCount / 1.5);
|
||||
}),
|
||||
new WeightedModifierType(new ModifierTypeGenerator((party: PlayerPokemon[]) => {
|
||||
const partyMemberCompatibleTms = party.map(p => p.compatibleTms);
|
||||
const uniqueCompatibleTms = partyMemberCompatibleTms.flat().filter((tm, i, array) => array.indexOf(tm) === i);
|
||||
if (!uniqueCompatibleTms.length)
|
||||
return null;
|
||||
const randTmIndex = Utils.randInt(uniqueCompatibleTms.length);
|
||||
return new TmModifierType(uniqueCompatibleTms[randTmIndex]);
|
||||
}), 4),
|
||||
new WeightedModifierType(new ModifierType('EXP. SHARE', 'All POKéMON in your party gain an additional 10% of a battle\'s EXP. Points', (type, _args) => new Modifiers.ExpShareModifier(type), 'exp_share'), 2),
|
||||
new WeightedModifierType(new ModifierTypeGenerator((party: PlayerPokemon[]) => {
|
||||
const randStat = Utils.randInt(6) as Stat;
|
||||
return new PokemonBaseStatBoosterModifierType(getBaseStatBoosterItemName(randStat), randStat);
|
||||
}), 4)
|
||||
new WeightedModifierType(modifierTypes.TEMP_STAT_BOOSTER, 4),
|
||||
new WeightedModifierType(modifierTypes.EXP_SHARE, 2),
|
||||
new WeightedModifierType(modifierTypes.BASE_STAT_BOOSTER, 4)
|
||||
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
|
||||
[ModifierTier.ULTRA]: [
|
||||
new WeightedModifierType(new AddPokeballModifierType(PokeballType.ULTRA_BALL, 5, 'ub'), 8),
|
||||
new WeightedModifierType(new EvolutionItemModifierTypeGenerator(), 12),
|
||||
new WeightedModifierType(new AttackTypeBoosterModifierTypeGenerator(), 5),
|
||||
new ModifierType('OVAL CHARM', 'For every X (no. of party members) items in a POKéMON\'s held item stack, give one to each other party member',
|
||||
(type, _args) => new Modifiers.PartyShareModifier(type), 'oval_charm'),
|
||||
new ModifierType('HEALING CHARM', 'Doubles the effectiveness of HP restoring moves and items (excludes revives)', (type, _args) => new Modifiers.HealingBoosterModifier(type, 2), 'healing_charm'),
|
||||
new WeightedModifierType(new PokemonHeldItemModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s dealt damage', (type, args) => new Modifiers.HitHealModifier(type, (args[0] as PlayerPokemon).id)), 2),
|
||||
new WeightedModifierType(new ExpBoosterModifierType('EXP CHARM', 25), 4),
|
||||
new WeightedModifierType(new PokemonExpBoosterModifierType('LUCKY EGG', 50), 3),
|
||||
new WeightedModifierType(new ModifierType('BERRY POUCH', 'Adds a 25% chance that a used berry will not be consumed',
|
||||
(type, _args) => new Modifiers.PreserveBerryModifier(type)), 3),
|
||||
new WeightedModifierType(new ModifierType('EXP. BALANCE', 'All EXP. Points received from battles is split among the lower leveled party members', (type, _args) => new Modifiers.ExpBalanceModifier(type), 'exp_balance'), 1)
|
||||
new WeightedModifierType(modifierTypes.ULTRA_BALL, 8),
|
||||
new WeightedModifierType(modifierTypes.EVOLUTION_ITEM, 12),
|
||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 5),
|
||||
modifierTypes.OVAL_CHARM,
|
||||
modifierTypes.HEALING_CHARM,
|
||||
new WeightedModifierType(modifierTypes.SHELL_BELL, 2),
|
||||
new WeightedModifierType(modifierTypes.EXP_CHARM, 4),
|
||||
new WeightedModifierType(modifierTypes.LUCKY_EGG, 3),
|
||||
new WeightedModifierType(modifierTypes.BERRY_POUCH, 3),
|
||||
modifierTypes.EXP_BALANCE
|
||||
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
|
||||
[ModifierTier.MASTER]: [
|
||||
new AddPokeballModifierType(PokeballType.MASTER_BALL, 1, 'mb'),
|
||||
new WeightedModifierType(new ModifierType('SHINY CHARM', 'Dramatically increases the chance of a wild POKéMON being shiny', (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)), 2)
|
||||
modifierTypes.MASTER_BALL,
|
||||
new WeightedModifierType(modifierTypes.SHINY_CHARM, 2)
|
||||
].map(m => { m.setTier(ModifierTier.MASTER); return m; }),
|
||||
[ModifierTier.LUXURY]: [
|
||||
new ModifierType(`GOLDEN ${getPokeballName(PokeballType.POKEBALL)}`, 'Adds 1 extra item option at the end of every battle', (type, _args) => new Modifiers.ExtraModifierModifier(type), 'pb_gold', null, 'pb_bounce_1'),
|
||||
new ExpBoosterModifierType('GOLDEN EXP CHARM', 100)
|
||||
modifierTypes.GOLDEN_POKEBALL,
|
||||
modifierTypes.GOLDEN_EXP_CHARM
|
||||
].map(m => { m.setTier(ModifierTier.LUXURY); return m; }),
|
||||
};
|
||||
|
||||
const enemyModifierPool = {
|
||||
[ModifierTier.COMMON]: [
|
||||
modifierTypes.BERRY
|
||||
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
|
||||
[ModifierTier.GREAT]: [
|
||||
modifierTypes.BASE_STAT_BOOSTER
|
||||
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
|
||||
[ModifierTier.ULTRA]: [
|
||||
new WeightedModifierType(new AttackTypeBoosterModifierTypeGenerator(), 5),
|
||||
new WeightedModifierType(modifierTypes.LUCKY_EGG, 2),
|
||||
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
|
||||
[ModifierTier.MASTER]: [
|
||||
modifierTypes.SHELL_BELL
|
||||
].map(m => { m.setTier(ModifierTier.MASTER); return m; })
|
||||
};
|
||||
|
||||
let modifierPoolThresholds = {};
|
||||
let ignoredPoolIndexes = {};
|
||||
|
||||
export function regenerateModifierPoolThresholds(party: PlayerPokemon[]) {
|
||||
ignoredPoolIndexes = {};
|
||||
modifierPoolThresholds = Object.fromEntries(new Map(Object.keys(modifierPool).map(t => {
|
||||
ignoredPoolIndexes[t] = [];
|
||||
let enemyModifierPoolThresholds = {};
|
||||
let enemyIgnoredPoolIndexes = {};
|
||||
|
||||
export function regenerateModifierPoolThresholds(party: Pokemon[], player?: boolean) {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
const pool = player ? modifierPool : enemyModifierPool;
|
||||
const ignoredIndexes = {};
|
||||
const thresholds = Object.fromEntries(new Map(Object.keys(pool).map(t => {
|
||||
ignoredIndexes[t] = [];
|
||||
const thresholds = new Map();
|
||||
let i = 0;
|
||||
modifierPool[t].reduce((total: integer, modifierType: ModifierType | WeightedModifierType) => {
|
||||
pool[t].reduce((total: integer, modifierType: ModifierType | WeightedModifierType) => {
|
||||
if (modifierType instanceof WeightedModifierType) {
|
||||
const weightedModifierType = modifierType as WeightedModifierType;
|
||||
const weight = weightedModifierType.weight instanceof Function
|
||||
|
@ -557,7 +646,7 @@ export function regenerateModifierPoolThresholds(party: PlayerPokemon[]) {
|
|||
if (weight)
|
||||
total += weight;
|
||||
else {
|
||||
ignoredPoolIndexes[t].push(i++);
|
||||
ignoredIndexes[t].push(i++);
|
||||
return total;
|
||||
}
|
||||
} else
|
||||
|
@ -567,9 +656,16 @@ export function regenerateModifierPoolThresholds(party: PlayerPokemon[]) {
|
|||
}, 0);
|
||||
return [ t, Object.fromEntries(thresholds) ]
|
||||
})));
|
||||
if (player) {
|
||||
modifierPoolThresholds = thresholds;
|
||||
ignoredPoolIndexes = ignoredIndexes;
|
||||
} else {
|
||||
enemyModifierPoolThresholds = thresholds;
|
||||
enemyIgnoredPoolIndexes = ignoredIndexes;
|
||||
}
|
||||
}
|
||||
|
||||
export function getModifierTypeOptionsForWave(waveIndex: integer, count: integer, party: PlayerPokemon[]): ModifierTypeOption[] {
|
||||
export function getPlayerModifierTypeOptionsForWave(waveIndex: integer, count: integer, party: PlayerPokemon[]): ModifierTypeOption[] {
|
||||
if (waveIndex % 10 === 0)
|
||||
return modifierPool[ModifierTier.LUXURY].map(m => new ModifierTypeOption(m, false));
|
||||
const options: ModifierTypeOption[] = [];
|
||||
|
@ -578,43 +674,58 @@ export function getModifierTypeOptionsForWave(waveIndex: integer, count: integer
|
|||
let candidate = getNewModifierTypeOption(party);
|
||||
let r = 0;
|
||||
while (options.length && ++r < retryCount && options.filter(o => o.type.name === candidate.type.name || o.type.group === candidate.type.group).length)
|
||||
candidate = getNewModifierTypeOption(party, candidate.type.tier, candidate.upgraded);
|
||||
candidate = getNewModifierTypeOption(party, true, candidate.type.tier, candidate.upgraded);
|
||||
options.push(candidate);
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
||||
function getNewModifierTypeOption(party: PlayerPokemon[], tier?: ModifierTier, upgrade?: boolean): ModifierTypeOption {
|
||||
export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[]): PokemonHeldItemModifierType[] {
|
||||
return new Array(count).fill(0).map(() => getNewModifierTypeOption(party, false).type as PokemonHeldItemModifierType);
|
||||
}
|
||||
|
||||
function getNewModifierTypeOption(party: Pokemon[], player?: boolean, tier?: ModifierTier, upgrade?: boolean): ModifierTypeOption {
|
||||
if (player === undefined)
|
||||
player = true;
|
||||
const tierValue = Utils.randInt(256);
|
||||
if (tier === undefined) {
|
||||
const partyShinyCount = party.filter(p => p.shiny).length;
|
||||
const upgradeOdds = Math.floor(32 / Math.max((partyShinyCount * 2), 1));
|
||||
upgrade = !Utils.randInt(upgradeOdds);
|
||||
if (player) {
|
||||
const partyShinyCount = party.filter(p => p.shiny).length;
|
||||
const upgradeOdds = Math.floor(32 / Math.max((partyShinyCount * 2), 1));
|
||||
upgrade = !Utils.randInt(upgradeOdds);
|
||||
} else
|
||||
upgrade = false;
|
||||
tier = (tierValue >= 52 ? ModifierTier.COMMON : tierValue >= 8 ? ModifierTier.GREAT : tierValue >= 1 ? ModifierTier.ULTRA : ModifierTier.MASTER) + (upgrade ? 1 : 0);
|
||||
}
|
||||
const thresholds = Object.keys(modifierPoolThresholds[tier]);
|
||||
|
||||
const thresholds = Object.keys((player ? modifierPoolThresholds : enemyModifierPoolThresholds)[tier]);
|
||||
const totalWeight = parseInt(thresholds[thresholds.length - 1]);
|
||||
const value = Utils.randInt(totalWeight);
|
||||
let index: integer;
|
||||
for (let t of thresholds) {
|
||||
let threshold = parseInt(t);
|
||||
if (value < threshold) {
|
||||
index = modifierPoolThresholds[tier][threshold];
|
||||
index = (player ? modifierPoolThresholds : enemyModifierPoolThresholds)[tier][threshold];
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier])
|
||||
let modifierType: ModifierType | WeightedModifierType = modifierPool[tier][index];
|
||||
|
||||
if (player)
|
||||
console.log(index, ignoredPoolIndexes[tier].filter(i => i <= index).length, ignoredPoolIndexes[tier])
|
||||
let modifierType: ModifierType | WeightedModifierType = (player ? modifierPool : enemyModifierPool)[tier][index];
|
||||
if (modifierType instanceof WeightedModifierType)
|
||||
modifierType = (modifierType as WeightedModifierType).modifierType;
|
||||
if (modifierType instanceof ModifierTypeGenerator) {
|
||||
modifierType = (modifierType as ModifierTypeGenerator).generateType(party);
|
||||
if (modifierType === null) {
|
||||
console.log(ModifierTier[tier], upgrade);
|
||||
return getNewModifierTypeOption(party, tier, upgrade);
|
||||
if (player)
|
||||
console.log(ModifierTier[tier], upgrade);
|
||||
return getNewModifierTypeOption(party, player, tier, upgrade);
|
||||
}
|
||||
}
|
||||
console.log(modifierType);
|
||||
|
||||
console.log(modifierType, !player ? '(enemy)' : '');
|
||||
|
||||
return new ModifierTypeOption(modifierType as ModifierType, upgrade);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import * as ModifierTypes from './modifier-type';
|
||||
import { CommonAnimPhase, LearnMovePhase, LevelUpPhase, PokemonHealPhase } from "../battle-phases";
|
||||
import { LearnMovePhase, LevelUpPhase, PokemonHealPhase } from "../battle-phases";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { getLevelTotalExp } from "../data/exp";
|
||||
import { PokeballType } from "../data/pokeball";
|
||||
import Pokemon, { PlayerPokemon } from "../pokemon";
|
||||
import Pokemon, { EnemyPokemon, PlayerPokemon } from "../pokemon";
|
||||
import { Stat } from "../data/pokemon-stat";
|
||||
import { addTextObject, TextStyle } from "../ui/text";
|
||||
import { Type } from '../data/type';
|
||||
|
@ -13,15 +13,17 @@ import { getPokemonMessage } from '../messages';
|
|||
import * as Utils from "../utils";
|
||||
import { TempBattleStat } from '../data/temp-battle-stat';
|
||||
import { BerryType, getBerryEffectFunc, getBerryPredicate } from '../data/berry';
|
||||
import { CommonAnim } from '../data/battle-anims';
|
||||
|
||||
type ModifierType = ModifierTypes.ModifierType;
|
||||
export type ModifierPredicate = (modifier: Modifier) => boolean;
|
||||
|
||||
export class ModifierBar extends Phaser.GameObjects.Container {
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, 1, 2);
|
||||
private player: boolean;
|
||||
|
||||
constructor(scene: BattleScene, enemy?: boolean) {
|
||||
super(scene, 1 + (enemy ? 302 : 0), 2);
|
||||
|
||||
this.player = !enemy;
|
||||
this.setScale(0.5);
|
||||
}
|
||||
|
||||
|
@ -41,7 +43,7 @@ export class ModifierBar extends Phaser.GameObjects.Container {
|
|||
const x = (this.getIndex(icon) % rowIcons) * 26 / (rowIcons / 12);
|
||||
const y = Math.floor(this.getIndex(icon) / rowIcons) * 20;
|
||||
|
||||
icon.setPosition(x, y);
|
||||
icon.setPosition(this.player ? x : -x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +274,8 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
|
|||
}
|
||||
|
||||
getPokemon(scene: BattleScene) {
|
||||
return scene.getParty().find(p => p.id === this.pokemonId);
|
||||
const findInParty = (party: Pokemon[]) => party.find(p => p.id === this.pokemonId);
|
||||
return findInParty(scene.getParty()) || findInParty(scene.getEnemyParty());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,7 +354,7 @@ export class HitHealModifier extends PokemonHeldItemModifier {
|
|||
}
|
||||
|
||||
apply(args: any[]): boolean {
|
||||
const pokemon = args[0] as PlayerPokemon;
|
||||
const pokemon = args[0] as Pokemon;
|
||||
|
||||
if (pokemon.turnData.damageDealt && pokemon.getHpRatio() < 1) {
|
||||
const scene = pokemon.scene;
|
||||
|
@ -375,7 +378,7 @@ export class BerryModifier extends PokemonHeldItemModifier {
|
|||
}
|
||||
|
||||
match(modifier: Modifier) {
|
||||
return modifier instanceof BerryModifier && (modifier as BerryModifier).berryType === this.berryType;
|
||||
return modifier instanceof BerryModifier && (modifier as BerryModifier).berryType === this.berryType && modifier.pokemonId === this.pokemonId;
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
@ -390,7 +393,9 @@ export class BerryModifier extends PokemonHeldItemModifier {
|
|||
const pokemon = args[0] as Pokemon;
|
||||
|
||||
const preserve = new Utils.BooleanHolder(false);
|
||||
pokemon.scene.applyModifiers(PreserveBerryModifier, preserve);
|
||||
pokemon.scene.applyModifiers(PreserveBerryModifier, pokemon.isPlayer(), preserve);
|
||||
|
||||
console.log(pokemon.isPlayer());
|
||||
|
||||
getBerryEffectFunc(this.berryType)(pokemon);
|
||||
if (!preserve.value)
|
||||
|
@ -439,7 +444,7 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier {
|
|||
}
|
||||
|
||||
shouldApply(args: any[]): boolean {
|
||||
return args.length && args[0] instanceof Pokemon && (this.pokemonId === -1 || (args[0] as Pokemon).id === this.pokemonId);
|
||||
return args.length && args[0] instanceof PlayerPokemon && (this.pokemonId === -1 || (args[0] as PlayerPokemon).id === this.pokemonId);
|
||||
}
|
||||
|
||||
getPokemon(scene: BattleScene) {
|
||||
|
@ -623,7 +628,7 @@ export class PartyShareModifier extends PersistentModifier {
|
|||
continue;
|
||||
const newHeldItemModifier = heldItemModifier.clone() as PokemonHeldItemModifier;
|
||||
newHeldItemModifier.pokemonId = p.id;
|
||||
scene.addModifier(newHeldItemModifier, true);
|
||||
scene.addModifier(newHeldItemModifier, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
|
||||
if (this.shiny === undefined) {
|
||||
let shinyThreshold = new Utils.IntegerHolder(32);
|
||||
this.scene.applyModifiers(ShinyRateBoosterModifier, shinyThreshold);
|
||||
this.scene.applyModifiers(ShinyRateBoosterModifier, this.isPlayer(), shinyThreshold);
|
||||
console.log(shinyThreshold.value);
|
||||
|
||||
this.shiny = (E ^ F) < shinyThreshold.value;
|
||||
|
@ -267,7 +267,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
const battleStat = (stat - 1) as BattleStat;
|
||||
const statLevel = new Utils.IntegerHolder(this.summonData.battleStats[battleStat]);
|
||||
if (this.isPlayer())
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, battleStat as integer as TempBattleStat, statLevel);
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), battleStat as integer as TempBattleStat, statLevel);
|
||||
let ret = this.stats[stat] * (Math.max(2, 2 + statLevel.value) / Math.max(2, 2 - statLevel.value));
|
||||
if (stat === Stat.SPDEF && this.scene.arena.weather?.weatherType === WeatherType.SANDSTORM)
|
||||
ret *= 1.5;
|
||||
|
@ -280,7 +280,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
if (!this.stats)
|
||||
this.stats = [ 0, 0, 0, 0, 0, 0 ];
|
||||
const baseStats = this.getSpeciesForm().baseStats.slice(0);
|
||||
this.scene.applyModifiers(PokemonBaseStatModifier, this, baseStats);
|
||||
this.scene.applyModifiers(PokemonBaseStatModifier, this.isPlayer(), this, baseStats);
|
||||
const stats = Utils.getEnumValues(Stat);
|
||||
for (let s of stats) {
|
||||
const isHp = s === Stat.HP;
|
||||
|
@ -464,11 +464,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
const typeMultiplier = getTypeDamageMultiplier(move.type, this.getSpeciesForm().type1) * (this.getSpeciesForm().type2 !== null ? getTypeDamageMultiplier(move.type, this.getSpeciesForm().type2) : 1);
|
||||
const weatherTypeMultiplier = this.scene.arena.getAttackTypeMultiplier(move.type);
|
||||
applyMoveAttrs(VariablePowerAttr, source, this, move, power);
|
||||
this.scene.applyModifiers(AttackTypeBoosterModifier, source, power);
|
||||
this.scene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, power);
|
||||
const critLevel = new Utils.IntegerHolder(0);
|
||||
applyMoveAttrs(HighCritAttr, source, this, move, critLevel);
|
||||
if (source.isPlayer())
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, TempBattleStat.CRIT, critLevel);
|
||||
this.scene.applyModifiers(TempBattleStatBoosterModifier, source.isPlayer(), TempBattleStat.CRIT, critLevel);
|
||||
const critChance = Math.ceil(16 / Math.pow(2, critLevel.value));
|
||||
let isCritical = !source.getTag(BattleTagType.NO_CRIT) && (critChance === 1 || !Utils.randInt(critChance));
|
||||
const sourceAtk = source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK);
|
||||
|
@ -968,7 +967,7 @@ export class EnemyPokemon extends Pokemon {
|
|||
let ret: PlayerPokemon = null;
|
||||
|
||||
if (party.length < 6) {
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level, this.formIndex, this.gender, this.shiny);
|
||||
const newPokemon = new PlayerPokemon(this.scene, this.species, this.level, this.formIndex, this.gender, this.shiny, this);
|
||||
party.push(newPokemon);
|
||||
ret = newPokemon;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue