156 lines
4.8 KiB
TypeScript
156 lines
4.8 KiB
TypeScript
import { Pawn } from '../Pawn.js';
|
||
import log from '../log.js';
|
||
import { menuPanel, Renderable } from './UI.js';
|
||
import { Game } from '../Game.js';
|
||
import { ChopTreeTask } from '../tasks/ChopTreeTask.js';
|
||
import { progressbar, stats, barCache } from '../Progressbar.js';
|
||
import { Popup } from './Popup.js';
|
||
import mdns from '../multiplayer/mDNS.js';
|
||
import { GiftPopup } from './GiftPopup.js';
|
||
import { PawnDetails } from './PawnDetails.js';
|
||
import { defaultTheme, getTheme } from './Theme.js';
|
||
import { inspect } from 'util';
|
||
import PawnsView from './view/PawnsView.js';
|
||
import InventoryView from './view/InventoryView.js';
|
||
import MultiplayerView from './view/MultiplayerView.js';
|
||
|
||
// TODO extract View
|
||
export abstract class View implements Renderable, KeypressAcceptor {
|
||
abstract render(): void;
|
||
abstract keypress(key: {full: string}): void;
|
||
|
||
static PAWNS: View = new PawnsView();
|
||
static INVENTORY: View = new InventoryView();
|
||
static MULTIPLAYER: View = new MultiplayerView();
|
||
|
||
name: string
|
||
}
|
||
|
||
// TODO move KeypressAcceptor to ui something idk
|
||
export interface KeypressAcceptor {
|
||
keypress(key: {full: string}): void
|
||
}
|
||
|
||
export class Menu implements Renderable {
|
||
|
||
trees: number = 10;
|
||
view: View = View.PAWNS;
|
||
|
||
constructor() {
|
||
menuPanel.on('keypress', (evt, key) => {
|
||
log.info('keypress', key);
|
||
|
||
if (key.full === 'left') {
|
||
this.view = View[Object.keys(View)[Math.min(Math.max(Object.values(View).indexOf(this.view) - 1, 0), Object.keys(View).length - 1)]]
|
||
} else if (key.full === 'right') {
|
||
this.view = View[Object.keys(View)[Math.min(Math.max(Object.values(View).indexOf(this.view) + 1, 0), Object.keys(View).length - 1)]]
|
||
|
||
// debugging hotkeys
|
||
} else if (key.full === '1') {
|
||
Popup.show(inspect(stats));
|
||
} else if (key.full === 'z') {
|
||
Game.current.pawns.push(new Pawn());
|
||
} else if (key.full === 'x') {
|
||
Game.current.board.clear();
|
||
}
|
||
|
||
// if(this.view === View.PAWNS) {
|
||
// if (key.full === 'delete') {
|
||
// Game.current.removePawn(Game.current.selected);
|
||
// } else if (key.full === 'up') {
|
||
// Game.current.advanceSelection(-1);
|
||
// } else if (key.full === 'down') {
|
||
// Game.current.advanceSelection(1);
|
||
// } else if (key.full === 'enter') {
|
||
// new PawnDetails(Game.current.selected);
|
||
// }
|
||
// }
|
||
|
||
// if(this.view === View.MULTIPLAYER) {
|
||
// if (key.full === 'enter') {
|
||
// new GiftPopup(mdns.players[this.multiplayerSelected]);
|
||
// // mdns.players[this.multiplayerSelected].sendItem(null);
|
||
// } else if (key.full === 'up') {
|
||
// this.multiplayerSelected --;
|
||
// } else if (key.full === 'down') {
|
||
// this.multiplayerSelected ++;
|
||
// }
|
||
// }
|
||
|
||
Game.current.sync();
|
||
});
|
||
}
|
||
|
||
renderTopBar() {
|
||
const idlers = Game.current.pawns.filter(pawn => pawn.idle);
|
||
return ` ${Game.current.clock.render()}{|}${getTheme().normal(`Idle: ${idlers.length}`)} `;
|
||
}
|
||
|
||
renderPawns() {
|
||
return `${
|
||
Game.current.pawns.map(pawn => `${(function() {
|
||
const selected = pawn === Game.current.selected;
|
||
let str = '';
|
||
if(selected) {
|
||
str += ` ${getTheme().selected(` ❯ ${pawn.toString()}`)}{|}${pawn.status} \n`;
|
||
str += ` ${getTheme().normal('Energy')}{|}${progressbar(pawn.energy / 100, (menuPanel.width - 4) / 2)} \n`;
|
||
} else {
|
||
str += ` ${getTheme().normal(pawn.toString())}{|}${pawn.status} `;
|
||
}
|
||
return str;
|
||
})()}`).join('\n')
|
||
}`;
|
||
}
|
||
|
||
renderView() {
|
||
const colSpace = ((menuPanel.width - 2) / 2);
|
||
return `${
|
||
// ' '.repeat(colSpace - 20)
|
||
'{center}'
|
||
}${(() => {
|
||
return Object.values(View).map(view => {
|
||
if(view === this.view) {
|
||
return getTheme().tab.selected(` ${view} `);
|
||
} else {
|
||
return getTheme().tab.normal(` ${view} `);
|
||
}
|
||
}).join('');
|
||
})()}{/center}\n\n${(() => {
|
||
this.view.view.render();
|
||
})()}`
|
||
}
|
||
|
||
multiplayerSelected = 0;
|
||
|
||
renderMultiplayer() {
|
||
if(mdns.players.length === 0) return `{center}${getTheme().normal('No friends online')}{/center}`;
|
||
return mdns.players.map((player, i) => {
|
||
if(i === this.multiplayerSelected) return ' ' + getTheme().selected(' ❯ ' + player.toString());
|
||
else return ' ' + getTheme().normal(player.toString());
|
||
}).join('\n');
|
||
}
|
||
|
||
renderInv() {
|
||
return Game.current.inv.render();
|
||
}
|
||
|
||
renderTreesSubMenu() {
|
||
return [
|
||
`{center}Chop Trees`,
|
||
`{left} ${getTheme().hotkey('-=_+')}: ${this.trees}`,
|
||
`{left} ${getTheme().hotkey('enter')}: Create Task`,
|
||
`{left} ${getTheme().hotkey('escape')}: Cancel`
|
||
].join('\n');
|
||
}
|
||
|
||
render() {
|
||
const width = menuPanel.width - 2;
|
||
const hr = getTheme().normal('━'.repeat(width));
|
||
const content = [
|
||
this.renderTopBar(),
|
||
hr,
|
||
this.renderView(),
|
||
].join('\n');
|
||
menuPanel.setContent(content);
|
||
}
|
||
} |