Fix various issues with enemy modifiers

pull/2/head
Flashfyre 2023-10-24 10:05:07 -04:00
parent d135591b75
commit 10733fd98d
5 changed files with 80 additions and 31 deletions

View File

@ -539,13 +539,15 @@ export default class BattleScene extends Phaser.Scene {
getPokemonById(pokemonId: integer): Pokemon { getPokemonById(pokemonId: integer): Pokemon {
const findInParty = (party: Pokemon[]) => party.find(p => p.id === pokemonId); const findInParty = (party: Pokemon[]) => party.find(p => p.id === pokemonId);
return findInParty(this.getParty()) || findInParty(this.getEnemyField()); return findInParty(this.getParty()) || findInParty(this.getEnemyParty());
} }
reset(): void { reset(): void {
this.seed = Utils.randomString(16); this.seed = Utils.randomString(16);
console.log('Seed:', this.seed); console.log('Seed:', this.seed);
this.gameMode = GameMode.CLASSIC;
this.money = startingMoney; this.money = startingMoney;
this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ])); this.pokeballCounts = Object.fromEntries(Utils.getEnumValues(PokeballType).filter(p => p <= PokeballType.MASTER_BALL).map(t => [ t, 0 ]));
@ -559,7 +561,7 @@ export default class BattleScene extends Phaser.Scene {
for (let p of this.getParty()) for (let p of this.getParty())
p.destroy(); p.destroy();
this.party = []; this.party = [];
for (let p of this.getEnemyField()) for (let p of this.getEnemyParty())
p.destroy(); p.destroy();
this.currentBattle = null; this.currentBattle = null;
@ -590,7 +592,7 @@ export default class BattleScene extends Phaser.Scene {
this.resetSeed(newWaveIndex); this.resetSeed(newWaveIndex);
if (fixedBattles.hasOwnProperty(newWaveIndex)) { if (fixedBattles.hasOwnProperty(newWaveIndex) && this.gameMode === GameMode.CLASSIC) {
battleConfig = fixedBattles[newWaveIndex]; battleConfig = fixedBattles[newWaveIndex];
newDouble = battleConfig.double; newDouble = battleConfig.double;
newBattleType = battleConfig.battleType; newBattleType = battleConfig.battleType;
@ -598,7 +600,9 @@ export default class BattleScene extends Phaser.Scene {
if (newTrainer) if (newTrainer)
this.field.add(newTrainer); this.field.add(newTrainer);
} else { } else {
if (battleType === undefined) { if (this.gameMode === GameMode.ENDLESS)
newBattleType = BattleType.WILD;
else if (battleType === undefined) {
if (newWaveIndex > 20 && !(newWaveIndex % 30)) if (newWaveIndex > 20 && !(newWaveIndex % 30))
newBattleType = BattleType.TRAINER; newBattleType = BattleType.TRAINER;
else if (newWaveIndex % 10 !== 1 && newWaveIndex % 10) { else if (newWaveIndex % 10 !== 1 && newWaveIndex % 10) {
@ -644,7 +648,7 @@ export default class BattleScene extends Phaser.Scene {
const showTrainer = isNewBiome || this.currentBattle.battleType === BattleType.TRAINER; const showTrainer = isNewBiome || this.currentBattle.battleType === BattleType.TRAINER;
const availablePartyMemberCount = this.getParty().filter(p => !p.isFainted()).length; const availablePartyMemberCount = this.getParty().filter(p => !p.isFainted()).length;
if (lastBattle) { if (lastBattle) {
this.getEnemyField().forEach(enemyPokemon => enemyPokemon.destroy()); this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
if (showTrainer) { if (showTrainer) {
playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p))); playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p)));
this.unshiftPhase(new ShowTrainerPhase(this)); this.unshiftPhase(new ShowTrainerPhase(this));
@ -741,7 +745,7 @@ export default class BattleScene extends Phaser.Scene {
} }
updateUIPositions(): void { updateUIPositions(): void {
this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.length ? 15 : 0)); this.waveCountText.setY(-(this.game.canvas.height / 6) + (this.enemyModifiers.filter(m => m.isIconVisible(this)).length ? 15 : 0));
this.moneyText.setY(this.waveCountText.y + 10); this.moneyText.setY(this.waveCountText.y + 10);
this.partyExpBar.setY(this.moneyText.y + 15); this.partyExpBar.setY(this.moneyText.y + 15);
} }
@ -1125,22 +1129,30 @@ export default class BattleScene extends Phaser.Scene {
return new Promise(resolve => { return new Promise(resolve => {
const waveIndex = this.currentBattle.waveIndex; const waveIndex = this.currentBattle.waveIndex;
const chances = Math.ceil(waveIndex / 10); const chances = Math.ceil(waveIndex / 10);
const isBoss = !(waveIndex % 10); const isBoss = !(waveIndex % 10) || (this.currentBattle.battleType === BattleType.TRAINER && this.currentBattle.trainer.config.isBoss);
let count = 0;
for (let c = 0; c < chances; c++) { let modifierChance: integer;
let modifierChance = !isBoss ? 16 : 6; if (this.gameMode === GameMode.CLASSIC)
modifierChance = !isBoss ? 18 : 6;
else
modifierChance = !isBoss ? 12 : 4;
this.getEnemyParty().forEach((enemyPokemon: EnemyPokemon, i: integer) => {
let pokemonModifierChance = modifierChance;
if (this.currentBattle.battleType === BattleType.TRAINER) if (this.currentBattle.battleType === BattleType.TRAINER)
modifierChance /= 2; pokemonModifierChance = Math.ceil(pokemonModifierChance * this.currentBattle.trainer.getPartyMemberModifierChanceMultiplier(i));
if (!Utils.randSeedInt(modifierChance)) let count = 0;
count++; for (let c = 0; c < chances; c++) {
if (count === 12) if (!Utils.randSeedInt(modifierChance))
break; count++;
} if (count === 12)
if (isBoss) break;
count = Math.max(count, Math.floor(chances / 2)); }
const enemyField = this.getEnemyField(); if (isBoss)
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyField(), this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD) count = Math.max(count, Math.floor(chances / 2));
.map(mt => mt.newModifier(enemyField[Utils.randInt(enemyField.length)]).add(this.enemyModifiers, false)); getEnemyModifierTypesForWave(waveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD)
.map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false));
});
this.updateModifiers(false).then(() => resolve()); this.updateModifiers(false).then(() => resolve());
}); });
@ -1172,7 +1184,7 @@ export default class BattleScene extends Phaser.Scene {
modifiers.splice(modifiers.indexOf(modifier), 1); modifiers.splice(modifiers.indexOf(modifier), 1);
} }
this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyField().filter(p => p.isActive())).then(() => { this.updatePartyForModifiers(player ? this.getParty() : this.getEnemyParty()).then(() => {
(player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers); (player ? this.modifierBar : this.enemyModifierBar).updateModifiers(modifiers);
if (!player) if (!player)
this.updateUIPositions(); this.updateUIPositions();

View File

@ -256,7 +256,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm {
let evolutionChance: number; let evolutionChance: number;
if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE)
evolutionChance = Math.min(0.5 + easeInFunc((level - ev.level) / 40) / 2, 1); evolutionChance = Math.min(0.5 + easeInFunc(Math.min(level - ev.level, 40) / 40) / 2, 1);
else { else {
let preferredMinLevel = ev.wildDelay * 10; let preferredMinLevel = ev.wildDelay * 10;
let evolutionLevel = ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2); let evolutionLevel = ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2);

View File

@ -280,7 +280,8 @@ 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 staticParty: boolean = false; public isBoss: boolean = false;
public hasStaticParty: boolean = false;
public battleBgm: string; public battleBgm: string;
public encounterBgm: string; public encounterBgm: string;
public femaleEncounterBgm: string; public femaleEncounterBgm: string;
@ -349,8 +350,13 @@ export class TrainerConfig {
return this; return this;
} }
setBoss(): TrainerConfig {
this.isBoss = true;
return this;
}
setStaticParty(): TrainerConfig { setStaticParty(): TrainerConfig {
this.staticParty = true; this.hasStaticParty = true;
return this; return this;
} }
@ -428,6 +434,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.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_gym'); this.setBattleBgm('battle_gym');
this.setVictoryBgm('victory_gym'); this.setVictoryBgm('victory_gym');
@ -441,6 +448,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.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_elite'); this.setBattleBgm('battle_elite');
this.setVictoryBgm('victory_gym'); this.setVictoryBgm('victory_gym');
@ -451,6 +459,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.setBoss();
this.setStaticParty(); this.setStaticParty();
this.setBattleBgm('battle_champion'); this.setBattleBgm('battle_champion');
this.setVictoryBgm('victory_champion'); this.setVictoryBgm('victory_champion');
@ -707,7 +716,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).setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_2').setPartyTemplates(trainerPartyTemplates.RIVAL_4).setEncounterMessages([ [TrainerType.RIVAL_4]: new TrainerConfig(++t).setBoss().setStaticParty().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.
@ -721,13 +730,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).setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_5).setEncounterMessages([ `` ]).setVictoryMessages([ '…' ]) [TrainerType.RIVAL_5]: new TrainerConfig(++t).setBoss().setStaticParty().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).setStaticParty().setEncounterBgm('final').setBattleBgm('battle_rival_3').setPartyTemplates(trainerPartyTemplates.RIVAL_6) [TrainerType.RIVAL_6]: new TrainerConfig(++t).setBoss().setStaticParty().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

@ -31,10 +31,14 @@ export class ModifierBar extends Phaser.GameObjects.Container {
updateModifiers(modifiers: PersistentModifier[]) { updateModifiers(modifiers: PersistentModifier[]) {
this.removeAll(true); this.removeAll(true);
for (let modifier of modifiers) { const visibleIconModifiers = modifiers.filter(m => m.isIconVisible(this.scene as BattleScene));
for (let modifier of visibleIconModifiers) {
if (!modifier.isIconVisible(this.scene as BattleScene))
continue;
const icon = modifier.getIcon(this.scene as BattleScene); const icon = modifier.getIcon(this.scene as BattleScene);
this.add(icon); this.add(icon);
this.setModifierIconPosition(icon, modifiers.length); this.setModifierIconPosition(icon, visibleIconModifiers.length);
} }
} }
@ -116,6 +120,10 @@ export abstract class PersistentModifier extends Modifier {
return 99; return 99;
} }
isIconVisible(scene: BattleScene): boolean {
return true;
}
getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container {
const container = scene.add.container(0, 0); const container = scene.add.container(0, 0);
@ -329,6 +337,11 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
return true; return true;
} }
isIconVisible(scene: BattleScene): boolean {
const pokemon = this.getPokemon(scene);
return pokemon instanceof PlayerPokemon || this.getPokemon(scene).isOnField();
}
getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container { getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container {
const container = !forSummary ? scene.add.container(0, 0) : super.getIcon(scene); const container = !forSummary ? scene.add.container(0, 0) : super.getIcon(scene);

View File

@ -132,7 +132,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
: this.genNewPartyMemberSpecies(level); : this.genNewPartyMemberSpecies(level);
ret = new EnemyPokemon(this.scene, species, level); ret = new EnemyPokemon(this.scene, species, level);
}, this.config.staticParty ? this.config.getDerivedType() + ((index + 1) << 8) : this.scene.currentBattle.waveIndex + (this.config.getDerivedType() << 10) + ((index + 1) << 8)); }, this.config.hasStaticParty ? this.config.getDerivedType() + ((index + 1) << 8) : this.scene.currentBattle.waveIndex + (this.config.getDerivedType() << 10) + ((index + 1) << 8));
return ret; return ret;
} }
@ -189,6 +189,21 @@ export default class Trainer extends Phaser.GameObjects.Container {
const maxScorePartyMemberIndexes = partyMemberScores.filter(pms => pms[1] === sortedPartyMemberScores[0][1]).map(pms => pms[0]); const maxScorePartyMemberIndexes = partyMemberScores.filter(pms => pms[1] === sortedPartyMemberScores[0][1]).map(pms => pms[0]);
return maxScorePartyMemberIndexes[Utils.randSeedInt(maxScorePartyMemberIndexes.length)]; return maxScorePartyMemberIndexes[Utils.randSeedInt(maxScorePartyMemberIndexes.length)];
} }
getPartyMemberModifierChanceMultiplier(index: integer): number {
switch (this.getPartyTemplate().getStrength(index)) {
case TrainerPartyMemberStrength.WEAKER:
return 0.75;
case TrainerPartyMemberStrength.WEAK:
return 0.675;
case TrainerPartyMemberStrength.AVERAGE:
return 0.5625;
case TrainerPartyMemberStrength.STRONG:
return 0.45;
case TrainerPartyMemberStrength.STRONGER:
return 0.375;
}
}
loadAssets(): Promise<void> { loadAssets(): Promise<void> {
return this.config.loadAssets(this.scene, this.female); return this.config.loadAssets(this.scene, this.female);