Implement Beat Up

pull/593/head
Alvin Zou 2024-05-07 02:59:03 -07:00
parent 20a09c2b92
commit 161ceb4daa
2 changed files with 58 additions and 2 deletions

View File

@ -804,6 +804,7 @@ export enum MultiHitType {
_3, _3,
_3_INCR, _3_INCR,
_1_TO_10, _1_TO_10,
BEAT_UP,
} }
export class HealAttr extends MoveEffectAttr { export class HealAttr extends MoveEffectAttr {
@ -1069,6 +1070,11 @@ export class MultiHitAttr extends MoveAttr {
hitTimes = 10; hitTimes = 10;
} }
break; break;
case MultiHitType.BEAT_UP:
// No status means the ally pokemon can contribute to Beat Up
hitTimes = user.scene.getParty().reduce((total, pokemon) => {
return total + (pokemon.id === user.id ? 1 : pokemon?.status && pokemon.status.effect !== StatusEffect.NONE ? 0 : 1)
}, 0);
} }
(args[0] as Utils.IntegerHolder).value = hitTimes; (args[0] as Utils.IntegerHolder).value = hitTimes;
return true; return true;
@ -1866,6 +1872,45 @@ export class MovePowerMultiplierAttr extends VariablePowerAttr {
} }
} }
/**
* Helper function to calculate the the base power of an ally's hit when using Beat Up.
* @param user The Pokemon that used Beat Up.
* @param allyIndex The party position of the ally contributing to Beat Up.
* @returns The base power of the Beat Up hit.
*/
const beatUpFunc = (user: Pokemon, allyIndex: number): number => {
const party = user.scene.getParty();
for (let i = allyIndex; i < party.length; i++) {
const pokemon = party[i];
// The user contributes to Beat Up regardless of status condition.
// Allies can contribute only if they do not have a non-volatile status condition.
if (pokemon.id !== user.id && pokemon?.status && pokemon.status.effect !== StatusEffect.NONE) {
continue;
}
return (pokemon.species.getBaseStat(Stat.ATK) / 10) + 5;
}
}
export class BeatUpAttr extends VariablePowerAttr {
/**
* Gets the next party member to contribute to a Beat Up hit, and calculates the base power for it.
* @param user Pokemon that used the move
* @param _target N/A
* @param _move Move with this attribute
* @param args N/A
* @returns true if the function succeeds
*/
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
const power = args[0] as Utils.NumberHolder;
const allyIndex = user.turnData.hitCount - user.turnData.hitsLeft;
power.value = beatUpFunc(user, allyIndex);
return true;
}
}
const doublePowerChanceMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => { const doublePowerChanceMessageFunc = (user: Pokemon, target: Pokemon, move: Move) => {
let message: string = null; let message: string = null;
user.scene.executeWithSeedOffset(() => { user.scene.executeWithSeedOffset(() => {
@ -4831,8 +4876,9 @@ export function initMoves() {
.attr(TrapAttr, BattlerTagType.WHIRLPOOL) .attr(TrapAttr, BattlerTagType.WHIRLPOOL)
.attr(HitsTagAttr, BattlerTagType.UNDERWATER, true), .attr(HitsTagAttr, BattlerTagType.UNDERWATER, true),
new AttackMove(Moves.BEAT_UP, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 2) new AttackMove(Moves.BEAT_UP, Type.DARK, MoveCategory.PHYSICAL, -1, 100, 10, -1, 0, 2)
.makesContact(false) .attr(MultiHitAttr, MultiHitType.BEAT_UP)
.unimplemented(), .attr(BeatUpAttr)
.makesContact(false),
new AttackMove(Moves.FAKE_OUT, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 10, 100, 3, 3) new AttackMove(Moves.FAKE_OUT, Type.NORMAL, MoveCategory.PHYSICAL, 40, 100, 10, 100, 3, 3)
.attr(FlinchAttr) .attr(FlinchAttr)
.condition(new FirstMoveCondition()), .condition(new FirstMoveCondition()),

View File

@ -16,6 +16,7 @@ import { GameMode } from '../game-mode';
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities"; import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
import { VariantSet } from './variant'; import { VariantSet } from './variant';
import i18next, { Localizable } from '../plugins/i18n'; import i18next, { Localizable } from '../plugins/i18n';
import { Stat } from "./pokemon-stat";
export enum Region { export enum Region {
NORMAL, NORMAL,
@ -192,6 +193,15 @@ export abstract class PokemonSpeciesForm {
return false; return false;
} }
/**
* Gets the species' base stat amount for the given stat.
* @param stat The desired stat.
* @returns The species' base stat amount.
*/
getBaseStat(stat: Stat): integer {
return this.baseStats[stat]
}
getBaseExp(): integer { getBaseExp(): integer {
let ret = this.baseExp; let ret = this.baseExp;
switch (this.getFormSpriteKey()) { switch (this.getFormSpriteKey()) {