Show terrain details on empty tile click

This commit is contained in:
2026-06-22 12:59:08 +09:00
parent 56dd248136
commit a6d8b453ee

View File

@@ -189,6 +189,16 @@ const factionLabels: Record<ActiveFaction, string> = {
enemy: '적군'
};
const terrainDisplayLabels: Record<TerrainType, string> = {
plain: '평지',
road: '길',
forest: '숲',
hill: '언덕',
village: '마을',
fort: '요새',
camp: '진영'
};
const mapMenuLabels: Partial<Record<MapMenuAction, string>> = {
endTurn: '턴 종료',
roster: '부대 일람',
@@ -248,6 +258,11 @@ export class BattleScene extends Phaser.Scene {
this.input.on('pointerdown', (pointer: Phaser.Input.Pointer) => {
if (pointer.rightButtonDown()) {
this.handleRightClick(pointer);
return;
}
if (pointer.leftButtonDown()) {
this.handleLeftClick(pointer);
}
});
this.installDebugHotkeys();
@@ -1050,6 +1065,26 @@ export class BattleScene extends Phaser.Scene {
this.hideMapMenu();
}
private handleLeftClick(pointer: Phaser.Input.Pointer) {
if (this.phase !== 'idle' || !this.isPointerOnEmptyMapTile(pointer)) {
return;
}
const tile = this.pointerToTile(pointer);
if (!tile) {
return;
}
this.selectedUnit = undefined;
this.pendingMove = undefined;
this.targetingAction = undefined;
this.clearMarkers();
this.hideCommandMenu();
this.hideTurnEndPrompt();
this.hideMapMenu();
this.renderTerrainDetail(tile.x, tile.y);
}
private isPointerOnEmptyMapTile(pointer: Phaser.Input.Pointer) {
const tile = this.pointerToTile(pointer);
if (!tile) {
@@ -2426,6 +2461,47 @@ export class BattleScene extends Phaser.Scene {
this.renderPanelMessage(message ?? '빈 맵에서 우클릭하면 전술 메뉴를 다시 열 수 있습니다.', left, top + 286, width);
}
private renderTerrainDetail(x: number, y: number) {
this.clearSidePanelContent();
const terrain = firstBattleMap.terrain[y][x];
const terrainRule = getTerrainRule(terrain);
const { panelX, panelY, panelWidth } = this.layout;
const left = panelX + 24;
const width = panelWidth - 48;
const top = panelY + 132;
const attackDefense = Math.floor(terrainRule.defenseBonus / 3);
const strategyDefense = Math.floor(terrainRule.defenseBonus / 4);
const itemDefense = Math.floor(terrainRule.defenseBonus / 5);
this.trackSideObject(this.add.text(left, top, '지형 정보', {
fontFamily: '"Malgun Gothic", "Noto Sans KR", sans-serif',
fontSize: '24px',
color: '#f2e3bf',
fontStyle: '700'
}));
this.renderSituationLine('좌표', `${x + 1}, ${y + 1}`, left, top + 48, width);
this.renderSituationLine('지형', terrainDisplayLabels[terrain], left, top + 92, width);
this.renderSituationLine('이동 비용', `${terrainRule.moveCost}`, left, top + 136, width);
this.renderSituationLine('방어 보정', this.formatSignedValue(terrainRule.defenseBonus), left, top + 180, width);
this.renderSituationLine('공격 방어', this.formatSignedValue(attackDefense), left, top + 224, width);
this.renderSituationLine('책략 저항', this.formatSignedValue(strategyDefense), left, top + 268, width);
this.renderSituationLine('도구 피해', this.formatSignedValue(itemDefense), left, top + 312, width);
const message =
terrainRule.defenseBonus > 0
? '이 지형에 있는 부대는 방어 보정으로 받는 피해가 줄어듭니다.'
: '이 지형은 기본 방어 보정이 없습니다.';
this.renderPanelMessage(message, left, top + 370, width, 66);
}
private formatSignedValue(value: number) {
if (value > 0) {
return `+${value}`;
}
return `${value}`;
}
private renderSituationLine(label: string, value: string, x: number, y: number, width: number) {
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 34, 0x101820, 0.86));
bg.setOrigin(0);