Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ability] Ignore Held Items for Stat Calculation #5254

Merged
Merged
3 changes: 1 addition & 2 deletions src/data/battler-tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1752,7 +1752,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
super.onAdd(pokemon);

let highestStat: EffectiveStat;
EFFECTIVE_STATS.map(s => pokemon.getEffectiveStat(s)).reduce((highestValue: number, value: number, i: number) => {
EFFECTIVE_STATS.map(s => pokemon.getEffectiveStat(s, undefined, undefined, undefined, undefined, undefined, undefined, true)).reduce((highestValue: number, value: number, i: number) => {
if (value > highestValue) {
highestStat = EFFECTIVE_STATS[i];
return value;
Expand All @@ -1771,7 +1771,6 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
this.multiplier = 1.3;
break;
}

globalScene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: i18next.t(getStatKey(highestStat)) }), null, false, null, true);
}

Expand Down
16 changes: 11 additions & 5 deletions src/field/pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -947,11 +947,14 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param ignoreOppAbility during an attack, determines whether the opposing Pokemon's abilities should be ignored during the stat calculation.
* @param isCritical determines whether a critical hit has occurred or not (`false` by default)
* @param simulated if `true`, nullifies any effects that produce any changes to game state from triggering
* @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false`
* @returns the final in-battle value of a stat
*/
getEffectiveStat(stat: EffectiveStat, opponent?: Pokemon, move?: Move, ignoreAbility: boolean = false, ignoreOppAbility: boolean = false, isCritical: boolean = false, simulated: boolean = true): number {
getEffectiveStat(stat: EffectiveStat, opponent?: Pokemon, move?: Move, ignoreAbility: boolean = false, ignoreOppAbility: boolean = false, isCritical: boolean = false, simulated: boolean = true, ignoreHeldItems: boolean = false): number {
const statValue = new Utils.NumberHolder(this.getStat(stat, false));
globalScene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statValue);
if (!ignoreHeldItems) {
globalScene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statValue);
}

// The Ruin abilities here are never ignored, but they reveal themselves on summon anyway
const fieldApplied = new Utils.BooleanHolder(false);
Expand All @@ -965,7 +968,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
applyStatMultiplierAbAttrs(StatMultiplierAbAttr, this, stat, statValue, simulated);
}

let ret = statValue.value * this.getStatStageMultiplier(stat, opponent, move, ignoreOppAbility, isCritical, simulated);
let ret = statValue.value * this.getStatStageMultiplier(stat, opponent, move, ignoreOppAbility, isCritical, simulated, ignoreHeldItems);

switch (stat) {
case Stat.ATK:
Expand Down Expand Up @@ -2487,9 +2490,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param ignoreOppAbility determines whether the effects of the opponent's abilities (i.e. Unaware) should be ignored (`false` by default)
* @param isCritical determines whether a critical hit has occurred or not (`false` by default)
* @param simulated determines whether effects are applied without altering game state (`true` by default)
* @param ignoreHeldItems determines whether this Pokemon's held items should be ignored during the stat calculation, default `false`
* @return the stat stage multiplier to be used for effective stat calculation
*/
getStatStageMultiplier(stat: EffectiveStat, opponent?: Pokemon, move?: Move, ignoreOppAbility: boolean = false, isCritical: boolean = false, simulated: boolean = true): number {
getStatStageMultiplier(stat: EffectiveStat, opponent?: Pokemon, move?: Move, ignoreOppAbility: boolean = false, isCritical: boolean = false, simulated: boolean = true, ignoreHeldItems: boolean = false): number {
const statStage = new Utils.IntegerHolder(this.getStatStage(stat));
const ignoreStatStage = new Utils.BooleanHolder(false);

Expand All @@ -2516,7 +2520,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {

if (!ignoreStatStage.value) {
const statStageMultiplier = new Utils.NumberHolder(Math.max(2, 2 + statStage.value) / Math.max(2, 2 - statStage.value));
globalScene.applyModifiers(TempStatStageBoosterModifier, this.isPlayer(), stat, statStageMultiplier);
if (!ignoreHeldItems) {
globalScene.applyModifiers(TempStatStageBoosterModifier, this.isPlayer(), stat, statStageMultiplier);
}
return Math.min(statStageMultiplier.value, 4);
}
return 1;
Expand Down