Show terrain details on empty tile click
This commit is contained in:
@@ -189,6 +189,16 @@ const factionLabels: Record<ActiveFaction, string> = {
|
|||||||
enemy: '적군'
|
enemy: '적군'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const terrainDisplayLabels: Record<TerrainType, string> = {
|
||||||
|
plain: '평지',
|
||||||
|
road: '길',
|
||||||
|
forest: '숲',
|
||||||
|
hill: '언덕',
|
||||||
|
village: '마을',
|
||||||
|
fort: '요새',
|
||||||
|
camp: '진영'
|
||||||
|
};
|
||||||
|
|
||||||
const mapMenuLabels: Partial<Record<MapMenuAction, string>> = {
|
const mapMenuLabels: Partial<Record<MapMenuAction, string>> = {
|
||||||
endTurn: '턴 종료',
|
endTurn: '턴 종료',
|
||||||
roster: '부대 일람',
|
roster: '부대 일람',
|
||||||
@@ -248,6 +258,11 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
this.input.on('pointerdown', (pointer: Phaser.Input.Pointer) => {
|
this.input.on('pointerdown', (pointer: Phaser.Input.Pointer) => {
|
||||||
if (pointer.rightButtonDown()) {
|
if (pointer.rightButtonDown()) {
|
||||||
this.handleRightClick(pointer);
|
this.handleRightClick(pointer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointer.leftButtonDown()) {
|
||||||
|
this.handleLeftClick(pointer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.installDebugHotkeys();
|
this.installDebugHotkeys();
|
||||||
@@ -1050,6 +1065,26 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
this.hideMapMenu();
|
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) {
|
private isPointerOnEmptyMapTile(pointer: Phaser.Input.Pointer) {
|
||||||
const tile = this.pointerToTile(pointer);
|
const tile = this.pointerToTile(pointer);
|
||||||
if (!tile) {
|
if (!tile) {
|
||||||
@@ -2426,6 +2461,47 @@ export class BattleScene extends Phaser.Scene {
|
|||||||
this.renderPanelMessage(message ?? '빈 맵에서 우클릭하면 전술 메뉴를 다시 열 수 있습니다.', left, top + 286, width);
|
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) {
|
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));
|
const bg = this.trackSideObject(this.add.rectangle(x, y, width, 34, 0x101820, 0.86));
|
||||||
bg.setOrigin(0);
|
bg.setOrigin(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user