mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-01-30 04:37:14 +00:00
[Fix] Refactor Disguise to work like Ice Face (#2684)
* Fix typos in `src/data/egg.ts` comments * Refactor Disguise using Ice Face as a base i18n { Co-authored-by: Arxxer <javiptn7@gmail.com> Co-authored-by: GoldTra <162721984+GoldTra@users.noreply.github.com> Co-authored-by: sodam <66295123+sodaMelon@users.noreply.github.com> Co-authored-by: José Ricardo Fleury Oliveira <josefleury@discente.ufg.br> Co-authored-by: mercurius-00 <80205689+mercurius-00@users.noreply.github.com> } Update tests * Update jsdoc * Make recoil damage a parameter * Fix Ice Face i18n parameter name * Add i18n placeholder strings for translation * Update disguise test with override helper functions * Move a form change from `battle-scene.ts` to `ability.ts` * Remove a bit of obsolete code from the Disguise test * Add some translations Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> Co-authored-by: returntoice <dieandbecome@gmail.com> Co-authored-by: José Ricardo Fleury Oliveira <josefleury@discente.ufg.br> Co-authored-by: Sonny Ding <93831983+sonnyding1@users.noreply.github.com> * Add translation placeholder strings for Japanese and Catalan * Update for strict-null * Remove unused parameter from the `BattlerTag` class * Remove species checks, fusion doesn't seem to be an issue (any more?) * Move Ice Face weather-based code to a subclass * Condense conditionals Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com> --------- Co-authored-by: Lugiad' <adrien.grivel@hotmail.fr> Co-authored-by: returntoice <dieandbecome@gmail.com> Co-authored-by: José Ricardo Fleury Oliveira <josefleury@discente.ufg.br> Co-authored-by: Sonny Ding <93831983+sonnyding1@users.noreply.github.com> Co-authored-by: innerthunder <168692175+innerthunder@users.noreply.github.com>
This commit is contained in:
parent
d3d376dca3
commit
223295e827
@ -55,7 +55,6 @@ import {UiInputs} from "./ui-inputs";
|
||||
import { NewArenaEvent } from "./events/battle-scene";
|
||||
import { ArenaFlyout } from "./ui/arena-flyout";
|
||||
import { EaseType } from "#enums/ease-type";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { BattleSpec } from "#enums/battle-spec";
|
||||
import { BattleStyle } from "#enums/battle-style";
|
||||
import { Biome } from "#enums/biome";
|
||||
@ -1153,12 +1152,6 @@ export default class BattleScene extends SceneBase {
|
||||
playerField.forEach((_, p) => this.pushPhase(new ReturnPhase(this, p)));
|
||||
|
||||
for (const pokemon of this.getParty()) {
|
||||
// Only trigger form change when Eiscue is in Noice form
|
||||
// Hardcoded Eiscue for now in case it is fused with another pokemon
|
||||
if (pokemon.species.speciesId === Species.EISCUE && pokemon.hasAbility(Abilities.ICE_FACE) && pokemon.formIndex === 1) {
|
||||
this.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
||||
}
|
||||
|
||||
pokemon.resetBattleData();
|
||||
applyPostBattleInitAbAttrs(PostBattleInitAbAttr, pokemon);
|
||||
}
|
||||
|
@ -245,25 +245,6 @@ export class PreDefendAbAttr extends AbAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class PreDefendFormChangeAbAttr extends PreDefendAbAttr {
|
||||
private formFunc: (p: Pokemon) => integer;
|
||||
|
||||
constructor(formFunc: ((p: Pokemon) => integer)) {
|
||||
super(true);
|
||||
|
||||
this.formFunc = formFunc;
|
||||
}
|
||||
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
const formIndex = this.formFunc(pokemon);
|
||||
if (formIndex !== pokemon.formIndex) {
|
||||
pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
if (pokemon.isFullHp() &&
|
||||
@ -330,21 +311,6 @@ export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultip
|
||||
}
|
||||
}
|
||||
|
||||
export class PreDefendMoveDamageToOneAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
||||
constructor(condition: PokemonDefendCondition) {
|
||||
super(condition, 1);
|
||||
}
|
||||
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
if (this.condition(pokemon, attacker, move)) {
|
||||
(args[0] as Utils.NumberHolder).value = Math.floor(pokemon.getMaxHp() / 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a Pokemon is immune to a move because of an ability.
|
||||
* @extends PreDefendAbAttr
|
||||
@ -539,45 +505,6 @@ export class PostDefendGulpMissileAbAttr extends PostDefendAbAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
|
||||
|
||||
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
if (pokemon.formIndex === 0 && pokemon.battleData.hitCount !== 0 && (move.category === MoveCategory.SPECIAL || move.category === MoveCategory.PHYSICAL)) {
|
||||
|
||||
const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt);
|
||||
if (!recoilDamage) {
|
||||
return false;
|
||||
}
|
||||
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
|
||||
pokemon.turnData.damageTaken += recoilDamage;
|
||||
pokemon.scene.queueMessage(i18next.t("abilityTriggers:postDefendDisguise", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class PostDefendFormChangeAbAttr extends PostDefendAbAttr {
|
||||
private formFunc: (p: Pokemon) => integer;
|
||||
|
||||
constructor(formFunc: ((p: Pokemon) => integer)) {
|
||||
super(true);
|
||||
|
||||
this.formFunc = formFunc;
|
||||
}
|
||||
|
||||
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
|
||||
const formIndex = this.formFunc(pokemon);
|
||||
if (formIndex !== pokemon.formIndex) {
|
||||
pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
const attackPriority = new Utils.IntegerHolder(move.priority);
|
||||
@ -4045,34 +3972,44 @@ export class PostSummonStatChangeOnArenaAbAttr extends PostSummonStatChangeAbAtt
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes no damage from the first hit of a physical move.
|
||||
* This is used in Ice Face ability.
|
||||
* Takes no damage from the first hit of a damaging move.
|
||||
* This is used in the Disguise and Ice Face abilities.
|
||||
* @extends ReceivedMoveDamageMultiplierAbAttr
|
||||
*/
|
||||
export class IceFaceBlockPhysicalAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
||||
export class FormBlockDamageAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
||||
private multiplier: number;
|
||||
private tagType: BattlerTagType;
|
||||
private recoilDamageFunc: ((pokemon: Pokemon) => number) | undefined;
|
||||
private triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string;
|
||||
|
||||
constructor(condition: PokemonDefendCondition, multiplier: number) {
|
||||
constructor(condition: PokemonDefendCondition, multiplier: number, tagType: BattlerTagType, triggerMessageFunc: (pokemon: Pokemon, abilityName: string) => string, recoilDamageFunc?: (pokemon: Pokemon) => number) {
|
||||
super(condition, multiplier);
|
||||
|
||||
this.multiplier = multiplier;
|
||||
this.tagType = tagType;
|
||||
this.recoilDamageFunc = recoilDamageFunc;
|
||||
this.triggerMessageFunc = triggerMessageFunc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the Ice Face pre-defense ability to the Pokémon.
|
||||
* Removes BattlerTagType.ICE_FACE when hit by physical attack and is in Ice Face form.
|
||||
* Applies the pre-defense ability to the Pokémon.
|
||||
* Removes the appropriate `BattlerTagType` when hit by an attack and is in its defense form.
|
||||
*
|
||||
* @param {Pokemon} pokemon - The Pokémon with the Ice Face ability.
|
||||
* @param {boolean} passive - Whether the ability is passive.
|
||||
* @param {Pokemon} attacker - The attacking Pokémon.
|
||||
* @param {PokemonMove} move - The move being used.
|
||||
* @param {Utils.BooleanHolder} cancelled - A holder for whether the move was cancelled.
|
||||
* @param {any[]} args - Additional arguments.
|
||||
* @returns {boolean} - Whether the immunity was applied.
|
||||
* @param {Pokemon} pokemon The Pokémon with the ability.
|
||||
* @param {boolean} passive n/a
|
||||
* @param {Pokemon} attacker The attacking Pokémon.
|
||||
* @param {PokemonMove} move The move being used.
|
||||
* @param {Utils.BooleanHolder} cancelled n/a
|
||||
* @param {any[]} args Additional arguments.
|
||||
* @returns {boolean} Whether the immunity was applied.
|
||||
*/
|
||||
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||
if (this.condition(pokemon, attacker, move)) {
|
||||
(args[0] as Utils.NumberHolder).value = this.multiplier;
|
||||
pokemon.removeTag(BattlerTagType.ICE_FACE);
|
||||
pokemon.removeTag(this.tagType);
|
||||
if (this.recoilDamageFunc) {
|
||||
pokemon.damageAndUpdate(this.recoilDamageFunc(pokemon), HitResult.OTHER);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4080,14 +4017,14 @@ export class IceFaceBlockPhysicalAbAttr extends ReceivedMoveDamageMultiplierAbAt
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message triggered when the Pokémon avoids damage using the Ice Face ability.
|
||||
* @param {Pokemon} pokemon - The Pokémon with the Ice Face ability.
|
||||
* @param {string} abilityName - The name of the ability.
|
||||
* @param {...any} args - Additional arguments.
|
||||
* @returns {string} - The trigger message.
|
||||
* Gets the message triggered when the Pokémon avoids damage using the form-changing ability.
|
||||
* @param {Pokemon} pokemon The Pokémon with the ability.
|
||||
* @param {string} abilityName The name of the ability.
|
||||
* @param {...any} args n/a
|
||||
* @returns {string} The trigger message.
|
||||
*/
|
||||
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
|
||||
return i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName });
|
||||
return this.triggerMessageFunc(pokemon, abilityName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5004,20 +4941,18 @@ export function initAbilities() {
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
.bypassFaint(),
|
||||
new Ability(Abilities.DISGUISE, 7)
|
||||
.attr(PreDefendMoveDamageToOneAbAttr, (target, user, move) => target.formIndex === 0 && target.getAttackTypeEffectiveness(move.type, user) > 0)
|
||||
.attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
.attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
||||
.attr(PreDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
|
||||
.attr(PostDefendDisguiseAbAttr)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
.attr(UnswappableAbilityAbAttr)
|
||||
.attr(UnsuppressableAbilityAbAttr)
|
||||
.attr(NoTransformAbilityAbAttr)
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
.bypassFaint()
|
||||
.ignorable()
|
||||
.partial(),
|
||||
// Add BattlerTagType.DISGUISE if the pokemon is in its disguised form
|
||||
.conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false)
|
||||
.attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getAttackTypeEffectiveness(move.type, user) > 0, 0, BattlerTagType.DISGUISE,
|
||||
(pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
|
||||
(pokemon) => Math.floor(pokemon.getMaxHp() / 8))
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.BATTLE_BOND, 7)
|
||||
.attr(PostVictoryFormChangeAbAttr, () => 2)
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 1)
|
||||
@ -5166,7 +5101,9 @@ export function initAbilities() {
|
||||
.conditionalAttr(getWeatherCondition(WeatherType.HAIL, WeatherType.SNOW), PostSummonAddBattlerTagAbAttr, BattlerTagType.ICE_FACE, 0)
|
||||
// When weather changes to HAIL or SNOW while pokemon is fielded, add BattlerTagType.ICE_FACE
|
||||
.attr(PostWeatherChangeAddBattlerTagAttr, BattlerTagType.ICE_FACE, 0, WeatherType.HAIL, WeatherType.SNOW)
|
||||
.attr(IceFaceBlockPhysicalAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0)
|
||||
.attr(FormBlockDamageAbAttr, (target, user, move) => move.category === MoveCategory.PHYSICAL && !!target.getTag(BattlerTagType.ICE_FACE), 0, BattlerTagType.ICE_FACE,
|
||||
(pokemon, abilityName) => i18next.t("abilityTriggers:iceFaceAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }))
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.POWER_SPOT, 8)
|
||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3),
|
||||
|
@ -1558,36 +1558,25 @@ export class GroundedTag extends BattlerTag {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the Ice Face ability's effects.
|
||||
*/
|
||||
export class IceFaceTag extends BattlerTag {
|
||||
constructor(sourceMove: Moves) {
|
||||
super(BattlerTagType.ICE_FACE, BattlerTagLapseType.CUSTOM, 1, sourceMove);
|
||||
/** Common attributes of form change abilities that block damage */
|
||||
export class FormBlockDamageTag extends BattlerTag {
|
||||
constructor(tagType: BattlerTagType) {
|
||||
super(tagType, BattlerTagLapseType.CUSTOM, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Ice Face tag can be added to the Pokémon.
|
||||
* @param {Pokemon} pokemon - The Pokémon to which the tag might be added.
|
||||
* @returns {boolean} - True if the tag can be added, false otherwise.
|
||||
* Determines if the tag can be added to the Pokémon.
|
||||
* @param {Pokemon} pokemon The Pokémon to which the tag might be added.
|
||||
* @returns {boolean} True if the tag can be added, false otherwise.
|
||||
*/
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
const weatherType = pokemon.scene.arena.weather?.weatherType;
|
||||
const isWeatherSnowOrHail = weatherType === WeatherType.HAIL || weatherType === WeatherType.SNOW;
|
||||
const isFormIceFace = pokemon.formIndex === 0;
|
||||
|
||||
|
||||
// Hard code Eiscue for now, this is to prevent the game from crashing if fused pokemon has Ice Face
|
||||
if ((pokemon.species.speciesId === Species.EISCUE && isFormIceFace) || isWeatherSnowOrHail) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return pokemon.formIndex === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the Ice Face tag to the Pokémon.
|
||||
* Triggers a form change to Ice Face if the Pokémon is not in its Ice Face form.
|
||||
* @param {Pokemon} pokemon - The Pokémon to which the tag is added.
|
||||
* Applies the tag to the Pokémon.
|
||||
* Triggers a form change if the Pokémon is not in its defense form.
|
||||
* @param {Pokemon} pokemon The Pokémon to which the tag is added.
|
||||
*/
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
@ -1598,9 +1587,9 @@ export class IceFaceTag extends BattlerTag {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the Ice Face tag from the Pokémon.
|
||||
* Triggers a form change to Noice when the tag is removed.
|
||||
* @param {Pokemon} pokemon - The Pokémon from which the tag is removed.
|
||||
* Removes the tag from the Pokémon.
|
||||
* Triggers a form change when the tag is removed.
|
||||
* @param {Pokemon} pokemon The Pokémon from which the tag is removed.
|
||||
*/
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
@ -1609,6 +1598,24 @@ export class IceFaceTag extends BattlerTag {
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides the additional weather-based effects of the Ice Face ability */
|
||||
export class IceFaceBlockDamageTag extends FormBlockDamageTag {
|
||||
constructor(tagType: BattlerTagType) {
|
||||
super(tagType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the tag can be added to the Pokémon.
|
||||
* @param {Pokemon} pokemon The Pokémon to which the tag might be added.
|
||||
* @returns {boolean} True if the tag can be added, false otherwise.
|
||||
*/
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
const weatherType = pokemon.scene.arena.weather?.weatherType;
|
||||
const isWeatherSnowOrHail = weatherType === WeatherType.HAIL || weatherType === WeatherType.SNOW;
|
||||
|
||||
return super.canAdd(pokemon) || isWeatherSnowOrHail;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Battler tag enabling the Stockpile mechanic. This tag handles:
|
||||
@ -1890,7 +1897,9 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
||||
case BattlerTagType.DESTINY_BOND:
|
||||
return new DestinyBondTag(sourceMove, sourceId);
|
||||
case BattlerTagType.ICE_FACE:
|
||||
return new IceFaceTag(sourceMove);
|
||||
return new IceFaceBlockDamageTag(tagType);
|
||||
case BattlerTagType.DISGUISE:
|
||||
return new FormBlockDamageTag(tagType);
|
||||
case BattlerTagType.STOCKPILING:
|
||||
return new StockpilingTag(sourceMove);
|
||||
case BattlerTagType.OCTOLOCK:
|
||||
|
@ -372,6 +372,9 @@ export function getSpeciesFormChangeMessage(pokemon: Pokemon, formChange: Specie
|
||||
if (isRevert) {
|
||||
return i18next.t("battlePokemonForm:revertChange", { pokemonName: getPokemonNameWithAffix(pokemon) });
|
||||
}
|
||||
if (pokemon.getAbility().id === Abilities.DISGUISE) {
|
||||
return i18next.t("battlePokemonForm:disguiseChange");
|
||||
}
|
||||
return i18next.t("battlePokemonForm:formChange", { preName });
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@ export enum BattlerTagType {
|
||||
DESTINY_BOND = "DESTINY_BOND",
|
||||
CENTER_OF_ATTENTION = "CENTER_OF_ATTENTION",
|
||||
ICE_FACE = "ICE_FACE",
|
||||
DISGUISE = "DISGUISE",
|
||||
STOCKPILING = "STOCKPILING",
|
||||
RECEIVE_DOUBLE_DAMAGE = "RECEIVE_DOUBLE_DAMAGE",
|
||||
ALWAYS_GET_HIT = "ALWAYS_GET_HIT",
|
||||
|
@ -10,6 +10,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!",
|
||||
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
|
||||
"quickDraw": "{{pokemonName}} can act faster than normal, thanks to its Quick Draw!",
|
||||
"disguiseAvoidedDamage" : "{{pokemonNameWithAffix}}'s disguise was busted!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents item theft!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} avoided damage\nwith {{abilityName}}!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} Eternamaxed\ninto {{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}} reverted\nto its original form!",
|
||||
"formChange": "{{preName}} changed form!",
|
||||
"disguiseChange": "Its disguise served it as a decoy!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,7 +4,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage": "{{pokemonName}} wurde durch {{abilityName}} vor Rückstoß geschützt!",
|
||||
"badDreams": "{{pokemonName}} ist in einem Alptraum gefangen!",
|
||||
"costar": "{{pokemonName}} kopiert die Statusveränderungen von {{allyName}}!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}} wehrt Schaden mit {{abilityName}} ab!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} wehrt Schaden mit {{abilityName}} ab!",
|
||||
"perishBody": "Durch {{abilityName}} von {{pokemonName}} werden beide Pokémon nach drei Runden K.O. gehen!",
|
||||
"poisonHeal": "{{abilityName}} von {{pokemonName}} füllte einige KP auf!",
|
||||
"trace": "{{pokemonName}} kopiert {{abilityName}} von {{targetName}}!",
|
||||
@ -13,7 +13,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockItemTheft": "{{abilityName}} von {{pokemonNameWithAffix}} verhindert Item-Diebstahl!",
|
||||
"typeImmunityHeal": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} vermeidet Schaden mit {{abilityName}}!",
|
||||
"postDefendDisguise": "Die Tarnung von {{pokemonNameWithAffix}} ist aufgeflogen!!",
|
||||
"disguiseAvoidedDamage": "Die Tarnung von {{pokemonNameWithAffix}} ist aufgeflogen!!",
|
||||
"moveImmunity": "Es hat keine Wirkung auf {{pokemonNameWithAffix}}...",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} saugt Kloakensoße auf!",
|
||||
"postDefendTypeChange": "{{abilityName}} von {{pokemonNameWithAffix}} macht es zu einem {{typeName}}-Typ!",
|
||||
|
@ -14,6 +14,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} hat sich zu {{pokemonName}} unendynamaximiert!",
|
||||
"revertChange": "{{pokemonName}} hat seine ursprüngliche Form zurückerlangt!",
|
||||
"formChange": "{{preName}} hat seine Form geändert!",
|
||||
"disguiseChange": "Its disguise served it as a decoy!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,16 +4,16 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage": "{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!",
|
||||
"badDreams": "{{pokemonName}} is tormented!",
|
||||
"costar": "{{pokemonName}} copied {{allyName}}'s stat changes!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}} avoided\ndamage with {{abilityName}}!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} avoided\ndamage with {{abilityName}}!",
|
||||
"perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!",
|
||||
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!",
|
||||
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
|
||||
"quickDraw": "{{pokemonName}} can act faster than normal, thanks to its Quick Draw!",
|
||||
"disguiseAvoidedDamage" : "{{pokemonNameWithAffix}}'s disguise was busted!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents item theft!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} avoided damage\nwith {{abilityName}}!",
|
||||
"postDefendDisguise": "{{pokemonNameWithAffix}}'s disguise was busted!",
|
||||
"moveImmunity": "It doesn't affect {{pokemonNameWithAffix}}!",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} sucked up the liquid ooze!",
|
||||
"postDefendTypeChange": "{{pokemonNameWithAffix}}'s {{abilityName}}\nmade it the {{typeName}} type!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} Eternamaxed\ninto {{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}} reverted\nto its original form!",
|
||||
"formChange": "{{preName}} changed form!",
|
||||
"disguiseChange": "Its disguise served it as a decoy!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -7,13 +7,13 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"iceFaceAvoidedDamage": "¡{{pokemonNameWithAffix}} evitó\ndaño con {{abilityName}}!",
|
||||
"perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!",
|
||||
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!",
|
||||
"trace": "¡{{pokemonName}} ha copiado la habilidad {{abilityName}} \nde {{targetName}}!",
|
||||
"windPowerCharged": "¡{{pokemonName}} se ha cargado de electricidad gracias a {{moveName}}!",
|
||||
"quickDraw": "{{pokemonName}} can act faster than normal, thanks to its Quick Draw!",
|
||||
"quickDraw": "¡{{pokemonName}} ataca primero gracias a la habilidad Mano Rápida!",
|
||||
"disguiseAvoidedDamage" : "¡El disfraz de {{pokemonNameWithAffix}} se ha roto!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents item theft!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} avoided damage\nwith {{abilityName}}!",
|
||||
"postDefendDisguise": "{{pokemonNameWithAffix}}'s disguise was busted!",
|
||||
"moveImmunity": "It doesn't affect {{pokemonNameWithAffix}}!",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} sucked up the liquid ooze!",
|
||||
"postDefendTypeChange": "{{pokemonNameWithAffix}}'s {{abilityName}}\nmade it the {{typeName}} type!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} Eternamaxed\ninto {{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}} reverted\nto its original form!",
|
||||
"formChange": "{{preName}} changed form!",
|
||||
"disguiseChange": "Its disguise served it as a decoy!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,7 +4,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage" : "{{abilityName}}\nde {{pokemonName}} le protège du contrecoup !",
|
||||
"badDreams": "{{pokemonName}} a le sommeil agité !",
|
||||
"costar": "{{pokemonName}} copie les changements de stats\nde {{allyName}} !",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}} évite les dégâts\navec {{abilityName}} !",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} évite les dégâts\navec {{abilityName}} !",
|
||||
"perishBody": "{{abilityName}} de {{pokemonName}}\nmettra les deux Pokémon K.O. dans trois tours !",
|
||||
"poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaure un peu ses PV !",
|
||||
"trace": "{{pokemonName}} copie le talent {{abilityName}}\nde {{targetName}} !",
|
||||
@ -13,7 +13,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockItemTheft": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche son objet d’être volé !",
|
||||
"typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} évite\nles dégâts avec {{abilityName}} !",
|
||||
"postDefendDisguise": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !",
|
||||
"disguiseAvoidedDamage": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !",
|
||||
"moveImmunity": "Ça n'affecte pas {{pokemonNameWithAffix}}…",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} aspire\nle suintement !",
|
||||
"postDefendTypeChange": "{{abilityName}} de {{pokemonNameWithAffix}}\nle transforme en type {{typeName}} !",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} devient\n{{pokemonName}} !",
|
||||
"revertChange": "{{pokemonName}} retourne\nà sa forme initiale !",
|
||||
"formChange": "{{preName}} change de forme !",
|
||||
"disguiseChange": "Le déguisement absorbe l’attaque !",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,7 +4,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage" : "{{abilityName}} di {{pokemonName}}\nl'ha protetto dal contraccolpo!",
|
||||
"badDreams": "{{pokemonName}} è tormentato dagli incubi!",
|
||||
"costar": "{{pokemonName}} ha copiato le modifiche alle statistiche\ndel suo alleato {{allyName}}!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}} ha evitato\ni danni grazie a {{abilityName}}!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} ha evitato\ni danni grazie a {{abilityName}}!",
|
||||
"perishBody": "{{abilityName}} di {{pokemonName}}\nmanderà KO entrambi i Pokémon dopo 3 turni!",
|
||||
"poisonHeal": "{{pokemonName}} recupera alcuni PS\ncon {{abilityName}}!",
|
||||
"trace": "L'abilità {{abilityName}} di {{targetName}}\nviene copiata da {{pokemonName}} con Traccia!",
|
||||
@ -13,7 +13,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockItemTheft": "{{abilityName}} di {{pokemonNameWithAffix}}\nlo rende immune ai furti!",
|
||||
"typeImmunityHeal": "{{pokemonName}} recupera alcuni PS\ncon {{abilityName}}!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} evita il colpo\ncon {{abilityName}}!",
|
||||
"postDefendDisguise": "{{pokemonNameWithAffix}} è stato smascherato!",
|
||||
"disguiseAvoidedDamage": "{{pokemonNameWithAffix}} è stato smascherato!",
|
||||
"moveImmunity": "Non ha effetto su {{pokemonNameWithAffix}}!",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} ha assorbito la melma!",
|
||||
"postDefendTypeChange": "{{abilityName}} di {{pokemonNameWithAffix}}\nlo ha reso di tipo {{typeName}}!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} si Dynamaxxa infinitamente\nin {{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}} è tornato\nalla sua forma originaria!",
|
||||
"formChange": "{{preName}} ha cambiato forma!",
|
||||
"disguiseChange": "Its disguise served it as a decoy!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -10,6 +10,7 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"trace": "{{pokemonName}}は 相手の {{targetName}}の\n{{abilityName}}を トレースした!",
|
||||
"windPowerCharged": "{{pokemonName}}は\n{{moveName}}を 受けて じゅうでんした!",
|
||||
"quickDraw": "{{pokemonName}}は クイックドロウで\n行動が はやくなった!",
|
||||
"disguiseAvoidedDamage" : "{{pokemonNameWithAffix}}'s disguise was busted!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}の {{abilityName}}で\n道具を うばわれない!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}は {{abilityName}}で\n体力を 回復した!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}は {{abilityName}}で\nダメージを 受けない。",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} Eternamaxed\ninto {{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}} reverted\nto its original form!",
|
||||
"formChange": "{{preName}} changed form!",
|
||||
"disguiseChange": "Its disguise served it as a decoy!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,16 +4,16 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage" : "{{pokemonName}}[[는]] {{abilityName}} 때문에\n반동 데미지를 받지 않는다!",
|
||||
"badDreams": "{{pokemonName}}[[는]]\n나이트메어 때문에 시달리고 있다!",
|
||||
"costar": "{{pokemonName}}[[는]] {{allyName}}의\n능력 변화를 복사했다!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}}[[는]] {{abilityName}} 때문에\n데미지를 받지 않는다!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}}[[는]] {{abilityName}} 때문에\n데미지를 받지 않는다!",
|
||||
"perishBody": "{{pokemonName}}의 {{abilityName}} 때문에\n양쪽 포켓몬 모두는 3턴 후에 쓰러져 버린다!",
|
||||
"poisonHeal": "{{pokemonName}}[[는]] {{abilityName}}[[로]]인해\n조금 회복했다.",
|
||||
"trace": "{{pokemonName}}[[는]] 상대 {{targetName}}의 \n{{abilityName}}[[를]] 트레이스했다!",
|
||||
"windPowerCharged": "{{pokemonName}}[[는]]\n{{moveName}}에 맞아 충전되었다!",
|
||||
"quickDraw": "{{pokemonName}}[[는]]\n퀵드로에 의해 행동이 빨라졌다!",
|
||||
"disguiseAvoidedDamage" : "{{pokemonNameWithAffix}}의 정체가 드러났다!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}의 {{abilityName}}에 의해\n도구를 빼앗기지 않는다!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}[[는]]\n{{abilityName}}[[로]] 체력이 회복되었다!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}[[는]] {{abilityName}} 때문에\n데미지를 입지 않는다!",
|
||||
"postDefendDisguise": "{{pokemonNameWithAffix}}의\n정체가 드러났다!",
|
||||
"moveImmunity": "{{pokemonNameWithAffix}}에게는\n효과가 없는 것 같다...",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}}[[는]]\n해감액을 흡수했다!",
|
||||
"postDefendTypeChange": "{{pokemonNameWithAffix}}[[는]] {{abilityName}}[[로]] 인해\n{{typeName}}타입이 됐다!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}}[[는]]\n{{pokemonName}}가 되었다!",
|
||||
"revertChange": "{{pokemonName}}[[는]]\n원래 모습으로 되돌아왔다!",
|
||||
"formChange": "{{preName}}[[는]]\n다른 모습으로 변화했다!",
|
||||
"disguiseChange": "탈이 대타가 되었다!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,16 +4,16 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage": "{{abilityName}} de {{pokemonName}}\nprotegeu-o do dano reverso!",
|
||||
"badDreams": "{{pokemonName}} está tendo pesadelos!",
|
||||
"costar": "{{pokemonName}} copiou as mudanças\nde atributo de {{allyName}}!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}} evitou\ndanos com sua {{abilityName}}!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} evitou\ndanos com sua {{abilityName}}!",
|
||||
"perishBody": "{{abilityName}} de {{pokemonName}}\nirá desmaiar ambos os Pokémon em 3 turnos!",
|
||||
"poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaurou seus PS um pouco!",
|
||||
"trace": "{{pokemonName}} copiou {{abilityName}}\nde {{targetName}}!",
|
||||
"windPowerCharged": "Ser atingido por {{moveName}} carregou {{pokemonName}} com poder!",
|
||||
"quickDraw": "{{pokemonName}} pode agir mais rápido que o normal\ngraças ao seu Quick Draw!",
|
||||
"disguiseAvoidedDamage" : "O disfarce de {{pokemonNameWithAffix}} foi descoberto!",
|
||||
"blockItemTheft": "{{abilityName}} de {{pokemonNameWithAffix}}\nprevine o roubo de itens!",
|
||||
"typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaurou um pouco de PS!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} evitou dano\ncom {{abilityName}}!",
|
||||
"postDefendDisguise": "O disfarce de {{pokemonNameWithAffix}} foi descoberto!",
|
||||
"moveImmunity": "Isso não afeta {{pokemonNameWithAffix}}!",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} absorveu a gosma líquida!",
|
||||
"postDefendTypeChange": "{{abilityName}} de {{pokemonNameWithAffix}}\ntransformou-o no tipo {{typeName}}!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}} Eternamaxou\npara {{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}} voltou\npara sua forma original!",
|
||||
"formChange": "{{preName}} mudou de forma!",
|
||||
"disguiseChange": "O seu disfarce serviu-lhe de isca!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,16 +4,16 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage" : "{{pokemonName}}的{{abilityName}}\n抵消了反作用力!",
|
||||
"badDreams": "{{pokemonName}}被折磨着!",
|
||||
"costar": "{{pokemonName}}复制了{{allyName}}的能力变化!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}}因为{{abilityName}}\n避免了伤害!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}}因为{{abilityName}}\n避免了伤害!",
|
||||
"perishBody": "因为{{pokemonName}}的{{abilityName}}\n双方将在3回合后灭亡!",
|
||||
"poisonHeal": "{{pokemonName}}因{{abilityName}}\n回复了少许HP!",
|
||||
"trace": "{{pokemonName}}复制了{{targetName}}的\n{{abilityName}}!",
|
||||
"windPowerCharged": "受{{moveName}}的影响,{{pokemonName}}提升了能力!",
|
||||
"quickDraw":"因为速击效果发动,\n{{pokemonName}}比平常出招更快了!",
|
||||
"disguiseAvoidedDamage" : "{{pokemonNameWithAffix}}的画皮脱落了!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}的{{abilityName}}\n阻止了对方夺取道具!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}因{{abilityName}}\n回复了少许HP!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}}因{{abilityName}}\n避免了伤害!",
|
||||
"postDefendDisguise": "{{pokemonNameWithAffix}}的\n画皮脱落了",
|
||||
"moveImmunity": "对{{pokemonNameWithAffix}}没有效果!",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}}\n吸到了污泥浆!",
|
||||
"postDefendTypeChange": "{{pokemonNameWithAffix}}因{{abilityName}}\n变成了{{typeName}}属性!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}}无极巨化成了\n{{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}}变回了\n原本的样子!",
|
||||
"formChange": "{{preName}}变成其他样子了。",
|
||||
"disguiseChange": "它的画皮被当作诱饵使用了!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -4,16 +4,16 @@ export const abilityTriggers: SimpleTranslationEntries = {
|
||||
"blockRecoilDamage" : "{{pokemonName}} 的 {{abilityName}}\n抵消了反作用力!",
|
||||
"badDreams": "{{pokemonName}} 被折磨着!",
|
||||
"costar": "{{pokemonName}} 複製了 {{allyName}} 的\n能力變化!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonName}} 因爲 {{abilityName}}\n避免了傷害!",
|
||||
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} 因爲 {{abilityName}}\n避免了傷害!",
|
||||
"perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!",
|
||||
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"trace": "{{pokemonName}} 複製了 {{targetName}} 的\n{{abilityName}}!",
|
||||
"windPowerCharged": "受 {{moveName}} 的影響, {{pokemonName}} 提升了能力!",
|
||||
"quickDraw":"{{pokemonName}} can act faster than normal, thanks to its Quick Draw!",
|
||||
"disguiseAvoidedDamage" : "{{pokemonNameWithAffix}}的畫皮脫落了!",
|
||||
"blockItemTheft": "{{pokemonNameWithAffix}}'s {{abilityName}}\nprevents item theft!",
|
||||
"typeImmunityHeal": "{{pokemonNameWithAffix}}'s {{abilityName}}\nrestored its HP a little!",
|
||||
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} avoided damage\nwith {{abilityName}}!",
|
||||
"postDefendDisguise": "{{pokemonNameWithAffix}}'s disguise was busted!",
|
||||
"moveImmunity": "It doesn't affect {{pokemonNameWithAffix}}!",
|
||||
"reverseDrain": "{{pokemonNameWithAffix}} sucked up the liquid ooze!",
|
||||
"postDefendTypeChange": "{{pokemonNameWithAffix}}'s {{abilityName}}\nmade it the {{typeName}} type!",
|
||||
|
@ -13,6 +13,7 @@ export const battlePokemonForm: SimpleTranslationEntries = {
|
||||
"eternamaxChange": "{{preName}}無極巨化成了\n{{pokemonName}}!",
|
||||
"revertChange": "{{pokemonName}}變回了\n原本的樣子!",
|
||||
"formChange": "{{preName}}變為其他樣子了。",
|
||||
"disguiseChange": "它的畫皮被當作誘餌使用了!",
|
||||
} as const;
|
||||
|
||||
export const pokemonForm: SimpleTranslationEntries = {
|
||||
|
@ -1,18 +1,21 @@
|
||||
import { Status, StatusEffect } from "#app/data/status-effect.js";
|
||||
import { QuietFormChangePhase } from "#app/form-change-phase.js";
|
||||
import { TurnEndPhase } from "#app/phases.js";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Species } from "#enums/species";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import GameManager from "#test/utils/gameManager";
|
||||
import { getMovePosition } from "#test/utils/gameManagerUtils";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { Species } from "#enums/species";
|
||||
import { StatusEffect } from "#app/data/status-effect.js";
|
||||
import { MoveEffectPhase, MoveEndPhase, TurnEndPhase, TurnInitPhase } from "#app/phases.js";
|
||||
import { BattleStat } from "#app/data/battle-stat.js";
|
||||
import { SPLASH_ONLY } from "../utils/testUtils";
|
||||
|
||||
const TIMEOUT = 20 * 1000;
|
||||
|
||||
describe("Abilities - DISGUISE", () => {
|
||||
describe("Abilities - Disguise", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
const bustedForm = 1;
|
||||
const disguisedForm = 0;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
@ -26,72 +29,134 @@ describe("Abilities - DISGUISE", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
const moveToUse = Moves.SPLASH;
|
||||
game.override.battleType("single");
|
||||
game.override.ability(Abilities.DISGUISE);
|
||||
game.override.moveset([moveToUse]);
|
||||
game.override.enemyMoveset([Moves.TACKLE, Moves.TACKLE, Moves.TACKLE, Moves.TACKLE]);
|
||||
});
|
||||
|
||||
test(
|
||||
"check if fainted pokemon switched to base form on arena reset",
|
||||
async () => {
|
||||
const baseForm = 0,
|
||||
bustedForm = 1;
|
||||
game.override.startingWave(4);
|
||||
game.override.starterForms({
|
||||
[Species.MIMIKYU]: bustedForm,
|
||||
});
|
||||
game.override.enemySpecies(Species.MIMIKYU);
|
||||
game.override.enemyMoveset(SPLASH_ONLY);
|
||||
|
||||
await game.startBattle([Species.MAGIKARP, Species.MIMIKYU]);
|
||||
game.override.starterSpecies(Species.REGIELEKI);
|
||||
game.override.moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]);
|
||||
}, TIMEOUT);
|
||||
|
||||
const mimikyu = game.scene.getParty().find((p) => p.species.speciesId === Species.MIMIKYU);
|
||||
expect(mimikyu).not.toBe(undefined);
|
||||
expect(mimikyu!.formIndex).toBe(bustedForm);
|
||||
it("takes no damage from attacking move and transforms to Busted form, taking 1/8 max HP damage from the disguise breaking", async () => {
|
||||
await game.startBattle();
|
||||
|
||||
mimikyu!.hp = 0;
|
||||
mimikyu!.status = new Status(StatusEffect.FAINT);
|
||||
expect(mimikyu!.isFainted()).toBe(true);
|
||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||
const maxHp = mimikyu.getMaxHp();
|
||||
const disguiseDamage = Math.floor(maxHp / 8);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
game.doSelectModifier();
|
||||
await game.phaseInterceptor.to(QuietFormChangePhase);
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
|
||||
expect(mimikyu!.formIndex).toBe(baseForm);
|
||||
},
|
||||
TIMEOUT
|
||||
);
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SHADOW_SNEAK));
|
||||
|
||||
test(
|
||||
"damage taken should be equal to 1/8 of its maximum HP, rounded down",
|
||||
async () => {
|
||||
const baseForm = 0,
|
||||
bustedForm = 1;
|
||||
await game.phaseInterceptor.to(MoveEndPhase);
|
||||
|
||||
game.override.enemyMoveset([Moves.DARK_PULSE, Moves.DARK_PULSE, Moves.DARK_PULSE, Moves.DARK_PULSE]);
|
||||
game.override.startingLevel(20);
|
||||
game.override.enemyLevel(20);
|
||||
game.override.enemySpecies(Species.MAGIKARP);
|
||||
game.override.starterForms({
|
||||
[Species.MIMIKYU]: baseForm,
|
||||
});
|
||||
expect(mimikyu.hp).equals(maxHp - disguiseDamage);
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
await game.startBattle([Species.MIMIKYU]);
|
||||
it("doesn't break disguise when attacked with ineffective move", async () => {
|
||||
await game.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getPlayerPokemon()!;
|
||||
const damage = (Math.floor(mimikyu!.getMaxHp()/8));
|
||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||
|
||||
expect(mimikyu).not.toBe(undefined);
|
||||
expect(mimikyu!.formIndex).toBe(baseForm);
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.VACUUM_WAVE));
|
||||
|
||||
expect(mimikyu!.formIndex).toBe(bustedForm);
|
||||
expect(game.scene.getEnemyPokemon()!.turnData.currDamageDealt).toBe(damage);
|
||||
},
|
||||
TIMEOUT
|
||||
);
|
||||
await game.phaseInterceptor.to(MoveEndPhase);
|
||||
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("takes no damage from the first hit of a multihit move and transforms to Busted form, then takes damage from the second hit", async () => {
|
||||
game.override.moveset([Moves.SURGING_STRIKES]);
|
||||
game.override.enemyLevel(5);
|
||||
await game.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||
const maxHp = mimikyu.getMaxHp();
|
||||
const disguiseDamage = Math.floor(maxHp / 8);
|
||||
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SURGING_STRIKES));
|
||||
|
||||
// First hit
|
||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||
expect(mimikyu.hp).equals(maxHp - disguiseDamage);
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
|
||||
// Second hit
|
||||
await game.phaseInterceptor.to(MoveEffectPhase);
|
||||
expect(mimikyu.hp).lessThan(maxHp - disguiseDamage);
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("takes effects from status moves and damage from status effects", async () => {
|
||||
await game.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getEnemyPokemon()!;
|
||||
expect(mimikyu.hp).toBe(mimikyu.getMaxHp());
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.TOXIC_THREAD));
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
expect(mimikyu.status?.effect).toBe(StatusEffect.POISON);
|
||||
expect(mimikyu.summonData.battleStats[BattleStat.SPD]).toBe(-1);
|
||||
expect(mimikyu.hp).toBeLessThan(mimikyu.getMaxHp());
|
||||
}, TIMEOUT);
|
||||
|
||||
it("persists form change when switched out", async () => {
|
||||
game.override.enemyMoveset(Array(4).fill(Moves.SHADOW_SNEAK));
|
||||
game.override.starterSpecies(0);
|
||||
|
||||
await game.startBattle([Species.MIMIKYU, Species.FURRET]);
|
||||
|
||||
const mimikyu = game.scene.getPlayerPokemon()!;
|
||||
const maxHp = mimikyu.getMaxHp();
|
||||
const disguiseDamage = Math.floor(maxHp / 8);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
expect(mimikyu.hp).equals(maxHp - disguiseDamage);
|
||||
|
||||
await game.toNextTurn();
|
||||
game.doSwitchPokemon(1);
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
}, TIMEOUT);
|
||||
|
||||
it("reverts to Disguised on arena reset", async () => {
|
||||
game.override.startingWave(4);
|
||||
|
||||
game.override.starterSpecies(Species.MIMIKYU);
|
||||
game.override.starterForms({
|
||||
[Species.MIMIKYU]: bustedForm
|
||||
});
|
||||
|
||||
game.override.enemySpecies(Species.MAGIKARP);
|
||||
game.override.enemyAbility(Abilities.BALL_FETCH);
|
||||
|
||||
await game.startBattle();
|
||||
|
||||
const mimikyu = game.scene.getPlayerPokemon()!;
|
||||
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
|
||||
game.doAttack(getMovePosition(game.scene, 0, Moves.SPLASH));
|
||||
await game.doKillOpponents();
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
game.doSelectModifier();
|
||||
await game.phaseInterceptor.to(TurnInitPhase);
|
||||
|
||||
expect(mimikyu.formIndex).toBe(disguisedForm);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user