Refactored turn order calculation & Implemented Grassy Glide

Changed the TurnCommand interface to include a priority attribute.
Turn order is computed based on this priority attribute along with Pokemon speed.
Priority is +6 for item use and pokemon switch, and equal to the move priority otherwise.
Added VariablePriorityAttr extends MoveAttr, to implement move that have a conditional changing priority (Pursuit and Grassy Glide), and implemented grassy glide.
This commit is contained in:
ggiroussens 2024-05-01 11:01:08 +02:00
parent 77caa8ece5
commit da9d2c8899
3 changed files with 75 additions and 4 deletions

View File

@ -28,6 +28,7 @@ export enum BattlerIndex {
export interface TurnCommand {
command: Command;
priority?: integer;
cursor?: integer;
move?: QueuedMove;
targets?: BattlerIndex[];

View File

@ -437,6 +437,25 @@ export enum MoveEffectTrigger {
HIT
}
export class VariablePriorityAttr extends MoveAttr {
private priorityChangeFunc: (user: Pokemon, target: Pokemon, move: Move) => number;
constructor(priorityChangeFunc: (user: Pokemon, target: Pokemon, move: Move) => number) {
super();
this.priorityChangeFunc = priorityChangeFunc;
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[])
{
console.log(`Checking dynamic priority for move ${move}`);
(args[0] as Utils.NumberHolder).value = this.priorityChangeFunc(user, target, move);
console.log(`Returned Priority ${args[0].value}`);
return true;
}
}
export class MoveEffectAttr extends MoveAttr {
public trigger: MoveEffectTrigger;
public firstHitOnly: boolean;
@ -5936,7 +5955,7 @@ export function initMoves() {
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.MISTY && user.isGrounded() ? 1.5 : 1)
.condition(failIfDampCondition),
new AttackMove(Moves.GRASSY_GLIDE, Type.GRASS, MoveCategory.PHYSICAL, 55, 100, 20, -1, 0, 8)
.partial(),
.attr(VariablePriorityAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.GRASSY && user.isGrounded() ? 1 : 0),
new AttackMove(Moves.RISING_VOLTAGE, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 20, -1, 0, 8)
.attr(MovePowerMultiplierAttr, (user, target, move) => user.scene.arena.getTerrainType() === TerrainType.ELECTRIC && target.isGrounded() ? 2 : 1),
new AttackMove(Moves.TERRAIN_PULSE, Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, 0, 8)

View File

@ -2,7 +2,7 @@ import BattleScene, { bypassLogin, startingWave } from "./battle-scene";
import { default as Pokemon, PlayerPokemon, EnemyPokemon, PokemonMove, MoveResult, DamageResult, FieldPosition, HitResult, TurnMove } from "./field/pokemon";
import * as Utils from './utils';
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, IgnoreOpponentStatChangesAttr, NoEffectAttr, FixedDamageAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr } 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, NoEffectAttr, FixedDamageAttr, OneHitKOAccuracyAttr, ForceSwitchOutAttr, VariablePriorityAttr } from "./data/move";
import { Mode } from './ui/ui';
import { Command } from "./ui/command-ui-handler";
import { Stat } from "./data/pokemon-stat";
@ -1932,10 +1932,61 @@ export class TurnStartPhase extends FieldPhase {
super.start();
const field = this.scene.getField();
// Battle index of all the pokemon in the scene, ordered by speed,
// or inverted speed in if the scene is under distorsion.
const order = this.getOrder();
const moveOrder = order.slice(0);
// Set the priority of the different move command
for (let _battlerIndex of moveOrder) {
let command = this.scene.currentBattle.turnCommands[_battlerIndex];
if(command.command === Command.FIGHT) {
// The command Priority is the Command of the Move
let source = this.scene.getField().find(p => p?.isActive() && p.getBattlerIndex() === _battlerIndex);
let target = null;
let move = allMoves[command.move.move];
const movePriority = new Utils.NumberHolder(move.priority);
applyMoveAttrs(VariablePriorityAttr, source, target, move, movePriority);
applyAbAttrs(IncrementMovePriorityAbAttr, source, null, move, movePriority);
command.priority = movePriority.value;
}
else {
// The command Priority is +6
command.priority = 6;
}
}
moveOrder.sort((a, b) => {
// Comparison of the priority Brackets
const priorityComp = this.scene.currentBattle.turnCommands[b].priority - this.scene.currentBattle.turnCommands[a].priority;
const speedOrderComp = order.indexOf(a) - order.indexOf(b);
//
return Math.sign(priorityComp == 0 ? speedOrderComp : priorityComp);
});
// Logging Battle Order:
/*
let orderInTurn = 1
for (let _battlerIndex of moveOrder) {
const pokemon = field[_battlerIndex];
const command = this.scene.currentBattle.turnCommands[_battlerIndex];
if(command.command === Command.FIGHT) {
console.log(`${orderInTurn} : ${pokemon.name} - ${allMoves[command.move.move].name} - (${command.priority}, ${pokemon.getBattleStat(Stat.SPD)})`);
}
else {
console.log(`${orderInTurn} : ${pokemon.name} - ${command.command} - (${command.priority}, ${pokemon.getBattleStat(Stat.SPD)})`);
}
orderInTurn += 1;
}*/
/* Old Command Priority Comparison
moveOrder.sort((a, b) => {
const aCommand = this.scene.currentBattle.turnCommands[a];
const bCommand = this.scene.currentBattle.turnCommands[b];
@ -1957,13 +2008,13 @@ export class TurnStartPhase extends FieldPhase {
if (aPriority.value !== bPriority.value)
return aPriority.value < bPriority.value ? 1 : -1;
}
}
const aIndex = order.indexOf(a);
const bIndex = order.indexOf(b);
return aIndex < bIndex ? -1 : aIndex > bIndex ? 1 : 0;
});
}); */
for (let o of moveOrder) {