Implement Parental Bond
parent
79a87e1c65
commit
14d3396f6a
|
@ -913,6 +913,34 @@ export class PostStatChangeStatChangeAbAttr extends PostStatChangeAbAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PreHitAbAttr extends AbAttr {
|
||||||
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExtraHitMoveAbAttr extends PreHitAbAttr {
|
||||||
|
private extraHits: integer;
|
||||||
|
private powerMultiplier: number;
|
||||||
|
|
||||||
|
constructor(extraHits: integer, powerMultiplier: number){
|
||||||
|
super(true);
|
||||||
|
this.extraHits = extraHits;
|
||||||
|
this.powerMultiplier = powerMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
|
||||||
|
const hits = (args[0] as number[]);
|
||||||
|
if (this.extraHits > 0) {
|
||||||
|
for (let i = 0; i < this.extraHits; i++)
|
||||||
|
hits.push(this.powerMultiplier);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class PreAttackAbAttr extends AbAttr {
|
export class PreAttackAbAttr extends AbAttr {
|
||||||
applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean | Promise<boolean> {
|
applyPreAttack(pokemon: Pokemon, passive: boolean, defender: Pokemon, move: PokemonMove, args: any[]): boolean | Promise<boolean> {
|
||||||
return false;
|
return false;
|
||||||
|
@ -3285,7 +3313,7 @@ export function initAbilities() {
|
||||||
new Ability(Abilities.AERILATE, 6)
|
new Ability(Abilities.AERILATE, 6)
|
||||||
.attr(MoveTypeChangePowerMultiplierAbAttr, Type.NORMAL, Type.FLYING, 1.2),
|
.attr(MoveTypeChangePowerMultiplierAbAttr, Type.NORMAL, Type.FLYING, 1.2),
|
||||||
new Ability(Abilities.PARENTAL_BOND, 6)
|
new Ability(Abilities.PARENTAL_BOND, 6)
|
||||||
.unimplemented(),
|
.attr(ExtraHitMoveAbAttr, 1, 0.25),
|
||||||
new Ability(Abilities.DARK_AURA, 6)
|
new Ability(Abilities.DARK_AURA, 6)
|
||||||
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a Dark Aura!'))
|
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a Dark Aura!'))
|
||||||
.attr(FieldMoveTypePowerBoostAbAttr, Type.DARK, 4 / 3),
|
.attr(FieldMoveTypePowerBoostAbAttr, Type.DARK, 4 / 3),
|
||||||
|
|
|
@ -1415,7 +1415,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
return (this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.getFieldIndex() ? 0 : 1];
|
return (this.isPlayer() ? this.scene.getPlayerField() : this.scene.getEnemyField())[this.getFieldIndex() ? 0 : 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(source: Pokemon, battlerMove: PokemonMove): HitResult {
|
apply(source: Pokemon, battlerMove: PokemonMove, extraHitModifier: number = 1): HitResult {
|
||||||
let result: HitResult;
|
let result: HitResult;
|
||||||
const move = battlerMove.getMove();
|
const move = battlerMove.getMove();
|
||||||
let damage = new Utils.NumberHolder(0);
|
let damage = new Utils.NumberHolder(0);
|
||||||
|
@ -1541,7 +1541,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
applyMoveAttrs(VariableDefAttr, source, this, move, targetDef);
|
applyMoveAttrs(VariableDefAttr, source, this, move, targetDef);
|
||||||
|
|
||||||
if (!isTypeImmune) {
|
if (!isTypeImmune) {
|
||||||
damage.value = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk.value / targetDef.value) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * arenaAttackTypeMultiplier.value * screenMultiplier.value * ((this.scene.randBattleSeedInt(15) + 85) / 100) * criticalMultiplier.value);
|
damage.value = Math.ceil(((((2 * source.level / 5 + 2) * power.value * sourceAtk.value / targetDef.value) / 50) + 2) * stabMultiplier.value * typeMultiplier.value * arenaAttackTypeMultiplier.value * screenMultiplier.value * extraHitModifier * ((this.scene.randBattleSeedInt(15) + 85) / 100) * criticalMultiplier.value);
|
||||||
if (isPhysical && source.status && source.status.effect === StatusEffect.BURN) {
|
if (isPhysical && source.status && source.status.effect === StatusEffect.BURN) {
|
||||||
const burnDamageReductionCancelled = new Utils.BooleanHolder(false);
|
const burnDamageReductionCancelled = new Utils.BooleanHolder(false);
|
||||||
applyAbAttrs(BypassBurnDamageReductionAbAttr, source, burnDamageReductionCancelled);
|
applyAbAttrs(BypassBurnDamageReductionAbAttr, source, burnDamageReductionCancelled);
|
||||||
|
@ -3310,6 +3310,7 @@ export class PokemonTurnData {
|
||||||
public damageDealt: integer = 0;
|
public damageDealt: integer = 0;
|
||||||
public damageTaken: integer = 0;
|
public damageTaken: integer = 0;
|
||||||
public attacksReceived: AttackMoveResult[] = [];
|
public attacksReceived: AttackMoveResult[] = [];
|
||||||
|
public multipliersExtraHits: number[] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AiType {
|
export enum AiType {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import { Weather, WeatherType, getRandomWeatherType, getTerrainBlockMessage, get
|
||||||
import { TempBattleStat } from "./data/temp-battle-stat";
|
import { TempBattleStat } from "./data/temp-battle-stat";
|
||||||
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
import { ArenaTagSide, ArenaTrapTag, MistTag, TrickRoomTag } from "./data/arena-tag";
|
||||||
import { ArenaTagType } from "./data/enums/arena-tag-type";
|
import { ArenaTagType } from "./data/enums/arena-tag-type";
|
||||||
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr } from "./data/ability";
|
import { CheckTrappedAbAttr, IgnoreOpponentStatChangesAbAttr, PostAttackAbAttr, PostBattleAbAttr, PostDefendAbAttr, PostSummonAbAttr, PostTurnAbAttr, PostWeatherLapseAbAttr, PreSwitchOutAbAttr, PreWeatherDamageAbAttr, ProtectStatAbAttr, RedirectMoveAbAttr, BlockRedirectAbAttr, RunSuccessAbAttr, StatChangeMultiplierAbAttr, SuppressWeatherEffectAbAttr, SyncEncounterNatureAbAttr, applyAbAttrs, applyCheckTrappedAbAttrs, applyPostAttackAbAttrs, applyPostBattleAbAttrs, applyPostDefendAbAttrs, applyPostSummonAbAttrs, applyPostTurnAbAttrs, applyPostWeatherLapseAbAttrs, applyPreStatChangeAbAttrs, applyPreSwitchOutAbAttrs, applyPreWeatherEffectAbAttrs, BattleStatMultiplierAbAttr, applyBattleStatMultiplierAbAttrs, IncrementMovePriorityAbAttr, applyPostVictoryAbAttrs, PostVictoryAbAttr, applyPostBattleInitAbAttrs, PostBattleInitAbAttr, BlockNonDirectDamageAbAttr as BlockNonDirectDamageAbAttr, applyPostKnockOutAbAttrs, PostKnockOutAbAttr, PostBiomeChangeAbAttr, applyPostFaintAbAttrs, PostFaintAbAttr, IncreasePpAbAttr, PostStatChangeAbAttr, applyPostStatChangeAbAttrs, AlwaysHitAbAttr, PreventBerryUseAbAttr, StatChangeCopyAbAttr, ExtraHitMoveAbAttr } from "./data/ability";
|
||||||
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
import { Unlockables, getUnlockableName } from "./system/unlockables";
|
||||||
import { getBiomeKey } from "./field/arena";
|
import { getBiomeKey } from "./field/arena";
|
||||||
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
import { BattleType, BattlerIndex, TurnCommand } from "./battle";
|
||||||
|
@ -2399,12 +2399,14 @@ export class MovePhase extends BattlePhase {
|
||||||
export class MoveEffectPhase extends PokemonPhase {
|
export class MoveEffectPhase extends PokemonPhase {
|
||||||
public move: PokemonMove;
|
public move: PokemonMove;
|
||||||
protected targets: BattlerIndex[];
|
protected targets: BattlerIndex[];
|
||||||
|
public multiHitId: integer;
|
||||||
|
|
||||||
constructor(scene: BattleScene, battlerIndex: BattlerIndex, targets: BattlerIndex[], move: PokemonMove) {
|
constructor(scene: BattleScene, battlerIndex: BattlerIndex, targets: BattlerIndex[], move: PokemonMove, multiHitId: integer = 0) {
|
||||||
super(scene, battlerIndex);
|
super(scene, battlerIndex);
|
||||||
|
|
||||||
this.move = move;
|
this.move = move;
|
||||||
this.targets = targets;
|
this.targets = targets;
|
||||||
|
this.multiHitId = multiHitId;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
@ -2432,6 +2434,15 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||||
applyMoveAttrs(MultiHitAttr, user, this.getTarget(), this.move.getMove(), hitCount);
|
applyMoveAttrs(MultiHitAttr, user, this.getTarget(), this.move.getMove(), hitCount);
|
||||||
if (this.move.getMove() instanceof AttackMove && !this.move.getMove().getAttrs(FixedDamageAttr).length)
|
if (this.move.getMove() instanceof AttackMove && !this.move.getMove().getAttrs(FixedDamageAttr).length)
|
||||||
this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new Utils.IntegerHolder(0));
|
this.scene.applyModifiers(PokemonMultiHitModifier, user.isPlayer(), user, hitCount, new Utils.IntegerHolder(0));
|
||||||
|
|
||||||
|
// Check for abilities that add extra hits with damage multipliers for them
|
||||||
|
if (this.move.getMove() instanceof AttackMove) {
|
||||||
|
const multipliersHits: number[] = [];
|
||||||
|
applyAbAttrs(ExtraHitMoveAbAttr, user, null, multipliersHits);
|
||||||
|
user.turnData.multipliersExtraHits = multipliersHits;
|
||||||
|
hitCount.value *= (multipliersHits.length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
user.turnData.hitsLeft = user.turnData.hitCount = hitCount.value;
|
user.turnData.hitsLeft = user.turnData.hitCount = hitCount.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2475,7 +2486,9 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||||
|
|
||||||
moveHistoryEntry.result = MoveResult.SUCCESS;
|
moveHistoryEntry.result = MoveResult.SUCCESS;
|
||||||
|
|
||||||
const hitResult = !isProtected ? target.apply(user, this.move) : HitResult.NO_EFFECT;
|
const multiHitMultiplier = this.multiHitId ? user.turnData.multipliersExtraHits[this.multiHitId - 1] ?? 1 : 1;
|
||||||
|
|
||||||
|
const hitResult = !isProtected ? target.apply(user, this.move, multiHitMultiplier) : HitResult.NO_EFFECT;
|
||||||
|
|
||||||
this.scene.triggerPokemonFormChange(user, SpeciesFormChangePostMoveTrigger);
|
this.scene.triggerPokemonFormChange(user, SpeciesFormChangePostMoveTrigger);
|
||||||
|
|
||||||
|
@ -2622,7 +2635,11 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||||
}
|
}
|
||||||
|
|
||||||
getNewHitPhase() {
|
getNewHitPhase() {
|
||||||
return new MoveEffectPhase(this.scene, this.battlerIndex, this.targets, this.move);
|
const hitId = new Utils.IntegerHolder(0);
|
||||||
|
const user = this.getUserPokemon();
|
||||||
|
if (user)
|
||||||
|
hitId.value = (this.multiHitId + 1) % (user.turnData.multipliersExtraHits.length + 1);
|
||||||
|
return new MoveEffectPhase(this.scene, this.battlerIndex, this.targets, this.move, hitId.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue