Add rerolling modifiers for money and fix field UI layering issues

pull/2/head
Flashfyre 2023-11-10 15:51:34 -05:00
parent 5a88344173
commit 83fae68abf
8 changed files with 237 additions and 94 deletions

BIN
public/audio/se/buy.wav Normal file

Binary file not shown.

View File

@ -2204,13 +2204,15 @@ export class TrainerVictoryPhase extends BattlePhase {
start() { start() {
this.scene.playBgm(this.scene.currentBattle.trainer.config.victoryBgm); this.scene.playBgm(this.scene.currentBattle.trainer.config.victoryBgm);
this.scene.unshiftPhase(new MoneyRewardPhase(this.scene, this.scene.currentBattle.trainer.config.moneyMultiplier));
const modifierRewardFuncs = this.scene.currentBattle.trainer.config.modifierRewardFuncs; const modifierRewardFuncs = this.scene.currentBattle.trainer.config.modifierRewardFuncs;
for (let modifierRewardFunc of modifierRewardFuncs) for (let modifierRewardFunc of modifierRewardFuncs)
this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, modifierRewardFunc)); this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, modifierRewardFunc));
this.scene.ui.showText(`You defeated\n${this.scene.currentBattle.trainer.getName()}!`, null, () => { this.scene.ui.showText(`You defeated\n${this.scene.currentBattle.trainer.getName()}!`, null, () => {
const defeatMessages = this.scene.currentBattle.trainer.config.victoryMessages; const defeatMessages = this.scene.currentBattle.trainer.config.victoryMessages;
let showMessageAndEnd = () => this.end();//this.scene.ui.showText(`You got ₽0\nfor winning!`, null, () => this.end(), null, true); let showMessageAndEnd = () => this.end();
if (defeatMessages.length) { if (defeatMessages.length) {
let message: string; let message: string;
this.scene.executeWithSeedOffset(() => message = Phaser.Math.RND.pick(this.scene.currentBattle.trainer.config.victoryMessages), this.scene.currentBattle.waveIndex); this.scene.executeWithSeedOffset(() => message = Phaser.Math.RND.pick(this.scene.currentBattle.trainer.config.victoryMessages), this.scene.currentBattle.waveIndex);
@ -2235,6 +2237,28 @@ export class TrainerVictoryPhase extends BattlePhase {
} }
} }
export class MoneyRewardPhase extends BattlePhase {
private moneyMultiplier: number;
constructor(scene: BattleScene, moneyMultiplier: number) {
super(scene);
this.moneyMultiplier = moneyMultiplier;
}
start() {
const waveIndex = this.scene.currentBattle.waveIndex;
const waveSetIndex = Math.ceil(waveIndex / 10) - 1;
const moneyValue = Math.pow((waveSetIndex + 1 + (0.75 + (((waveIndex - 1) % 10) + 1) / 10)) * 100, 1 + 0.005 * waveSetIndex) * this.moneyMultiplier;
const moneyAmount = Math.floor(moneyValue / 10) * 10;
this.scene.money += moneyAmount;
this.scene.updateMoneyText();
this.scene.ui.showText(`You got ₽${moneyAmount.toLocaleString('en-US')}\nfor winning!`, null, () => this.end(), null, true);
}
}
export class ModifierRewardPhase extends BattlePhase { export class ModifierRewardPhase extends BattlePhase {
private modifierType: ModifierType; private modifierType: ModifierType;
@ -2864,14 +2888,19 @@ export class AttemptRunPhase extends PokemonPhase {
} }
export class SelectModifierPhase extends BattlePhase { export class SelectModifierPhase extends BattlePhase {
constructor(scene: BattleScene) { private rerollCount: integer;
constructor(scene: BattleScene, rerollCount: integer = 0) {
super(scene); super(scene);
this.rerollCount = rerollCount;
} }
start() { start() {
super.start(); super.start();
this.updateSeed(); if (!this.rerollCount)
this.updateSeed();
const party = this.scene.getParty(); const party = this.scene.getParty();
regenerateModifierPoolThresholds(party, this.getPoolType()); regenerateModifierPoolThresholds(party, this.getPoolType());
@ -2884,8 +2913,22 @@ export class SelectModifierPhase extends BattlePhase {
if (cursor < 0) { if (cursor < 0) {
this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.setMode(Mode.MESSAGE);
super.end(); super.end();
return; return true;
} else if (cursor >= typeOptions.length) { } else if (cursor === typeOptions.length) {
const rerollCost = this.getRerollCost();
if (this.scene.money < rerollCost) {
this.scene.ui.playError();
return false;
} else {
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, this.rerollCount + 1));
this.scene.ui.clearText();
this.scene.ui.setMode(Mode.MESSAGE).then(() => super.end());
this.scene.money -= rerollCost;
this.scene.updateMoneyText();
this.scene.playSound('buy');
}
return true;
} else if (cursor === typeOptions.length + 1) {
this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, toSlotIndex: integer) => { this.scene.ui.setModeWithoutClear(Mode.PARTY, PartyUiMode.MODIFIER_TRANSFER, -1, (fromSlotIndex: integer, itemIndex: integer, toSlotIndex: integer) => {
if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) { if (toSlotIndex !== undefined && fromSlotIndex < 6 && toSlotIndex < 6 && fromSlotIndex !== toSlotIndex && itemIndex > -1) {
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => { this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer()).then(() => {
@ -2898,13 +2941,13 @@ export class SelectModifierPhase extends BattlePhase {
this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.setMode(Mode.MESSAGE);
super.end(); super.end();
} else } else
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback); this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost());
}); });
}); });
} else } else
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback); this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost());
}, PartyUiHandler.FilterItemMaxStacks); }, PartyUiHandler.FilterItemMaxStacks);
return; return true;
} }
const modifierType = typeOptions[cursor].type; const modifierType = typeOptions[cursor].type;
@ -2919,7 +2962,7 @@ export class SelectModifierPhase extends BattlePhase {
this.scene.addModifier(modifier, false, true).then(() => super.end()); this.scene.addModifier(modifier, false, true).then(() => super.end());
}); });
} else } else
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback); this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost());
}, modifierType.selectFilter); }, modifierType.selectFilter);
} else { } else {
const pokemonModifierType = modifierType as PokemonModifierType; const pokemonModifierType = modifierType as PokemonModifierType;
@ -2947,7 +2990,7 @@ export class SelectModifierPhase extends BattlePhase {
this.scene.addModifier(modifier, false, true).then(() => super.end()); this.scene.addModifier(modifier, false, true).then(() => super.end());
}); });
} else } else
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, ); this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost());
}, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId); }, pokemonModifierType.selectFilter, modifierType instanceof PokemonMoveModifierType ? (modifierType as PokemonMoveModifierType).moveSelectFilter : undefined, tmMoveId);
} }
} else { } else {
@ -2955,8 +2998,10 @@ export class SelectModifierPhase extends BattlePhase {
this.scene.ui.clearText(); this.scene.ui.clearText();
this.scene.ui.setMode(Mode.MESSAGE); this.scene.ui.setMode(Mode.MESSAGE);
} }
return true;
}; };
this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback); this.scene.ui.setMode(Mode.MODIFIER_SELECT, this.isPlayer(), typeOptions, modifierSelectCallback, this.getRerollCost());
} }
updateSeed(): void { updateSeed(): void {
@ -2967,6 +3012,10 @@ export class SelectModifierPhase extends BattlePhase {
return true; return true;
} }
getRerollCost(): integer {
return Math.ceil(this.scene.currentBattle.waveIndex / 10) * 250 * Math.pow(2, this.rerollCount);
}
getPoolType(): ModifierPoolType { getPoolType(): ModifierPoolType {
return ModifierPoolType.PLAYER; return ModifierPoolType.PLAYER;
} }

View File

@ -106,6 +106,7 @@ export default class BattleScene extends Phaser.Scene {
private moneyText: Phaser.GameObjects.Text; private moneyText: Phaser.GameObjects.Text;
private modifierBar: ModifierBar; private modifierBar: ModifierBar;
private enemyModifierBar: ModifierBar; private enemyModifierBar: ModifierBar;
private fieldOverlay: Phaser.GameObjects.Rectangle;
private modifiers: PersistentModifier[]; private modifiers: PersistentModifier[];
private enemyModifiers: PersistentModifier[]; private enemyModifiers: PersistentModifier[];
public uiContainer: Phaser.GameObjects.Container; public uiContainer: Phaser.GameObjects.Container;
@ -304,6 +305,7 @@ export default class BattleScene extends Phaser.Scene {
this.loadSe('charge'); this.loadSe('charge');
this.loadSe('beam'); this.loadSe('beam');
this.loadSe('upgrade'); this.loadSe('upgrade');
this.loadSe('buy');
this.loadSe('error'); this.loadSe('error');
this.loadSe('pb_rel'); this.loadSe('pb_rel');
@ -370,6 +372,13 @@ export default class BattleScene extends Phaser.Scene {
this.uiContainer = uiContainer; this.uiContainer = uiContainer;
const overlayWidth = this.game.canvas.width / 6;
const overlayHeight = (this.game.canvas.height / 6) - 48;
this.fieldOverlay = this.add.rectangle(0, overlayHeight * -1 - 48, overlayWidth, overlayHeight, 0x424242);
this.fieldOverlay.setOrigin(0, 0);
this.fieldOverlay.setAlpha(0);
this.fieldUI.add(this.fieldOverlay);
this.modifiers = []; this.modifiers = [];
this.enemyModifiers = []; this.enemyModifiers = [];
@ -788,6 +797,30 @@ export default class BattleScene extends Phaser.Scene {
Phaser.Math.RND.state(state); Phaser.Math.RND.state(state);
} }
showFieldOverlay(duration: integer): Promise<void> {
return new Promise(resolve => {
this.tweens.add({
targets: this.fieldOverlay,
alpha: 0.5,
ease: 'Sine.easeOut',
duration: duration,
onComplete: () => resolve()
});
});
}
hideFieldOverlay(duration: integer): Promise<void> {
return new Promise(resolve => {
this.tweens.add({
targets: this.fieldOverlay,
alpha: 0,
duration: duration,
ease: 'Cubic.easeIn',
onComplete: () => resolve()
});
});
}
updateWaveCountText(): void { updateWaveCountText(): void {
const isBoss = !(this.currentBattle.waveIndex % 10); const isBoss = !(this.currentBattle.waveIndex % 10);
this.waveCountText.setText(this.currentBattle.waveIndex.toString()); this.waveCountText.setText(this.currentBattle.waveIndex.toString());

View File

@ -65,7 +65,7 @@ export const biomeLinks: BiomeLinks = {
[Biome.PLAINS]: [ Biome.GRASS, Biome.CITY, Biome.LAKE ], [Biome.PLAINS]: [ Biome.GRASS, Biome.CITY, Biome.LAKE ],
[Biome.GRASS]: Biome.TALL_GRASS, [Biome.GRASS]: Biome.TALL_GRASS,
[Biome.TALL_GRASS]: [ Biome.FOREST, Biome.CAVE ], [Biome.TALL_GRASS]: [ Biome.FOREST, Biome.CAVE ],
[Biome.CITY]: [ Biome.CONSTRUCTION_SITE ], [Biome.CITY]: Biome.CONSTRUCTION_SITE,
[Biome.FOREST]: [ Biome.JUNGLE, Biome.MEADOW ], [Biome.FOREST]: [ Biome.JUNGLE, Biome.MEADOW ],
[Biome.SEA]: [ Biome.SEABED, Biome.ICE_CAVE ], [Biome.SEA]: [ Biome.SEABED, Biome.ICE_CAVE ],
[Biome.SWAMP]: [ Biome.GRAVEYARD, Biome.TALL_GRASS ], [Biome.SWAMP]: [ Biome.GRAVEYARD, Biome.TALL_GRASS ],

View File

@ -279,6 +279,7 @@ export class TrainerConfig {
public nameFemale: string; public nameFemale: string;
public hasGenders: boolean = false; public hasGenders: boolean = false;
public isDouble: boolean = false; public isDouble: boolean = false;
public moneyMultiplier: number = 1;
public isBoss: boolean = false; public isBoss: boolean = false;
public hasStaticParty: boolean = false; public hasStaticParty: boolean = false;
public battleBgm: string; public battleBgm: string;
@ -349,6 +350,11 @@ export class TrainerConfig {
return this; return this;
} }
setMoneyMultiplier(moneyMultiplier: number): TrainerConfig {
this.moneyMultiplier = moneyMultiplier;
return this;
}
setBoss(): TrainerConfig { setBoss(): TrainerConfig {
this.isBoss = true; this.isBoss = true;
return this; return this;
@ -433,6 +439,7 @@ export class TrainerConfig {
this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ])); this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ]));
if (specialtyType !== undefined) if (specialtyType !== undefined)
this.setSpeciesFilter(p => p.isOfType(specialtyType)); this.setSpeciesFilter(p => p.isOfType(specialtyType));
this.setMoneyMultiplier(2.5);
this.setBoss(); this.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_gym'); this.setBattleBgm('battle_gym');
@ -447,6 +454,7 @@ export class TrainerConfig {
this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= 450); this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= 450);
else else
this.setSpeciesFilter(p => p.baseTotal >= 450); this.setSpeciesFilter(p => p.baseTotal >= 450);
this.setMoneyMultiplier(3.25);
this.setBoss(); this.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_elite'); this.setBattleBgm('battle_elite');
@ -458,6 +466,7 @@ export class TrainerConfig {
this.setPartyTemplates(trainerPartyTemplates.CHAMPION); this.setPartyTemplates(trainerPartyTemplates.CHAMPION);
this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ])); this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ]));
this.setSpeciesFilter(p => p.baseTotal >= 470); this.setSpeciesFilter(p => p.baseTotal >= 470);
this.setMoneyMultiplier(10);
this.setBoss(); this.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_champion'); this.setBattleBgm('battle_champion');
@ -539,23 +548,23 @@ function getSpeciesFilterRandomPartyMemberFunc(speciesFilter: PokemonSpeciesFilt
} }
export const trainerConfigs: TrainerConfigs = { export const trainerConfigs: TrainerConfigs = {
[TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.ACE_TRAINER) [TrainerType.ACE_TRAINER]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER)
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.THREE_WEAK_BALANCED, trainerPartyTemplates.FOUR_WEAK_BALANCED, trainerPartyTemplates.FIVE_WEAK_BALANCED, trainerPartyTemplates.SIX_WEAK_BALANCED)), .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.THREE_WEAK_BALANCED, trainerPartyTemplates.FOUR_WEAK_BALANCED, trainerPartyTemplates.FIVE_WEAK_BALANCED, trainerPartyTemplates.SIX_WEAK_BALANCED)),
[TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG).setSpeciesPools([ Species.SMEARGLE ]), [TrainerType.ARTIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setPartyTemplates(trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.THREE_AVG).setSpeciesPools([ Species.SMEARGLE ]),
[TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders().setDouble().setEncounterBgm(TrainerType.CYCLIST), [TrainerType.BACKERS]: new TrainerConfig(++t).setHasGenders().setDouble().setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders().setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER), [TrainerType.BACKPACKER]: new TrainerConfig(++t).setHasGenders().setSpeciesFilter(s => s.isOfType(Type.FLYING) || s.isOfType(Type.ROCK)).setEncounterBgm(TrainerType.BACKPACKER),
[TrainerType.BAKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.GRASS) || s.isOfType(Type.FIRE)), [TrainerType.BAKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.35).setSpeciesFilter(s => s.isOfType(Type.GRASS) || s.isOfType(Type.FIRE)),
[TrainerType.BEAUTY]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PARASOL_LADY), [TrainerType.BEAUTY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY),
[TrainerType.BIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON)), [TrainerType.BIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON)),
[TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders('Battle Girl', TrainerType.PSYCHIC).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.FIGHTING)), [TrainerType.BLACK_BELT]: new TrainerConfig(++t).setHasGenders('Battle Girl', TrainerType.PSYCHIC).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.FIGHTING)),
[TrainerType.BREEDER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.POKEFAN).setHasGenders().setDouble() [TrainerType.BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(1.325).setEncounterBgm(TrainerType.POKEFAN).setHasGenders().setDouble()
.setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)), .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.FOUR_WEAKER, trainerPartyTemplates.FIVE_WEAKER, trainerPartyTemplates.SIX_WEAKER)),
[TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CLERK), [TrainerType.CLERK]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CLERK),
[TrainerType.CYCLIST]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CYCLIST).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.QUICK_ATTACK)), [TrainerType.CYCLIST]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setHasGenders().setEncounterBgm(TrainerType.CYCLIST).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.QUICK_ATTACK)),
[TrainerType.DANCER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.DANCER]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK), [TrainerType.DEPOT_AGENT]: new TrainerConfig(++t).setMoneyMultiplier(1.45).setEncounterBgm(TrainerType.CLERK),
[TrainerType.DOCTOR]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK), [TrainerType.DOCTOR]: new TrainerConfig(++t).setMoneyMultiplier(3).setEncounterBgm(TrainerType.CLERK),
[TrainerType.FISHERMAN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER) [TrainerType.FISHERMAN]: new TrainerConfig(++t).setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.BACKPACKER)
.setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER) .setPartyTemplates(trainerPartyTemplates.TWO_WEAK_SAME_ONE_AVG, trainerPartyTemplates.ONE_AVG, trainerPartyTemplates.THREE_WEAK_SAME, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.SIX_WEAKER)
.setSpeciesPools({ .setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.TENTACOOL, Species.MAGIKARP, Species.GOLDEEN, Species.STARYU, Species.REMORAID ], [TrainerPoolTier.COMMON]: [ Species.TENTACOOL, Species.MAGIKARP, Species.GOLDEEN, Species.STARYU, Species.REMORAID ],
@ -564,46 +573,48 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerPoolTier.SUPER_RARE]: [ Species.LAPRAS, Species.FEEBAS, Species.RELICANTH ] [TrainerPoolTier.SUPER_RARE]: [ Species.LAPRAS, Species.FEEBAS, Species.RELICANTH ]
} }
), ),
[TrainerType.GUITARIST]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.ELECTRIC)), [TrainerType.GUITARIST]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.ELECTRIC)),
[TrainerType.HARLEQUIN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PSYCHIC).setSpeciesFilter(s => tmSpecies[Moves.TRICK_ROOM].indexOf(s.speciesId) > -1), [TrainerType.HARLEQUIN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PSYCHIC).setSpeciesFilter(s => tmSpecies[Moves.TRICK_ROOM].indexOf(s.speciesId) > -1),
[TrainerType.HIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER).setSpeciesFilter(s => s.isOfType(Type.GROUND) || s.isOfType(Type.ROCK)) [TrainerType.HIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER).setSpeciesFilter(s => s.isOfType(Type.GROUND) || s.isOfType(Type.ROCK))
.setPartyTemplates(trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, trainerPartyTemplates.TWO_AVG_SAME_ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.ONE_STRONG), .setPartyTemplates(trainerPartyTemplates.TWO_AVG_SAME_ONE_AVG, trainerPartyTemplates.TWO_AVG_SAME_ONE_STRONG, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.ONE_STRONG),
[TrainerType.HOOLIGANS]: new TrainerConfig(++t).setDouble().setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON) || s.isOfType(Type.DARK)), [TrainerType.HOOLIGANS]: new TrainerConfig(++t).setDouble().setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.POISON) || s.isOfType(Type.DARK)),
[TrainerType.HOOPSTER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.HOOPSTER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.INFIELDER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.INFIELDER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.JANITOR]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK), [TrainerType.JANITOR]: new TrainerConfig(++t).setMoneyMultiplier(1.1).setEncounterBgm(TrainerType.CLERK),
[TrainerType.LINEBACKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.LINEBACKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.MAID]: new TrainerConfig(++t).setEncounterBgm(TrainerType.RICH).setSpeciesFilter(s => s.eggType1 === 'Field' || s.eggType2 === 'Field'), [TrainerType.MAID]: new TrainerConfig(++t).setMoneyMultiplier(1.6).setEncounterBgm(TrainerType.RICH).setSpeciesFilter(s => s.eggType1 === 'Field' || s.eggType2 === 'Field'),
[TrainerType.MUSICIAN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SING)), [TrainerType.MUSICIAN]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.SING)),
[TrainerType.NURSE]: new TrainerConfig(++t).setEncounterBgm('lass').setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.CHARM) || !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)), [TrainerType.NURSE]: new TrainerConfig(++t).setMoneyMultiplier(1.8).setEncounterBgm('lass').setSpeciesFilter(s => !!s.getLevelMoves().find(plm => plm[1] === Moves.CHARM) || !!s.getLevelMoves().find(plm => plm[1] === Moves.HEAL_PULSE)),
[TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setEncounterBgm('lass'), [TrainerType.NURSERY_AIDE]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm('lass'),
[TrainerType.OFFICER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesPools([ Species.VULPIX, Species.GROWLITHE, Species.SNUBBULL, Species.HOUNDOUR, Species.POOCHYENA, Species.ELECTRIKE, Species.LILLIPUP ]), [TrainerType.OFFICER]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.CLERK).setSpeciesPools([ Species.VULPIX, Species.GROWLITHE, Species.SNUBBULL, Species.HOUNDOUR, Species.POOCHYENA, Species.ELECTRIKE, Species.LILLIPUP ]),
[TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.PARASOL_LADY]: new TrainerConfig(++t).setMoneyMultiplier(1.55).setEncounterBgm(TrainerType.PARASOL_LADY).setSpeciesFilter(s => s.isOfType(Type.WATER)),
[TrainerType.PILOT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1), [TrainerType.PILOT]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => tmSpecies[Moves.FLY].indexOf(s.speciesId) > -1),
[TrainerType.POKEFAN]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.POKEFAN) [TrainerType.POKEFAN]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setHasGenders().setEncounterBgm(TrainerType.POKEFAN)
.setPartyTemplates(trainerPartyTemplates.SIX_WEAKER, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.FOUR_WEAK_SAME, trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.SIX_WEAKER_SAME), .setPartyTemplates(trainerPartyTemplates.SIX_WEAKER, trainerPartyTemplates.FOUR_WEAK, trainerPartyTemplates.TWO_AVG, trainerPartyTemplates.ONE_STRONG, trainerPartyTemplates.FOUR_WEAK_SAME, trainerPartyTemplates.FIVE_WEAK, trainerPartyTemplates.SIX_WEAKER_SAME),
[TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders(undefined, 'lass'), [TrainerType.PRESCHOOLER]: new TrainerConfig(++t).setMoneyMultiplier(0.2).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders(undefined, 'lass'),
[TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.PSYCHIC), [TrainerType.PSYCHIC]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.PSYCHIC),
[TrainerType.RANGER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.BACKPACKER).setHasGenders(), [TrainerType.RANGER]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.BACKPACKER).setHasGenders(),
[TrainerType.RICH]: new TrainerConfig(++t).setName('Gentleman').setHasGenders().setSpeciesFilter(s => s.eggType1 === 'Field' || s.eggType2 === 'Field'), [TrainerType.RICH]: new TrainerConfig(++t).setMoneyMultiplier(5).setName('Gentleman').setHasGenders().setSpeciesFilter(s => s.eggType1 === 'Field' || s.eggType2 === 'Field'),
[TrainerType.RICH_KID]: new TrainerConfig(++t).setName('Rich Boy').setHasGenders('Lady').setEncounterBgm(TrainerType.RICH), [TrainerType.RICH_KID]: new TrainerConfig(++t).setMoneyMultiplier(3.75).setName('Rich Boy').setHasGenders('Lady').setEncounterBgm(TrainerType.RICH),
[TrainerType.ROUGHNECK]: new TrainerConfig(++t).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.DARK)), [TrainerType.ROUGHNECK]: new TrainerConfig(++t).setMoneyMultiplier(1.4).setEncounterBgm(TrainerType.ROUGHNECK).setSpeciesFilter(s => s.isOfType(Type.DARK)),
[TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.SCIENTIST).setSpeciesPools({ [TrainerType.SCIENTIST]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.SCIENTIST).setSpeciesPools({
[TrainerPoolTier.COMMON]: [ Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING ], [TrainerPoolTier.COMMON]: [ Species.MAGNEMITE, Species.GRIMER, Species.DROWZEE, Species.VOLTORB, Species.KOFFING ],
[TrainerPoolTier.UNCOMMON]: [ Species.KLINK ], [TrainerPoolTier.UNCOMMON]: [ Species.KLINK ],
[TrainerPoolTier.RARE ]: [ Species.ABRA, Species.PORYGON ], [TrainerPoolTier.RARE ]: [ Species.ABRA, Species.PORYGON ],
[TrainerPoolTier.SUPER_RARE ]: [ Species.OMANYTE, Species.KABUTO, Species.AERODACTYL, Species.LILEEP, Species.ANORITH, Species.CRANIDOS, Species.SHIELDON, Species.TIRTOUGA, Species.ARCHEN ] [TrainerPoolTier.SUPER_RARE ]: [ Species.OMANYTE, Species.KABUTO, Species.AERODACTYL, Species.LILEEP, Species.ANORITH, Species.CRANIDOS, Species.SHIELDON, Species.TIRTOUGA, Species.ARCHEN ]
}), }),
[TrainerType.SMASHER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.SMASHER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName('Worker').setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)), [TrainerType.SNOW_WORKER]: new TrainerConfig(++t).setName('Worker').setMoneyMultiplier(1.7).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ICE) || s.isOfType(Type.STEEL)),
[TrainerType.STRIKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CYCLIST), [TrainerType.STRIKER]: new TrainerConfig(++t).setMoneyMultiplier(1.2).setEncounterBgm(TrainerType.CYCLIST),
[TrainerType.STUDENT]: new TrainerConfig(++t).setHasGenders(), [TrainerType.STUDENT]: new TrainerConfig(++t).setHasGenders(),
[TrainerType.SWIMMER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders().setSpeciesFilter(s => s.isOfType(Type.WATER)), [TrainerType.SWIMMER]: new TrainerConfig(++t).setMoneyMultiplier(1.3).setEncounterBgm(TrainerType.PARASOL_LADY).setHasGenders().setSpeciesFilter(s => s.isOfType(Type.WATER)),
[TrainerType.TWINS]: new TrainerConfig(++t).setDouble().setEncounterBgm(TrainerType.TWINS), [TrainerType.TWINS]: new TrainerConfig(++t).setDouble().setMoneyMultiplier(0.65)
[TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.RICH), .setPartyTemplateFunc(scene => getWavePartyTemplate(scene, trainerPartyTemplates.TWO_WEAK, trainerPartyTemplates.FOUR_WEAK))
[TrainerType.WAITER]: new TrainerConfig(++t).setHasGenders().setEncounterBgm(TrainerType.CLERK), .setEncounterBgm(TrainerType.TWINS),
[TrainerType.WORKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)), [TrainerType.VETERAN]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(2.5).setEncounterBgm(TrainerType.RICH),
[TrainerType.YOUNGSTER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders('Lass', 'lass').setPartyTemplates(trainerPartyTemplates.TWO_WEAKER) [TrainerType.WAITER]: new TrainerConfig(++t).setHasGenders().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.CLERK),
[TrainerType.WORKER]: new TrainerConfig(++t).setEncounterBgm(TrainerType.CLERK).setMoneyMultiplier(1.7).setSpeciesFilter(s => s.isOfType(Type.ROCK) || s.isOfType(Type.STEEL)),
[TrainerType.YOUNGSTER]: new TrainerConfig(++t).setMoneyMultiplier(0.5).setEncounterBgm(TrainerType.YOUNGSTER).setHasGenders('Lass', 'lass').setPartyTemplates(trainerPartyTemplates.TWO_WEAKER)
.setSpeciesPools( .setSpeciesPools(
[ Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP ] [ Species.CATERPIE, Species.WEEDLE, Species.RATTATA, Species.SENTRET, Species.POOCHYENA, Species.ZIGZAGOON, Species.WURMPLE, Species.BIDOOF, Species.PATRAT, Species.LILLIPUP ]
).setEncounterMessages([ ).setEncounterMessages([
@ -693,7 +704,7 @@ export const trainerConfigs: TrainerConfigs = {
$Do your best like always! I believe in you!` $Do your best like always! I believe in you!`
]).setModifierRewardFuncs(() => modifierTypes.EXP_CHARM, () => modifierTypes.EXP_SHARE).setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT ])) ]).setModifierRewardFuncs(() => modifierTypes.EXP_CHARM, () => modifierTypes.EXP_SHARE).setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE ])), .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE ])),
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL_2).setEncounterMessages([ [TrainerType.RIVAL_2]: new TrainerConfig(++t).setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL_2).setEncounterMessages([
`Oh, fancy meeting you here. Looks like you're still undefeated. Right on! `Oh, fancy meeting you here. Looks like you're still undefeated. Right on!
$I know what you're thinking, and no, I wasn't following you. I just happened to be in the area. $I know what you're thinking, and no, I wasn't following you. I just happened to be in the area.
$I'm happy for you but I just want to let you know that it's OK to lose sometimes. $I'm happy for you but I just want to let you know that it's OK to lose sometimes.
@ -704,7 +715,7 @@ export const trainerConfigs: TrainerConfigs = {
]).setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT ])) ]).setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL ]))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)), .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
[TrainerType.RIVAL_3]: new TrainerConfig(++t).setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL_3).setEncounterMessages([ [TrainerType.RIVAL_3]: new TrainerConfig(++t).setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival').setPartyTemplates(trainerPartyTemplates.RIVAL_3).setEncounterMessages([
`Long time no see! Still haven't lost, huh.\nYou're starting to get on my nerves. Just kidding! `Long time no see! Still haven't lost, huh.\nYou're starting to get on my nerves. Just kidding!
$But really, I think it's about time you came home.\nYour family and friends miss you, you know. $But really, I think it's about time you came home.\nYour family and friends miss you, you know.
$I know your dream means a lot to you, but the reality is you're going to lose sooner or later. $I know your dream means a lot to you, but the reality is you're going to lose sooner or later.
@ -715,7 +726,7 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ]))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540), .setSpeciesFilter(species => species.baseTotal >= 540),
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setBoss().setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_2').setPartyTemplates(trainerPartyTemplates.RIVAL_4).setEncounterMessages([ [TrainerType.RIVAL_4]: new TrainerConfig(++t).setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_2').setPartyTemplates(trainerPartyTemplates.RIVAL_4).setEncounterMessages([
`It's me! You didn't forget about me again did you? `It's me! You didn't forget about me again did you?
$You made it really far! I'm proud of you.\nBut it looks like it's the end of your journey. $You made it really far! I'm proud of you.\nBut it looks like it's the end of your journey.
$You've awoken something in me I never knew was there.\nIt seems like all I do now is train. $You've awoken something in me I never knew was there.\nIt seems like all I do now is train.
@ -729,13 +740,13 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ]))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540), .setSpeciesFilter(species => species.baseTotal >= 540),
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setBoss().setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_5).setEncounterMessages([ `` ]).setVictoryMessages([ '…' ]) [TrainerType.RIVAL_5]: new TrainerConfig(++t).setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_5).setEncounterMessages([ `` ]).setVictoryMessages([ '…' ])
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT ])) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ]))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540) .setSpeciesFilter(species => species.baseTotal >= 540)
.setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.RAYQUAZA ])), .setPartyMemberFunc(5, getRandomPartyMemberFunc([ Species.RAYQUAZA ])),
[TrainerType.RIVAL_6]: new TrainerConfig(++t).setBoss().setStaticParty().setEncounterBgm('final').setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_6) [TrainerType.RIVAL_6]: new TrainerConfig(++t).setBoss().setStaticParty().setMoneyMultiplier(3).setEncounterBgm('final').setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_6)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT ])) .setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT ]))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ])) .setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT ]))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)) .setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))

View File

@ -165,7 +165,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.fieldPosition = FieldPosition.CENTER; this.fieldPosition = FieldPosition.CENTER;
scene.fieldUI.add(this.battleInfo); scene.fieldUI.addAt(this.battleInfo, 0);
this.battleInfo.initInfo(this); this.battleInfo.initInfo(this);
@ -684,6 +684,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
showInfo() { showInfo() {
if (!this.battleInfo.visible) { if (!this.battleInfo.visible) {
const otherBattleInfo = this.scene.fieldUI.getAll().slice(0, 4).filter(ui => ui instanceof BattleInfo && ((ui as BattleInfo) instanceof PlayerBattleInfo) === this.isPlayer()).find(() => true);
if (!otherBattleInfo || !this.getFieldIndex())
this.scene.fieldUI.sendToBack(this.battleInfo);
else
this.scene.fieldUI.moveAbove(this.battleInfo, otherBattleInfo);
this.battleInfo.setX(this.battleInfo.x + (this.isPlayer() ? 150 : -150)); this.battleInfo.setX(this.battleInfo.x + (this.isPlayer() ? 150 : -150));
this.battleInfo.setVisible(true); this.battleInfo.setVisible(true);
this.scene.tweens.add({ this.scene.tweens.add({

View File

@ -34,6 +34,7 @@ interface SessionSaveData {
enemyModifiers: PersistentModifierData[]; enemyModifiers: PersistentModifierData[];
arena: ArenaData; arena: ArenaData;
pokeballCounts: PokeballCounts; pokeballCounts: PokeballCounts;
money: integer;
waveIndex: integer; waveIndex: integer;
battleType: BattleType; battleType: BattleType;
trainer: TrainerData; trainer: TrainerData;
@ -173,6 +174,7 @@ export class GameData {
enemyModifiers: scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)), enemyModifiers: scene.findModifiers(() => true, false).map(m => new PersistentModifierData(m, false)),
arena: new ArenaData(scene.arena), arena: new ArenaData(scene.arena),
pokeballCounts: scene.pokeballCounts, pokeballCounts: scene.pokeballCounts,
money: scene.money,
waveIndex: scene.currentBattle.waveIndex, waveIndex: scene.currentBattle.waveIndex,
battleType: scene.currentBattle.battleType, battleType: scene.currentBattle.battleType,
trainer: scene.currentBattle.battleType == BattleType.TRAINER ? new TrainerData(scene.currentBattle.trainer) : null, trainer: scene.currentBattle.battleType == BattleType.TRAINER ? new TrainerData(scene.currentBattle.trainer) : null,
@ -244,6 +246,9 @@ export class GameData {
scene.pokeballCounts[key] = sessionData.pokeballCounts[key] || 0; scene.pokeballCounts[key] = sessionData.pokeballCounts[key] || 0;
}); });
scene.money = sessionData.money || 0;
scene.updateMoneyText();
// TODO: Remove this // TODO: Remove this
if (sessionData.enemyField) if (sessionData.enemyField)
sessionData.enemyParty = sessionData.enemyField; sessionData.enemyParty = sessionData.enemyField;

View File

@ -1,15 +1,16 @@
import BattleScene, { Button } from "../battle-scene"; import BattleScene, { Button } from "../battle-scene";
import { ModifierTier, ModifierTypeOption } from "../modifier/modifier-type"; import { ModifierTypeOption } from "../modifier/modifier-type";
import { getPokeballAtlasKey, PokeballType } from "../data/pokeball"; import { getPokeballAtlasKey, PokeballType } from "../data/pokeball";
import { addTextObject, getModifierTierTextTint, TextStyle } from "./text"; import { addTextObject, getModifierTierTextTint, getTextColor, TextStyle } from "./text";
import AwaitableUiHandler from "./awaitable-ui-handler"; import AwaitableUiHandler from "./awaitable-ui-handler";
import { Mode } from "./ui"; import { Mode } from "./ui";
import { PokemonHeldItemModifier } from "../modifier/modifier"; import { PokemonHeldItemModifier } from "../modifier/modifier";
export default class ModifierSelectUiHandler extends AwaitableUiHandler { export default class ModifierSelectUiHandler extends AwaitableUiHandler {
private overlayBg: Phaser.GameObjects.Rectangle;
private modifierContainer: Phaser.GameObjects.Container; private modifierContainer: Phaser.GameObjects.Container;
private rerollButtonContainer: Phaser.GameObjects.Container;
private transferButtonContainer: Phaser.GameObjects.Container; private transferButtonContainer: Phaser.GameObjects.Container;
private rerollCostText: Phaser.GameObjects.Text;
private lastCursor: integer = 0; private lastCursor: integer = 0;
private player: boolean; private player: boolean;
@ -27,13 +28,6 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
setup() { setup() {
const ui = this.getUi(); const ui = this.getUi();
const overlayWidth = this.scene.game.canvas.width / 6;
const overlayHeight = (this.scene.game.canvas.height / 6) - 48;
this.overlayBg = this.scene.add.rectangle(0, overlayHeight * -1 - 48, overlayWidth, overlayHeight, 0x424242);
this.overlayBg.setOrigin(0, 0);
this.overlayBg.setAlpha(0);
ui.add(this.overlayBg);
this.modifierContainer = this.scene.add.container(0, 0); this.modifierContainer = this.scene.add.container(0, 0);
ui.add(this.modifierContainer); ui.add(this.modifierContainer);
@ -44,18 +38,31 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
const transferButtonText = addTextObject(this.scene, -4, -2, 'Transfer', TextStyle.PARTY); const transferButtonText = addTextObject(this.scene, -4, -2, 'Transfer', TextStyle.PARTY);
transferButtonText.setOrigin(1, 0); transferButtonText.setOrigin(1, 0);
this.transferButtonContainer.add(transferButtonText); this.transferButtonContainer.add(transferButtonText);
this.rerollButtonContainer = this.scene.add.container(16, -64);
this.rerollButtonContainer.setVisible(false);
ui.add(this.rerollButtonContainer);
const rerollButtonText = addTextObject(this.scene, -4, -2, 'Reroll', TextStyle.PARTY);
rerollButtonText.setOrigin(0, 0);
this.rerollButtonContainer.add(rerollButtonText);
this.rerollCostText = addTextObject(this.scene, 0, 0, '', TextStyle.MONEY);
this.rerollCostText.setOrigin(0, 0);
this.rerollCostText.setPositionRelative(rerollButtonText, rerollButtonText.displayWidth + 5, 1);
this.rerollButtonContainer.add(this.rerollCostText);
} }
show(args: any[]) { show(args: any[]) {
if (this.active) { if (this.active) {
if (args.length === 3) { if (args.length >= 3) {
this.awaitingActionInput = true; this.awaitingActionInput = true;
this.onActionInput = args[2]; this.onActionInput = args[2];
} }
return; return;
} }
if (args.length !== 3 || !(args[1] instanceof Array) || !args[1].length || !(args[2] instanceof Function)) if (args.length !== 4 || !(args[1] instanceof Array) || !args[1].length || !(args[2] instanceof Function))
return; return;
super.show(args); super.show(args);
@ -69,6 +76,11 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
this.transferButtonContainer.setVisible(false); this.transferButtonContainer.setVisible(false);
this.transferButtonContainer.setAlpha(0); this.transferButtonContainer.setAlpha(0);
this.rerollButtonContainer.setVisible(false);
this.rerollButtonContainer.setAlpha(0);
this.updateRerollCostText(args[3] as integer);
const typeOptions = args[1] as ModifierTypeOption[]; const typeOptions = args[1] as ModifierTypeOption[];
for (let m = 0; m < typeOptions.length; m++) { for (let m = 0; m < typeOptions.length; m++) {
const sliceWidth = (this.scene.game.canvas.width / 6) / (typeOptions.length + 2); const sliceWidth = (this.scene.game.canvas.width / 6) / (typeOptions.length + 2);
@ -81,12 +93,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
const hasUpgrade = typeOptions.filter(to => to.upgraded).length; const hasUpgrade = typeOptions.filter(to => to.upgraded).length;
this.scene.tweens.add({ this.scene.showFieldOverlay(750);
targets: this.overlayBg,
alpha: 0.5,
ease: 'Sine.easeOut',
duration: 750
});
let i = 0; let i = 0;
@ -114,6 +121,16 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
}); });
} }
if (this.scene.currentBattle.waveIndex % 10) {
this.rerollButtonContainer.setAlpha(0);
this.rerollButtonContainer.setVisible(true);
this.scene.tweens.add({
targets: this.rerollButtonContainer,
alpha: 1,
duration: 250
});
}
this.setCursor(0); this.setCursor(0);
this.awaitingActionInput = true; this.awaitingActionInput = true;
this.onActionInput = args[2]; this.onActionInput = args[2];
@ -134,7 +151,10 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
const originalOnActionInput = this.onActionInput; const originalOnActionInput = this.onActionInput;
this.awaitingActionInput = false; this.awaitingActionInput = false;
this.onActionInput = null; this.onActionInput = null;
originalOnActionInput(this.cursor); if (!originalOnActionInput(this.cursor)) {
this.awaitingActionInput = true;
this.onActionInput = originalOnActionInput;
}
} }
} else if (button === Button.CANCEL) { } else if (button === Button.CANCEL) {
if (this.player) { if (this.player) {
@ -149,20 +169,24 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
} else { } else {
switch (button) { switch (button) {
case Button.UP: case Button.UP:
if (this.cursor === this.options.length) if (this.cursor >= this.options.length)
success = this.setCursor(this.lastCursor); success = this.setCursor(this.lastCursor < this.options.length ? this.lastCursor : this.cursor - this.options.length ? this.options.length - 1 : 0);
break; break;
case Button.DOWN: case Button.DOWN:
if (this.cursor < this.options.length && this.transferButtonContainer.visible) if (this.cursor < this.options.length && (this.rerollButtonContainer.visible || this.transferButtonContainer.visible)) {
success = this.setCursor(this.options.length); const isLeftOption = this.cursor <= Math.floor(this.options.length / 2);
success = this.setCursor(this.options.length + (this.rerollButtonContainer.visible && (isLeftOption || !this.transferButtonContainer.visible) ? 0 : 1));
}
break; break;
case Button.LEFT: case Button.LEFT:
if (this.cursor) if ((this.cursor || this.rerollButtonContainer.visible) && this.cursor !== this.options.length)
success = this.setCursor(this.cursor - 1); success = this.setCursor(this.cursor ? this.cursor - 1 : this.options.length);
break; break;
case Button.RIGHT: case Button.RIGHT:
if (this.cursor < this.options.length - (this.transferButtonContainer.visible ? 0 : 1)) if (this.cursor < this.options.length - 1)
success = this.setCursor(this.cursor + 1); success = this.setCursor(this.cursor + 1);
else if (this.cursor === this.options.length && this.transferButtonContainer.visible)
success = this.setCursor(this.options.length + 1);
break; break;
} }
} }
@ -191,6 +215,9 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
const sliceWidth = (this.scene.game.canvas.width / 6) / (this.options.length + 2); const sliceWidth = (this.scene.game.canvas.width / 6) / (this.options.length + 2);
this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, -this.scene.game.canvas.height / 12 - 20); this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, -this.scene.game.canvas.height / 12 - 20);
ui.showText(this.options[this.cursor].modifierTypeOption.type.description); ui.showText(this.options[this.cursor].modifierTypeOption.type.description);
} else if (cursor === this.options.length) {
this.cursorObj.setPosition(6, -60);
ui.showText('Spend money to reroll your item options');
} else { } else {
this.cursorObj.setPosition((this.scene.game.canvas.width / 6) - 50, -60); this.cursorObj.setPosition((this.scene.game.canvas.width / 6) - 50, -60);
ui.showText('Transfer a held item from one Pokémon to another instead of selecting an item'); ui.showText('Transfer a held item from one Pokémon to another instead of selecting an item');
@ -199,6 +226,14 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
return ret; return ret;
} }
updateRerollCostText(rerollCost: integer): void {
const canReroll = this.scene.money >= rerollCost;
this.rerollCostText.setText(`${rerollCost.toLocaleString('en-US')}`);
this.rerollCostText.setColor(getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED));
this.rerollCostText.setShadowColor(getTextColor(canReroll ? TextStyle.MONEY : TextStyle.PARTY_RED, true));
}
clear() { clear() {
super.clear(); super.clear();
@ -207,29 +242,34 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
this.getUi().clearText(); this.getUi().clearText();
this.eraseCursor(); this.eraseCursor();
this.scene.hideFieldOverlay(250);
const options = this.options.slice(0);
this.options.splice(0, this.options.length);
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.overlayBg, targets: options,
alpha: 0,
duration: 250,
ease: 'Cubic.easeIn'
});
this.scene.tweens.add({
targets: this.options,
scale: 0.01, scale: 0.01,
duration: 250, duration: 250,
ease: 'Cubic.easeIn', ease: 'Cubic.easeIn',
onComplete: () => { onComplete: () => options.forEach(o => o.destroy())
this.options.forEach(o => o.destroy());
this.options.splice(0, this.options.length);
}
}); });
if (this.transferButtonContainer.visible) { if (this.transferButtonContainer.visible) {
this.scene.tweens.add({ this.scene.tweens.add({
targets: this.transferButtonContainer, targets: [ this.rerollButtonContainer, this.transferButtonContainer ],
alpha: 0, alpha: 0,
duration: 250, duration: 250,
ease: 'Cubic.easeIn', ease: 'Cubic.easeIn',
onComplete: () => this.transferButtonContainer.setVisible(false) onComplete: () => {
if (!this.options.length) {
this.rerollButtonContainer.setVisible(false);
this.transferButtonContainer.setVisible(false);
} else {
this.rerollButtonContainer.setAlpha(1);
this.transferButtonContainer.setAlpha(1);
}
}
}) })
} }
} }