Fix stand-still commands and ally pathing
This commit is contained in:
@@ -105,6 +105,76 @@ try {
|
||||
throw new Error('Expected all unit action textures to be loaded.');
|
||||
}
|
||||
|
||||
const movementBlockingState = await page.evaluate(() => {
|
||||
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');
|
||||
const state = window.__HEROS_DEBUG__?.battle();
|
||||
const liuBei = state?.units?.find((unit) => unit.id === 'liu-bei');
|
||||
const guanYu = state?.units?.find((unit) => unit.id === 'guan-yu');
|
||||
const enemy = state?.units?.find((unit) => unit.faction === 'enemy');
|
||||
|
||||
if (!scene || !liuBei || !guanYu || !enemy) {
|
||||
throw new Error('Expected battle scene and movement test units.');
|
||||
}
|
||||
|
||||
return {
|
||||
allyBlocksPath: scene.isMovementBlocked(liuBei, guanYu.x, guanYu.y),
|
||||
enemyBlocksPath: scene.isMovementBlocked(liuBei, enemy.x, enemy.y),
|
||||
allyStopTileReachable: scene.reachableTiles(liuBei).some((tile) => tile.x === guanYu.x && tile.y === guanYu.y)
|
||||
};
|
||||
});
|
||||
if (
|
||||
movementBlockingState.allyBlocksPath ||
|
||||
!movementBlockingState.enemyBlocksPath ||
|
||||
movementBlockingState.allyStopTileReachable
|
||||
) {
|
||||
throw new Error(`Expected allies to be passable path blockers only as stop tiles, and enemies to block movement: ${JSON.stringify(movementBlockingState)}`);
|
||||
}
|
||||
|
||||
const liuBeiScreen = await page.evaluate(() => {
|
||||
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');
|
||||
const state = window.__HEROS_DEBUG__?.battle();
|
||||
const liuBei = state?.units?.find((unit) => unit.id === 'liu-bei');
|
||||
|
||||
if (!scene || !liuBei) {
|
||||
throw new Error('Expected Liu Bei and battle scene for stand-still command test.');
|
||||
}
|
||||
|
||||
return {
|
||||
x: scene.tileCenterX(liuBei.x),
|
||||
y: scene.tileCenterY(liuBei.y)
|
||||
};
|
||||
});
|
||||
await page.mouse.click(liuBeiScreen.x, liuBeiScreen.y);
|
||||
await page.waitForTimeout(140);
|
||||
await page.mouse.click(liuBeiScreen.x, liuBeiScreen.y);
|
||||
await page.waitForTimeout(180);
|
||||
|
||||
const standStillCommandState = await page.evaluate(() => window.__HEROS_DEBUG__?.battle());
|
||||
if (
|
||||
standStillCommandState?.phase !== 'command' ||
|
||||
standStillCommandState.selectedUnitId !== 'liu-bei' ||
|
||||
standStillCommandState.pendingMove?.unitId !== 'liu-bei' ||
|
||||
standStillCommandState.pendingMove.from.x !== standStillCommandState.pendingMove.to.x ||
|
||||
standStillCommandState.pendingMove.from.y !== standStillCommandState.pendingMove.to.y
|
||||
) {
|
||||
throw new Error(`Expected Liu Bei to open commands without moving: ${JSON.stringify(standStillCommandState)}`);
|
||||
}
|
||||
|
||||
await page.evaluate(() => {
|
||||
const scene = window.__HEROS_GAME__?.scene.getScene('BattleScene');
|
||||
if (!scene) {
|
||||
return;
|
||||
}
|
||||
scene.selectedUnit = undefined;
|
||||
scene.pendingMove = undefined;
|
||||
scene.targetingAction = undefined;
|
||||
scene.selectedUsable = undefined;
|
||||
scene.phase = 'idle';
|
||||
scene.clearMarkers();
|
||||
scene.hideCommandMenu();
|
||||
scene.hideMapMenu();
|
||||
});
|
||||
|
||||
await page.waitForTimeout(700);
|
||||
await page.mouse.click(260, 300, { button: 'right' });
|
||||
await page.waitForTimeout(120);
|
||||
|
||||
@@ -1106,6 +1106,11 @@ export class BattleScene extends Phaser.Scene {
|
||||
this.centerCameraOnTile(unit.x, unit.y);
|
||||
}
|
||||
|
||||
if (this.phase === 'moving' && this.selectedUnit?.id === unit.id) {
|
||||
this.moveSelectedUnit(unit.x, unit.y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.phase === 'targeting' && this.selectedUnit) {
|
||||
if (unit.hp > 0 && this.targetingAction) {
|
||||
if (this.selectedUsable && this.selectedUsable.effect !== 'damage') {
|
||||
@@ -1214,6 +1219,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
const fromX = unit.x;
|
||||
const fromY = unit.y;
|
||||
const stayingInPlace = fromX === x && fromY === y;
|
||||
unit.x = x;
|
||||
unit.y = y;
|
||||
this.pendingMove = { unit, fromX, fromY, toX: x, toY: y };
|
||||
@@ -1224,7 +1230,9 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
const targetX = this.tileCenterX(x);
|
||||
const targetY = this.tileCenterY(y);
|
||||
this.moveUnitView(unit, x, y, view);
|
||||
if (!stayingInPlace) {
|
||||
this.moveUnitView(unit, x, y, view);
|
||||
}
|
||||
this.showCommandMenu(unit, pointer?.x ?? targetX, pointer?.y ?? targetY);
|
||||
this.renderUnitDetail(unit, '공격, 책략, 도구, 대기 중 하나를 선택하세요.\n우클릭하면 이동을 취소합니다.');
|
||||
}
|
||||
@@ -1240,9 +1248,10 @@ export class BattleScene extends Phaser.Scene {
|
||||
{ x: 0, y: 1 },
|
||||
{ x: 0, y: -1 }
|
||||
];
|
||||
const costs = new Map<string, number>([[this.tileKey(unit.x, unit.y), 0]]);
|
||||
const originKey = this.tileKey(unit.x, unit.y);
|
||||
const costs = new Map<string, number>([[originKey, 0]]);
|
||||
const queue = [{ x: unit.x, y: unit.y, cost: 0 }];
|
||||
const reachable = new Map<string, { x: number; y: number; cost: number }>();
|
||||
const reachable = new Map<string, { x: number; y: number; cost: number }>([[originKey, { x: unit.x, y: unit.y, cost: 0 }]]);
|
||||
|
||||
while (queue.length > 0) {
|
||||
queue.sort((a, b) => a.cost - b.cost);
|
||||
@@ -1254,7 +1263,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
directions.forEach((direction) => {
|
||||
const nextX = current.x + direction.x;
|
||||
const nextY = current.y + direction.y;
|
||||
if (!this.isInBounds(nextX, nextY) || this.isOccupied(nextX, nextY, unit.id)) {
|
||||
if (!this.isInBounds(nextX, nextY) || this.isMovementBlocked(unit, nextX, nextY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1271,7 +1280,9 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
costs.set(key, nextCost);
|
||||
const tile = { x: nextX, y: nextY, cost: nextCost };
|
||||
reachable.set(key, tile);
|
||||
if (!this.isOccupied(nextX, nextY, unit.id)) {
|
||||
reachable.set(key, tile);
|
||||
}
|
||||
queue.push(tile);
|
||||
});
|
||||
}
|
||||
@@ -1300,6 +1311,15 @@ export class BattleScene extends Phaser.Scene {
|
||||
return battleUnits.some((unit) => unit.id !== exceptUnitId && unit.hp > 0 && unit.x === x && unit.y === y);
|
||||
}
|
||||
|
||||
private isMovementBlocked(unit: UnitData, x: number, y: number) {
|
||||
return battleUnits.some((other) => {
|
||||
if (other.id === unit.id || other.hp <= 0 || other.x !== x || other.y !== y) {
|
||||
return false;
|
||||
}
|
||||
return other.faction !== unit.faction;
|
||||
});
|
||||
}
|
||||
|
||||
private tileCenterX(x: number) {
|
||||
return this.tileTopLeftX(x) + this.layout.tileSize / 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user