implement Darkest Lariat, Chip Away and Sacred Sword (#26)

* implement darkest lariat, chip away, sacred sword

* fix
pull/27/head^2
LaukkaE 2024-04-02 20:51:38 +03:00 committed by GitHub
parent 7b7185300c
commit bd1af25c01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 8 deletions

View File

@ -441,6 +441,14 @@ export class StatusMoveTypeImmunityAttr extends MoveAttr {
} }
} }
export class IgnoreOpponentStatChangesAttr extends MoveAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
(args[0] as Utils.IntegerHolder).value = 0;
return true;
}
}
export class HighCritAttr extends MoveAttr { export class HighCritAttr extends MoveAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean { apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
(args[0] as Utils.IntegerHolder).value++; (args[0] as Utils.IntegerHolder).value++;
@ -3925,7 +3933,8 @@ export function initMoves() {
new AttackMove(Moves.ECHOED_VOICE, "Echoed Voice", Type.NORMAL, MoveCategory.SPECIAL, 40, 100, 15, "The user attacks the target with an echoing voice. If this move is used every turn, its power is increased.", -1, 0, 5) new AttackMove(Moves.ECHOED_VOICE, "Echoed Voice", Type.NORMAL, MoveCategory.SPECIAL, 40, 100, 15, "The user attacks the target with an echoing voice. If this move is used every turn, its power is increased.", -1, 0, 5)
.attr(ConsecutiveUseMultiBasePowerAttr, 5, false) .attr(ConsecutiveUseMultiBasePowerAttr, 5, false)
.soundBased(), .soundBased(),
new AttackMove(Moves.CHIP_AWAY, "Chip Away (P)", Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, "Looking for an opening, the user strikes consistently. The target's stat changes don't affect this attack's damage.", -1, 0, 5), new AttackMove(Moves.CHIP_AWAY, "Chip Away", Type.NORMAL, MoveCategory.PHYSICAL, 70, 100, 20, "Looking for an opening, the user strikes consistently. The target's stat changes don't affect this attack's damage.", -1, 0, 5)
.attr(IgnoreOpponentStatChangesAttr),
new AttackMove(Moves.CLEAR_SMOG, "Clear Smog (P)", Type.POISON, MoveCategory.SPECIAL, 50, -1, 15, "The user attacks the target by throwing a clump of special mud. All stat changes are returned to normal.", -1, 0, 5), new AttackMove(Moves.CLEAR_SMOG, "Clear Smog (P)", Type.POISON, MoveCategory.SPECIAL, 50, -1, 15, "The user attacks the target by throwing a clump of special mud. All stat changes are returned to normal.", -1, 0, 5),
new AttackMove(Moves.STORED_POWER, "Stored Power (P)", Type.PSYCHIC, MoveCategory.SPECIAL, 20, 100, 10, "The user attacks the target with stored power. The more the user's stats are raised, the greater the move's power.", -1, 0, 5), new AttackMove(Moves.STORED_POWER, "Stored Power (P)", Type.PSYCHIC, MoveCategory.SPECIAL, 20, 100, 10, "The user attacks the target with stored power. The more the user's stats are raised, the greater the move's power.", -1, 0, 5),
new StatusMove(Moves.QUICK_GUARD, "Quick Guard (N)", Type.FIGHTING, -1, 15, "The user protects itself and its allies from priority moves.", -1, 3, 5) new StatusMove(Moves.QUICK_GUARD, "Quick Guard (N)", Type.FIGHTING, -1, 15, "The user protects itself and its allies from priority moves.", -1, 3, 5)
@ -3998,7 +4007,8 @@ export function initMoves() {
.attr(FlinchAttr), .attr(FlinchAttr),
new AttackMove(Moves.HORN_LEECH, "Horn Leech", Type.GRASS, MoveCategory.PHYSICAL, 75, 100, 10, "The user drains the target's energy with its horns. The user's HP is restored by half the damage taken by the target.", -1, 0, 5) new AttackMove(Moves.HORN_LEECH, "Horn Leech", Type.GRASS, MoveCategory.PHYSICAL, 75, 100, 10, "The user drains the target's energy with its horns. The user's HP is restored by half the damage taken by the target.", -1, 0, 5)
.attr(HitHealAttr), .attr(HitHealAttr),
new AttackMove(Moves.SACRED_SWORD, "Sacred Sword (P)", Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 15, "The user attacks by slicing with a long horn. The target's stat changes don't affect this attack's damage.", -1, 0, 5) new AttackMove(Moves.SACRED_SWORD, "Sacred Sword", Type.FIGHTING, MoveCategory.PHYSICAL, 90, 100, 15, "The user attacks by slicing with a long horn. The target's stat changes don't affect this attack's damage.", -1, 0, 5)
.attr(IgnoreOpponentStatChangesAttr)
.slicingMove(), .slicingMove(),
new AttackMove(Moves.RAZOR_SHELL, "Razor Shell", Type.WATER, MoveCategory.PHYSICAL, 75, 95, 10, "The user cuts its target with sharp shells. This may also lower the target's Defense stat.", 50, 0, 5) new AttackMove(Moves.RAZOR_SHELL, "Razor Shell", Type.WATER, MoveCategory.PHYSICAL, 75, 95, 10, "The user cuts its target with sharp shells. This may also lower the target's Defense stat.", 50, 0, 5)
.attr(StatChangeAttr, BattleStat.DEF, -1) .attr(StatChangeAttr, BattleStat.DEF, -1)
@ -4262,7 +4272,8 @@ export function initMoves() {
.attr(ProtectAttr, BattlerTagType.BANEFUL_BUNKER), .attr(ProtectAttr, BattlerTagType.BANEFUL_BUNKER),
new AttackMove(Moves.SPIRIT_SHACKLE, "Spirit Shackle (P)", Type.GHOST, MoveCategory.PHYSICAL, 80, 100, 10, "The user attacks while simultaneously stitching the target's shadow to the ground to prevent the target from escaping.", -1, 0, 7) new AttackMove(Moves.SPIRIT_SHACKLE, "Spirit Shackle (P)", Type.GHOST, MoveCategory.PHYSICAL, 80, 100, 10, "The user attacks while simultaneously stitching the target's shadow to the ground to prevent the target from escaping.", -1, 0, 7)
.makesContact(false), .makesContact(false),
new AttackMove(Moves.DARKEST_LARIAT, "Darkest Lariat (P)", Type.DARK, MoveCategory.PHYSICAL, 85, 100, 10, "The user swings both arms and hits the target. The target's stat changes don't affect this attack's damage.", -1, 0, 7), new AttackMove(Moves.DARKEST_LARIAT, "Darkest Lariat", Type.DARK, MoveCategory.PHYSICAL, 85, 100, 10, "The user swings both arms and hits the target. The target's stat changes don't affect this attack's damage.", -1, 0, 7)
.attr(IgnoreOpponentStatChangesAttr),
new AttackMove(Moves.SPARKLING_ARIA, "Sparkling Aria", Type.WATER, MoveCategory.SPECIAL, 90, 100, 10, "The user bursts into song, emitting many bubbles. Any Pokémon suffering from a burn will be healed by the touch of these bubbles.", -1, 0, 7) new AttackMove(Moves.SPARKLING_ARIA, "Sparkling Aria", Type.WATER, MoveCategory.SPECIAL, 90, 100, 10, "The user bursts into song, emitting many bubbles. Any Pokémon suffering from a burn will be healed by the touch of these bubbles.", -1, 0, 7)
.attr(HealStatusEffectAttr, false, StatusEffect.BURN) .attr(HealStatusEffectAttr, false, StatusEffect.BURN)
.soundBased() .soundBased()

View File

@ -2,7 +2,7 @@ import Phaser from 'phaser';
import BattleScene, { ABILITY_OVERRIDE, AnySound, MOVE_OVERRIDE, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE } from '../battle-scene'; import BattleScene, { ABILITY_OVERRIDE, AnySound, MOVE_OVERRIDE, OPP_ABILITY_OVERRIDE, OPP_MOVE_OVERRIDE } from '../battle-scene';
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info'; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from '../ui/battle-info';
import { Moves } from "../data/enums/moves"; import { Moves } from "../data/enums/moves";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr } from "../data/move"; import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, VariablePowerAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, MultiHitAttr, StatusMoveTypeImmunityAttr, MoveTarget, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from '../data/pokemon-species'; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from '../data/pokemon-species';
import * as Utils from '../utils'; import * as Utils from '../utils';
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type'; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from '../data/type';
@ -481,13 +481,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this.stats[stat]; return this.stats[stat];
} }
getBattleStat(stat: Stat, opponent?: Pokemon): integer { getBattleStat(stat: Stat, opponent?: Pokemon, move?: Move): integer {
if (stat === Stat.HP) if (stat === Stat.HP)
return this.getStat(Stat.HP); return this.getStat(Stat.HP);
const battleStat = (stat - 1) as BattleStat; const battleStat = (stat - 1) as BattleStat;
const statLevel = new Utils.IntegerHolder(this.summonData.battleStats[battleStat]); const statLevel = new Utils.IntegerHolder(this.summonData.battleStats[battleStat]);
if (opponent) if (opponent) {
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, opponent, null, statLevel); applyAbAttrs(IgnoreOpponentStatChangesAbAttr, opponent, null, statLevel);
if (move)
applyMoveAttrs(IgnoreOpponentStatChangesAttr, this, opponent, move, statLevel);
}
if (this.isPlayer()) if (this.isPlayer())
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), battleStat as integer as TempBattleStat, statLevel); this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), battleStat as integer as TempBattleStat, statLevel);
const statValue = new Utils.NumberHolder(this.getStat(stat)); const statValue = new Utils.NumberHolder(this.getStat(stat));
@ -1098,7 +1101,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
} }
const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this)); const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this));
const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source)); const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source, move));
const criticalMultiplier = isCritical ? 2 : 1; const criticalMultiplier = isCritical ? 2 : 1;
const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier) === 0; const isTypeImmune = (typeMultiplier.value * arenaAttackTypeMultiplier) === 0;
const sourceTypes = source.getTypes(); const sourceTypes = source.getTypes();

View File

@ -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 { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
import * as Utils from './utils'; import * as Utils from './utils';
import { Moves } from "./data/enums/moves"; 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 } 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 } from "./data/move";
import { Mode } from './ui/ui'; import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler"; import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat"; import { Stat } from "./data/pokemon-stat";
@ -2313,6 +2313,7 @@ export class MoveEffectPhase extends PokemonPhase {
const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]); const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]);
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, target, null, userAccuracyLevel); applyAbAttrs(IgnoreOpponentStatChangesAbAttr, target, null, userAccuracyLevel);
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, this.getUserPokemon(), null, targetEvasionLevel); applyAbAttrs(IgnoreOpponentStatChangesAbAttr, this.getUserPokemon(), null, targetEvasionLevel);
applyMoveAttrs(IgnoreOpponentStatChangesAttr, this.getUserPokemon(), target, this.move.getMove(), targetEvasionLevel);
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.player, TempBattleStat.ACC, userAccuracyLevel); this.scene.applyModifiers(TempBattleStatBoosterModifier, this.player, TempBattleStat.ACC, userAccuracyLevel);
const rand = this.getUserPokemon().randSeedInt(100, 1); const rand = this.getUserPokemon().randSeedInt(100, 1);