diff --git a/sh.exe.stackdump b/sh.exe.stackdump new file mode 100644 index 00000000000..267398fdde9 --- /dev/null +++ b/sh.exe.stackdump @@ -0,0 +1,11 @@ +Stack trace: +Frame Function Args +00600000010 001800617BE (0018024BE50, 0018023DFD1, 00600000010, 000FFFFB940) +00600000010 001800490FA (00100002000, 00000000000, 0018031EDB0, 00000000000) +00600000010 00180049132 (00000000000, 0018031F0C0, 00600000010, 000FFFFCDF0) +00600000010 0018005B0CF (615C745C615C445C, 635C6F5C4C5C5C5C, 545C5C5C6C5C615C, 2F5C705C6D5C655C) +000FFFFCCE0 0018005B149 (0060003A75E, 00000000000, 001802F5A0B, 001802F5A0B) +000FFFFCCE0 00180049877 (00000000000, 00000000000, 00000000000, 00000000000) +000FFFFFFF0 001800482C6 (00000000000, 00000000000, 00000000000, 00000000000) +000FFFFFFF0 00180048374 (00000000000, 00000000000, 00000000000, 00000000000) +End of stack trace diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 92df6fc294f..ee67d3ee985 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -1632,10 +1632,15 @@ export class CursedTag extends BattlerTag { } } +export class BurnedUpTag extends BattlerTag { + constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: Moves) { + super(tagType, lapseType, 1, sourceMove); + } +} + /** * Battler tag for effects that ground the source, allowing Ground-type moves to hit them. Encompasses two tag types: * @item `IGNORE_FLYING`: Persistent grounding effects (i.e. from Smack Down and Thousand Waves) - * @item `ROOSTED`: One-turn grounding effects (i.e. from Roost) */ export class GroundedTag extends BattlerTag { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: Moves) { @@ -1643,6 +1648,78 @@ export class GroundedTag extends BattlerTag { } } +/** + * @item `ROOSTED`: Roost removes flying from the friendly pokemon until end of turn. If this is the only thing keeping it ungrounded, it becomes + * grounded until end of turn. + * + * If a pokemon was pure flying, it becomes normal type until end of turn. (even if it was affected by forests curse/trick or treat). + * If a pokemon used burn up (losing its fire type), then uses roost, it becomes TYPELESS (stored as UNKNOWN) until end of turn. + */ + +export class RoostedTag extends BattlerTag { + private isOriginallyOnlyFlying : boolean = false; + private isOriginallyFlying: boolean = false; + + constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, sourceMove: Moves) { + super(tagType, lapseType, 1, sourceMove); + } + + onRemove(pokemon: Pokemon): void { + + let userTypes = pokemon.getTypes(true); + let forestsCurseApplied: boolean = false; + let trickOrTreatApplied: boolean = false; + const isOriginallyGrass = pokemon.getSpeciesForm().type1 === Type.GRASS || pokemon.getSpeciesForm().type2 === Type.GRASS; + const isOriginallyGhost = pokemon.getSpeciesForm().type1 === Type.GHOST || pokemon.getSpeciesForm().type2 === Type.GHOST; + + if (!!userTypes.find(type => type === Type.GHOST) && !isOriginallyGhost) { + trickOrTreatApplied = true; + } + + if (!!userTypes.find(type => type === Type.GRASS) && !isOriginallyGrass) { + forestsCurseApplied = true; + } + + if (this.isOriginallyFlying) { + if (this.isOriginallyOnlyFlying) { + if (forestsCurseApplied || trickOrTreatApplied) { + userTypes = userTypes.filter(type => type !== Type.NORMAL); + userTypes.push(Type.FLYING); + } else { + userTypes = [Type.FLYING]; + } + } else { + userTypes.push(Type.FLYING); + } + pokemon.summonData.types = userTypes; + pokemon.updateInfo(); + } + } + + onAdd(pokemon: Pokemon): void { + const userTypes = pokemon.getTypes(true); + const isOriginallyDualType = !!pokemon.getSpeciesForm().type1 && !!pokemon.getSpeciesForm().type2; + const isCurrentlyDualType = userTypes.length > 1; + this.isOriginallyFlying = pokemon.getSpeciesForm().type1 === Type.FLYING || pokemon.getSpeciesForm().type2 === Type.FLYING; + this.isOriginallyOnlyFlying = pokemon.getSpeciesForm().type1 === Type.FLYING && pokemon.getSpeciesForm().type2 === null; + + if (this.isOriginallyFlying) { + let modifiedTypes: Type[]; + if (this.isOriginallyOnlyFlying && !isCurrentlyDualType) { + modifiedTypes = [Type.NORMAL]; + } else { + if (!!pokemon.getTag(BurnedUpTag) && isOriginallyDualType && !isCurrentlyDualType) { + modifiedTypes = [Type.UNKNOWN]; + } else { + modifiedTypes = userTypes.filter(type => type !== Type.FLYING); + } + } + pokemon.summonData.types = modifiedTypes; + pokemon.updateInfo(); + } + } +} + /** Common attributes of form change abilities that block damage */ export class FormBlockDamageTag extends BattlerTag { constructor(tagType: BattlerTagType) { @@ -1974,7 +2051,9 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source case BattlerTagType.IGNORE_FLYING: return new GroundedTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); case BattlerTagType.ROOSTED: - return new GroundedTag(tagType, BattlerTagLapseType.TURN_END, sourceMove); + return new RoostedTag(tagType, BattlerTagLapseType.TURN_END, sourceMove); + case BattlerTagType.BURNED_UP: + return new BurnedUpTag(tagType, BattlerTagLapseType.CUSTOM, sourceMove); case BattlerTagType.SALT_CURED: return new SaltCuredTag(sourceId); case BattlerTagType.CURSED: diff --git a/src/data/move.ts b/src/data/move.ts index 1dc715f264a..9031be4f3d0 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -8358,6 +8358,7 @@ export function initMoves() { return userTypes.includes(Type.FIRE); }) .attr(HealStatusEffectAttr, true, StatusEffect.FREEZE) + .attr(AddBattlerTagAttr, BattlerTagType.BURNED_UP, true, false) .attr(RemoveTypeAttr, Type.FIRE, (user) => { user.scene.queueMessage(i18next.t("moveTriggers:burnedItselfOut", {pokemonName: getPokemonNameWithAffix(user)})); }), diff --git a/src/enums/battler-tag-type.ts b/src/enums/battler-tag-type.ts index 20ceb1b331f..3c615c125fc 100644 --- a/src/enums/battler-tag-type.ts +++ b/src/enums/battler-tag-type.ts @@ -72,4 +72,5 @@ export enum BattlerTagType { SHELL_TRAP = "SHELL_TRAP", DRAGON_CHEER = "DRAGON_CHEER", NO_RETREAT = "NO_RETREAT", + BURNED_UP = "BURNED_UP", } diff --git a/src/overrides.ts b/src/overrides.ts index 48c118b55bc..d2ef5a29233 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -93,12 +93,12 @@ class DefaultOverrides { * default is 0 to not override * @example SPECIES_OVERRIDE = Species.Bulbasaur; */ - readonly STARTER_SPECIES_OVERRIDE: Species | number = 0; + readonly STARTER_SPECIES_OVERRIDE: Species | number = Species.TORNADUS; readonly ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; readonly GENDER_OVERRIDE: Gender | null = null; - readonly MOVESET_OVERRIDE: Array = []; + readonly MOVESET_OVERRIDE: Array = [Moves.ROOST, Moves.SPLASH]; readonly SHINY_OVERRIDE: boolean = false; readonly VARIANT_OVERRIDE: Variant = 0; @@ -111,7 +111,7 @@ class DefaultOverrides { readonly OPP_PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE; readonly OPP_STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE; readonly OPP_GENDER_OVERRIDE: Gender | null = null; - readonly OPP_MOVESET_OVERRIDE: Array = []; + readonly OPP_MOVESET_OVERRIDE: Array = [Moves.FORESTS_CURSE, Moves.FORESTS_CURSE, Moves.FORESTS_CURSE, Moves.FORESTS_CURSE]; readonly OPP_SHINY_OVERRIDE: boolean = false; readonly OPP_VARIANT_OVERRIDE: Variant = 0; readonly OPP_IVS_OVERRIDE: number | number[] = [];