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.');
|
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.waitForTimeout(700);
|
||||||
await page.mouse.click(260, 300, { button: 'right' });
|
await page.mouse.click(260, 300, { button: 'right' });
|
||||||
await page.waitForTimeout(120);
|
await page.waitForTimeout(120);
|
||||||
|
|||||||
@@ -1106,6 +1106,11 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
this.centerCameraOnTile(unit.x, unit.y);
|
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 (this.phase === 'targeting' && this.selectedUnit) {
|
||||||
if (unit.hp > 0 && this.targetingAction) {
|
if (unit.hp > 0 && this.targetingAction) {
|
||||||
if (this.selectedUsable && this.selectedUsable.effect !== 'damage') {
|
if (this.selectedUsable && this.selectedUsable.effect !== 'damage') {
|
||||||
@@ -1214,6 +1219,7 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
|
|
||||||
const fromX = unit.x;
|
const fromX = unit.x;
|
||||||
const fromY = unit.y;
|
const fromY = unit.y;
|
||||||
|
const stayingInPlace = fromX === x && fromY === y;
|
||||||
unit.x = x;
|
unit.x = x;
|
||||||
unit.y = y;
|
unit.y = y;
|
||||||
this.pendingMove = { unit, fromX, fromY, toX: x, toY: 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 targetX = this.tileCenterX(x);
|
||||||
const targetY = this.tileCenterY(y);
|
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.showCommandMenu(unit, pointer?.x ?? targetX, pointer?.y ?? targetY);
|
||||||
this.renderUnitDetail(unit, '공격, 책략, 도구, 대기 중 하나를 선택하세요.\n우클릭하면 이동을 취소합니다.');
|
this.renderUnitDetail(unit, '공격, 책략, 도구, 대기 중 하나를 선택하세요.\n우클릭하면 이동을 취소합니다.');
|
||||||
}
|
}
|
||||||
@@ -1240,9 +1248,10 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
{ x: 0, y: 1 },
|
{ x: 0, y: 1 },
|
||||||
{ 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 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) {
|
while (queue.length > 0) {
|
||||||
queue.sort((a, b) => a.cost - b.cost);
|
queue.sort((a, b) => a.cost - b.cost);
|
||||||
@@ -1254,7 +1263,7 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
directions.forEach((direction) => {
|
directions.forEach((direction) => {
|
||||||
const nextX = current.x + direction.x;
|
const nextX = current.x + direction.x;
|
||||||
const nextY = current.y + direction.y;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1271,7 +1280,9 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
|
|
||||||
costs.set(key, nextCost);
|
costs.set(key, nextCost);
|
||||||
const tile = { x: nextX, y: nextY, cost: 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);
|
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);
|
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) {
|
private tileCenterX(x: number) {
|
||||||
return this.tileTopLeftX(x) + this.layout.tileSize / 2;
|
return this.tileTopLeftX(x) + this.layout.tileSize / 2;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user