Implemented Disguise

Somehow it works.
This commit is contained in:
NxKarim 2024-04-17 02:59:25 -06:00
parent b116828b07
commit 7a6307d200
5 changed files with 160 additions and 76 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

View File

@ -4923,6 +4923,48 @@
"h": 22
}
},
{
"filename": "778-busted",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 40,
"h": 30
},
"spriteSourceSize": {
"x": 13,
"y": 5,
"w": 17,
"h": 22
},
"frame": {
"x": 156,
"y": 443,
"w": 17,
"h": 22
}
},
{
"filename": "778s-busted",
"rotated": false,
"trimmed": true,
"sourceSize": {
"w": 40,
"h": 30
},
"spriteSourceSize": {
"x": 13,
"y": 5,
"w": 17,
"h": 22
},
"frame": {
"x": 217,
"y": 367,
"w": 17,
"h": 22
}
},
{
"filename": "741s-pompom",
"rotated": false,

View File

@ -52,10 +52,10 @@ export class Ability {
const attr = new AttrType(...args);
attr.addCondition(condition);
this.attrs.push(attr);
return this;
}
hasAttr(attrType: { new(...args: any[]): AbAttr }): boolean {
return !!this.getAttrs(attrType).length;
}
@ -91,7 +91,7 @@ export abstract class AbAttr {
constructor(showAbility: boolean = true) {
this.showAbility = showAbility;
}
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
return false;
}
@ -166,8 +166,8 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) {
super();
this.stats = typeof(stats) === 'number'
? [ stats as BattleStat ]
this.stats = typeof (stats) === 'number'
? [stats as BattleStat]
: stats as BattleStat[];
this.levels = levels;
this.selfTarget = !!selfTarget;
@ -189,7 +189,7 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
else
pokemon.scene.unshiftPhase(statChangePhase);
}
return true;
}
}
@ -214,7 +214,7 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
export class BlockItemTheftAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
cancelled.value = true;
return true;
}
@ -229,13 +229,13 @@ export class StabBoostAbAttr extends AbAttr {
(args[0] as Utils.NumberHolder).value += 0.5;
return true;
}
return false;
}
}
export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr {
private condition: PokemonDefendCondition;
protected condition: PokemonDefendCondition;
private powerMultiplier: number;
constructor(condition: PokemonDefendCondition, powerMultiplier: number) {
@ -261,6 +261,21 @@ export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultip
}
}
export class SetMovePowerToOneAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
constructor(condition: PokemonDefendCondition) {
super(condition, 1);
}
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (this.condition(pokemon, attacker, move.getMove())) {
(args[0] as Utils.NumberHolder).value = 0.001;
return true;
}
return false;
}
}
export class TypeImmunityAbAttr extends PreDefendAbAttr {
private immuneType: Type;
private condition: AbAttrCondition;
@ -305,7 +320,7 @@ export class TypeImmunityHealAbAttr extends TypeImmunityAbAttr {
}
return true;
}
return false;
}
}
@ -328,9 +343,9 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
cancelled.value = true;
const simulated = args.length > 1 && args[1];
if (!simulated)
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [this.stat], this.levels));
}
return ret;
}
}
@ -355,7 +370,7 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
if (!simulated)
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
}
return ret;
}
}
@ -386,16 +401,36 @@ export class PostDefendAbAttr extends AbAttr {
}
}
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
constructor(damageRatio?: number) {
super(true);
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon.formIndex == 0 && pokemon.battleData.hitCount != 0 && (move.getMove().category == MoveCategory.SPECIAL || move.getMove().category == MoveCategory.PHYSICAL)) {
const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt);
if (!recoilDamage)
return false;
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s disguise was busted!'));
return true;
}
return false;
}
}
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const attackPriority = new Utils.IntegerHolder(move.getMove().priority);
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
if(attackPriority.value > 0 && !move.getMove().isMultiTarget()) {
cancelled.value = true;
return true;
}
const attackPriority = new Utils.IntegerHolder(move.getMove().priority);
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
if (attackPriority.value > 0 && !move.getMove().isMultiTarget()) {
cancelled.value = true;
return true;
}
return false;
}
}
@ -446,7 +481,7 @@ export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (this.condition(pokemon, attacker, move.getMove())) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, [ this.stat ], this.levels));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, [this.stat], this.levels));
return true;
}
@ -460,7 +495,7 @@ export class PostDefendTypeChangeAbAttr extends PostDefendAbAttr {
const type = move.getMove().type;
const pokemonTypes = pokemon.getTypes(true);
if (pokemonTypes.length !== 1 || pokemonTypes[0] !== type) {
pokemon.summonData.types = [ type ];
pokemon.summonData.types = [type];
return true;
}
}
@ -544,8 +579,8 @@ export class PostDefendCritStatChangeAbAttr extends PostDefendAbAttr {
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [this.stat], this.levels));
return true;
}
@ -562,13 +597,13 @@ export class PostDefendContactDamageAbAttr extends PostDefendAbAttr {
this.damageRatio = damageRatio;
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
attacker.damageAndUpdate(Math.ceil(attacker.getMaxHp() * (1 / this.damageRatio)), HitResult.OTHER);
return true;
}
return false;
}
@ -598,7 +633,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
constructor() {
super();
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnswappableAbilityAbAttr)) {
const tempAbilityId = attacker.getAbility().id;
@ -606,7 +641,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
pokemon.summonData.ability = tempAbilityId;
return true;
}
return false;
}
@ -619,14 +654,14 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr {
constructor() {
super();
}
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && !attacker.getAbility().hasAttr(UnsuppressableAbilityAbAttr) && !attacker.getAbility().hasAttr(PostDefendAbilityGiveAbAttr)) {
attacker.summonData.ability = pokemon.getAbility().id;
return true;
}
return false;
}
@ -674,7 +709,7 @@ export class VariableMovePowerAbAttr extends PreAttackAbAttr {
export class VariableMoveTypeAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
//const power = args[0] as Utils.IntegerHolder;
return false;
return false;
}
}
@ -683,7 +718,7 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
private newType: Type;
private powerMultiplier: number;
constructor(matchType: Type, newType: Type, powerMultiplier: number){
constructor(matchType: Type, newType: Type, powerMultiplier: number) {
super(true);
this.matchType = matchType;
this.newType = newType;
@ -697,7 +732,7 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
(args[1] as Utils.NumberHolder).value *= this.powerMultiplier;
return true;
}
return false;
}
}
@ -707,7 +742,7 @@ export class MoveTypeChangeAttr extends PreAttackAbAttr {
private powerMultiplier: number;
private condition: PokemonAttackCondition;
constructor(newType: Type, powerMultiplier: number, condition: PokemonAttackCondition){
constructor(newType: Type, powerMultiplier: number, condition: PokemonAttackCondition) {
super(true);
this.newType = newType;
this.powerMultiplier = powerMultiplier;
@ -766,7 +801,7 @@ export class LowHpMoveTypePowerBoostAbAttr extends MoveTypePowerBoostAbAttr {
export class FieldVariableMovePowerAbAttr extends AbAttr {
applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
//const power = args[0] as Utils.NumberHolder;
return false;
return false;
}
}
@ -940,8 +975,8 @@ class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
const stat = typeof this.stat === 'function'
? this.stat(pokemon)
: this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [stat], this.levels));
return true;
}
}
@ -967,8 +1002,8 @@ export class PostKnockOutStatChangeAbAttr extends PostKnockOutAbAttr {
const stat = typeof this.stat === 'function'
? this.stat(pokemon)
: this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [stat], this.levels));
return true;
}
}
@ -984,7 +1019,7 @@ export class CopyFaintedAllyAbilityAbAttr extends PostKnockOutAbAttr {
pokemon.scene.queueMessage(getPokemonMessage(knockedOut, `'s ${allAbilities[knockedOut.getAbility().id].name} was taken over!`));
return true;
}
return false;
}
}
@ -1047,8 +1082,8 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) {
super();
this.stats = typeof(stats) === 'number'
? [ stats as BattleStat ]
this.stats = typeof (stats) === 'number'
? [stats as BattleStat]
: stats as BattleStat[];
this.levels = levels;
this.selfTarget = !!selfTarget;
@ -1070,7 +1105,7 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
else
pokemon.scene.unshiftPhase(statChangePhase);
}
return true;
}
}
@ -1083,12 +1118,12 @@ export class DownloadAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
this.enemyDef = 0;
this.enemySpDef = 0;
for (let opponent of pokemon.getOpponents()) {
this.enemyDef += opponent.stats[BattleStat.DEF];
this.enemySpDef += opponent.stats[BattleStat.SPDEF];
}
if (this.enemyDef < this.enemySpDef)
this.stats = [BattleStat.ATK];
else
@ -1098,7 +1133,7 @@ export class DownloadAbAttr extends PostSummonAbAttr {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1));
return true;
}
return false;
}
}
@ -1193,11 +1228,11 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
pokemon.summonData.ability = target.getAbility().id;
pokemon.summonData.gender = target.getGender();
pokemon.summonData.fusionGender = target.getFusionGender();
pokemon.summonData.stats = [ pokemon.stats[Stat.HP] ].concat(target.stats.slice(1));
pokemon.summonData.stats = [pokemon.stats[Stat.HP]].concat(target.stats.slice(1));
pokemon.summonData.battleStats = target.summonData.battleStats.slice(0);
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp));
pokemon.summonData.types = target.getTypes();
pokemon.scene.playSound('PRSFX- Transform');
pokemon.loadAssets(false).then(() => pokemon.playAnim());
@ -1232,7 +1267,7 @@ export class PreSwitchOutResetStatusAbAttr extends PreSwitchOutAbAttr {
export class PreSwitchOutHealAbAttr extends PreSwitchOutAbAttr {
applyPreSwitchOut(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
if (pokemon.getHpRatio() < 1 ) {
if (pokemon.getHpRatio() < 1) {
const healAmount = Math.floor(pokemon.getMaxHp() * 0.33);
pokemon.heal(healAmount);
pokemon.updateInfo();
@ -1263,7 +1298,7 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
cancelled.value = true;
return true;
}
return false;
}
@ -1372,7 +1407,7 @@ export class IncrementMovePriorityAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!this.moveIncrementFunc(pokemon, args[0] as Move))
return false;
(args[1] as Utils.IntegerHolder).value += this.increaseAmount;
return true;
}
@ -1484,7 +1519,7 @@ export class PostWeatherLapseHealAbAttr extends PostWeatherLapseAbAttr {
constructor(healFactor: integer, ...weatherTypes: WeatherType[]) {
super(...weatherTypes);
this.healFactor = healFactor;
}
@ -1506,7 +1541,7 @@ export class PostWeatherLapseDamageAbAttr extends PostWeatherLapseAbAttr {
constructor(damageFactor: integer, ...weatherTypes: WeatherType[]) {
super(...weatherTypes);
this.damageFactor = damageFactor;
}
@ -1566,13 +1601,13 @@ export class PostTurnAbAttr extends AbAttr {
export class PostTurnResetStatusAbAttr extends PostTurnAbAttr {
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
if (pokemon.status) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status?.effect)));
pokemon.resetStatus();
pokemon.updateInfo();
return true;
}
return false;
}
}
@ -1586,7 +1621,7 @@ export class PostTurnStatChangeAbAttr extends PostTurnAbAttr {
this.stats = Array.isArray(stats)
? stats
: [ stats ];
: [stats];
this.levels = levels;
}
@ -1719,7 +1754,7 @@ export class CheckTrappedAbAttr extends AbAttr {
constructor() {
super(false);
}
applyCheckTrapped(pokemon: Pokemon, passive: boolean, trapped: Utils.BooleanHolder, args: any[]): boolean | Promise<boolean> {
return false;
}
@ -1778,7 +1813,7 @@ export class PostFaintAbAttr extends AbAttr {
export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
private damageRatio: integer;
constructor(damageRatio: integer) {
super();
@ -1812,10 +1847,10 @@ export class RedirectMoveAbAttr extends AbAttr {
return false;
}
canRedirect(moveId: Moves): boolean {
const move = allMoves[moveId];
return !![ MoveTarget.NEAR_OTHER, MoveTarget.OTHER ].find(t => move.moveTarget === t);
return !![MoveTarget.NEAR_OTHER, MoveTarget.OTHER].find(t => move.moveTarget === t);
}
}
@ -1866,7 +1901,7 @@ export class FlinchStatChangeAbAttr extends FlinchEffectAbAttr {
this.stats = Array.isArray(stats)
? stats
: [ stats ];
: [stats];
this.levels = levels;
}
@ -2060,7 +2095,7 @@ export function applyPostAttackAbAttrs(attrType: { new(...args: any[]): PostAtta
export function applyPostKnockOutAbAttrs(attrType: { new(...args: any[]): PostKnockOutAbAttr },
pokemon: Pokemon, knockedOut: Pokemon, ...args: any[]): Promise<void> {
return applyAbAttrsInternal<PostKnockOutAbAttr>(attrType, pokemon, (attr, passive) => attr.applyPostKnockOut(pokemon, passive, knockedOut, args), args);
}
}
export function applyPostVictoryAbAttrs(attrType: { new(...args: any[]): PostVictoryAbAttr },
pokemon: Pokemon, ...args: any[]): Promise<void> {
@ -2148,7 +2183,7 @@ function queueShowAbility(pokemon: Pokemon, passive: boolean): void {
pokemon.scene.clearPhaseQueueSplice();
}
export const allAbilities = [ new Ability(Abilities.NONE, "-", "", 3) ];
export const allAbilities = [new Ability(Abilities.NONE, "-", "", 3)];
export function initAbilities() {
allAbilities.push(
@ -2161,7 +2196,7 @@ export function initAbilities() {
new Ability(Abilities.BATTLE_ARMOR, "Battle Armor", "Hard armor protects the Pokémon from critical hits.", 3)
.attr(BlockCritAbAttr)
.ignorable(),
new Ability(Abilities.STURDY, "Sturdy", "It cannot be knocked out with one hit. One-hit KO moves cannot knock it out, either.", 3)
new Ability(Abilities.STURDY, "Sturdy", "It cannot be knocked out with one hit. One-hit KO moves cannot knock it out, either.", 3)
.attr(PreDefendFullHpEndureAbAttr)
.attr(BlockOneHitKOAbAttr)
.ignorable(),
@ -2401,8 +2436,8 @@ export function initAbilities() {
.conditionalAttr(pokemon => pokemon.status.effect === StatusEffect.PARALYSIS, BattleStatMultiplierAbAttr, BattleStat.SPD, 2)
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5),
new Ability(Abilities.NORMALIZE, "Normalize", "All the Pokémon's moves become Normal type. The power of those moves is boosted a little.", 4)
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL &&
move.id !== Moves.NATURAL_GIFT && move.id !== Moves.JUDGMENT && move.id !== Moves.TECHNO_BLAST),
.attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL &&
move.id !== Moves.NATURAL_GIFT && move.id !== Moves.JUDGMENT && move.id !== Moves.TECHNO_BLAST),
new Ability(Abilities.SNIPER, "Sniper (N)", "Powers up moves if they become critical hits when attacking.", 4),
new Ability(Abilities.MAGIC_GUARD, "Magic Guard", "The Pokémon only takes damage from attacks.", 4)
.attr(BlockNonDirectDamageAbAttr),
@ -2421,7 +2456,7 @@ export function initAbilities() {
new Ability(Abilities.SUPER_LUCK, "Super Luck (P)", "The Pokémon is so lucky that the critical-hit ratios of its moves are boosted.", 4)
.attr(BonusCritAbAttr),
new Ability(Abilities.AFTERMATH, "Aftermath", "Damages the attacker if it contacts the Pokémon with a finishing hit.", 4)
.attr(PostFaintContactDamageAbAttr,4)
.attr(PostFaintContactDamageAbAttr, 4)
.bypassFaint(),
new Ability(Abilities.ANTICIPATION, "Anticipation (N)", "The Pokémon can sense an opposing Pokémon's dangerous moves.", 4),
new Ability(Abilities.FOREWARN, "Forewarn (N)", "When it enters a battle, the Pokémon can tell one of the moves an opposing Pokémon has.", 4),
@ -2431,7 +2466,7 @@ export function initAbilities() {
new Ability(Abilities.TINTED_LENS, "Tinted Lens", "The Pokémon can use \"not very effective\" moves to deal regular damage.", 4)
.attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type) <= 0.5, 2),
new Ability(Abilities.FILTER, "Filter", "Reduces the power of supereffective attacks taken.", 4)
.attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 0.75)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 0.75)
.ignorable(),
new Ability(Abilities.SLOW_START, "Slow Start", "For five turns, the Pokémon's Attack and Speed stats are halved.", 4)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
@ -2444,7 +2479,7 @@ export function initAbilities() {
.attr(BlockWeatherDamageAttr, WeatherType.HAIL)
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW),
new Ability(Abilities.SOLID_ROCK, "Solid Rock", "Reduces the power of supereffective attacks taken.", 4)
.attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 0.75)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 0.75)
.ignorable(),
new Ability(Abilities.SNOW_WARNING, "Snow Warning", "The Pokémon makes it snow when it enters a battle.", 4)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW)
@ -2491,7 +2526,7 @@ export function initAbilities() {
.attr(WeightMultiplierAbAttr, 0.5)
.ignorable(),
new Ability(Abilities.MULTISCALE, "Multiscale", "Reduces the amount of damage the Pokémon takes while its HP is full.", 5)
.attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getHpRatio() === 1, 0.5)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getHpRatio() === 1, 0.5)
.ignorable(),
new Ability(Abilities.TOXIC_BOOST, "Toxic Boost", "Powers up physical attacks when the Pokémon is poisoned.", 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.category === MoveCategory.PHYSICAL && (user.status?.effect === StatusEffect.POISON || user.status?.effect === StatusEffect.TOXIC), 1.5),
@ -2510,7 +2545,7 @@ export function initAbilities() {
new Ability(Abilities.POISON_TOUCH, "Poison Touch", "May poison a target when the Pokémon makes contact.", 5)
.attr(PostAttackContactApplyStatusEffectAbAttr, 30, StatusEffect.POISON),
new Ability(Abilities.REGENERATOR, "Regenerator", "Restores a little HP when withdrawn from battle.", 5)
.attr(PreSwitchOutHealAbAttr),
.attr(PreSwitchOutHealAbAttr),
new Ability(Abilities.BIG_PECKS, "Big Pecks", "Protects the Pokémon from Defense-lowering effects.", 5)
.attr(ProtectStatAbAttr, BattleStat.DEF)
.ignorable(),
@ -2669,7 +2704,10 @@ export function initAbilities() {
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr),
new Ability(Abilities.DISGUISE, "Disguise (N)", "Once per battle, the shroud that covers the Pokémon can protect it from an attack.", 7)
new Ability(Abilities.DISGUISE, "Disguise (T)", "Once per battle, the shroud that covers the Pokémon can protect it from an attack.", 7)
.attr(SetMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0)
.attr(PostTurnFormChangeAbAttr, pokemon => pokemon.battleData.hitCount === 0 ? 0 : 1)
.attr(PostDefendDisguiseAbAttr)
.attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr)
@ -2744,9 +2782,9 @@ export function initAbilities() {
new Ability(Abilities.FULL_METAL_BODY, "Full Metal Body", "Prevents other Pokémon's moves or Abilities from lowering the Pokémon's stats.", 7)
.attr(ProtectStatAbAttr),
new Ability(Abilities.SHADOW_SHIELD, "Shadow Shield", "Reduces the amount of damage the Pokémon takes while its HP is full.", 7)
.attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getHpRatio() === 1, 0.5),
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getHpRatio() === 1, 0.5),
new Ability(Abilities.PRISM_ARMOR, "Prism Armor", "Reduces the power of supereffective attacks taken.", 7)
.attr(ReceivedMoveDamageMultiplierAbAttr,(target, user, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 0.75),
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 0.75),
new Ability(Abilities.NEUROFORCE, "Neuroforce", "Powers up moves that are super effective.", 7)
.attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type) >= 2, 1.25),
new Ability(Abilities.INTREPID_SWORD, "Intrepid Sword", "Boosts the Pokémon's Attack stat when the Pokémon enters a battle.", 8)
@ -2899,7 +2937,7 @@ export function initAbilities() {
new Ability(Abilities.COSTAR, "Costar (N)", "When the Pokémon enters a battle, it copies an ally's stat changes.", 9),
new Ability(Abilities.TOXIC_DEBRIS, "Toxic Debris (N)", "Scatters poison spikes at the feet of the opposing team when the Pokémon takes damage from physical moves.", 9),
new Ability(Abilities.ARMOR_TAIL, "Armor Tail", "The mysterious tail covering the Pokémon's head makes opponents unable to use priority moves against the Pokémon or its allies.", 9)
.attr(FieldPriorityMoveImmunityAbAttr)
.attr(FieldPriorityMoveImmunityAbAttr)
.ignorable(),
new Ability(Abilities.EARTH_EATER, "Earth Eater", "If hit by a Ground-type move, the Pokémon has its HP restored instead of taking damage.", 9)
.attr(TypeImmunityHealAbAttr, Type.GROUND)

View File

@ -565,6 +565,10 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.MINIOR, 'violet-meteor', 'violet', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MINIOR, 'violet', 'violet-meteor', new SpeciesFormChangeManualTrigger(), true)
],
[Species.MIMIKYU]: [
new SpeciesFormChange(Species.MIMIKYU, 'disguised', 'busted', new SpeciesFormChangeManualTrigger(), true),
new SpeciesFormChange(Species.MIMIKYU, 'busted', 'disquised', new SpeciesFormChangeManualTrigger(), true)
],
[Species.NECROZMA]: [
new SpeciesFormChange(Species.NECROZMA, '', 'dawn-wings', new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER)),
new SpeciesFormChange(Species.NECROZMA, '', 'dusk-mane', new SpeciesFormChangeItemTrigger(FormChangeItem.N_SOLARIZER))