Rework token modifiers in endless mode (WiP)

This commit is contained in:
Flashfyre 2023-11-05 10:56:09 -05:00
parent bd8fa9811f
commit 446d00b4cd
3 changed files with 91 additions and 79 deletions

View File

@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov
import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat";
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyInstantReviveChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier } from "./modifier/modifier";
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyInstantReviveChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PersistentModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TempBattleStatBoosterModifier, TurnHealModifier, TurnHeldItemTransferModifier } 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 { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, TmModifierType, getEnemyBuffModifierTypeOptionsForWave, getModifierType, getPlayerModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import { FusePokemonModifierType, ModifierPoolType, ModifierTier, ModifierType, ModifierTypeFunc, ModifierTypeOption, PokemonModifierType, PokemonMoveModifierType, TmModifierType, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptionsForWave, modifierTypes, regenerateModifierPoolThresholds } from "./modifier/modifier-type";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { BattlerTagLapseType, BattlerTagType, HideSpriteTag as HiddenTag, TrappedTag } from "./data/battler-tag";
import { getPokemonMessage } from "./messages";
@ -473,7 +473,7 @@ export class SelectBiomePhase extends BattlePhase {
if (this.scene.gameMode === GameMode.CLASSIC && this.scene.currentBattle.waveIndex === this.scene.finalWave - 9)
setNextBiome(Biome.END);
else if (this.scene.gameMode !== GameMode.CLASSIC) {
if (this.scene.currentBattle.waveIndex % 50 === 0)
if (!(this.scene.currentBattle.waveIndex % 50))
setNextBiome(Biome.END);
else {
const allBiomes = Utils.getEnumValues(Biome);
@ -2155,8 +2155,8 @@ export class VictoryPhase extends PokemonPhase {
if (this.scene.gameMode !== GameMode.CLASSIC || this.scene.currentBattle.waveIndex < this.scene.finalWave) {
if (this.scene.currentBattle.waveIndex > 30 || this.scene.currentBattle.waveIndex % 10) {
this.scene.pushPhase(new SelectModifierPhase(this.scene));
if (this.scene.gameMode !== GameMode.CLASSIC && !(this.scene.currentBattle.waveIndex % 50))
this.scene.pushPhase(new SelectEnemyBuffModifierPhase(this.scene));
if (this.scene.gameMode !== GameMode.CLASSIC && !(this.scene.currentBattle.waveIndex % 50))
this.scene.pushPhase(new AddEnemyBuffModifierPhase(this.scene));
} else
this.scene.pushPhase(new ModifierRewardPhase(this.scene, modifierTypes.GOLDEN_EXP_CHARM))
this.scene.pushPhase(new NewBattlePhase(this.scene));
@ -2947,31 +2947,19 @@ export class SelectModifierPhase extends BattlePhase {
}
}
export class SelectEnemyBuffModifierPhase extends SelectModifierPhase {
export class AddEnemyBuffModifierPhase extends BattlePhase {
constructor(scene: BattleScene) {
super(scene);
}
start() {
this.scene.time.delayedCall(500, () => super.start());
}
super.start();
updateSeed(): void { }
const waveIndex = this.scene.currentBattle.waveIndex;
const tier = !(waveIndex % 1000) ? ModifierTier.ULTRA : !(waveIndex % 250) ? ModifierTier.GREAT : ModifierTier.COMMON;
isPlayer(): boolean {
return false;
}
getPoolType(): ModifierPoolType {
return ModifierPoolType.ENEMY_BUFF;
}
getModifierTypeOptions(modifierCount: integer): ModifierTypeOption[] {
return getEnemyBuffModifierTypeOptionsForWave(modifierCount);
}
addModifier(modifier: Modifier): Promise<void> {
return this.scene.addEnemyModifier(modifier as PersistentModifier);
regenerateModifierPoolThresholds(this.scene.getEnemyParty(), ModifierPoolType.ENEMY_BUFF);
this.scene.addEnemyModifier(getEnemyBuffModifierForWave(tier, this.scene.findModifiers(m => m instanceof EnemyPersistentModifier, false))).then(() => this.end());
}
}

View File

@ -555,7 +555,7 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType {
}
export class EnemyInstantReviveChanceModifierType extends ModifierType {
constructor(name: string, chancePercent: integer, fullHeal: boolean, iconImage?: string) {
constructor(name: string, chancePercent: number, fullHeal: boolean, iconImage?: string) {
super(name, `Adds a ${chancePercent}% chance of reviving with ${fullHeal ? 100 : 50}% HP`, (type, _args) => new Modifiers.EnemyInstantReviveChanceModifier(type, fullHeal, chancePercent), iconImage, 'enemy_revive');
}
}
@ -703,8 +703,8 @@ export const modifierTypes = {
ENEMY_DAMAGE_BOOSTER: () => new ModifierType('Damage Token', 'Increases damage by 20%', (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 20), 'wl_item_drop'),
ENEMY_DAMAGE_REDUCTION: () => new ModifierType('Protection Token', 'Reduces incoming damage by 10%', (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 10), 'wl_guard_spec'),
ENEMY_HEAL: () => new ModifierType('Recovery Token', 'Heals 10% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 10), 'wl_potion'),
ENEMY_SUPER_HEAL: () => new ModifierType('Recovery Token', 'Heals 25% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 25), 'wl_super_potion'),
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_super_potion'),
ENEMY_HEAL: () => new ModifierType('Recovery Token', 'Heals 5% of max HP every turn', (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 10), 'wl_potion'),
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Poison Token', 10, StatusEffect.POISON, 'wl_antidote'),
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Paralyze Token', 10, StatusEffect.PARALYSIS, 'wl_paralyze_heal'),
ENEMY_ATTACK_SLEEP_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType('Sleep Token', 10, StatusEffect.SLEEP, 'wl_awakening'),
@ -869,8 +869,22 @@ const enemyBuffModifierPool = {
new WeightedModifierType(modifierTypes.ENEMY_INSTANT_REVIVE_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_INSTANT_MAX_REVIVE_CHANCE, 3)
].map(m => { m.setTier(ModifierTier.COMMON); return m; }),
[ModifierTier.GREAT]: [ ].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [ ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.GREAT]: [
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 5),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 5),
new WeightedModifierType(modifierTypes.ENEMY_HEAL, 5),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_INSTANT_REVIVE_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_INSTANT_MAX_REVIVE_CHANCE, 3)
].map(m => { m.setTier(ModifierTier.GREAT); return m; }),
[ModifierTier.ULTRA]: [
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_BOOSTER, 5),
new WeightedModifierType(modifierTypes.ENEMY_DAMAGE_REDUCTION, 5),
new WeightedModifierType(modifierTypes.ENEMY_HEAL, 5),
new WeightedModifierType(modifierTypes.ENEMY_STATUS_EFFECT_HEAL_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_INSTANT_REVIVE_CHANCE, 5),
new WeightedModifierType(modifierTypes.ENEMY_INSTANT_MAX_REVIVE_CHANCE, 3)
].map(m => { m.setTier(ModifierTier.ULTRA); return m; }),
[ModifierTier.MASTER]: [ ].map(m => { m.setTier(ModifierTier.MASTER); return m; })
};
@ -948,17 +962,19 @@ export function getPlayerModifierTypeOptionsForWave(waveIndex: integer, count: i
return options;
}
export function getEnemyBuffModifierTypeOptionsForWave(count: integer): ModifierTypeOption[] {
const options: ModifierTypeOption[] = [];
const retryCount = Math.min(count * 5, 50);
new Array(count).fill(0).map(() => {
let candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, ModifierTier.COMMON);
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(null, ModifierPoolType.ENEMY_BUFF, candidate.type.tier);
options.push(candidate);
});
return options;
export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: Modifiers.PersistentModifier[]): Modifiers.EnemyPersistentModifier {
const tierStackCount = tier === ModifierTier.ULTRA ? 10 : tier === ModifierTier.GREAT ? 5 : 1;
const retryCount = 35;
let candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, tier);
let r = 0;
let matchingModifier: Modifiers.PersistentModifier;
while (++r < retryCount && (matchingModifier = enemyModifiers.find(m => m.type.id === candidate.type.id)) && matchingModifier.getMaxStackCount() < matchingModifier.stackCount + (r < 10 ? tierStackCount : 1))
candidate = getNewModifierTypeOption(null, ModifierPoolType.ENEMY_BUFF, tier);
const modifier = candidate.type.newModifier() as Modifiers.EnemyPersistentModifier;
modifier.stackCount = tierStackCount;
return modifier;
}
export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, gameMode: GameMode): PokemonHeldItemModifierType[] {

View File

@ -457,7 +457,7 @@ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier {
private moveType: Type;
private boostMultiplier: number;
constructor(type: ModifierType, pokemonId: integer, moveType: Type, boostPercent: integer, stackCount?: integer) {
constructor(type: ModifierType, pokemonId: integer, moveType: Type, boostPercent: number, stackCount?: integer) {
super(type, pokemonId, stackCount);
this.moveType = moveType;
@ -763,10 +763,10 @@ export abstract class ConsumablePokemonModifier extends ConsumableModifier {
export class PokemonHpRestoreModifier extends ConsumablePokemonModifier {
private restorePoints: integer;
private restorePercent: integer;
private restorePercent: number;
public fainted: boolean;
constructor(type: ModifierType, pokemonId: integer, restorePoints: integer, restorePercent: integer, fainted?: boolean) {
constructor(type: ModifierType, pokemonId: integer, restorePoints: integer, restorePercent: number, fainted?: boolean) {
super(type, pokemonId);
this.restorePoints = restorePoints;
@ -998,7 +998,7 @@ export class HealingBoosterModifier extends PersistentModifier {
export class ExpBoosterModifier extends PersistentModifier {
private boostMultiplier: integer;
constructor(type: ModifierType, boostPercent: integer, stackCount?: integer) {
constructor(type: ModifierType, boostPercent: number, stackCount?: integer) {
super(type, stackCount);
this.boostMultiplier = boostPercent * 0.01;
@ -1034,7 +1034,7 @@ export class ExpBoosterModifier extends PersistentModifier {
export class PokemonExpBoosterModifier extends PokemonHeldItemModifier {
private boostMultiplier: integer;
constructor(type: ModifierTypes.PokemonExpBoosterModifierType, pokemonId: integer, boostPercent: integer, stackCount?: integer) {
constructor(type: ModifierTypes.PokemonExpBoosterModifierType, pokemonId: integer, boostPercent: number, stackCount?: integer) {
super(type, pokemonId, stackCount);
this.boostMultiplier = boostPercent * 0.01;
}
@ -1259,7 +1259,7 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
export class ContactHeldItemTransferChanceModifier extends HeldItemTransferModifier {
private chance: number;
constructor(type: ModifierType, pokemonId: integer, chancePercent: integer, stackCount?: integer) {
constructor(type: ModifierType, pokemonId: integer, chancePercent: number, stackCount?: integer) {
super(type, pokemonId, stackCount);
this.chance = chancePercent / 100;
@ -1314,23 +1314,39 @@ export class ExtraModifierModifier extends PersistentModifier {
}
}
export abstract class EnemyPersistentModifer extends PersistentModifier {
export abstract class EnemyPersistentModifier extends PersistentModifier {
constructor(type: ModifierType, stackCount?: integer) {
super(type, stackCount);
}
getMaxStackCount(): number {
getMaxStackCount(): integer {
return this.type.tier ? 1 : 5;
}
}
export class EnemyDamageBoosterModifier extends EnemyPersistentModifer {
private damageMultiplier: number;
abstract class EnemyDamageMultiplierModifier extends EnemyPersistentModifier {
protected damageMultiplier: number;
constructor(type: ModifierType, boostPercent: integer, stackCount?: integer) {
constructor(type: ModifierType, damageMultiplier: number, stackCount?: integer) {
super(type, stackCount);
this.damageMultiplier = 1 + ((boostPercent || 20) * 0.01);
this.damageMultiplier = damageMultiplier;
}
apply(args: any[]): boolean {
(args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * Math.pow(this.damageMultiplier, this.getStackCount()));
return true;
}
getMaxStackCount(): integer {
return 99;
}
}
export class EnemyDamageBoosterModifier extends EnemyDamageMultiplierModifier {
constructor(type: ModifierType, boostPercent: number, stackCount?: integer) {
super(type, 1 + ((boostPercent || 20) * 0.01), stackCount);
}
match(modifier: Modifier): boolean {
@ -1344,21 +1360,11 @@ export class EnemyDamageBoosterModifier extends EnemyPersistentModifer {
getArgs(): any[] {
return [ (this.damageMultiplier - 1) * 100 ];
}
apply(args: any[]): boolean {
(args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * (this.damageMultiplier * this.getStackCount()));
return true;
}
}
export class EnemyDamageReducerModifier extends EnemyPersistentModifer {
private damageMultiplier: number;
constructor(type: ModifierType, reductionPercent: integer, stackCount?: integer) {
super(type, stackCount);
this.damageMultiplier = 1 - ((reductionPercent || 10) * 0.01);
export class EnemyDamageReducerModifier extends EnemyDamageMultiplierModifier {
constructor(type: ModifierType, reductionPercent: number, stackCount?: integer) {
super(type, 1 - ((reductionPercent || 10) * 0.01), stackCount);
}
match(modifier: Modifier): boolean {
@ -1372,18 +1378,12 @@ export class EnemyDamageReducerModifier extends EnemyPersistentModifer {
getArgs(): any[] {
return [ (1 - this.damageMultiplier) * 100 ];
}
apply(args: any[]): boolean {
(args[0] as Utils.NumberHolder).value = Math.floor((args[0] as Utils.NumberHolder).value * (this.damageMultiplier * this.getStackCount()));
return true;
}
}
export class EnemyTurnHealModifier extends EnemyPersistentModifer {
private healPercent: integer;
export class EnemyTurnHealModifier extends EnemyPersistentModifier {
private healPercent: number;
constructor(type: ModifierType, healPercent: integer, stackCount?: integer) {
constructor(type: ModifierType, healPercent: number, stackCount?: integer) {
super(type, stackCount);
this.healPercent = healPercent || 10;
@ -1413,13 +1413,17 @@ export class EnemyTurnHealModifier extends EnemyPersistentModifer {
return false;
}
getMaxStackCount(): integer {
return 20;
}
}
export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifer {
export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModifier {
public effect: StatusEffect;
private chance: number;
constructor(type: ModifierType, effect: StatusEffect, chancePercent: integer, stackCount?: integer) {
constructor(type: ModifierType, effect: StatusEffect, chancePercent: number, stackCount?: integer) {
super(type, stackCount);
this.effect = effect;
@ -1449,10 +1453,10 @@ export class EnemyAttackStatusEffectChanceModifier extends EnemyPersistentModife
}
}
export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifer {
export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifier {
private chance: number;
constructor(type: ModifierType, chancePercent: integer, stackCount?: integer) {
constructor(type: ModifierType, chancePercent: number, stackCount?: integer) {
super(type, stackCount);
this.chance = (chancePercent || 10) / 100;
@ -1483,11 +1487,11 @@ export class EnemyStatusEffectHealChanceModifier extends EnemyPersistentModifer
}
}
export class EnemyInstantReviveChanceModifier extends EnemyPersistentModifer {
export class EnemyInstantReviveChanceModifier extends EnemyPersistentModifier {
public fullHeal: boolean;
private chance: number;
constructor(type: ModifierType, healFull: boolean, chancePercent: integer, stackCount?: integer) {
constructor(type: ModifierType, healFull: boolean, chancePercent: number, stackCount?: integer) {
super(type, stackCount);
this.fullHeal = healFull;
@ -1519,4 +1523,8 @@ export class EnemyInstantReviveChanceModifier extends EnemyPersistentModifer {
return true;
}
getMaxStackCount(): integer {
return 10;
}
}