Fix various issues with enemy modifiers

This commit is contained in:
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 {
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 {
this.seed = Utils.randomString(16);
console.log('Seed:', this.seed);
this.gameMode = GameMode.CLASSIC;
this.money = startingMoney;
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())
p.destroy();
this.party = [];
for (let p of this.getEnemyField())
for (let p of this.getEnemyParty())
p.destroy();
this.currentBattle = null;
@ -590,7 +592,7 @@ export default class BattleScene extends Phaser.Scene {
this.resetSeed(newWaveIndex);
if (fixedBattles.hasOwnProperty(newWaveIndex)) {
if (fixedBattles.hasOwnProperty(newWaveIndex) && this.gameMode === GameMode.CLASSIC) {
battleConfig = fixedBattles[newWaveIndex];
newDouble = battleConfig.double;
newBattleType = battleConfig.battleType;
@ -598,7 +600,9 @@ export default class BattleScene extends Phaser.Scene {
if (newTrainer)
this.field.add(newTrainer);
} else {
if (battleType === undefined) {
if (this.gameMode === GameMode.ENDLESS)
newBattleType = BattleType.WILD;
else if (battleType === undefined) {
if (newWaveIndex > 20 && !(newWaveIndex % 30))
newBattleType = BattleType.TRAINER;
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 availablePartyMemberCount = this.getParty().filter(p => !p.isFainted()).length;
if (lastBattle) {
this.getEnemyField().forEach(enemyPokemon => enemyPokemon.destroy());
this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
if (showTrainer) {
playerField.forEach((_, p) => this.unshiftPhase(new ReturnPhase(this, p)));
this.unshiftPhase(new ShowTrainerPhase(this));
@ -741,7 +745,7 @@ export default class BattleScene extends Phaser.Scene {
}
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.partyExpBar.setY(this.moneyText.y + 15);
}
@ -1125,22 +1129,30 @@ export default class BattleScene extends Phaser.Scene {
return new Promise(resolve => {
const waveIndex = this.currentBattle.waveIndex;
const chances = Math.ceil(waveIndex / 10);
const isBoss = !(waveIndex % 10);
let count = 0;
for (let c = 0; c < chances; c++) {
let modifierChance = !isBoss ? 16 : 6;
const isBoss = !(waveIndex % 10) || (this.currentBattle.battleType === BattleType.TRAINER && this.currentBattle.trainer.config.isBoss);
let modifierChance: integer;
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)
modifierChance /= 2;
if (!Utils.randSeedInt(modifierChance))
count++;
if (count === 12)
break;
}
if (isBoss)
count = Math.max(count, Math.floor(chances / 2));
const enemyField = this.getEnemyField();
getEnemyModifierTypesForWave(waveIndex, count, this.getEnemyField(), this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD)
.map(mt => mt.newModifier(enemyField[Utils.randInt(enemyField.length)]).add(this.enemyModifiers, false));
pokemonModifierChance = Math.ceil(pokemonModifierChance * this.currentBattle.trainer.getPartyMemberModifierChanceMultiplier(i));
let count = 0;
for (let c = 0; c < chances; c++) {
if (!Utils.randSeedInt(modifierChance))
count++;
if (count === 12)
break;
}
if (isBoss)
count = Math.max(count, Math.floor(chances / 2));
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());
});
@ -1172,7 +1184,7 @@ export default class BattleScene extends Phaser.Scene {
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);
if (!player)
this.updateUIPositions();

View File

@ -256,7 +256,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm {
let evolutionChance: number;
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 {
let preferredMinLevel = ev.wildDelay * 10;
let evolutionLevel = ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2);

View File

@ -280,7 +280,8 @@ export class TrainerConfig {
public nameFemale: string;
public hasGenders: boolean = false;
public isDouble: boolean = false;
public staticParty: boolean = false;
public isBoss: boolean = false;
public hasStaticParty: boolean = false;
public battleBgm: string;
public encounterBgm: string;
public femaleEncounterBgm: string;
@ -349,8 +350,13 @@ export class TrainerConfig {
return this;
}
setBoss(): TrainerConfig {
this.isBoss = true;
return this;
}
setStaticParty(): TrainerConfig {
this.staticParty = true;
this.hasStaticParty = true;
return this;
}
@ -428,6 +434,7 @@ export class TrainerConfig {
this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ]));
if (specialtyType !== undefined)
this.setSpeciesFilter(p => p.isOfType(specialtyType));
this.setBoss();
this.setStaticParty();
this.setBattleBgm('battle_gym');
this.setVictoryBgm('victory_gym');
@ -441,6 +448,7 @@ export class TrainerConfig {
this.setSpeciesFilter(p => p.isOfType(specialtyType) && p.baseTotal >= 450);
else
this.setSpeciesFilter(p => p.baseTotal >= 450);
this.setBoss();
this.setStaticParty();
this.setBattleBgm('battle_elite');
this.setVictoryBgm('victory_gym');
@ -451,6 +459,7 @@ export class TrainerConfig {
this.setPartyTemplates(trainerPartyTemplates.CHAMPION);
this.setPartyMemberFunc(-1, getRandomPartyMemberFunc([ signatureSpecies ]));
this.setSpeciesFilter(p => p.baseTotal >= 470);
this.setBoss();
this.setStaticParty();
this.setBattleBgm('battle_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(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.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?
$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.
@ -721,13 +730,13 @@ export const trainerConfigs: TrainerConfigs = {
.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))
.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(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))
.setSpeciesFilter(species => species.baseTotal >= 540)
.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(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))

View File

@ -31,10 +31,14 @@ export class ModifierBar extends Phaser.GameObjects.Container {
updateModifiers(modifiers: PersistentModifier[]) {
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);
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;
}
isIconVisible(scene: BattleScene): boolean {
return true;
}
getIcon(scene: BattleScene, forSummary?: boolean): Phaser.GameObjects.Container {
const container = scene.add.container(0, 0);
@ -329,6 +337,11 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier {
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 {
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);
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;
}
@ -190,6 +190,21 @@ export default class Trainer extends Phaser.GameObjects.Container {
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> {
return this.config.loadAssets(this.scene, this.female);
}