Added Wring Out. Attempted Healing Wish ( WIP )

pull/16/head
Xiaphear 2024-03-11 18:18:49 +01:00
parent 4c5981c126
commit 03989d07b2
2 changed files with 113 additions and 6 deletions

View File

@ -607,6 +607,35 @@ export class HealAttr extends MoveEffectAttr {
} }
} }
export class SacrificialFullRestoreAttr extends SacrificialAttr {
constructor() {
super();
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args))
return false;
// We don't know which party member will be chosen, so pick the highest max HP in the party
const maxPartyMemberHp = user.scene.getParty().map(p => p.getMaxHp()).reduce((maxHp: integer, hp: integer) => Math.max(hp, maxHp), 0);
console.log(maxPartyMemberHp);
user.scene.pushPhase(new PokemonHealPhase(user.scene, user.getBattlerIndex(),
maxPartyMemberHp, getPokemonMessage(user, '\'s Healing Wish\nwas granted!'), true, false, false, true));
return true;
}
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
return -20;
}
getCondition(): MoveConditionFunc {
return (user, target, move) => user.scene.getParty().filter(p => p.isActive()).length > user.scene.currentBattle.getBattlerCount();
}
}
export abstract class WeatherHealAttr extends HealAttr { export abstract class WeatherHealAttr extends HealAttr {
constructor() { constructor() {
super(0.5); super(0.5);
@ -827,6 +856,52 @@ export class StealHeldItemChanceAttr extends MoveEffectAttr {
} }
} }
export class RemoveHeldItemAttr extends MoveEffectAttr {
private chance: number;
constructor(chance: number) {
super(false, MoveEffectTrigger.HIT);
this.chance = chance;
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): Promise<boolean> {
return new Promise<boolean>(resolve => {
const rand = Phaser.Math.RND.realInRange(0, 1);
if (rand >= this.chance)
return resolve(false);
const heldItems = this.getTargetHeldItems(target).filter(i => i.getTransferrable(false));
if (heldItems.length) {
const highestItemTier = heldItems.map(m => m.type.getOrInferTier()).reduce((highestTier, tier) => Math.max(tier, highestTier), 0);
const tierHeldItems = heldItems.filter(m => m.type.getOrInferTier() === highestItemTier);
const stolenItem = tierHeldItems[user.randSeedInt(tierHeldItems.length)];
user.scene.tryTransferHeldItemModifier(stolenItem, user, false, false).then(success => {
if (success)
user.scene.queueMessage(getPokemonMessage(user, ` knocked off\n${target.name}'s ${stolenItem.type.name}!`));
resolve(success);
});
return;
}
resolve(false);
});
}
getTargetHeldItems(target: Pokemon): PokemonHeldItemModifier[] {
return target.scene.findModifiers(m => m instanceof PokemonHeldItemModifier
&& (m as PokemonHeldItemModifier).pokemonId === target.id, target.isPlayer()) as PokemonHeldItemModifier[];
}
getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
const heldItems = this.getTargetHeldItems(target);
return heldItems.length ? 5 : 0;
}
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
const heldItems = this.getTargetHeldItems(target);
return heldItems.length ? -5 : 0;
}
}
export class HealStatusEffectAttr extends MoveEffectAttr { export class HealStatusEffectAttr extends MoveEffectAttr {
private effects: StatusEffect[]; private effects: StatusEffect[];
@ -2084,6 +2159,25 @@ export class CopyMoveAttr extends OverrideMoveEffectAttr {
} }
} }
export class ReducePPMoveAttr extends OverrideMoveEffectAttr {
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
//const lastMove = target.getLastXMoves().find(() => true);
const lastMove = user.scene.currentBattle.lastMove;
const moveTargets = getMoveTargets(user, lastMove);
if (!moveTargets.targets.length)
return false;
const targets = moveTargets.multiple || moveTargets.targets.length === 1
? moveTargets.targets
: moveTargets.targets.indexOf(target.getBattlerIndex()) > -1
? [ target.getBattlerIndex() ]
: [ moveTargets.targets[user.randSeedInt(moveTargets.targets.length)] ];
return true;
}
}
// TODO: Review this // TODO: Review this
const targetMoveCopiableCondition: MoveConditionFunc = (user, target, move) => { const targetMoveCopiableCondition: MoveConditionFunc = (user, target, move) => {
const targetMoves = target.getMoveHistory().filter(m => !m.virtual); const targetMoves = target.getMoveHistory().filter(m => !m.virtual);
@ -3230,8 +3324,8 @@ export function initMoves() {
new AttackMove(Moves.GYRO_BALL, "Gyro Ball", Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 5, -1, "The user tackles the target with a high-speed spin. The slower the user compared to the target, the greater the move's power.", -1, 0, 4) new AttackMove(Moves.GYRO_BALL, "Gyro Ball", Type.STEEL, MoveCategory.PHYSICAL, -1, 100, 5, -1, "The user tackles the target with a high-speed spin. The slower the user compared to the target, the greater the move's power.", -1, 0, 4)
.attr(BattleStatRatioPowerAttr, Stat.SPD, true) .attr(BattleStatRatioPowerAttr, Stat.SPD, true)
.ballBombMove(), .ballBombMove(),
new SelfStatusMove(Moves.HEALING_WISH, "Healing Wish", Type.PSYCHIC, -1, 10, -1, "The user faints. In return, the Pokémon taking its place will have its HP restored and status conditions cured.", -1, 0, 4) new SelfStatusMove(Moves.HEALING_WISH, "Healing Wish (N)", Type.PSYCHIC, -1, 10, -1, "The user faints. In return, the Pokémon taking its place will have its HP restored and status conditions cured.", -1, 0, 4)
.attr(SacrificialAttr), .attr(SacrificialFullRestoreAttr),
new AttackMove(Moves.BRINE, "Brine", Type.WATER, MoveCategory.SPECIAL, 65, 100, 10, -1, "If the target's HP is half or less, this attack will hit with double the power.", -1, 0, 4) new AttackMove(Moves.BRINE, "Brine", Type.WATER, MoveCategory.SPECIAL, 65, 100, 10, -1, "If the target's HP is half or less, this attack will hit with double the power.", -1, 0, 4)
.attr(MovePowerMultiplierAttr, (user, target, move) => target.getHpRatio() < 0.5 ? 2 : 1), .attr(MovePowerMultiplierAttr, (user, target, move) => target.getHpRatio() < 0.5 ? 2 : 1),
new AttackMove(Moves.NATURAL_GIFT, "Natural Gift (N)", Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, "The user draws power to attack by using its held Berry. The Berry determines the move's type and power.", -1, 0, 4) new AttackMove(Moves.NATURAL_GIFT, "Natural Gift (N)", Type.NORMAL, MoveCategory.PHYSICAL, -1, 100, 15, -1, "The user draws power to attack by using its held Berry. The Berry determines the move's type and power.", -1, 0, 4)
@ -3264,7 +3358,8 @@ export function initMoves() {
.makesContact(), .makesContact(),
new StatusMove(Moves.HEAL_BLOCK, "Heal Block (N)", Type.PSYCHIC, 100, 15, -1, "For five turns, the user prevents the opposing team from using any moves, Abilities, or held items that recover HP.", -1, 0, 4) new StatusMove(Moves.HEAL_BLOCK, "Heal Block (N)", Type.PSYCHIC, 100, 15, -1, "For five turns, the user prevents the opposing team from using any moves, Abilities, or held items that recover HP.", -1, 0, 4)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new AttackMove(Moves.WRING_OUT, "Wring Out (N)", Type.NORMAL, MoveCategory.SPECIAL, -1, 100, 5, -1, "The user powerfully wrings the target. The more HP the target has, the greater the move's power.", -1, 0, 4) new AttackMove(Moves.WRING_OUT, "Wring Out", Type.NORMAL, MoveCategory.SPECIAL, -1, 100, 5, -1, "The user powerfully wrings the target. The more HP the target has, the greater the move's power.", -1, 0, 4)
.attr(OpponentHighHpPowerAttr)
.makesContact(), .makesContact(),
new SelfStatusMove(Moves.POWER_TRICK, "Power Trick (N)", Type.PSYCHIC, -1, 10, -1, "The user employs its psychic power to switch its Attack stat with its Defense stat.", -1, 0, 4), new SelfStatusMove(Moves.POWER_TRICK, "Power Trick (N)", Type.PSYCHIC, -1, 10, -1, "The user employs its psychic power to switch its Attack stat with its Defense stat.", -1, 0, 4),
new StatusMove(Moves.GASTRO_ACID, "Gastro Acid (N)", Type.POISON, 100, 10, -1, "The user hurls up its stomach acids on the target. The fluid eliminates the effect of the target's Ability.", -1, 0, 4), new StatusMove(Moves.GASTRO_ACID, "Gastro Acid (N)", Type.POISON, 100, 10, -1, "The user hurls up its stomach acids on the target. The fluid eliminates the effect of the target's Ability.", -1, 0, 4),

View File

@ -3318,15 +3318,17 @@ export class PokemonHealPhase extends CommonAnimPhase {
private showFullHpMessage: boolean; private showFullHpMessage: boolean;
private skipAnim: boolean; private skipAnim: boolean;
private revive: boolean; private revive: boolean;
private healStatus: boolean;
constructor(scene: BattleScene, battlerIndex: BattlerIndex, hpHealed: integer, message: string, showFullHpMessage: boolean, skipAnim?: boolean, revive?: boolean) { constructor(scene: BattleScene, battlerIndex: BattlerIndex, hpHealed: integer, message: string, showFullHpMessage: boolean, skipAnim: boolean = false, revive: boolean = false, healStatus: boolean = false) {
super(scene, battlerIndex, undefined, CommonAnim.HEALTH_UP); super(scene, battlerIndex, undefined, CommonAnim.HEALTH_UP);
this.hpHealed = hpHealed; this.hpHealed = hpHealed;
this.message = message; this.message = message;
this.showFullHpMessage = showFullHpMessage; this.showFullHpMessage = showFullHpMessage;
this.skipAnim = !!skipAnim; this.skipAnim = skipAnim;
this.revive = !!revive; this.revive = revive;
this.healStatus = healStatus;
} }
start() { start() {
@ -3346,6 +3348,9 @@ export class PokemonHealPhase extends CommonAnimPhase {
const fullHp = pokemon.getHpRatio() >= 1; const fullHp = pokemon.getHpRatio() >= 1;
const hasMessage = !!this.message;
let lastStatusEffect = StatusEffect.NONE;
if (!fullHp) { if (!fullHp) {
const hpRestoreMultiplier = new Utils.IntegerHolder(1); const hpRestoreMultiplier = new Utils.IntegerHolder(1);
if (!this.revive) if (!this.revive)
@ -3359,6 +3364,10 @@ export class PokemonHealPhase extends CommonAnimPhase {
if (healAmount.value > this.scene.gameData.gameStats.highestHeal) if (healAmount.value > this.scene.gameData.gameStats.highestHeal)
this.scene.gameData.gameStats.highestHeal = healAmount.value; this.scene.gameData.gameStats.highestHeal = healAmount.value;
} }
if (this.healStatus && !this.revive && pokemon.status) {
lastStatusEffect = pokemon.status.effect;
pokemon.resetStatus();
}
pokemon.updateInfo().then(() => super.end()); pokemon.updateInfo().then(() => super.end());
} else if (this.showFullHpMessage) } else if (this.showFullHpMessage)
this.message = getPokemonMessage(pokemon, `'s\nHP is full!`); this.message = getPokemonMessage(pokemon, `'s\nHP is full!`);
@ -3366,6 +3375,9 @@ export class PokemonHealPhase extends CommonAnimPhase {
if (this.message) if (this.message)
this.scene.queueMessage(this.message); this.scene.queueMessage(this.message);
if (this.healStatus && lastStatusEffect && !hasMessage)
this.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(lastStatusEffect)));
if (fullHp) if (fullHp)
super.end(); super.end();
} }