oh lots of stuff
parent
4da31d058e
commit
206e5852a0
|
|
@ -68,7 +68,9 @@ export const FLINT_HATCHET = new Item()
|
||||||
.setName("Flint Hatchet")
|
.setName("Flint Hatchet")
|
||||||
.setId('core:flint-hatchet')
|
.setId('core:flint-hatchet')
|
||||||
|
|
||||||
export const FLINT_ARROWHEAD = new Item()
|
export const ARROWHEAD = new Item<{
|
||||||
|
baseMaterial: ItemState<any>
|
||||||
|
}>()
|
||||||
.setName("Flint Arrowhead")
|
.setName("Flint Arrowhead")
|
||||||
.setId('core:flint-arrowhead')
|
.setId('core:flint-arrowhead')
|
||||||
|
|
||||||
|
|
@ -102,9 +104,9 @@ export const OBSIDIAN_SPEAR = new Item()
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
export function FILTER_CRAFTABLE_ROCK(item: ItemState) {
|
// export function FILTER_CRAFTABLE_ROCK(item: ItemState<any>) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
// tools: plant fibres = rope, flint hatchet
|
// tools: plant fibres = rope, flint hatchet
|
||||||
// shale - igneous. metamorphasis => slate
|
// shale - igneous. metamorphasis => slate
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Task } from "@tasks";
|
import { Task } from "@tasks";
|
||||||
import { Game } from '@game';
|
import { Game } from '@game';
|
||||||
import { FLINT_NORMAL, SLATE_NORMAL } from '../items/CoreItems.js';
|
import { ARROWHEAD, FLINT_NORMAL, SLATE_NORMAL } from '../items/CoreItems.js';
|
||||||
import { ItemState } from "@items";
|
import { ItemState } from "@items";
|
||||||
import { Popup } from "../../../src/ui/Popup.js";
|
import { Popup } from "../../../src/ui/Popup.js";
|
||||||
import { inspect } from 'util';
|
import { inspect } from 'util';
|
||||||
|
|
@ -17,13 +17,16 @@ export const GATHER_FLINT = new Task('core:gather-flint')
|
||||||
});
|
});
|
||||||
|
|
||||||
export const MAKE_ARROWHEAD = new Task<{
|
export const MAKE_ARROWHEAD = new Task<{
|
||||||
baseMaterial: ItemState
|
baseMaterial: ItemState<any>
|
||||||
}>('core:gather-slate')
|
}>('core:gather-slate')
|
||||||
.setName('Gather Slate')
|
.setName('Craft Arrowhead')
|
||||||
.setStatus('SCAVENGING')
|
.setStatus('CRAFTING')
|
||||||
.setWork(1)
|
.setWork(1000)
|
||||||
.setTasklistVisibility(true)
|
.setTasklistVisibility(true)
|
||||||
.setCategory("work")
|
.setCategory("craft")
|
||||||
.setCompletionEvent((data) => {
|
.setCompletionEvent((data) => {
|
||||||
Popup.show(inspect(data));
|
const itemState = new ItemState(ARROWHEAD, 1, {
|
||||||
|
baseMaterial: data.baseMaterial
|
||||||
|
});
|
||||||
|
Game.current.inv.add(itemState);
|
||||||
});
|
});
|
||||||
|
|
@ -22,8 +22,11 @@
|
||||||
"mocha": "^9.0.1",
|
"mocha": "^9.0.1",
|
||||||
"module-alias": "^2.2.2",
|
"module-alias": "^2.2.2",
|
||||||
"neo-blessed": "^0.2.0",
|
"neo-blessed": "^0.2.0",
|
||||||
|
"node-dev": "^7.0.0",
|
||||||
|
"nodemon": "^2.0.7",
|
||||||
"printable-characters": "^1.0.42",
|
"printable-characters": "^1.0.42",
|
||||||
"sisteransi": "^1.0.5",
|
"sisteransi": "^1.0.5",
|
||||||
|
"supervisor": "^0.12.0",
|
||||||
"typescript": "^4.3.2",
|
"typescript": "^4.3.2",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"walk-sync": "^3.0.0",
|
"walk-sync": "^3.0.0",
|
||||||
|
|
@ -33,7 +36,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile:watch": "tsc --watch",
|
"compile:watch": "tsc --watch",
|
||||||
"start": "node --no-warnings --loader ./lib/aliases.mjs --enable-source-maps out/src/index.js",
|
"start": "node --no-warnings --loader ./lib/aliases.mjs --enable-source-maps out/src/index.js",
|
||||||
"dev": "supervisor -w out -n exit -t -k --exec yarn -- start",
|
"dev": "nodemon -I --watch out --exec yarn start",
|
||||||
"prod": "git fetch && git pull && yarn && tsc && yarn start",
|
"prod": "git fetch && git pull && yarn && tsc && yarn start",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"lint": "eslint src/**/*.ts",
|
"lint": "eslint src/**/*.ts",
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@ import { Popup } from './ui/Popup.js';
|
||||||
import { Renderable } from './ui/UI.js';
|
import { Renderable } from './ui/UI.js';
|
||||||
|
|
||||||
export class Inventory extends Serializable implements Renderable {
|
export class Inventory extends Serializable implements Renderable {
|
||||||
items: ItemState[];
|
items: ItemState<any>[];
|
||||||
|
|
||||||
ctor() {
|
ctor() {
|
||||||
this.items ??= [];
|
this.items ??= [];
|
||||||
}
|
}
|
||||||
|
|
||||||
validate() {
|
validate() {
|
||||||
const invalid: ItemState[] = [];
|
const invalid: ItemState<any>[] = [];
|
||||||
for(const itemState of this.items) {
|
for(const itemState of this.items) {
|
||||||
try {
|
try {
|
||||||
itemState.item;
|
itemState.item;
|
||||||
|
|
@ -32,11 +32,11 @@ export class Inventory extends Serializable implements Renderable {
|
||||||
return [ItemState];
|
return [ItemState];
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(itemState: ItemState) {
|
remove(itemState: ItemState<any>) {
|
||||||
this.items = this.items.filter(test => test !== itemState);
|
this.items = this.items.filter(test => test !== itemState);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(itemState: ItemState) {
|
add(itemState: ItemState<any>) {
|
||||||
this.items.push(itemState);
|
this.items.push(itemState);
|
||||||
this.reduceInv();
|
this.reduceInv();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import Time, { Tickable } from './Time.js';
|
||||||
import { Game } from './Game.js';
|
import { Game } from './Game.js';
|
||||||
import { render } from './ui/UI.js';
|
import { render } from './ui/UI.js';
|
||||||
import { Memory } from './Memory.js';
|
import { Memory } from './Memory.js';
|
||||||
import { getTheme } from './registries/Themes.js';
|
import { getTheme } from '@themes';
|
||||||
|
|
||||||
// const STATUS = {
|
// const STATUS = {
|
||||||
// IDLE: Symbol('IDLE')
|
// IDLE: Symbol('IDLE')
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { getTheme } from "./registries/Themes.js";
|
import { getTheme } from "@themes";
|
||||||
|
|
||||||
export enum ProgressbarStyle {
|
export enum ProgressbarStyle {
|
||||||
indicator = 'indicator',
|
indicator = 'indicator',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { Serializable } from "frigid";
|
import { Serializable } from "frigid";
|
||||||
import { getTheme } from "./registries/Themes.js";
|
import { getTheme } from "@themes";
|
||||||
import { Renderable } from "./ui/UI.js";
|
import { Renderable } from "./ui/UI.js";
|
||||||
|
|
||||||
type AbbreviatedMonthName = string;
|
type AbbreviatedMonthName = string;
|
||||||
|
|
|
||||||
18
src/index.ts
18
src/index.ts
|
|
@ -5,6 +5,24 @@ import { parse, resolve } from 'path';
|
||||||
import walkSync from 'walk-sync';
|
import walkSync from 'walk-sync';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { Game } from '@game';
|
import { Game } from '@game';
|
||||||
|
import { isStarted, stop } from './ui/UI.js';
|
||||||
|
import { writeFileSync } from 'fs';
|
||||||
|
|
||||||
|
|
||||||
|
function gracefulShutdown() {
|
||||||
|
if(isStarted()) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
console.log('shutting down gracefully...');
|
||||||
|
if(Game.current) {
|
||||||
|
console.log('saving world...');
|
||||||
|
Game.current.sync();
|
||||||
|
}
|
||||||
|
console.log('exitting');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
process.on('exit', gracefulShutdown);
|
||||||
|
|
||||||
|
|
||||||
const saveFile = process.argv[2] || 'data/world01.json';
|
const saveFile = process.argv[2] || 'data/world01.json';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export class Player {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(items: (ItemState | Pawn)[]) {
|
send(items: (ItemState<any> | Pawn)[]) {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
const pawnJsons: string[] = [];
|
const pawnJsons: string[] = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import { Serializable } from 'frigid';
|
import { Serializable } from 'frigid';
|
||||||
import { getTheme } from './Themes.js';
|
import { getTheme } from '@themes';
|
||||||
import { Renderable } from '../ui/UI.js';
|
import { Renderable } from '../ui/UI.js';
|
||||||
|
|
||||||
export type ItemID = string;
|
export type ItemID = string;
|
||||||
|
|
||||||
const items = new Map<ItemID, Item>();
|
const items = new Map<ItemID, Item<any>>();
|
||||||
|
|
||||||
export type PropertyValue = number | boolean;
|
export type PropertyValue = number | boolean;
|
||||||
|
|
||||||
// ITEMS SHALL BE SINGULAR
|
// ITEMS SHALL BE SINGULAR
|
||||||
export class Item extends Serializable {
|
export class Item<Data> extends Serializable {
|
||||||
|
|
||||||
name = '';
|
name = '';
|
||||||
id: ItemID = '';
|
id: ItemID = '';
|
||||||
|
|
@ -45,10 +45,10 @@ export class Item extends Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ItemState extends Serializable implements Renderable {
|
export class ItemState<Data> extends Serializable implements Renderable {
|
||||||
qty: number;
|
qty: number;
|
||||||
itemId: ItemID;
|
itemId: ItemID;
|
||||||
data: any;
|
data: Data;
|
||||||
|
|
||||||
get item() {
|
get item() {
|
||||||
if(!items.has(this.itemId))
|
if(!items.has(this.itemId))
|
||||||
|
|
@ -56,7 +56,7 @@ export class ItemState extends Serializable implements Renderable {
|
||||||
return items.get(this.itemId);
|
return items.get(this.itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(item: Item, amount: number, data: any) {
|
constructor(item: Item<Data>, amount: number, data: Data) {
|
||||||
super();
|
super();
|
||||||
this.qty = amount;
|
this.qty = amount;
|
||||||
this.itemId = item.id;
|
this.itemId = item.id;
|
||||||
|
|
@ -76,4 +76,4 @@ export class ItemProperty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ItemFilter = (itemState: ItemState) => boolean;
|
export type ItemFilter = (itemState: ItemState<any>) => boolean;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export type TaskCategory = "self" | "work" | "craft" | "idle";
|
||||||
export class Task<Data> {
|
export class Task<Data> {
|
||||||
id: string;
|
id: string;
|
||||||
work: number;
|
work: number;
|
||||||
name: string;
|
name: string | ((data: Data) => string);
|
||||||
status: string;
|
status: string;
|
||||||
tasklistVisibility: boolean;
|
tasklistVisibility: boolean;
|
||||||
category: TaskCategory;
|
category: TaskCategory;
|
||||||
|
|
@ -23,7 +23,7 @@ export class Task<Data> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setName(name: string) {
|
setName(name: string | ((data: Data) => string)) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ export class Task<Data> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCompletionEvent(fn: (data: any) => void) {
|
setCompletionEvent(fn: (data: Data) => void) {
|
||||||
this.completionEvent = fn;
|
this.completionEvent = fn;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,3 +92,22 @@ export function setTheme(name: ThemeName): void {
|
||||||
export function getTheme(): Theme {
|
export function getTheme(): Theme {
|
||||||
return currentTheme;
|
return currentTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move this to theme
|
||||||
|
export const boxStyle = () => {
|
||||||
|
return {
|
||||||
|
style: {
|
||||||
|
border: {
|
||||||
|
fg: getTheme().border.normal
|
||||||
|
},
|
||||||
|
focus: {
|
||||||
|
border: {
|
||||||
|
fg: getTheme().border.focused
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
type: 'line'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -4,8 +4,8 @@ import { Game } from '../Game.js';
|
||||||
import { ItemState } from '../registries/Items.js';
|
import { ItemState } from '../registries/Items.js';
|
||||||
import { Player } from "../multiplayer/Player";
|
import { Player } from "../multiplayer/Player";
|
||||||
import { Pawn } from '../Pawn.js';
|
import { Pawn } from '../Pawn.js';
|
||||||
import { getTheme } from '../registries/Themes.js';
|
import { getTheme, boxStyle } from '@themes';
|
||||||
import { boxStyle, panels } from './UI.js';
|
import { panels } from './UI.js';
|
||||||
|
|
||||||
export class GiftPopup {
|
export class GiftPopup {
|
||||||
box;
|
box;
|
||||||
|
|
@ -50,7 +50,7 @@ export class GiftPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
send() {
|
send() {
|
||||||
const stuffToSend: (Pawn | ItemState)[] = [];
|
const stuffToSend: (Pawn | ItemState<any>)[] = [];
|
||||||
for(const [pawn, qty] of this.pawns) {
|
for(const [pawn, qty] of this.pawns) {
|
||||||
if(qty === 0) continue;
|
if(qty === 0) continue;
|
||||||
stuffToSend.push(pawn);
|
stuffToSend.push(pawn);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ export class Menu implements Renderable {
|
||||||
this.regressView();
|
this.regressView();
|
||||||
} else if (key.full === 'right') {
|
} else if (key.full === 'right') {
|
||||||
this.advanceView();
|
this.advanceView();
|
||||||
|
} else if (key.full === 'escape') {
|
||||||
|
this.advanceView();
|
||||||
|
|
||||||
// debugging hotkeys
|
// debugging hotkeys
|
||||||
} else if (key.full === '1') {
|
} else if (key.full === '1') {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import { Game } from '../Game.js';
|
||||||
import { stringify } from '../Memory.js';
|
import { stringify } from '../Memory.js';
|
||||||
import { Pawn } from '../Pawn.js';
|
import { Pawn } from '../Pawn.js';
|
||||||
import Time from '../Time.js';
|
import Time from '../Time.js';
|
||||||
import { boxStyle, panels } from './UI.js';
|
import { panels } from './UI.js';
|
||||||
|
import { boxStyle } from '@themes';
|
||||||
|
|
||||||
export class PawnDetails {
|
export class PawnDetails {
|
||||||
box;
|
box;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import blessed from 'neo-blessed';
|
import blessed from 'neo-blessed';
|
||||||
import { Game } from '../Game.js';
|
import { Game } from '../Game.js';
|
||||||
import { getTheme } from '@themes';
|
import { boxStyle, getTheme } from '@themes';
|
||||||
import { boxStyle, panels } from './UI.js';
|
import { panels } from './UI.js';
|
||||||
|
|
||||||
export class Popup {
|
export class Popup {
|
||||||
box;
|
box;
|
||||||
|
|
@ -15,7 +15,7 @@ export class Popup {
|
||||||
this.box = blessed.box({
|
this.box = blessed.box({
|
||||||
top: 'center',
|
top: 'center',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
width: '100%',
|
width: 'shrink',
|
||||||
height: 'shrink',
|
height: 'shrink',
|
||||||
content: getTheme().normal(content) + `\n\n{right}` + getTheme().hotkey('enter') + getTheme().normal(`: Okay `) + '{/right}',
|
content: getTheme().normal(content) + `\n\n{right}` + getTheme().hotkey('enter') + getTheme().normal(`: Okay `) + '{/right}',
|
||||||
tags: true,
|
tags: true,
|
||||||
|
|
|
||||||
31
src/ui/UI.ts
31
src/ui/UI.ts
|
|
@ -2,31 +2,13 @@
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import blessed from 'neo-blessed';
|
import blessed from 'neo-blessed';
|
||||||
import ansi from 'sisteransi';
|
import ansi from 'sisteransi';
|
||||||
import { getTheme } from '../registries/Themes.js';
|
import { boxStyle, getTheme } from '@themes';
|
||||||
|
export { Popup } from './Popup.js';
|
||||||
|
|
||||||
export interface Renderable {
|
export interface Renderable {
|
||||||
render(): void
|
render(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO move this to theme
|
|
||||||
export const boxStyle = () => {
|
|
||||||
return {
|
|
||||||
style: {
|
|
||||||
border: {
|
|
||||||
fg: getTheme().border.normal
|
|
||||||
},
|
|
||||||
focus: {
|
|
||||||
border: {
|
|
||||||
fg: getTheme().border.focused
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
border: {
|
|
||||||
type: 'line'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
let leftPanel: any;
|
let leftPanel: any;
|
||||||
let rightPanel: any;
|
let rightPanel: any;
|
||||||
let titleBar: any;
|
let titleBar: any;
|
||||||
|
|
@ -76,6 +58,9 @@ export function render(thing?: Renderable) {
|
||||||
|
|
||||||
export function start() {
|
export function start() {
|
||||||
assertNotStarted();
|
assertNotStarted();
|
||||||
|
|
||||||
|
process.stdout.write('\x1b[?1049h');
|
||||||
|
|
||||||
screen = blessed.screen({
|
screen = blessed.screen({
|
||||||
smartCSR: true,
|
smartCSR: true,
|
||||||
terminal: 'xterm-256color'
|
terminal: 'xterm-256color'
|
||||||
|
|
@ -133,6 +118,12 @@ export function start() {
|
||||||
setTitle('');
|
setTitle('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function stop() {
|
||||||
|
screen.destroy();
|
||||||
|
process.stdout.write('\x1b[?1049l');
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to some debugging shit, idk
|
||||||
let ansiTestCard = '{center}';
|
let ansiTestCard = '{center}';
|
||||||
for(let i = 16; i < 34; i ++) ansiTestCard += chalk.bgAnsi256(i).black(` ${i.toString().padStart(3, ' ')} ${(i-15)%6===0?chalk.reset(' '):''}`); ansiTestCard += '\n';
|
for(let i = 16; i < 34; i ++) ansiTestCard += chalk.bgAnsi256(i).black(` ${i.toString().padStart(3, ' ')} ${(i-15)%6===0?chalk.reset(' '):''}`); ansiTestCard += '\n';
|
||||||
for(let i = 52; i < 70; i ++) ansiTestCard += chalk.bgAnsi256(i).black(` ${i.toString().padStart(3, ' ')} ${(i-15)%6===0?chalk.reset(' '):''}`); ansiTestCard += '\n';
|
for(let i = 52; i < 70; i ++) ansiTestCard += chalk.bgAnsi256(i).black(` ${i.toString().padStart(3, ' ')} ${(i-15)%6===0?chalk.reset(' '):''}`); ansiTestCard += '\n';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { getTheme } from "../../registries/Themes.js";
|
import { getTheme } from "@themes";
|
||||||
import { Game } from "../../Game.js";
|
import { Game } from "../../Game.js";
|
||||||
import { Renderable } from "../UI.js";
|
import { Renderable } from "../UI.js";
|
||||||
import { View } from "../View.js";
|
import { View } from "../View.js";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue