diff --git a/src/battle-phases.ts b/src/battle-phases.ts index 9b79ca95c..46e5ad712 100644 --- a/src/battle-phases.ts +++ b/src/battle-phases.ts @@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, ChargeAttr, HitsTagAttr, MissEffectAttr, Move import { Mode } from './ui/ui'; import { Command } from "./ui/command-ui-handler"; import { Stat } from "./pokemon-stat"; -import { ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier } from "./modifier"; +import { ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, HitHealModifier } from "./modifier"; import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler"; import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./pokeball"; import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveAnim, chargeAnims, initMoveAnim, loadMoveAnimAssets } from "./battle-anims"; @@ -535,6 +535,22 @@ export abstract class PartyMemberPokemonPhase extends PokemonPhase { } } +export class CommonAnimPhase extends PokemonPhase { + private anim: CommonAnim; + + constructor(scene: BattleScene, player: boolean, anim: CommonAnim) { + super(scene, player); + + this.anim = anim; + } + + start() { + new CommonBattleAnim(this.anim, this.getPokemon()).play(this.scene, () => { + this.end(); + }); + } +} + abstract class MovePhase extends BattlePhase { protected pokemon: Pokemon; protected move: PokemonMove; @@ -710,6 +726,8 @@ abstract class MoveEffectPhase extends PokemonPhase { else { if (user.turnData.hitsTotal > 1) this.scene.unshiftPhase(new MessagePhase(this.scene, `Hit ${user.turnData.hitCount} time(s)!`)); + if (this.player) + this.scene.applyModifiers(HitHealModifier, user); } super.end(); @@ -1235,6 +1253,23 @@ export class LearnMovePhase extends PartyMemberPokemonPhase { } } +export class PokemonHealPhase extends CommonAnimPhase { + private hpHealed: integer; + + constructor(scene: BattleScene, player: boolean, hpHealed: integer) { + super(scene, player, CommonAnim.HEALTH_UP); + + this.hpHealed = hpHealed; + } + + end() { + const pokemon = this.getPokemon(); + + pokemon.hp = Math.min(pokemon.hp + this.hpHealed, pokemon.getMaxHp()); + pokemon.updateInfo().then(() => super.end()); + } +} + export class AttemptCapturePhase extends BattlePhase { private pokeballType: PokeballType; private pokeball: Phaser.GameObjects.Sprite; diff --git a/src/modifier-type.ts b/src/modifier-type.ts index 7435e3346..7b2fccae0 100644 --- a/src/modifier-type.ts +++ b/src/modifier-type.ts @@ -49,7 +49,7 @@ class AddPokeballModifierType extends ModifierType { } } -export abstract class PokemonModifierType extends ModifierType { +export class PokemonModifierType extends ModifierType { public selectFilter: PokemonSelectFilter; constructor(name: string, description: string, newModifierFunc: NewModifierFunc, selectFilter?: PokemonSelectFilter, iconImage?: string) { @@ -283,7 +283,8 @@ const modifierPool = { }), new ModifierType('OVAL CHARM', 'For every X (no. of party members) items in a POKéMON\'s held item stack, give one to each other party member', (type, _args) => new Modifiers.PartyShareModifier(type), 'oval_charm'), - new ModifierType('HEALING CHARM', 'Doubles the effectiveness of HP restoring items (excludes revives)', (type, _args) => new Modifiers.HealingBoosterModifier(type, 2), 'healing_charm'), + new ModifierType('HEALING CHARM', 'Doubles the effectiveness of HP restoring moves and items (excludes revives)', (type, _args) => new Modifiers.HealingBoosterModifier(type, 2), 'healing_charm'), + new WeightedModifierType(new PokemonModifierType('SHELL BELL', 'Heals 1/8 of a POKéMON\'s damage dealt', (type, args) => new Modifiers.HitHealModifier(type, (args[0] as PlayerPokemon).id)), 8), new ExpBoosterModifierType('LUCKY EGG', 25), new ModifierType('EXP. SHARE', 'All POKéMON in your party gain an additional 10% of a battle\'s EXP. Points', (type, _args) => new Modifiers.ExpShareModifier(type), 'exp_share') ].map(m => { m.setTier(ModifierTier.ULTRA); return m; }), diff --git a/src/modifier.ts b/src/modifier.ts index b8bbb7f3d..6ab1acd85 100644 --- a/src/modifier.ts +++ b/src/modifier.ts @@ -1,5 +1,5 @@ import * as ModifierTypes from './modifier-type'; -import { LearnMovePhase, LevelUpPhase } from "./battle-phases"; +import { CommonAnimPhase, LearnMovePhase, LevelUpPhase, MessagePhase, PokemonHealPhase } from "./battle-phases"; import BattleScene from "./battle-scene"; import { getLevelTotalExp } from "./exp"; import { PokeballType } from "./pokeball"; @@ -7,6 +7,7 @@ import Pokemon, { PlayerPokemon } from "./pokemon"; import { Stat } from "./pokemon-stat"; import { addTextObject, TextStyle } from "./text"; import * as Utils from "./utils"; +import { CommonAnim } from './battle-anims'; type ModifierType = ModifierTypes.ModifierType; @@ -199,6 +200,20 @@ export abstract class PokemonHeldItemModifier extends PersistentModifier { container.add(pokemonIcon); + const item = scene.add.sprite(16, this.virtualStackCount ? 8 : 16, 'items'); + item.setScale(0.5); + item.setOrigin(0, 0.5); + item.setTexture('items', this.type.iconImage); + container.add(item); + + const stackText = this.getIconStackText(scene); + if (stackText) + container.add(stackText); + + const virtualStackText = this.getIconStackText(scene, true); + if (virtualStackText) + container.add(virtualStackText); + return container; } @@ -236,25 +251,34 @@ export class PokemonBaseStatModifier extends PokemonHeldItemModifier { return true; } +} - getIcon(scene: BattleScene): Phaser.GameObjects.Container { - const container = super.getIcon(scene); +export class HitHealModifier extends PokemonHeldItemModifier { + constructor(type: ModifierType, pokemonId: integer) { + super(type, pokemonId); + } - const item = scene.add.sprite(16, this.virtualStackCount ? 8 : 16, 'items'); - item.setScale(0.5); - item.setOrigin(0, 0.5); - item.setTexture('items', this.type.iconImage); - container.add(item); + match(modifier: Modifier) { + return modifier instanceof HitHealModifier; + } - const stackText = this.getIconStackText(scene); - if (stackText) - container.add(stackText); + clone() { + return new HitHealModifier(this.type, this.pokemonId); + } - const virtualStackText = this.getIconStackText(scene, true); - if (virtualStackText) - container.add(virtualStackText); + apply(args: any[]): boolean { + const pokemon = args[0] as PlayerPokemon; - return container; + if (pokemon.turnData.damageDealt && pokemon.getHpRatio() < 1) { + const scene = pokemon.scene as BattleScene; + + const hpRestoreMultiplier = new Utils.IntegerHolder(1); + scene.applyModifiers(HealingBoosterModifier, hpRestoreMultiplier); + scene.unshiftPhase(new PokemonHealPhase(scene, true, Math.max(Math.floor(pokemon.turnData.damageDealt / 8) * this.stackCount * hpRestoreMultiplier.value, 1))); + scene.unshiftPhase(new MessagePhase(scene, `${pokemon.name}'s ${this.type.name}\nrestored its HP a little!`)); + } + + return true; } } diff --git a/src/pokemon.ts b/src/pokemon.ts index 2e282f8e3..65c78f137 100644 --- a/src/pokemon.ts +++ b/src/pokemon.ts @@ -442,6 +442,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { console.log('damage', damage, move.name, move.power, sourceAtk, targetDef); if (damage) { this.hp = Math.max(this.hp - damage, 0); + source.turnData.damageDealt += damage; if (isCritical) battleScene.unshiftPhase(new MessagePhase(battleScene, 'A critical hit!')); } @@ -908,6 +909,7 @@ export class PokemonTurnData { public hitCount: integer; public hitsLeft: integer; public hitsTotal: integer; + public damageDealt: integer = 0; } export enum AiType {