Skip to content

Commit

Permalink
[QoL] Highlight targets of multitarget moves instead of immediate exe…
Browse files Browse the repository at this point in the history
…cution (#2863)

* show targets for move targeting multiple pokemon

* dont allow selecting target if multiple

* fix targeting

* cleanup

* more cleanup

* only highlight targets is move is not status

* fix tests failing

* fix tests

* change "immediately" to "auto"

* nevermind just remove auto

* remove status move condition
  • Loading branch information
torranx authored Jul 11, 2024
1 parent 2f81bd5 commit aa90a9f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 41 deletions.
9 changes: 6 additions & 3 deletions src/phases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1973,6 +1973,9 @@ export class CommandPhase extends FieldPhase {
turnCommand.targets = [this.fieldIndex];
}
console.log(moveTargets, playerPokemon.name);
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
}
if (moveTargets.targets.length <= 1 || moveTargets.multiple) {
turnCommand.move.targets = moveTargets.targets;
} else if (playerPokemon.getTag(BattlerTagType.CHARGING) && playerPokemon.getMoveQueue().length >= 1) {
Expand Down Expand Up @@ -2222,13 +2225,13 @@ export class SelectTargetPhase extends PokemonPhase {

const turnCommand = this.scene.currentBattle.turnCommands[this.fieldIndex];
const move = turnCommand.move?.move;
this.scene.ui.setMode(Mode.TARGET_SELECT, this.fieldIndex, move, (cursor: integer) => {
this.scene.ui.setMode(Mode.TARGET_SELECT, this.fieldIndex, move, (targets: BattlerIndex[]) => {
this.scene.ui.setMode(Mode.MESSAGE);
if (cursor === -1) {
if (targets.length < 1) {
this.scene.currentBattle.turnCommands[this.fieldIndex] = null;
this.scene.unshiftPhase(new CommandPhase(this.scene, this.fieldIndex));
} else {
turnCommand.targets = [cursor];
turnCommand.targets = targets;
}
if (turnCommand.command === Command.BALL && this.fieldIndex) {
this.scene.currentBattle.turnCommands[this.fieldIndex - 1].skip = true;
Expand Down
12 changes: 11 additions & 1 deletion src/test/utils/gameManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
LoginPhase,
NewBattlePhase,
SelectStarterPhase,
TitlePhase, TurnInitPhase,
SelectTargetPhase,
TitlePhase, TurnEndPhase, TurnInitPhase,
TurnStartPhase,
} from "#app/phases";
import BattleScene from "#app/battle-scene.js";
Expand Down Expand Up @@ -170,6 +171,15 @@ export default class GameManager {
this.onNextPrompt("CommandPhase", Mode.FIGHT, () => {
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, movePosition, false);
});

// Confirm target selection if move is multi-target
this.onNextPrompt("SelectTargetPhase", Mode.TARGET_SELECT, () => {
const handler = this.scene.ui.getHandler() as TargetSelectUiHandler;
const move = (this.scene.getCurrentPhase() as SelectTargetPhase).getPokemon().getMoveset()[movePosition].getMove();
if (move.isMultiTarget()) {
handler.processInput(Button.ACTION);
}
}, () => this.isCurrentPhase(CommandPhase) || this.isCurrentPhase(TurnEndPhase));
}

/**
Expand Down
80 changes: 43 additions & 37 deletions src/ui/target-select-ui-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import * as Utils from "../utils";
import { getMoveTargets } from "../data/move";
import {Button} from "#enums/buttons";
import { Moves } from "#enums/moves";
import Pokemon from "#app/field/pokemon.js";

export type TargetSelectCallback = (cursor: integer) => void;
export type TargetSelectCallback = (targets: BattlerIndex[]) => void;

export default class TargetSelectUiHandler extends UiHandler {
private fieldIndex: integer;
private move: Moves;
private targetSelectCallback: TargetSelectCallback;

private isMultipleTargets: boolean = false;
private targets: BattlerIndex[];
private targetsHighlighted: Pokemon[];
private targetFlashTween: Phaser.Tweens.Tween;
private targetBattleInfoMoveTween: Phaser.Tweens.Tween;
private targetBattleInfoMoveTween: Phaser.Tweens.Tween[] = [];

constructor(scene: BattleScene) {
super(scene, Mode.TARGET_SELECT);
Expand All @@ -37,13 +40,15 @@ export default class TargetSelectUiHandler extends UiHandler {
this.move = args[1] as Moves;
this.targetSelectCallback = args[2] as TargetSelectCallback;

this.targets = getMoveTargets(this.scene.getPlayerField()[this.fieldIndex], this.move).targets;
const moveTargets = getMoveTargets(this.scene.getPlayerField()[this.fieldIndex], this.move);
this.targets = moveTargets.targets;
this.isMultipleTargets = moveTargets.multiple ?? false;

if (!this.targets.length) {
return false;
}

this.setCursor(this.targets.indexOf(this.cursor) > -1 ? this.cursor : this.targets[0]);
this.setCursor(this.targets.includes(this.cursor) ? this.cursor : this.targets[0]);

return true;
}
Expand All @@ -54,8 +59,11 @@ export default class TargetSelectUiHandler extends UiHandler {
let success = false;

if (button === Button.ACTION || button === Button.CANCEL) {
this.targetSelectCallback(button === Button.ACTION ? this.cursor : -1);
const targetIndexes: BattlerIndex[] = this.isMultipleTargets ? this.targets : [this.cursor];
this.targetSelectCallback(button === Button.ACTION ? targetIndexes : []);
success = true;
} else if (this.isMultipleTargets) {
success = false;
} else {
switch (button) {
case Button.UP:
Expand Down Expand Up @@ -89,73 +97,71 @@ export default class TargetSelectUiHandler extends UiHandler {
}

setCursor(cursor: integer): boolean {
const lastCursor = this.cursor;
const singleTarget = this.scene.getField()[cursor];
const multipleTargets = this.targets.map(index => this.scene.getField()[index]);

this.targetsHighlighted = this.isMultipleTargets ? multipleTargets : [ singleTarget ];

const ret = super.setCursor(cursor);

if (this.targetFlashTween) {
this.targetFlashTween.stop();
const lastTarget = this.scene.getField()[lastCursor];
if (lastTarget) {
lastTarget.setAlpha(1);
for (const pokemon of multipleTargets) {
pokemon.setAlpha(1);
}
}

const target = this.scene.getField()[cursor];

this.targetFlashTween = this.scene.tweens.add({
targets: [ target ],
targets: this.targetsHighlighted,
alpha: 0,
loop: -1,
duration: Utils.fixedInt(250),
ease: "Sine.easeIn",
yoyo: true,
onUpdate: t => {
if (target) {
for (const target of this.targetsHighlighted) {
target.setAlpha(t.getValue());
}
}
});

if (this.targetBattleInfoMoveTween) {
this.targetBattleInfoMoveTween.stop();
const lastTarget = this.scene.getField()[lastCursor];
if (lastTarget) {
lastTarget.getBattleInfo().resetY();
if (this.targetBattleInfoMoveTween.length >= 1) {
this.targetBattleInfoMoveTween.filter(t => t !== undefined).forEach(tween => tween.stop());
for (const pokemon of multipleTargets) {
pokemon.getBattleInfo().resetY();
}
}

const targetBattleInfo = target.getBattleInfo();

this.targetBattleInfoMoveTween = this.scene.tweens.add({
targets: [ targetBattleInfo ],
y: { start: targetBattleInfo.getBaseY(), to: targetBattleInfo.getBaseY() + 1 },
loop: -1,
duration: Utils.fixedInt(250),
ease: "Linear",
yoyo: true
const targetsBattleInfo = this.targetsHighlighted.map(target => target.getBattleInfo());

targetsBattleInfo.map(info => {
this.targetBattleInfoMoveTween.push(this.scene.tweens.add({
targets: [ info ],
y: { start: info.getBaseY(), to: info.getBaseY() + 1 },
loop: -1,
duration: Utils.fixedInt(250),
ease: "Linear",
yoyo: true
}));
});

return ret;
}

eraseCursor() {
const target = this.scene.getField()[this.cursor];
if (this.targetFlashTween) {
this.targetFlashTween.stop();
this.targetFlashTween = null;
}
if (target) {
target.setAlpha(1);
for (const pokemon of this.targetsHighlighted) {
pokemon.setAlpha(1);
}

const targetBattleInfo = target.getBattleInfo();
if (this.targetBattleInfoMoveTween) {
this.targetBattleInfoMoveTween.stop();
this.targetBattleInfoMoveTween = null;
if (this.targetBattleInfoMoveTween.length >= 1) {
this.targetBattleInfoMoveTween.filter(t => t !== undefined).forEach(tween => tween.stop());
this.targetBattleInfoMoveTween = [];
}
if (targetBattleInfo) {
targetBattleInfo.resetY();
for (const pokemon of this.targetsHighlighted) {
pokemon.getBattleInfo().resetY();
}
}

Expand Down

0 comments on commit aa90a9f

Please sign in to comment.