Aggregate Stat Changes (#266)
* Add stat change aggregation * Minor fixes to stat change aggregationpull/268/head
parent
3e296116bb
commit
9024eeb990
|
@ -2665,11 +2665,20 @@ export class StatChangePhase extends PokemonPhase {
|
||||||
start() {
|
start() {
|
||||||
const pokemon = this.getPokemon();
|
const pokemon = this.getPokemon();
|
||||||
|
|
||||||
if (!pokemon.isActive(true))
|
let random = false;
|
||||||
return this.end();
|
|
||||||
|
|
||||||
const allStats = Utils.getEnumValues(BattleStat);
|
const allStats = Utils.getEnumValues(BattleStat);
|
||||||
const filteredStats = this.stats.map(s => s !== BattleStat.RAND ? s : allStats[pokemon.randSeedInt(BattleStat.SPD + 1)]).filter(stat => {
|
if (this.stats.length === 1 && this.stats[0] === BattleStat.RAND) {
|
||||||
|
this.stats[0] = this.getRandomStat();
|
||||||
|
random = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.aggregateStatChanges(random);
|
||||||
|
|
||||||
|
if (!pokemon.isActive(true))
|
||||||
|
return this.end();
|
||||||
|
|
||||||
|
const filteredStats = this.stats.map(s => s !== BattleStat.RAND ? s : this.getRandomStat()).filter(stat => {
|
||||||
const cancelled = new Utils.BooleanHolder(false);
|
const cancelled = new Utils.BooleanHolder(false);
|
||||||
|
|
||||||
if (!this.selfTarget && this.levels < 0)
|
if (!this.selfTarget && this.levels < 0)
|
||||||
|
@ -2750,11 +2759,62 @@ export class StatChangePhase extends PokemonPhase {
|
||||||
end();
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRandomStat(): BattleStat {
|
||||||
|
const allStats = Utils.getEnumValues(BattleStat);
|
||||||
|
return allStats[this.getPokemon().randSeedInt(BattleStat.SPD + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
aggregateStatChanges(random: boolean = false): void {
|
||||||
|
const isAccEva = [ BattleStat.ACC, BattleStat.EVA ].some(s => this.stats.includes(s));
|
||||||
|
let existingPhase: StatChangePhase;
|
||||||
|
if (this.stats.length === 1) {
|
||||||
|
while ((existingPhase = (this.scene.findPhase(p => p instanceof StatChangePhase && p.battlerIndex === this.battlerIndex && p.stats.length === 1
|
||||||
|
&& (p.stats[0] === this.stats[0] || (random && p.stats[0] === BattleStat.RAND))
|
||||||
|
&& p.selfTarget === this.selfTarget && p.showMessage === this.showMessage && p.ignoreAbilities === this.ignoreAbilities) as StatChangePhase))) {
|
||||||
|
if (existingPhase.stats[0] === BattleStat.RAND) {
|
||||||
|
existingPhase.stats[0] = this.getRandomStat();
|
||||||
|
if (existingPhase.stats[0] !== this.stats[0])
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.levels += existingPhase.levels;
|
||||||
|
|
||||||
|
if (!this.scene.tryRemovePhase(p => p === existingPhase))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((existingPhase = (this.scene.findPhase(p => p instanceof StatChangePhase && p.battlerIndex === this.battlerIndex && p.selfTarget === this.selfTarget
|
||||||
|
&& ([ BattleStat.ACC, BattleStat.EVA ].some(s => p.stats.includes(s)) === isAccEva)
|
||||||
|
&& p.levels === this.levels && p.showMessage === this.showMessage && p.ignoreAbilities === this.ignoreAbilities) as StatChangePhase))) {
|
||||||
|
this.stats.push(...existingPhase.stats);
|
||||||
|
if (!this.scene.tryRemovePhase(p => p === existingPhase))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getStatChangeMessages(stats: BattleStat[], levels: integer, relLevels: integer[]): string[] {
|
getStatChangeMessages(stats: BattleStat[], levels: integer, relLevels: integer[]): string[] {
|
||||||
const messages: string[] = [];
|
const messages: string[] = [];
|
||||||
|
|
||||||
for (let s = 0; s < stats.length; s++)
|
const relLevelStatIndexes = {};
|
||||||
messages.push(getPokemonMessage(this.getPokemon(), `'s ${getBattleStatName(stats[s])} ${getBattleStatLevelChangeDescription(Math.abs(relLevels[s]), levels >= 1)}!`));
|
for (let rl = 0; rl < relLevels.length; rl++) {
|
||||||
|
const relLevel = relLevels[rl];
|
||||||
|
if (!relLevelStatIndexes[relLevel])
|
||||||
|
relLevelStatIndexes[relLevel] = [];
|
||||||
|
relLevelStatIndexes[relLevel].push(rl);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(relLevelStatIndexes).forEach(rl => {
|
||||||
|
const relLevelStats = stats.filter((_, i) => relLevelStatIndexes[rl].includes(i));
|
||||||
|
let statsFragment = '';
|
||||||
|
|
||||||
|
if (relLevelStats.length > 1) {
|
||||||
|
statsFragment = relLevelStats.length >= 5
|
||||||
|
? 'stats'
|
||||||
|
: `${relLevelStats.slice(0, -1).map(s => getBattleStatName(s)).join(', ')}, and ${getBattleStatName(relLevelStats[relLevelStats.length - 1])}`;
|
||||||
|
} else
|
||||||
|
statsFragment = getBattleStatName(relLevelStats[0]);
|
||||||
|
messages.push(getPokemonMessage(this.getPokemon(), `'s ${statsFragment} ${getBattleStatLevelChangeDescription(Math.abs(parseInt(rl)), levels >= 1)}!`));
|
||||||
|
});
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue