Make type boost items like silk scarf affect the move after its type change
This commit is contained in:
parent
9f09378de4
commit
d3b1dab17f
|
@ -9,3 +9,6 @@ export const SESSION_ID_COOKIE_NAME: string = "pokerogue_sessionId";
|
|||
|
||||
/** Max value for an integer attribute in {@linkcode SystemSaveData} */
|
||||
export const MAX_INT_ATTR_VALUE = 0x80000000;
|
||||
|
||||
/** The raw percentage power boost for type boost items*/
|
||||
export const TYPE_BOOST_ITEM_BOOST_PERCENT = 20;
|
||||
|
|
|
@ -69,6 +69,7 @@ import type { AbAttrCondition, PokemonDefendCondition, PokemonStatStageChangeCon
|
|||
import type { BattlerIndex } from "#app/battle";
|
||||
import type Move from "#app/data/moves/move";
|
||||
import type { ArenaTrapTag, SuppressAbilitiesTag } from "#app/data/arena-tag";
|
||||
import { noAbilityTypeOverrideMoves } from "../moves/invalid-moves";
|
||||
|
||||
export class BlockRecoilDamageAttr extends AbAttr {
|
||||
constructor() {
|
||||
|
@ -1240,12 +1241,40 @@ export class MoveTypeChangeAbAttr extends PreAttackAbAttr {
|
|||
super(false);
|
||||
}
|
||||
|
||||
override canApplyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon | null, move: Move, args: any[]): boolean {
|
||||
return (this.condition && this.condition(pokemon, defender, move)) ?? false;
|
||||
/**
|
||||
* Determine if the move type change attribute can be applied
|
||||
*
|
||||
* Can be applied if:
|
||||
* - The ability's condition is met, e.g. pixilate only boosts normal moves,
|
||||
* - The move is not forbidden from having its type changed by an ability, e.g. {@linkcode Moves.MULTI_ATTACK}
|
||||
* - The user is not terastallized and using tera blast
|
||||
* - The user is not a terastallized terapagos with tera stellar using tera starstorm
|
||||
* @param pokemon - The pokemon that has the move type changing ability and is using the attacking move
|
||||
* @param _passive - Unused
|
||||
* @param _simulated - Unused
|
||||
* @param _defender - The pokemon being attacked (unused)
|
||||
* @param move - The move being used
|
||||
* @param _args - args[0] holds the type that the move is changed to, args[1] holds the multiplier
|
||||
* @returns whether the move type change attribute can be applied
|
||||
*/
|
||||
override canApplyPreAttack(pokemon: Pokemon, _passive: boolean, _simulated: boolean, _defender: Pokemon | null, move: Move, _args: [NumberHolder?, NumberHolder?, ...any]): boolean {
|
||||
return (this.condition && this.condition(pokemon, _defender, move) &&
|
||||
!noAbilityTypeOverrideMoves.has(move.id) &&
|
||||
(!pokemon.isTerastallized ||
|
||||
(move.id !== Moves.TERA_BLAST &&
|
||||
(move.id !== Moves.TERA_STARSTORM || pokemon.getTeraType() !== PokemonType.STELLAR || !pokemon.hasSpecies(Species.TERAPAGOS)))))
|
||||
?? false;
|
||||
}
|
||||
|
||||
// TODO: Decouple this into two attributes (type change / power boost)
|
||||
override applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: any[]): void {
|
||||
/**
|
||||
* @param pokemon - The pokemon that has the move type changing ability and is using the attacking move
|
||||
* @param passive - Unused
|
||||
* @param simulated - Unused
|
||||
* @param defender - The pokemon being attacked (unused)
|
||||
* @param move - The move being used
|
||||
* @param args - args[0] holds the type that the move is changed to, args[1] holds the multiplier
|
||||
*/
|
||||
override applyPreAttack(pokemon: Pokemon, passive: boolean, simulated: boolean, defender: Pokemon, move: Move, args: [NumberHolder?, NumberHolder?, ...any]): void {
|
||||
if (args[0] && args[0] instanceof NumberHolder) {
|
||||
args[0].value = this.newType;
|
||||
}
|
||||
|
@ -6610,9 +6639,7 @@ export function initAbilities() {
|
|||
.conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, StatMultiplierAbAttr, Stat.SPD, 2)
|
||||
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5),
|
||||
new Ability(Abilities.NORMALIZE, 4)
|
||||
.attr(MoveTypeChangeAbAttr, PokemonType.NORMAL, 1.2, (user, target, move) => {
|
||||
return ![ Moves.MULTI_ATTACK, Moves.REVELATION_DANCE, Moves.TERRAIN_PULSE, Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST ].includes(move.id);
|
||||
}),
|
||||
.attr(MoveTypeChangeAbAttr, PokemonType.NORMAL, 1.2),
|
||||
new Ability(Abilities.SNIPER, 4)
|
||||
.attr(MultCritAbAttr, 1.5),
|
||||
new Ability(Abilities.MAGIC_GUARD, 4)
|
||||
|
|
|
@ -240,3 +240,18 @@ export const invalidMirrorMoveMoves: ReadonlySet<Moves> = new Set([
|
|||
Moves.WATER_SPORT,
|
||||
Moves.WIDE_GUARD,
|
||||
]);
|
||||
|
||||
/** Set of moves that can never have their type overridden by an ability like Pixilate or Normalize
|
||||
*
|
||||
* Excludes tera blast and tera starstorm, as these are only conditionally forbidden
|
||||
*/
|
||||
export const noAbilityTypeOverrideMoves: ReadonlySet<Moves> = new Set([
|
||||
Moves.WEATHER_BALL,
|
||||
Moves.JUDGMENT,
|
||||
Moves.REVELATION_DANCE,
|
||||
Moves.MULTI_ATTACK,
|
||||
Moves.TERRAIN_PULSE,
|
||||
Moves.NATURAL_GIFT,
|
||||
Moves.TECHNO_BLAST,
|
||||
Moves.HIDDEN_POWER,
|
||||
]);
|
||||
|
|
|
@ -797,8 +797,14 @@ export default class Move implements Localizable {
|
|||
|
||||
const power = new NumberHolder(this.power);
|
||||
const typeChangeMovePowerMultiplier = new NumberHolder(1);
|
||||
const typeChangeHolder = new NumberHolder(this.type);
|
||||
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, null, typeChangeMovePowerMultiplier);
|
||||
// apply move type changing ability attributes
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAbAttr, source, target, this, true, typeChangeHolder, typeChangeMovePowerMultiplier);
|
||||
if (typeChangeHolder.value !== this.type) {
|
||||
console.log("==========================================");
|
||||
console.log("Move type change to " + PokemonType[typeChangeHolder.value]);
|
||||
}
|
||||
|
||||
const sourceTeraType = source.getTeraType();
|
||||
if (source.isTerastallized && sourceTeraType === this.type && power.value < 60 && this.priority <= 0 && !this.hasAttr(MultiHitAttr) && !globalScene.findModifier(m => m instanceof PokemonMultiHitModifier && m.pokemonId === source.id)) {
|
||||
|
@ -828,7 +834,7 @@ export default class Move implements Localizable {
|
|||
|
||||
power.value *= typeChangeMovePowerMultiplier.value;
|
||||
|
||||
const typeBoost = source.findTag(t => t instanceof TypeBoostTag && t.boostedType === this.type) as TypeBoostTag;
|
||||
const typeBoost = source.findTag(t => t instanceof TypeBoostTag && t.boostedType === typeChangeHolder.value) as TypeBoostTag;
|
||||
if (typeBoost) {
|
||||
power.value *= typeBoost.boostValue;
|
||||
}
|
||||
|
@ -836,8 +842,10 @@ export default class Move implements Localizable {
|
|||
applyMoveAttrs(VariablePowerAttr, source, target, this, power);
|
||||
|
||||
if (!this.hasAttr(TypelessAttr)) {
|
||||
globalScene.arena.applyTags(WeakenMoveTypeTag, simulated, this.type, power);
|
||||
globalScene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, this.type, power);
|
||||
globalScene.arena.applyTags(WeakenMoveTypeTag, simulated, typeChangeHolder.value, power);
|
||||
console.log("Before applying attack type boosters, power is " + power.value);
|
||||
globalScene.applyModifiers(AttackTypeBoosterModifier, source.isPlayer(), source, typeChangeHolder.value, power);
|
||||
console.log("After applying attack type boosters, power is " + power.value);
|
||||
}
|
||||
|
||||
if (source.getTag(HelpingHandTag)) {
|
||||
|
|
|
@ -2547,22 +2547,19 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||
*/
|
||||
public getMoveType(move: Move, simulated = true): PokemonType {
|
||||
const moveTypeHolder = new NumberHolder(move.type);
|
||||
// If the user is terastallized and the move is tera blast, then the move type is the tera type
|
||||
|
||||
// Abilities that change the move type go first
|
||||
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
||||
applyPreAttackAbAttrs(
|
||||
MoveTypeChangeAbAttr,
|
||||
this,
|
||||
null,
|
||||
move,
|
||||
simulated,
|
||||
moveTypeHolder,
|
||||
moveTypeHolder
|
||||
);
|
||||
// And then moves that change the move type go
|
||||
applyMoveAttrs(VariableMoveTypeAttr, this, null, move, moveTypeHolder);
|
||||
|
||||
// If the user is terastallized and the move is tera blast, or tera starstorm that is stellar type,
|
||||
// then bypass the check for ion deluge
|
||||
// then bypass the check for ion deluge and electrify
|
||||
if (this.isTerastallized && (move.id === Moves.TERA_BLAST || move.id === Moves.TERA_STARSTORM && moveTypeHolder.value === PokemonType.STELLAR)) {
|
||||
return moveTypeHolder.value as PokemonType;
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@ import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
|||
import { StatusEffect } from "#enums/status-effect";
|
||||
import i18next from "i18next";
|
||||
import { timedEventManager } from "#app/global-event-manager";
|
||||
import { TYPE_BOOST_ITEM_BOOST_PERCENT } from "#app/constants";
|
||||
|
||||
const outputModifierData = false;
|
||||
const useMaxWeightForOutput = false;
|
||||
|
@ -1329,7 +1330,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||
constructor() {
|
||||
super((party: Pokemon[], pregenArgs?: any[]) => {
|
||||
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in PokemonType) {
|
||||
return new AttackTypeBoosterModifierType(pregenArgs[0] as PokemonType, 20);
|
||||
return new AttackTypeBoosterModifierType(pregenArgs[0] as PokemonType, TYPE_BOOST_ITEM_BOOST_PERCENT);
|
||||
}
|
||||
|
||||
const attackMoveTypes = party.flatMap(p =>
|
||||
|
@ -1377,7 +1378,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||
weight += typeWeight;
|
||||
}
|
||||
|
||||
return new AttackTypeBoosterModifierType(type!, 20);
|
||||
return new AttackTypeBoosterModifierType(type!, TYPE_BOOST_ITEM_BOOST_PERCENT);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1479,7 +1479,8 @@ export class AttackTypeBoosterModifier extends PokemonHeldItemModifier {
|
|||
return (
|
||||
super.shouldApply(pokemon, moveType, movePower) &&
|
||||
typeof moveType === "number" &&
|
||||
movePower instanceof NumberHolder
|
||||
movePower instanceof NumberHolder &&
|
||||
this.moveType === moveType
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue