finally fixed colors in blessed!
parent
3c6986acfe
commit
8e38189560
211
src/Pawn.ts
211
src/Pawn.ts
|
|
@ -1,6 +1,5 @@
|
||||||
import { Serializable } from 'frigid';
|
import { Serializable } from 'frigid';
|
||||||
import faker from 'faker';
|
import faker from 'faker';
|
||||||
import chalk from 'chalk';
|
|
||||||
import log from './log.js';
|
import log from './log.js';
|
||||||
import { Task } from './tasks/Task.js';
|
import { Task } from './tasks/Task.js';
|
||||||
import Time, { Tickable } from './Time.js';
|
import Time, { Tickable } from './Time.js';
|
||||||
|
|
@ -10,13 +9,13 @@ import { render } from './ui/UI.js';
|
||||||
import { Memory } from './Memory.js';
|
import { Memory } from './Memory.js';
|
||||||
|
|
||||||
const LABORS = {
|
const LABORS = {
|
||||||
CUT_TREE: Symbol('CUT_TREE'),
|
CUT_TREE: Symbol('CUT_TREE'),
|
||||||
MINING: Symbol('CUT_TREE'),
|
MINING: Symbol('CUT_TREE'),
|
||||||
}
|
}
|
||||||
|
|
||||||
const SKILLS = {
|
const SKILLS = {
|
||||||
PICKAXE: Symbol('PICKAXE'),
|
PICKAXE: Symbol('PICKAXE'),
|
||||||
HATCHET: Symbol('HATCHET')
|
HATCHET: Symbol('HATCHET')
|
||||||
}
|
}
|
||||||
|
|
||||||
// const STATUS = {
|
// const STATUS = {
|
||||||
|
|
@ -26,121 +25,121 @@ const SKILLS = {
|
||||||
const energyScale = 0.1;
|
const energyScale = 0.1;
|
||||||
|
|
||||||
export class Pawn extends Serializable implements Tickable {
|
export class Pawn extends Serializable implements Tickable {
|
||||||
name: {
|
name: {
|
||||||
first: string,
|
first: string,
|
||||||
last: string
|
last: string
|
||||||
};
|
};
|
||||||
job: Task;
|
job: Task;
|
||||||
awake: boolean;
|
awake: boolean;
|
||||||
sex: number;
|
sex: number;
|
||||||
|
|
||||||
energy: number;
|
energy: number;
|
||||||
fun: number;
|
fun: number;
|
||||||
|
|
||||||
age: number;
|
age: number;
|
||||||
|
|
||||||
memories: Memory[];
|
memories: Memory[];
|
||||||
|
|
||||||
async tick() {
|
async tick() {
|
||||||
this.age ++;
|
this.age ++;
|
||||||
|
|
||||||
this.energy -= energyScale;
|
this.energy -= energyScale;
|
||||||
|
|
||||||
if(this.awake === false) {
|
if(this.awake === false) {
|
||||||
this.energy += energyScale * 4;
|
this.energy += energyScale * 4;
|
||||||
if(this.energy >= 100) {
|
if(this.energy >= 100) {
|
||||||
this.awake = true;
|
this.awake = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(this.job) {
|
if(this.job) {
|
||||||
this.job.doWork(1, this);
|
this.job.doWork(1, this);
|
||||||
this.energy -= energyScale;
|
this.energy -= energyScale;
|
||||||
if(this.job?.completed) {
|
if(this.job?.completed) {
|
||||||
this.stopWorking();
|
this.stopWorking();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const inactive = Game.current.board.tasks.filter(task => {
|
const inactive = Game.current.board.tasks.filter(task => {
|
||||||
return task.worker === null;
|
return task.worker === null;
|
||||||
});
|
});
|
||||||
if(inactive.length > 0) {
|
if(inactive.length > 0) {
|
||||||
const task = inactive[0];
|
const task = inactive[0];
|
||||||
// const task = inactive[Math.floor(Math.random() * inactive.length)];
|
// const task = inactive[Math.floor(Math.random() * inactive.length)];
|
||||||
this.assignJob(task);
|
this.assignJob(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(this.energy <= 0) {
|
if(this.energy <= 0) {
|
||||||
this.stopWorking();
|
this.stopWorking();
|
||||||
this.awake = false;
|
this.awake = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get idle() {
|
get idle() {
|
||||||
return !this.job && this.awake;
|
return !this.job && this.awake;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctor() {
|
ctor() {
|
||||||
log.info('Pawn::ctor')
|
log.info('Pawn::ctor')
|
||||||
this.name ??= {
|
this.name ??= {
|
||||||
first: faker.name.firstName(),
|
first: faker.name.firstName(),
|
||||||
last: faker.name.lastName()
|
last: faker.name.lastName()
|
||||||
};
|
};
|
||||||
if(!this.sex) {
|
if(!this.sex) {
|
||||||
this.sex = Math.round(Math.random());
|
this.sex = Math.round(Math.random());
|
||||||
this.name.first = faker.name.firstName(this.sex);
|
this.name.first = faker.name.firstName(this.sex);
|
||||||
}
|
}
|
||||||
this.awake ??= true;
|
this.awake ??= true;
|
||||||
this.energy ??= 100;
|
this.energy ??= 100;
|
||||||
this.memories ??= [];
|
this.memories ??= [];
|
||||||
if(!this.age) {
|
if(!this.age) {
|
||||||
this.age = Math.floor(525600 * (16 + Math.random() * 9));
|
this.age = Math.floor(525600 * (16 + Math.random() * 9));
|
||||||
this.memories.push({
|
this.memories.push({
|
||||||
type: "birth",
|
type: "birth",
|
||||||
location: Game.current.name,
|
location: Game.current.name,
|
||||||
time: {
|
time: {
|
||||||
age: 0,
|
age: 0,
|
||||||
locale: new Time(Game.current.clock.stamp - this.age).toString()
|
locale: new Time(Game.current.clock.stamp - this.age).toString()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(this.job?.completed) {
|
if(this.job?.completed) {
|
||||||
this.stopWorking();
|
this.stopWorking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stopWorking() {
|
stopWorking() {
|
||||||
if(this.job) {
|
if(this.job) {
|
||||||
this.job.stopJob();
|
this.job.stopJob();
|
||||||
this.job = null;
|
this.job = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assignJob(task: Task) {
|
assignJob(task: Task) {
|
||||||
this.job?.stopJob()
|
this.job?.stopJob()
|
||||||
this.job = task;
|
this.job = task;
|
||||||
this.job.claim(this);
|
this.job.claim(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get status() {
|
get status() {
|
||||||
if(this.job) {
|
if(this.job) {
|
||||||
return this.job.status;
|
return this.job.status;
|
||||||
} else {
|
} else {
|
||||||
return this.awake ? chalk.bold.black('IDLE') : chalk.blue('RESTING')
|
return this.awake ? chalk.bold.black('IDLE') : chalk.blue('RESTING')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static serializationDependencies() {
|
static serializationDependencies() {
|
||||||
return [Task, ChopTreeTask]
|
return [Task, ChopTreeTask]
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
if(this.name) {
|
if(this.name) {
|
||||||
return this.name.first + ' ' + this.name.last;
|
return this.name.first + ' ' + this.name.last;
|
||||||
} else {
|
} else {
|
||||||
return '[Object Pawn]';
|
return '[Object Pawn]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
317
src/Time.ts
317
src/Time.ts
|
|
@ -1,197 +1,198 @@
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { Serializable } from "frigid";
|
import { Serializable } from "frigid";
|
||||||
import { isThisTypeNode } from "typescript";
|
|
||||||
import log from "./log.js";
|
|
||||||
import { getTheme } from "./ui/Theme.js";
|
import { getTheme } from "./ui/Theme.js";
|
||||||
import { Renderable } from "./ui/UI.js";
|
import { Renderable } from "./ui/UI.js";
|
||||||
|
|
||||||
|
type AbbreviatedMonthName = string;
|
||||||
|
|
||||||
|
|
||||||
const daysInMonth = [
|
const daysInMonth = [
|
||||||
31, 28, 31,
|
31, 28, 31,
|
||||||
30, 31, 30,
|
30, 31, 30,
|
||||||
31, 31, 30,
|
31, 31, 30,
|
||||||
31, 30, 31
|
31, 30, 31
|
||||||
];
|
];
|
||||||
|
|
||||||
const months = [
|
const months: AbbreviatedMonthName[] = [
|
||||||
'Jan', 'Feb', 'Mar',
|
'Jan', 'Feb', 'Mar',
|
||||||
'Apr', 'May', 'Jun',
|
'Apr', 'May', 'Jun',
|
||||||
'Jul', 'Aug', 'Sep',
|
'Jul', 'Aug', 'Sep',
|
||||||
'Oct', 'Nov', 'Dec'
|
'Oct', 'Nov', 'Dec'
|
||||||
]
|
]
|
||||||
|
|
||||||
export default class Time extends Serializable implements Renderable {
|
export default class Time extends Serializable implements Renderable {
|
||||||
rate: number;
|
rate: number;
|
||||||
paused = true;
|
paused = true;
|
||||||
|
|
||||||
thing: Tickable;
|
thing: Tickable;
|
||||||
|
|
||||||
year: number;
|
year: number;
|
||||||
month: number;
|
month: number;
|
||||||
day: number;
|
day: number;
|
||||||
hour: number;
|
hour: number;
|
||||||
minute: number;
|
minute: number;
|
||||||
|
|
||||||
constructor(timestamp: number = 0) {
|
constructor(timestamp: number = 0) {
|
||||||
super();
|
super();
|
||||||
this.minute = timestamp;
|
this.minute = timestamp;
|
||||||
this.normalize();
|
this.normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
asAge() {
|
asAge() {
|
||||||
if(this.year > 1) {
|
if(this.year > 1) {
|
||||||
return this.year + ' years old';
|
return this.year + ' years old';
|
||||||
} else {
|
} else {
|
||||||
if(this.month > 2) {
|
if(this.month > 2) {
|
||||||
return this.month + ' months old';
|
return this.month + ' months old';
|
||||||
} else {
|
} else {
|
||||||
if(this.day > 1) {
|
if(this.day > 1) {
|
||||||
return this.day + ' days old';
|
return this.day + ' days old';
|
||||||
} else if(this.day === 1) {
|
} else if(this.day === 1) {
|
||||||
return '1 day old';
|
return '1 day old';
|
||||||
} else {
|
} else {
|
||||||
return 'newborn';
|
return 'newborn';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const sym = (this.hour >= 6 && this.hour < 20) ?
|
const sym = (this.hour >= 6 && this.hour < 20) ?
|
||||||
chalk.ansi256(226).bgAnsi256(27)(' ⬤ ') :
|
chalk.ansi256(226).bgAnsi256(27)(' ☀ ') :
|
||||||
chalk.ansi256(254).bgAnsi256(17)(' ☾ ')
|
chalk.ansi256(254).bgAnsi256(17)(' ☾ ')
|
||||||
|
|
||||||
return `${sym} ${
|
return `${sym} ${
|
||||||
getTheme().normal(`${
|
getTheme().normal(`${
|
||||||
this.hour.toString().padStart(2, ' ')
|
this.hour.toString().padStart(2, ' ')
|
||||||
}:${
|
}:${
|
||||||
this.minute.toString().padStart(2, '0')
|
this.minute.toString().padStart(2, '0')
|
||||||
} ${
|
} ${
|
||||||
months[this.month]
|
months[this.month]
|
||||||
} ${
|
} ${
|
||||||
this.day + 1
|
this.day + 1
|
||||||
}, ${
|
}, ${
|
||||||
this.normalizedYear
|
this.normalizedYear
|
||||||
}`)
|
}`)
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
// return '☾' || '☼';
|
// return '☾' || '☼';
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
return `${this.hour}:${this.minute.toString().padStart(2, '0')} ${months[this.month]} ${this.day + 1}, ${this.normalizedYear}`
|
return `${this.hour}:${this.minute.toString().padStart(2, '0')} ${months[this.month]} ${this.day + 1}, ${this.normalizedYear}`
|
||||||
}
|
}
|
||||||
|
|
||||||
ctor() {
|
ctor() {
|
||||||
this.rate = 60;
|
this.rate = 60;
|
||||||
this.minute ??= 0;
|
this.minute ??= 0;
|
||||||
this.hour ??= 0;
|
this.hour ??= 0;
|
||||||
this.day ??= 0;
|
this.day ??= 0;
|
||||||
this.month ??= 0;
|
this.month ??= 0;
|
||||||
this.year ??= 0;
|
this.year ??= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get stamp() {
|
get stamp() {
|
||||||
let minute = this.minute;
|
let minute = this.minute;
|
||||||
let hour = this.hour;
|
let hour = this.hour;
|
||||||
let day = this.day;
|
let day = this.day;
|
||||||
let month = this.month;
|
let month = this.month;
|
||||||
let year = this.year;
|
let year = this.year;
|
||||||
|
|
||||||
const daysInYear = daysInMonth.reduce((a, b) => a+b, 0);
|
const daysInYear = daysInMonth.reduce((a, b) => a+b, 0);
|
||||||
|
|
||||||
day += daysInYear * year;
|
day += daysInYear * year;
|
||||||
year = 0;
|
year = 0;
|
||||||
while(month > 0) {
|
while(month > 0) {
|
||||||
day += daysInMonth[month];
|
day += daysInMonth[month];
|
||||||
month --;
|
month --;
|
||||||
}
|
}
|
||||||
|
|
||||||
hour += day * 24;
|
hour += day * 24;
|
||||||
day = 0;
|
day = 0;
|
||||||
|
|
||||||
minute += hour * 60;
|
minute += hour * 60;
|
||||||
hour = 0;
|
hour = 0;
|
||||||
|
|
||||||
return minute;
|
return minute;
|
||||||
}
|
}
|
||||||
|
|
||||||
pause() {
|
pause() {
|
||||||
this.paused = true;
|
this.paused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
this.paused = false;
|
this.paused = false;
|
||||||
setTimeout(this.doTick.bind(this), 0);
|
setTimeout(this.doTick.bind(this), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
advanceTime(minutes) {
|
advanceTime(minutes) {
|
||||||
this.minute ++;
|
this.minute ++;
|
||||||
this.normalize()
|
this.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
get normalizedYear() {
|
get normalizedYear() {
|
||||||
if(this.year >= 0) {
|
if(this.year >= 0) {
|
||||||
return (this.year + 1).toString().padStart(4, '0') + ' CE';
|
return (this.year + 1).toString().padStart(4, '0') + ' CE';
|
||||||
} else {
|
} else {
|
||||||
return Math.abs(this.year).toString().padStart(4, '0') + ' BCE';
|
return Math.abs(this.year).toString().padStart(4, '0') + ' BCE';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
normalize() {
|
normalize() {
|
||||||
while(this.minute >= 60) {
|
while(this.minute >= 60) {
|
||||||
this.minute -= 60;
|
this.minute -= 60;
|
||||||
this.hour ++;
|
this.hour ++;
|
||||||
}
|
}
|
||||||
while(this.minute < 0) {
|
while(this.minute < 0) {
|
||||||
this.minute += 60;
|
this.minute += 60;
|
||||||
this.hour --;
|
this.hour --;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(this.hour >= 24) {
|
while(this.hour >= 24) {
|
||||||
this.hour -= 24;
|
this.hour -= 24;
|
||||||
this.day ++;
|
this.day ++;
|
||||||
}
|
}
|
||||||
while(this.hour < 0) {
|
while(this.hour < 0) {
|
||||||
this.hour += 24;
|
this.hour += 24;
|
||||||
this.day --;
|
this.day --;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(this.day < 0) {
|
while(this.day < 0) {
|
||||||
this.day += daysInMonth[
|
this.day += daysInMonth[
|
||||||
((this.month % months.length) + months.length) % months.length
|
((this.month % months.length) + months.length) % months.length
|
||||||
];
|
];
|
||||||
this.month --;
|
this.month --;
|
||||||
}
|
}
|
||||||
while(this.day >= daysInMonth[this.month % months.length]) {
|
while(this.day >= daysInMonth[this.month % months.length]) {
|
||||||
this.day -= daysInMonth[this.month % months.length];
|
this.day -= daysInMonth[this.month % months.length];
|
||||||
this.month ++;
|
this.month ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(this.month >= 12) {
|
while(this.month >= 12) {
|
||||||
this.month -= 12;
|
this.month -= 12;
|
||||||
this.year ++;
|
this.year ++;
|
||||||
}
|
}
|
||||||
while(this.month < 0) {
|
while(this.month < 0) {
|
||||||
this.month += 12;
|
this.month += 12;
|
||||||
this.year --;
|
this.year --;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async doTick() {
|
async doTick() {
|
||||||
this.advanceTime(1);
|
this.advanceTime(1);
|
||||||
const timeout = 1000 / this.rate;
|
const timeout = 1000 / this.rate;
|
||||||
const start = new Date().getTime();
|
const start = new Date().getTime();
|
||||||
if(this.thing) {
|
if(this.thing) {
|
||||||
await this.thing.tick();
|
await this.thing.tick();
|
||||||
}
|
}
|
||||||
const elapsed = new Date().getTime() - start;
|
const elapsed = new Date().getTime() - start;
|
||||||
const wait = Math.max(timeout - elapsed, 0);
|
const wait = Math.max(timeout - elapsed, 0);
|
||||||
if(this.paused) return;
|
if(this.paused) return;
|
||||||
setTimeout(this.doTick.bind(this), wait)
|
setTimeout(this.doTick.bind(this), wait)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface Tickable {
|
export interface Tickable {
|
||||||
tick: () => Promise<void>
|
tick: () => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
@ -2,29 +2,17 @@ import { Pawn } from '../Pawn.js';
|
||||||
import log from '../log.js';
|
import log from '../log.js';
|
||||||
import { menuPanel, Renderable } from './UI.js';
|
import { menuPanel, Renderable } from './UI.js';
|
||||||
import { Game } from '../Game.js';
|
import { Game } from '../Game.js';
|
||||||
import { ChopTreeTask } from '../tasks/ChopTreeTask.js';
|
import { progressbar, stats } from '../Progressbar.js';
|
||||||
import { progressbar, stats, barCache } from '../Progressbar.js';
|
|
||||||
import { Popup } from './Popup.js';
|
import { Popup } from './Popup.js';
|
||||||
import mdns from '../multiplayer/mDNS.js';
|
import mdns from '../multiplayer/mDNS.js';
|
||||||
import { GiftPopup } from './GiftPopup.js';
|
import { getTheme } from './Theme.js';
|
||||||
import { PawnDetails } from './PawnDetails.js';
|
|
||||||
import { defaultTheme, getTheme } from './Theme.js';
|
|
||||||
import { inspect } from 'util';
|
import { inspect } from 'util';
|
||||||
import PawnsView from './view/PawnsView.js';
|
import PawnsView from './view/PawnsView.js';
|
||||||
import InventoryView from './view/InventoryView.js';
|
import InventoryView from './view/InventoryView.js';
|
||||||
import MultiplayerView from './view/MultiplayerView.js';
|
import MultiplayerView from './view/MultiplayerView.js';
|
||||||
|
import { View } from './View.js';
|
||||||
|
|
||||||
// TODO extract View
|
const clamp = (min, max, value) => Math.min(Math.max(value, min), max);
|
||||||
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
|
// TODO move KeypressAcceptor to ui something idk
|
||||||
export interface KeypressAcceptor {
|
export interface KeypressAcceptor {
|
||||||
|
|
@ -34,16 +22,35 @@ export interface KeypressAcceptor {
|
||||||
export class Menu implements Renderable {
|
export class Menu implements Renderable {
|
||||||
|
|
||||||
trees: number = 10;
|
trees: number = 10;
|
||||||
view: View = View.PAWNS;
|
viewIndex: number = 0;
|
||||||
|
views: View[] = [
|
||||||
|
new PawnsView(),
|
||||||
|
new InventoryView(),
|
||||||
|
new MultiplayerView()
|
||||||
|
]
|
||||||
|
|
||||||
|
get view() {
|
||||||
|
return this.views[this.viewIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
advanceView() {
|
||||||
|
this.viewIndex ++;
|
||||||
|
this.viewIndex = clamp(0, this.views.length - 1, this.viewIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
regressView() {
|
||||||
|
this.viewIndex --;
|
||||||
|
this.viewIndex = clamp(0, this.views.length - 1, this.viewIndex);
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
menuPanel.on('keypress', (evt, key) => {
|
menuPanel.on('keypress', (evt, key) => {
|
||||||
log.info('keypress', key);
|
log.info('keypress', key);
|
||||||
|
|
||||||
if (key.full === 'left') {
|
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)]]
|
this.regressView();
|
||||||
} else if (key.full === 'right') {
|
} 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)]]
|
this.advanceView();
|
||||||
|
|
||||||
// debugging hotkeys
|
// debugging hotkeys
|
||||||
} else if (key.full === '1') {
|
} else if (key.full === '1') {
|
||||||
|
|
@ -116,7 +123,7 @@ export class Menu implements Renderable {
|
||||||
}
|
}
|
||||||
}).join('');
|
}).join('');
|
||||||
})()}{/center}\n\n${(() => {
|
})()}{/center}\n\n${(() => {
|
||||||
this.view.view.render();
|
this.view.render();
|
||||||
})()}`
|
})()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,15 @@ export class Popup {
|
||||||
this.box = blessed.box({
|
this.box = blessed.box({
|
||||||
top: 'center',
|
top: 'center',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
width: 'shrink',
|
width: '100%',
|
||||||
height: 'shrink',
|
height: 'shrink',
|
||||||
content: getTheme().normal(content) + `\n\n{|}` + getTheme().hotkey('enter') + getTheme().normal(`: Okay `),
|
// content: getTheme().normal(content) + `\n\n{|}` + getTheme().hotkey('enter') + getTheme().normal(`: Okay `),
|
||||||
tags: true,
|
tags: true,
|
||||||
...boxStyle(),
|
...boxStyle(),
|
||||||
});
|
});
|
||||||
|
let stuff = '';
|
||||||
|
for(let i = 16; i < 232; i ++) stuff += chalk.bgAnsi256(i).black(` ${i.toString().padStart(3, ' ')} ${(i-15)%18===0?'\n':''}`)
|
||||||
|
this.box.setContent(stuff)
|
||||||
this.box.on('keypress', (evt, key) => {
|
this.box.on('keypress', (evt, key) => {
|
||||||
if(key.full === 'escape' || key.full === 'enter') {
|
if(key.full === 'escape' || key.full === 'enter') {
|
||||||
Game.current.clock.start();
|
Game.current.clock.start();
|
||||||
|
|
|
||||||
136
src/ui/Theme.ts
136
src/ui/Theme.ts
|
|
@ -1,77 +1,89 @@
|
||||||
import chalk from "chalk";
|
// blessed doesnt know QUITE how to deal with 16m color modes
|
||||||
|
// it will always downsample them to 256. which is fine, but
|
||||||
|
// blessed's algorithm sucks, and comes out with incorrect
|
||||||
|
// mappings for certain colors. Instead of dealing with that,
|
||||||
|
// here, we simply tell chalk to always output ansi256 codes
|
||||||
|
// instead of upsampling them to 16m codes.
|
||||||
|
import chalk from 'chalk';
|
||||||
|
chalk.level = 2;
|
||||||
|
|
||||||
type StyleFunction = (text: string) => string;
|
type StyleFunction = (text: string) => string;
|
||||||
|
|
||||||
export type Theme = {
|
export type Theme = {
|
||||||
header: StyleFunction,
|
header: StyleFunction,
|
||||||
subheader: StyleFunction,
|
subheader: StyleFunction,
|
||||||
normal: StyleFunction,
|
normal: StyleFunction,
|
||||||
selected: StyleFunction,
|
selected: StyleFunction,
|
||||||
hotkey: StyleFunction,
|
hotkey: StyleFunction,
|
||||||
tab: {
|
tab: {
|
||||||
normal: StyleFunction,
|
normal: StyleFunction,
|
||||||
selected: StyleFunction
|
selected: StyleFunction
|
||||||
},
|
},
|
||||||
border: {
|
border: {
|
||||||
focused: string,
|
focused: string,
|
||||||
normal: string
|
normal: string
|
||||||
},
|
},
|
||||||
progressBar: {
|
progressBar: {
|
||||||
indicator: {
|
indicator: {
|
||||||
critical: StyleFunction,
|
critical: StyleFunction,
|
||||||
warning: StyleFunction,
|
warning: StyleFunction,
|
||||||
normal: StyleFunction,
|
normal: StyleFunction,
|
||||||
excellent: StyleFunction,
|
excellent: StyleFunction,
|
||||||
buckets: [number, number, number]
|
buckets: [number, number, number]
|
||||||
},
|
},
|
||||||
normal: StyleFunction
|
normal: StyleFunction
|
||||||
}
|
},
|
||||||
|
status: {
|
||||||
|
idle: StyleFunction,
|
||||||
|
self: StyleFunction,
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const defaultTheme: Theme = {
|
export const defaultTheme: Theme = {
|
||||||
header: chalk.ansi256(255).bold,
|
header: chalk.ansi256(255).bold,
|
||||||
subheader: chalk.ansi256(243).bold,
|
subheader: chalk.ansi256(243).bold,
|
||||||
normal: chalk.ansi256(243),
|
normal: chalk.ansi256(243),
|
||||||
selected: chalk.ansi256(250),
|
selected: chalk.ansi256(250),
|
||||||
hotkey: chalk.ansi256(40),
|
hotkey: chalk.ansi256(40),
|
||||||
tab: {
|
tab: {
|
||||||
normal: chalk.ansi256(117),
|
normal: chalk.ansi256(117),
|
||||||
selected: chalk.ansi256(117).inverse
|
selected: chalk.ansi256(117).inverse
|
||||||
},
|
},
|
||||||
border: {
|
border: {
|
||||||
focused: '#ffffff',
|
focused: '#ffffff',
|
||||||
normal: '#222222'
|
normal: '#222222'
|
||||||
},
|
},
|
||||||
progressBar: {
|
progressBar: {
|
||||||
indicator: {
|
indicator: {
|
||||||
critical: chalk.bgAnsi256(235).ansi256(88),
|
critical: chalk.bgAnsi256(235).ansi256(88),
|
||||||
warning: chalk.bgAnsi256(235).ansi256(202),
|
warning: chalk.bgAnsi256(235).ansi256(202),
|
||||||
normal: chalk.bgAnsi256(235).ansi256(70),
|
normal: chalk.bgAnsi256(235).ansi256(70),
|
||||||
excellent: chalk.bgAnsi256(235).ansi256(87),
|
excellent: chalk.bgAnsi256(235).ansi256(87),
|
||||||
buckets: [.1, .25, .95]
|
buckets: [.1, .25, .95]
|
||||||
},
|
},
|
||||||
normal: chalk.bgAnsi256(235).ansi256(243)
|
normal: chalk.bgAnsi256(235).ansi256(243)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const debugStyle = chalk.ansi256(213);
|
const debugStyle = chalk.ansi256(213);
|
||||||
export const debugTheme: Theme = {
|
export const debugTheme: Theme = {
|
||||||
header: debugStyle.inverse,
|
header: debugStyle.inverse,
|
||||||
subheader: debugStyle,
|
subheader: debugStyle,
|
||||||
normal: debugStyle,
|
normal: debugStyle,
|
||||||
selected: debugStyle.inverse,
|
selected: debugStyle.inverse,
|
||||||
hotkey: debugStyle,
|
hotkey: debugStyle,
|
||||||
tab: {
|
tab: {
|
||||||
normal: debugStyle,
|
normal: debugStyle,
|
||||||
selected: debugStyle.inverse,
|
selected: debugStyle.inverse,
|
||||||
},
|
},
|
||||||
border: {
|
border: {
|
||||||
focused: '#ff88ff',
|
focused: '#ff88ff',
|
||||||
normal: '#ff00ff'
|
normal: '#ff00ff'
|
||||||
},
|
},
|
||||||
progressBar: defaultTheme.progressBar
|
progressBar: defaultTheme.progressBar
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTheme(): Theme {
|
export function getTheme(): Theme {
|
||||||
return defaultTheme;
|
return defaultTheme;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Renderable } from './UI.js';
|
||||||
|
import { KeypressAcceptor } from './Menu.js';
|
||||||
|
|
||||||
|
export abstract class View implements Renderable, KeypressAcceptor {
|
||||||
|
abstract render(): void;
|
||||||
|
abstract keypress(key: { full: string; }): void;
|
||||||
|
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
import { View } from "../Menu";
|
import { View } from "../View.js";
|
||||||
|
|
||||||
export default class InventoryView extends View {
|
export default class InventoryView extends View {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.name = 'Inventory';
|
||||||
|
}
|
||||||
keypress: (key: { full: string; }) => void;
|
keypress: (key: { full: string; }) => void;
|
||||||
render() { void 0 };
|
render() { void 0 };
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import { KeypressAcceptor, View } from "../Menu";
|
import { View } from "../View.js";
|
||||||
import { Renderable } from "../UI";
|
|
||||||
|
|
||||||
export default class MultiplayerView extends View {
|
export default class MultiplayerView extends View {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.name = 'Multiplayer';
|
||||||
|
}
|
||||||
keypress: (key: { full: string; }) => void;
|
keypress: (key: { full: string; }) => void;
|
||||||
render() { void 0 };
|
render() { void 0 };
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { View } from "../Menu.js";
|
import { View } from "../View.js";
|
||||||
|
|
||||||
export default class PawnsView extends View {
|
export default class PawnsView extends View {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ multicast-dns@^6.0.1:
|
||||||
neo-blessed@^0.2.0:
|
neo-blessed@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/neo-blessed/-/neo-blessed-0.2.0.tgz#30f9495fdd104494402b62c6273a9c9b82de4f2b"
|
resolved "https://registry.yarnpkg.com/neo-blessed/-/neo-blessed-0.2.0.tgz#30f9495fdd104494402b62c6273a9c9b82de4f2b"
|
||||||
|
integrity sha512-C2kC4K+G2QnNQFXUIxTQvqmrdSIzGTX1ZRKeDW6ChmvPRw8rTkTEJzbEQHiHy06d36PCl/yMOCjquCRV8SpSQw==
|
||||||
|
|
||||||
object-is@^1.0.1:
|
object-is@^1.0.1:
|
||||||
version "1.1.5"
|
version "1.1.5"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue