diff --git a/src/data/ability.ts b/src/data/ability.ts index c9b8d4bf3..e971d462b 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -860,6 +860,36 @@ export class PostDefendAbilityGiveAbAttr extends PostDefendAbAttr { } } +export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr { + private chance: integer; + private attacker: Pokemon; + private move: PokemonMove; + + constructor(chance: integer) { + super(); + + this.chance = chance; + } + + applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { + if (!attacker.summonData.disabledMove) { + if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) { + this.attacker = attacker; + this.move = move; + + attacker.summonData.disabledMove = move.moveId; + attacker.summonData.disabledTurns = 4; + return true; + } + } + return false; + } + + getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { + return getPokemonMessage(this.attacker, `'s ${this.move.getName()}\nwas disabled!`); + } +} + export class PostStatChangeStatChangeAbAttr extends PostStatChangeAbAttr { private condition: PokemonStatChangeCondition; private statsToChange: BattleStat[]; @@ -2044,13 +2074,30 @@ export class PostTurnAbAttr extends AbAttr { } } +/** + * After the turn ends, resets the status of either the ability holder or their ally + * @param {boolean} allyTarget Whether to target ally, defaults to false (self-target) + */ export class PostTurnResetStatusAbAttr extends PostTurnAbAttr { + private allyTarget: boolean; + private target: Pokemon; + + constructor(allyTarget: boolean = false) { + super(true); + this.allyTarget = allyTarget; + } + applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { - if (pokemon.status) { + if (this.allyTarget) { + this.target = pokemon.getAlly(); + } else { + this.target = pokemon; + } + if (this.target?.status) { - pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status?.effect))); - pokemon.resetStatus(); - pokemon.updateInfo(); + this.target.scene.queueMessage(getPokemonMessage(this.target, getStatusEffectHealText(this.target.status?.effect))); + this.target.resetStatus(false); + this.target.updateInfo(); return true; } @@ -3095,9 +3142,10 @@ export function initAbilities() { .attr(BattleStatMultiplierAbAttr, BattleStat.SPATK, 0.5) .condition((pokemon) => pokemon.getHpRatio() <= 0.5), new Ability(Abilities.CURSED_BODY, 5) - .unimplemented(), + .attr(PostDefendMoveDisableAbAttr, 30) + .bypassFaint(), new Ability(Abilities.HEALER, 5) - .unimplemented(), + .conditionalAttr(pokemon => pokemon.getAlly() && Utils.randSeedInt(10) < 3, PostTurnResetStatusAbAttr, true), new Ability(Abilities.FRIEND_GUARD, 5) .ignorable() .unimplemented(), diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 3b177ac93..37dd1e622 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -1959,8 +1959,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { return true; } - resetStatus(): void { + /** + * Resets the status of a pokemon + * @param revive whether revive should be cured, defaults to true + */ + resetStatus(revive: boolean = true): void { const lastStatus = this.status?.effect; + if (!revive && lastStatus === StatusEffect.FAINT) { + return; + } this.status = undefined; if (lastStatus === StatusEffect.SLEEP) { this.setFrameRate(12); diff --git a/src/locales/de/battle.ts b/src/locales/de/battle.ts index b48aa1129..656ebb851 100644 --- a/src/locales/de/battle.ts +++ b/src/locales/de/battle.ts @@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = { "runAwayCannotEscape": 'You can\'t escape!', "escapeVerbSwitch": "auswechseln", "escapeVerbFlee": "flucht", - "notDisabled": "{{moveName}} ist\nnicht mehr deaktiviert!", + "notDisabled": "{{pokemonName}}'s {{moveName}} ist\nnicht mehr deaktiviert!", "skipItemQuestion": "Are you sure you want to skip taking an item?", "eggHatching": "Oh?", "ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?" diff --git a/src/locales/en/battle.ts b/src/locales/en/battle.ts index d3990bddd..81d2d1639 100644 --- a/src/locales/en/battle.ts +++ b/src/locales/en/battle.ts @@ -47,7 +47,7 @@ export const battle: SimpleTranslationEntries = { "runAwayCannotEscape": 'You can\'t escape!', "escapeVerbSwitch": "switching", "escapeVerbFlee": "fleeing", - "notDisabled": "{{moveName}} is disabled\nno more!", + "notDisabled": "{{pokemonName}}'s {{moveName}} is disabled\nno more!", "skipItemQuestion": "Are you sure you want to skip taking an item?", "eggHatching": "Oh?", "ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?" diff --git a/src/locales/es/battle.ts b/src/locales/es/battle.ts index f4bf22bb9..6fdcf4fbc 100644 --- a/src/locales/es/battle.ts +++ b/src/locales/es/battle.ts @@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = { "runAwayCannotEscape": "¡No has podido escapar!", "escapeVerbSwitch": "cambiar", "escapeVerbFlee": "huir", - "notDisabled": "¡El movimiento {{moveName}}\nya no está anulado!", + "notDisabled": "¡El movimiento {{moveName}} de {{pokemonName}}\nya no está anulado!", "skipItemQuestion": "¿Estás seguro de que no quieres coger un objeto?", "eggHatching": "¿Y esto?", "ivScannerUseQuestion": "¿Quieres usar el Escáner de IVs en {{pokemonName}}?" diff --git a/src/locales/fr/battle.ts b/src/locales/fr/battle.ts index 56ab69215..e34902b8c 100644 --- a/src/locales/fr/battle.ts +++ b/src/locales/fr/battle.ts @@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = { "runAwayCannotEscape": "Fuite impossible !", "escapeVerbSwitch": "le changement", "escapeVerbFlee": "la fuite", - "notDisabled": "{{moveName}} n’est plus sous entrave !", + "notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} n’est plus sous entrave !", "skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre d’objet ?", "eggHatching": "Oh ?", "ivScannerUseQuestion": "Utiliser le Scanner d’IV sur {{pokemonName}} ?" diff --git a/src/locales/it/battle.ts b/src/locales/it/battle.ts index 247e6e38e..a3cffaa60 100644 --- a/src/locales/it/battle.ts +++ b/src/locales/it/battle.ts @@ -46,7 +46,7 @@ export const battle: SimpleTranslationEntries = { "runAwayCannotEscape": 'Non puoi fuggire!', "escapeVerbSwitch": "cambiando", "escapeVerbFlee": "fuggendo", - "notDisabled": "{{moveName}} non è più\ndisabilitata!", + "notDisabled": "{{pokemonName}}'s {{moveName}} non è più\ndisabilitata!", "skipItemQuestion": "Sei sicuro di non voler prendere nessun oggetto?", "eggHatching": "Oh?", "ivScannerUseQuestion": "Vuoi usare lo scanner di IV su {{pokemonName}}?" diff --git a/src/phases.ts b/src/phases.ts index f5d229002..49c5875d5 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -23,7 +23,7 @@ import { FusePokemonModifierType, ModifierPoolType, ModifierType, ModifierTypeFu import SoundFade from "phaser3-rex-plugins/plugins/soundfade"; import { BattlerTagLapseType, EncoreTag, HideSpriteTag as HiddenTag, ProtectedTag, TrappedTag } from "./data/battler-tags"; import { BattlerTagType } from "./data/enums/battler-tag-type"; -import { getPokemonMessage } from "./messages"; +import { getPokemonMessage, getPokemonPrefix } from "./messages"; import { Starter } from "./ui/starter-select-ui-handler"; import { Gender } from "./data/gender"; import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, getWeatherDamageMessage, getWeatherLapseMessage } from "./data/weather"; @@ -2056,7 +2056,7 @@ export class TurnEndPhase extends FieldPhase { pokemon.lapseTags(BattlerTagLapseType.TURN_END); if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) { - this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { moveName: allMoves[pokemon.summonData.disabledMove].name }))); + this.scene.pushPhase(new MessagePhase(this.scene, i18next.t('battle:notDisabled', { pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, moveName: allMoves[pokemon.summonData.disabledMove].name }))); pokemon.summonData.disabledMove = Moves.NONE; } diff --git a/src/utils.ts b/src/utils.ts index ef277630d..191b8f55b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -220,7 +220,7 @@ export function executeIf(condition: boolean, promiseFunc: () => Promise): } export const sessionIdKey = 'pokerogue_sessionId'; -export const isLocal = window.location.hostname === 'localhost'; +export const isLocal = window.location.hostname === 'localhost' || window.location.hostname === ''; export const serverUrl = isLocal ? 'http://localhost:8001' : ''; export const apiUrl = isLocal ? serverUrl : 'https://api.pokerogue.net'; export const fallbackApiUrl = isLocal ? serverUrl : 'api';