mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-04 07:22:19 +02:00
Merge branch 'main' into quick-feet-implementation
This commit is contained in:
commit
e5c0458ec9
@ -8,6 +8,7 @@ import { Weather, WeatherType } from "./weather";
|
||||
import { BattlerTag } from "./battler-tags";
|
||||
import { BattlerTagType } from "./enums/battler-tag-type";
|
||||
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
|
||||
import { Gender } from "./gender";
|
||||
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, allMoves } from "./move";
|
||||
import { ArenaTagType } from "./enums/arena-tag-type";
|
||||
import { Stat } from "./pokemon-stat";
|
||||
@ -657,6 +658,30 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
|
||||
}
|
||||
}
|
||||
|
||||
export class MoveTypeChangeAttr extends PreAttackAbAttr {
|
||||
private newType: Type;
|
||||
private powerMultiplier: number;
|
||||
private condition: PokemonAttackCondition;
|
||||
|
||||
constructor(newType: Type, powerMultiplier: number, condition: PokemonAttackCondition){
|
||||
super(true);
|
||||
this.newType = newType;
|
||||
this.powerMultiplier = powerMultiplier;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean {
|
||||
if (this.condition(pokemon, defender, move.getMove())) {
|
||||
const type = (args[0] as Utils.IntegerHolder);
|
||||
type.value = this.newType;
|
||||
(args[1] as Utils.NumberHolder).value *= this.powerMultiplier;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
|
||||
private condition: PokemonAttackCondition;
|
||||
private powerMultiplier: number;
|
||||
@ -788,19 +813,21 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class PostAttackContactApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
||||
export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
||||
private contactRequired: boolean;
|
||||
private chance: integer;
|
||||
private effects: StatusEffect[];
|
||||
|
||||
constructor(chance: integer, ...effects: StatusEffect[]) {
|
||||
constructor(contactRequired: boolean, chance: integer, ...effects: StatusEffect[]) {
|
||||
super();
|
||||
|
||||
this.contactRequired = contactRequired;
|
||||
this.chance = chance;
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
|
||||
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) {
|
||||
if (pokemon != attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) {
|
||||
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
|
||||
return attacker.trySetStatus(effect, true);
|
||||
}
|
||||
@ -809,6 +836,12 @@ export class PostAttackContactApplyStatusEffectAbAttr extends PostAttackAbAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class PostAttackContactApplyStatusEffectAbAttr extends PostAttackApplyStatusEffectAbAttr {
|
||||
constructor(chance: integer, ...effects: StatusEffect[]) {
|
||||
super(true, chance, ...effects);
|
||||
}
|
||||
}
|
||||
|
||||
export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
|
||||
private condition: PokemonDefendCondition;
|
||||
|
||||
@ -1111,6 +1144,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
|
||||
|
||||
pokemon.summonData.speciesForm = target.getSpeciesForm();
|
||||
pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
|
||||
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));
|
||||
@ -2271,7 +2305,9 @@ export function initAbilities() {
|
||||
new Ability(Abilities.MOTOR_DRIVE, "Motor Drive", "Boosts its Speed stat if hit by an Electric-type move instead of taking damage.", 4)
|
||||
.attr(TypeImmunityStatChangeAbAttr, Type.ELECTRIC, BattleStat.SPD, 1)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.RIVALRY, "Rivalry (N)", "Becomes competitive and deals more damage to Pokémon of the same gender, but deals less to Pokémon of the opposite gender.", 4),
|
||||
new Ability(Abilities.RIVALRY, "Rivalry", "Becomes competitive and deals more damage to Pokémon of the same gender, but deals less to Pokémon of the opposite gender.", 4)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => user.gender !== Gender.GENDERLESS && target.gender !== Gender.GENDERLESS && user.gender === target.gender, 1.25)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => user.gender !== Gender.GENDERLESS && target.gender !== Gender.GENDERLESS && user.gender !== target.gender, 0.75),
|
||||
new Ability(Abilities.STEADFAST, "Steadfast", "The Pokémon's determination boosts the Speed stat each time the Pokémon flinches.", 4)
|
||||
.attr(FlinchStatChangeAbAttr, BattleStat.SPD, 1),
|
||||
new Ability(Abilities.SNOW_CLOAK, "Snow Cloak", "Boosts evasiveness in a hailstorm.", 4)
|
||||
@ -2313,9 +2349,10 @@ export function initAbilities() {
|
||||
.attr(BattleStatMultiplierAbAttr, BattleStat.SPATK, 1.5)
|
||||
.condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)),
|
||||
new Ability(Abilities.QUICK_FEET, "Quick Feet", "Boosts the Speed stat if the Pokémon has a status condition. Ignores Speed loss from paralysis.", 4)
|
||||
.conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5)
|
||||
.attr(IgnoreParalysisSpeedLossAbAttr),
|
||||
new Ability(Abilities.NORMALIZE, "Normalize (N)", "All the Pokémon's moves become Normal type. The power of those moves is boosted a little.", 4),
|
||||
.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),
|
||||
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),
|
||||
@ -2561,7 +2598,8 @@ export function initAbilities() {
|
||||
.condition(getWeatherCondition(WeatherType.HAIL)),
|
||||
new Ability(Abilities.LONG_REACH, "Long Reach", "The Pokémon uses its moves without making contact with the target.", 7)
|
||||
.attr(IgnoreContactAbAttr),
|
||||
new Ability(Abilities.LIQUID_VOICE, "Liquid Voice (N)", "All sound-based moves become Water-type moves.", 7),
|
||||
new Ability(Abilities.LIQUID_VOICE, "Liquid Voice", "All sound-based moves become Water-type moves.", 7)
|
||||
.attr(MoveTypeChangeAttr, Type.WATER, 1, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED)),
|
||||
new Ability(Abilities.TRIAGE, "Triage", "Gives priority to a healing move.", 7)
|
||||
.attr(IncrementMovePriorityAbAttr, (pokemon, move) => move.hasFlag(MoveFlags.TRIAGE_MOVE), 3),
|
||||
new Ability(Abilities.GALVANIZE, "Galvanize", "Normal-type moves become Electric-type moves. The power of those moves is boosted a little.", 7)
|
||||
@ -2811,7 +2849,8 @@ export function initAbilities() {
|
||||
.ignorable(),
|
||||
new Ability(Abilities.SUPERSWEET_SYRUP, "Supersweet Syrup (N)", "A sickly sweet scent spreads across the field the first time the Pokémon enters a battle, lowering the evasiveness of opposing Pokémon.", 9),
|
||||
new Ability(Abilities.HOSPITALITY, "Hospitality (N)", "When the Pokémon enters a battle, it showers its ally with hospitality, restoring a small amount of the ally's HP.", 9),
|
||||
new Ability(Abilities.TOXIC_CHAIN, "Toxic Chain (N)", "The power of the Pokémon's toxic chain may badly poison any target the Pokémon hits with a move.", 9),
|
||||
new Ability(Abilities.TOXIC_CHAIN, "Toxic Chain", "The power of the Pokémon's toxic chain may badly poison any target the Pokémon hits with a move.", 9)
|
||||
.attr(PostAttackApplyStatusEffectAbAttr, false, 30, StatusEffect.TOXIC),
|
||||
new Ability(Abilities.EMBODY_ASPECT_TEAL, "Embody Aspect", "The Pokémon's heart fills with memories, causing the Teal Mask to shine and the Pokémon's Speed stat to be boosted.", 9)
|
||||
.attr(PostBattleInitStatChangeAbAttr, BattleStat.SPD, 1, true)
|
||||
.attr(UncopiableAbilityAbAttr)
|
||||
|
@ -22,6 +22,7 @@ import { TerrainType } from "./terrain";
|
||||
import { SpeciesFormChangeActiveTrigger } from "./pokemon-forms";
|
||||
import { Species } from "./enums/species";
|
||||
import { ModifierPoolType } from "#app/modifier/modifier-type";
|
||||
import { Command } from "../ui/command-ui-handler";
|
||||
|
||||
export enum MoveCategory {
|
||||
PHYSICAL,
|
||||
@ -3027,6 +3028,7 @@ export class TransformAttr extends MoveEffectAttr {
|
||||
|
||||
user.summonData.speciesForm = target.getSpeciesForm();
|
||||
user.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
|
||||
user.summonData.ability = target.getAbility().id;
|
||||
user.summonData.gender = target.getGender();
|
||||
user.summonData.fusionGender = target.getFusionGender();
|
||||
user.summonData.stats = [ user.stats[Stat.HP] ].concat(target.stats.slice(1));
|
||||
@ -3865,9 +3867,10 @@ export function initMoves() {
|
||||
new AttackMove(Moves.FACADE, "Facade", Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, "This attack move doubles its power if the user is poisoned, burned, or paralyzed.", -1, 0, 3)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.status
|
||||
&& (user.status.effect === StatusEffect.BURN || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.PARALYSIS) ? 2 : 1),
|
||||
new AttackMove(Moves.FOCUS_PUNCH, "Focus Punch (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 20, "The user focuses its mind before launching a punch. This move fails if the user is hit before it is used.", -1, -3, 3)
|
||||
new AttackMove(Moves.FOCUS_PUNCH, "Focus Punch", Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 20, "The user focuses its mind before launching a punch. This move fails if the user is hit before it is used.", -1, -3, 3)
|
||||
.punchingMove()
|
||||
.ignoresVirtual(),
|
||||
.ignoresVirtual()
|
||||
.condition((user, target, move) => !user.turnData.attacksReceived.find(r => r.damage)),
|
||||
new AttackMove(Moves.SMELLING_SALTS, "Smelling Salts", Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 10, "This attack's power is doubled when used on a target with paralysis. This also cures the target's paralysis, however.", -1, 0, 3)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.status?.effect === StatusEffect.PARALYSIS ? 2 : 1)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS),
|
||||
@ -3893,7 +3896,8 @@ export function initMoves() {
|
||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF ], -1, true),
|
||||
new SelfStatusMove(Moves.MAGIC_COAT, "Magic Coat (N)", Type.PSYCHIC, -1, 15, "Moves like Leech Seed and moves that inflict status conditions are blocked by a barrier and reflected back to the user of those moves.", -1, 4, 3),
|
||||
new SelfStatusMove(Moves.RECYCLE, "Recycle (N)", Type.NORMAL, -1, 10, "The user recycles a held item that has been used in battle so it can be used again.", -1, 0, 3),
|
||||
new AttackMove(Moves.REVENGE, "Revenge (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, "This attack move's power is doubled if the user has been hurt by the opponent in the same turn.", -1, -4, 3),
|
||||
new AttackMove(Moves.REVENGE, "Revenge", Type.FIGHTING, MoveCategory.PHYSICAL, 60, 100, 10, "This attack move's power is doubled if the user has been hurt by the opponent in the same turn.", -1, -4, 3)
|
||||
.attr(TurnDamagedDoublePowerAttr),
|
||||
new AttackMove(Moves.BRICK_BREAK, "Brick Break (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 75, 100, 15, "The user attacks with a swift chop. It can also break barriers, such as Light Screen and Reflect.", -1, 0, 3),
|
||||
new StatusMove(Moves.YAWN, "Yawn", Type.NORMAL, -1, 10, "The user lets loose a huge yawn that lulls the target into falling asleep on the next turn.", -1, 0, 3)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.DROWSY, false, true)
|
||||
@ -4165,7 +4169,8 @@ export function initMoves() {
|
||||
}),
|
||||
new StatusMove(Moves.WORRY_SEED, "Worry Seed", Type.GRASS, 100, 10, "A seed that causes worry is planted on the target. It prevents sleep by making the target's Ability Insomnia.", -1, 0, 4)
|
||||
.attr(AbilityChangeAttr, Abilities.INSOMNIA),
|
||||
new AttackMove(Moves.SUCKER_PUNCH, "Sucker Punch (P)", Type.DARK, MoveCategory.PHYSICAL, 70, 100, 5, "This move enables the user to attack first. This move fails if the target is not readying an attack.", -1, 1, 4),
|
||||
new AttackMove(Moves.SUCKER_PUNCH, "Sucker Punch", Type.DARK, MoveCategory.PHYSICAL, 70, 100, 5, "This move enables the user to attack first. This move fails if the target is not readying an attack.", -1, 1, 4)
|
||||
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()].move.move].category !== MoveCategory.STATUS),
|
||||
new StatusMove(Moves.TOXIC_SPIKES, "Toxic Spikes", Type.POISON, -1, 20, "The user lays a trap of poison spikes at the feet of the opposing team. The spikes will poison opposing Pokémon that switch into battle.", -1, 0, 4)
|
||||
.attr(AddArenaTrapTagAttr, ArenaTagType.TOXIC_SPIKES)
|
||||
.target(MoveTarget.ENEMY_SIDE),
|
||||
@ -4860,7 +4865,8 @@ export function initMoves() {
|
||||
new AttackMove(Moves.PULVERIZING_PANCAKE, "Pulverizing Pancake (P)", Type.NORMAL, MoveCategory.PHYSICAL, 210, -1, 1, "Z-Power brings out the true capabilities of the user, Snorlax. The Pokémon moves its enormous body energetically and attacks the target with full force.", -1, 0, 7),
|
||||
new SelfStatusMove(Moves.EXTREME_EVOBOOST, "Extreme Evoboost", Type.NORMAL, -1, 1, "After obtaining Z-Power, the user, Eevee, gets energy from its evolved friends and boosts its stats sharply.", 100, 0, 7)
|
||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 2, true),
|
||||
new AttackMove(Moves.GENESIS_SUPERNOVA, "Genesis Supernova (P)", Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, "After obtaining Z-Power, the user, Mew, attacks the target with full force. The terrain will be charged with psychic energy.", -1, 0, 7),
|
||||
new AttackMove(Moves.GENESIS_SUPERNOVA, "Genesis Supernova", Type.PSYCHIC, MoveCategory.SPECIAL, 185, -1, 1, "After obtaining Z-Power, the user, Mew, attacks the target with full force. The terrain will be charged with psychic energy.", -1, 0, 7)
|
||||
.attr(TerrainChangeAttr, TerrainType.PSYCHIC),
|
||||
/* End Unused */
|
||||
new AttackMove(Moves.SHELL_TRAP, "Shell Trap (P)", Type.FIRE, MoveCategory.SPECIAL, 150, 100, 5, "The user sets a shell trap. If the user is hit by a physical move, the trap will explode and inflict damage on opposing Pokémon.", -1, -3, 7)
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
@ -4908,6 +4914,7 @@ export function initMoves() {
|
||||
.attr(ClearTerrainAttr)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.CLANGOROUS_SOULBLAZE, "Clangorous Soulblaze (P)", Type.DRAGON, MoveCategory.SPECIAL, 185, -1, 1, "After obtaining Z-Power, the user, Kommo-o, attacks the opposing Pokémon with full force. This move boosts the user's stats.", 100, 0, 7)
|
||||
.attr(StatChangeAttr, [ BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD ], 1, true)
|
||||
.soundBased()
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
/* End Unused */
|
||||
@ -5048,8 +5055,9 @@ export function initMoves() {
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
new AttackMove(Moves.APPLE_ACID, "Apple Acid", Type.GRASS, MoveCategory.SPECIAL, 80, 100, 10, "The user attacks the target with an acidic liquid created from tart apples. This also lowers the target's Sp. Def stat.", 100, 0, 8)
|
||||
.attr(StatChangeAttr, BattleStat.SPDEF, -1),
|
||||
new AttackMove(Moves.GRAV_APPLE, "Grav Apple (P)", Type.GRASS, MoveCategory.PHYSICAL, 80, 100, 10, "The user inflicts damage by dropping an apple from high above. This also lowers the target's Defense stat.", 100, 0, 8)
|
||||
new AttackMove(Moves.GRAV_APPLE, "Grav Apple", Type.GRASS, MoveCategory.PHYSICAL, 80, 100, 10, "The user inflicts damage by dropping an apple from high above. This also lowers the target's Defense stat.", 100, 0, 8)
|
||||
.attr(StatChangeAttr, BattleStat.DEF, -1)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTag(ArenaTagType.GRAVITY) ? 1.5 : 1)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.SPIRIT_BREAK, "Spirit Break", Type.FAIRY, MoveCategory.PHYSICAL, 75, 100, 15, "The user attacks the target with so much force that it could break the target's spirit. This also lowers the target's Sp. Atk stat.", 100, 0, 8)
|
||||
.attr(StatChangeAttr, BattleStat.SPATK, -1),
|
||||
@ -5354,8 +5362,10 @@ export function initMoves() {
|
||||
new AttackMove(Moves.HYDRO_STEAM, "Hydro Steam (P)", Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, "The user blasts the target with boiling-hot water. This move's power is not lowered in harsh sunlight but rather boosted by 50 percent.", -1, 0, 9),
|
||||
new AttackMove(Moves.RUINATION, "Ruination", Type.DARK, MoveCategory.SPECIAL, 1, 90, 10, "The user summons a ruinous disaster. This cuts the target's HP in half.", -1, 0, 9)
|
||||
.attr(TargetHalfHpDamageAttr),
|
||||
new AttackMove(Moves.COLLISION_COURSE, "Collision Course (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 100, 100, 5, "The user transforms and crashes to the ground, causing a massive prehistoric explosion. This move's power is boosted more than usual if it's a supereffective hit.", -1, 0, 9),
|
||||
new AttackMove(Moves.ELECTRO_DRIFT, "Electro Drift (P)", Type.ELECTRIC, MoveCategory.SPECIAL, 100, 100, 5, "The user races forward at ultrafast speeds, piercing its target with futuristic electricity. This move's power is boosted more than usual if it's a supereffective hit.", -1, 0, 9)
|
||||
new AttackMove(Moves.COLLISION_COURSE, "Collision Course", Type.FIGHTING, MoveCategory.PHYSICAL, 100, 100, 5, "The user transforms and crashes to the ground, causing a massive prehistoric explosion. This move's power is boosted more than usual if it's a supereffective hit.", -1, 0, 9)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type) >= 2 ? 5461/4096 : 1),
|
||||
new AttackMove(Moves.ELECTRO_DRIFT, "Electro Drift", Type.ELECTRIC, MoveCategory.SPECIAL, 100, 100, 5, "The user races forward at ultrafast speeds, piercing its target with futuristic electricity. This move's power is boosted more than usual if it's a supereffective hit.", -1, 0, 9)
|
||||
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type) >= 2 ? 5461/4096 : 1)
|
||||
.makesContact(),
|
||||
new SelfStatusMove(Moves.SHED_TAIL, "Shed Tail (N)", Type.NORMAL, -1, 10, "The user creates a substitute for itself using its own HP before switching places with a party Pokémon in waiting.", -1, 0, 9),
|
||||
new StatusMove(Moves.CHILLY_RECEPTION, "Chilly Reception", Type.ICE, -1, 10, "The user tells a chillingly bad joke before switching places with a party Pokémon in waiting. This summons a snowstorm lasting five turns.", -1, 0, 9)
|
||||
@ -5388,7 +5398,11 @@ export function initMoves() {
|
||||
.triageMove(),
|
||||
new AttackMove(Moves.DOUBLE_SHOCK, "Double Shock (P)", Type.ELECTRIC, MoveCategory.PHYSICAL, 120, 100, 5, "The user discharges all the electricity from its body to perform a high-damage attack. After using this move, the user will no longer be Electric type.", -1, 0, 9),
|
||||
new AttackMove(Moves.GIGATON_HAMMER, "Gigaton Hammer (P)", Type.STEEL, MoveCategory.PHYSICAL, 160, 100, 5, "The user swings its whole body around to attack with its huge hammer. This move can't be used twice in a row.", -1, 0, 9)
|
||||
.makesContact(false),
|
||||
.makesContact(false)
|
||||
.condition((user, target, move) => {
|
||||
const turnMove = user.getLastXMoves(1);
|
||||
return !turnMove.length || turnMove[0].move !== move.id || turnMove[0].result !== MoveResult.SUCCESS;
|
||||
}), // TODO Add Instruct/Encore interaction
|
||||
new AttackMove(Moves.COMEUPPANCE, "Comeuppance", Type.DARK, MoveCategory.PHYSICAL, 1, 100, 10, "The user retaliates with much greater force against the opponent that last inflicted damage on it.", -1, 0, 9)
|
||||
.attr(CounterDamageAttr, (move: Move) => (move.category === MoveCategory.PHYSICAL || move.category === MoveCategory.SPECIAL), 1.5)
|
||||
.target(MoveTarget.ATTACKER),
|
||||
@ -5411,7 +5425,11 @@ export function initMoves() {
|
||||
new AttackMove(Moves.MAGICAL_TORQUE, "Magical Torque", Type.FAIRY, MoveCategory.PHYSICAL, 100, 100, 10, "The user revs their fae-like engine into the target. This may also confuse the target.", 30, 0, 9)
|
||||
.attr(ConfuseAttr)
|
||||
.makesContact(false),
|
||||
new AttackMove(Moves.BLOOD_MOON, "Blood Moon (P)", Type.NORMAL, MoveCategory.SPECIAL, 140, 100, 5, "The user unleashes the full brunt of its spirit from a full moon that shines as red as blood. This move can't be used twice in a row.", -1, 0, 9),
|
||||
new AttackMove(Moves.BLOOD_MOON, "Blood Moon (P)", Type.NORMAL, MoveCategory.SPECIAL, 140, 100, 5, "The user unleashes the full brunt of its spirit from a full moon that shines as red as blood. This move can't be used twice in a row.", -1, 0, 9)
|
||||
.condition((user, target, move) => {
|
||||
const turnMove = user.getLastXMoves(1);
|
||||
return !turnMove.length || turnMove[0].move !== move.id || turnMove[0].result !== MoveResult.SUCCESS;
|
||||
}), // TODO Add Instruct/Encore interaction
|
||||
new AttackMove(Moves.MATCHA_GOTCHA, "Matcha Gotcha", Type.GRASS, MoveCategory.SPECIAL, 80, 90, 15, "The user fires a blast of tea that it mixed. The user's HP is restored by up to half the damage taken by the target. This may also leave the target with a burn.", 20, 0, 9)
|
||||
.attr(HitHealAttr)
|
||||
.attr(HealStatusEffectAttr, true, StatusEffect.FREEZE)
|
||||
@ -5435,11 +5453,13 @@ export function initMoves() {
|
||||
.attr(DoublePowerChanceAttr),
|
||||
new StatusMove(Moves.BURNING_BULWARK, "Burning Bulwark", Type.FIRE, -1, 10, "The user's intensely hot fur protects it from attacks and also burns any attacker that makes direct contact with it.", 100, 4, 9)
|
||||
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK),
|
||||
new AttackMove(Moves.THUNDERCLAP, "Thunderclap (P)", Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, "This move enables the user to attack first with a jolt of electricity. This move fails if the target is not readying an attack.", -1, 1, 9),
|
||||
new AttackMove(Moves.THUNDERCLAP, "Thunderclap", Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, "This move enables the user to attack first with a jolt of electricity. This move fails if the target is not readying an attack.", -1, 1, 9)
|
||||
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()].command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()].move.move].category !== MoveCategory.STATUS),
|
||||
new AttackMove(Moves.MIGHTY_CLEAVE, "Mighty Cleave", Type.ROCK, MoveCategory.PHYSICAL, 95, 100, 5, "The user wields the light that has accumulated atop its head to cleave the target. This move hits even if the target protects itself.", -1, 0, 9)
|
||||
.ignoresProtect(),
|
||||
new AttackMove(Moves.TACHYON_CUTTER, "Tachyon Cutter", Type.STEEL, MoveCategory.SPECIAL, 50, -1, 10, "The user attacks by launching particle blades at the target twice in a row. This attack never misses.", -1, 0, 9)
|
||||
.attr(MultiHitAttr, MultiHitType._2),
|
||||
.attr(MultiHitAttr, MultiHitType._2)
|
||||
.slicingMove(),
|
||||
new AttackMove(Moves.HARD_PRESS, "Hard Press", Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, "The target is crushed with an arm, a claw, or the like to inflict damage. The more HP the target has left, the greater the move's power.", -1, 0, 9)
|
||||
.attr(OpponentHighHpPowerAttr),
|
||||
new StatusMove(Moves.DRAGON_CHEER, "Dragon Cheer (P)", Type.DRAGON, -1, 15, "The user raises its allies' morale with a draconic cry so that their future attacks have a heightened chance of landing critical hits. This rouses Dragon types more.", 100, 0, 9)
|
||||
|
@ -25,7 +25,7 @@ import { TempBattleStat } from '../data/temp-battle-stat';
|
||||
import { ArenaTagSide, WeakenMoveScreenTag, WeakenMoveTypeTag } from '../data/arena-tag';
|
||||
import { ArenaTagType } from "../data/enums/arena-tag-type";
|
||||
import { Biome } from "../data/enums/biome";
|
||||
import { Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreParalysisSpeedLossAbAttr, MoveImmunityAbAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from '../data/ability';
|
||||
import { Ability, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldVariableMovePowerAbAttr, IgnoreOpponentStatChangesAbAttr, IgnoreParalysisSpeedLossAbAttr, MoveImmunityAbAttr, MoveTypeChangeAttr, NonSuperEffectiveImmunityAbAttr, PreApplyBattlerTagAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, VariableMovePowerAbAttr, VariableMoveTypeAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPostDefendAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs } from '../data/ability';
|
||||
import { Abilities } from "#app/data/enums/abilities";
|
||||
import PokemonData from '../system/pokemon-data';
|
||||
import { BattlerIndex } from '../battle';
|
||||
@ -716,8 +716,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (OPP_ABILITY_OVERRIDE && !this.isPlayer())
|
||||
return allAbilities[OPP_ABILITY_OVERRIDE];
|
||||
if (this.isFusion())
|
||||
return allAbilities[this.getFusionSpeciesForm().getAbility(this.fusionAbilityIndex)];
|
||||
let abilityId = this.getSpeciesForm().getAbility(this.abilityIndex);
|
||||
return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)];
|
||||
let abilityId = this.getSpeciesForm(ignoreOverride).getAbility(this.abilityIndex);
|
||||
if (abilityId === Abilities.NONE)
|
||||
abilityId = this.species.ability1;
|
||||
return allAbilities[abilityId];
|
||||
@ -1124,6 +1124,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
applyMoveAttrs(VariableMoveTypeAttr, source, this, move, variableType);
|
||||
// 2nd argument is for MoveTypeChangePowerMultiplierAbAttr
|
||||
applyAbAttrs(VariableMoveTypeAbAttr, source, null, variableType, typeChangeMovePowerMultiplier);
|
||||
applyPreAttackAbAttrs(MoveTypeChangeAttr, source, this, battlerMove, variableType, typeChangeMovePowerMultiplier);
|
||||
const type = variableType.value as Type;
|
||||
const types = this.getTypes(true, true);
|
||||
|
||||
@ -2818,6 +2819,7 @@ export class PokemonBattleSummonData {
|
||||
|
||||
export class PokemonTurnData {
|
||||
public flinched: boolean;
|
||||
public acted: boolean;
|
||||
public hitCount: integer;
|
||||
public hitsLeft: integer;
|
||||
public damageDealt: integer = 0;
|
||||
|
@ -2,7 +2,7 @@ import BattleScene, { STARTER_FORM_OVERRIDE, STARTER_SPECIES_OVERRIDE, bypassLog
|
||||
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
|
||||
import * as Utils from './utils';
|
||||
import { Moves } from "./data/enums/moves";
|
||||
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr } from "./data/move";
|
||||
import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMoveAttrs, HitsTagAttr, MissEffectAttr, MoveAttr, MoveEffectAttr, MoveFlags, MultiHitAttr, OverrideMoveEffectAttr, VariableAccuracyAttr, MoveTarget, OneHitKOAttr, getMoveTargets, MoveTargetSet, MoveEffectTrigger, CopyMoveAttr, AttackMove, SelfStatusMove, DelayedAttackAttr, RechargeAttr, PreMoveMessageAttr, HealStatusEffectAttr, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr } from "./data/move";
|
||||
import { Mode } from './ui/ui';
|
||||
import { Command } from "./ui/command-ui-handler";
|
||||
import { Stat } from "./data/pokemon-stat";
|
||||
@ -2155,6 +2155,8 @@ export class MovePhase extends BattlePhase {
|
||||
});
|
||||
|
||||
const doMove = () => {
|
||||
this.pokemon.turnData.acted = true; // Record that the move was attempted, even if it fails
|
||||
|
||||
this.pokemon.lapseTags(BattlerTagLapseType.PRE_MOVE);
|
||||
|
||||
if (!this.followUp && this.canMove() && !this.cancelled) {
|
||||
@ -2319,7 +2321,7 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
const hitCount = new Utils.IntegerHolder(1);
|
||||
// Assume single target for multi hit
|
||||
applyMoveAttrs(MultiHitAttr, user, this.getTarget(), this.move.getMove(), hitCount);
|
||||
if (this.move.getMove() instanceof AttackMove)
|
||||
if (this.move.getMove() instanceof AttackMove && !this.move.getMove().getAttrs(FixedDamageAttr).length)
|
||||
this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new Utils.IntegerHolder(0));
|
||||
user.turnData.hitsLeft = user.turnData.hitCount = hitCount.value;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user