stuff, broken
parent
3554aef803
commit
d4c008a5e1
|
|
@ -2,16 +2,10 @@ import { registerAction } from '@actions';
|
|||
import { Game } from '@game';
|
||||
import { ItemState } from '@items';
|
||||
import { TaskState } from '@tasks';
|
||||
import { SelectItem } from '../../../src/ui/SelectItem.js';
|
||||
import { FLINT_NORMAL } from '../items/CoreItems.js';
|
||||
import { GATHER_FLINT, MAKE_ARROWHEAD } from '../tasks/CoreTasks.js';
|
||||
|
||||
// registerAction('Gather Flint', (qty) => {
|
||||
// Game.current.board.addTask({
|
||||
// taskId: 'core:gather-flint',
|
||||
// options: {}
|
||||
// })
|
||||
// });
|
||||
|
||||
// registerAction('Gather Slate', (qty) => {
|
||||
// Game.current.board.addTask({
|
||||
// taskId: 'core:gather-slate',
|
||||
|
|
@ -24,8 +18,9 @@ registerAction('Gather Flint', () => {
|
|||
Game.current.board.addTask(taskState);
|
||||
});
|
||||
|
||||
registerAction('Create Arrowhead', (qty) => {
|
||||
const rock = new ItemState(FLINT_NORMAL, 1, null);
|
||||
registerAction('Create Arrowhead', () => {
|
||||
// const rock = new ItemState(FLINT_NORMAL, 1, null);
|
||||
const item = SelectItem.show()
|
||||
const task = new TaskState(MAKE_ARROWHEAD, {
|
||||
baseMaterial: rock
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,23 @@
|
|||
import { Item, ItemFilter, ItemProperty, ItemState } from '@items'
|
||||
|
||||
class Material {
|
||||
name: string;
|
||||
hardness: number;
|
||||
|
||||
setName(name: string) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
setHardness(n: number) {
|
||||
this.hardness = n;
|
||||
}
|
||||
}
|
||||
|
||||
// #region properties!
|
||||
export const ROCK = new ItemProperty('core:rock')
|
||||
export const ROCK_HARDNESS = new ItemProperty('core:mohs-hardness')
|
||||
export const MATERIAL = new ItemProperty('core:material')
|
||||
export const ROCK_SIZE = new ItemProperty('core:rock-size')
|
||||
export const SEDIMENTARY = new ItemProperty('core:sedimentary')
|
||||
export const IGNEOUS = new ItemProperty('core:igneous')
|
||||
export const METAMORPHIC = new ItemProperty('core:metamorphic')
|
||||
|
|
@ -26,7 +41,12 @@ export const PLANT_FIBRES = new Item()
|
|||
export const FLINT_NORMAL = new Item()
|
||||
.setName("Flint")
|
||||
.setId('core:flint')
|
||||
.setProperty(ROCK_HARDNESS, 7)
|
||||
.setProperty(MATERIAL, new Material()
|
||||
.setName('Flint')
|
||||
.setHardness(7)
|
||||
)
|
||||
.setProperty(ROCK, true)
|
||||
.setProperty(IGNEOUS, true)
|
||||
|
||||
export const SANDSTONE_NORMAL = new Item()
|
||||
.setName("Sandstone")
|
||||
|
|
@ -104,9 +124,13 @@ export const OBSIDIAN_SPEAR = new Item()
|
|||
|
||||
// #endregion
|
||||
|
||||
// export function FILTER_CRAFTABLE_ROCK(item: ItemState<any>) {
|
||||
// return
|
||||
// }
|
||||
export function FILTER_CRAFTABLE_ROCK(itemState: ItemState<any>) {
|
||||
if(!itemState.item.getProperty(MATERIAL)) return false;
|
||||
const mat: Material = itemState.item.getProperty(MATERIAL) as Material;
|
||||
return itemState.item.getProperty(ROCK)
|
||||
&& mat.hardness >= 6
|
||||
&& mat.hardness < 10
|
||||
}
|
||||
|
||||
// tools: plant fibres = rope, flint hatchet
|
||||
// shale - igneous. metamorphasis => slate
|
||||
|
|
@ -4,5 +4,5 @@ import chalk from 'chalk'
|
|||
registerTheme("default", {});
|
||||
|
||||
registerTheme("high contrast", {
|
||||
selected: chalk.ansi256(250).inverse
|
||||
bright: chalk.ansi256(250).inverse
|
||||
});
|
||||
|
|
@ -5,6 +5,7 @@ const moduleAliases = {
|
|||
"@actions": "./out/src/registries/Actions.js",
|
||||
"@tasks": "./out/src/registries/Tasks.js",
|
||||
"@items": "./out/src/registries/Items.js",
|
||||
"@ui": "./out/src/ui/UI.js",
|
||||
"@game": "./out/src/Game.js"
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -42,29 +42,23 @@ export class Inventory extends Serializable implements Renderable {
|
|||
}
|
||||
|
||||
private reduceInv() {
|
||||
// TODO deduplicate itemstates...
|
||||
// use a reduce to reconstruct the array.
|
||||
// REMEMBER TO MAINTAIN THE OBJECTs!
|
||||
// dont do immutability to it, as the objects
|
||||
// may have crossreferences! (maybe)
|
||||
}
|
||||
this.items = this.items.reduce((items, itemState) => {
|
||||
|
||||
// add(item: Item, qty: number = 1) {
|
||||
// const id = item.id;
|
||||
// const existingArr = this.items.filter(itemState => {
|
||||
// return itemState.itemId === id;
|
||||
// });
|
||||
// let existing: ItemState = null;
|
||||
// if(existingArr.length === 1) {
|
||||
// existing = existingArr[0];
|
||||
// }
|
||||
// if(existing) {
|
||||
// existing.qty += qty;
|
||||
// } else {
|
||||
// this.items.push(new ItemState(item, qty, {}));
|
||||
// }
|
||||
// Game.current.sync();
|
||||
// }
|
||||
// TODO at some point, be able to merge data items?
|
||||
|
||||
const existing = items.find(testItemState => {
|
||||
return itemState.itemId === testItemState.itemId
|
||||
&& itemState.data === testItemState.data;
|
||||
});
|
||||
|
||||
if(existing) {
|
||||
existing.qty += itemState.qty;
|
||||
} else {
|
||||
items.push(itemState);
|
||||
}
|
||||
return items
|
||||
}, [] as ItemState<any>[])
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.items.map(item => item.render()).join('\n');
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Renderable } from "../ui/UI.js";
|
|||
|
||||
export const actions: Action[] = [];
|
||||
|
||||
export function registerAction(name: string, invoke: (qty: number) => void) {
|
||||
export function registerAction(name: string, invoke: () => void) {
|
||||
console.log('Registered action', name);
|
||||
actions.push(new Action(name, invoke))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,12 @@ export type ItemID = string;
|
|||
|
||||
const items = new Map<ItemID, Item<any>>();
|
||||
|
||||
export type PropertyValue = number | boolean;
|
||||
|
||||
// ITEMS SHALL BE SINGULAR
|
||||
export class Item<Data> extends Serializable {
|
||||
|
||||
name = '';
|
||||
id: ItemID = '';
|
||||
props: Map<string, PropertyValue> = new Map();
|
||||
props: Map<string, any> = new Map();
|
||||
|
||||
setName(name: string) {
|
||||
this.name = name;
|
||||
|
|
@ -50,6 +48,12 @@ export class ItemState<Data> extends Serializable implements Renderable {
|
|||
itemId: ItemID;
|
||||
data: Data;
|
||||
|
||||
take(qty: number) {
|
||||
if(this.qty < qty) throw new Error('cant split more than stack from stack...');
|
||||
this.qty -= qty;
|
||||
return new ItemState<Data>(this.item, qty, this.data);
|
||||
}
|
||||
|
||||
get item() {
|
||||
if(!items.has(this.itemId))
|
||||
throw new Error('unknown item: ' + this.itemId);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ type StyleFunction = (text: string) => string;
|
|||
export type Theme = {
|
||||
header: StyleFunction,
|
||||
subheader: StyleFunction,
|
||||
bright: StyleFunction,
|
||||
normal: StyleFunction,
|
||||
selected: StyleFunction,
|
||||
dimmed: StyleFunction,
|
||||
hotkey: StyleFunction,
|
||||
tab: {
|
||||
normal: StyleFunction,
|
||||
|
|
@ -42,10 +43,11 @@ export type Theme = {
|
|||
}
|
||||
|
||||
export const backupTheme: Theme = {
|
||||
header: chalk.ansi256(255).bold,
|
||||
subheader: chalk.ansi256(243).bold,
|
||||
normal: chalk.ansi256(243),
|
||||
selected: chalk.ansi256(250),
|
||||
header: chalk.ansi256(255),
|
||||
subheader: chalk.ansi256(250),
|
||||
bright: chalk.ansi256(255),
|
||||
normal: chalk.ansi256(250),
|
||||
dimmed: chalk.ansi256(245),
|
||||
hotkey: chalk.ansi256(40),
|
||||
tab: {
|
||||
normal: chalk.ansi256(117),
|
||||
|
|
@ -53,7 +55,7 @@ export const backupTheme: Theme = {
|
|||
},
|
||||
border: {
|
||||
focused: '#ffffff',
|
||||
normal: '#222222'
|
||||
normal: '#888888'
|
||||
},
|
||||
progressBar: {
|
||||
indicator: {
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export class GiftPopup {
|
|||
this.box.setContent(`${(() => {
|
||||
let pawns = [];
|
||||
for (const [pawn, qty] of this.pawns.entries()) {
|
||||
const style = i === this.selected ? getTheme().selected : getTheme().normal;
|
||||
const style = i === this.selected ? getTheme().bright : getTheme().normal;
|
||||
if(qty > 0) {
|
||||
pawns.push(style(`{|}${pawn.toString()} `))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
import { Game } from "@game";
|
||||
import { ItemState } from "@items";
|
||||
import { boxStyle, getTheme } from "@themes";
|
||||
import { panels } from "@ui";
|
||||
import EventEmitter from "events";
|
||||
import blessed from 'neo-blessed';
|
||||
|
||||
type ItemFilterFunction = (itemState: ItemState<any>) => boolean;
|
||||
|
||||
export class SelectItem {
|
||||
box: any;
|
||||
emitter: EventEmitter;
|
||||
qty: number;
|
||||
items: ItemState<any>[];
|
||||
selectedIdx: number;
|
||||
|
||||
static show(filter: ItemFilterFunction): Promise<ItemState<any>> {
|
||||
const si = new SelectItem(filter, 1);
|
||||
return new Promise(res => {
|
||||
si.emitter.on('selected', (itemState: ItemState<any>) => {
|
||||
res(itemState);
|
||||
});
|
||||
si.emitter.on('cancel', () => {
|
||||
res(null);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
private open() {
|
||||
panels.screen.append(this.box);
|
||||
this.box.focus();
|
||||
Game.current.clock.pause();
|
||||
}
|
||||
|
||||
private close() {
|
||||
Game.current.clock.start();
|
||||
panels.screen.remove(this.box);
|
||||
}
|
||||
|
||||
get selectedItem(): ItemState<any> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private constructor(filter: ItemFilterFunction, qty: number) {
|
||||
this.emitter = new EventEmitter();
|
||||
this.qty = qty;
|
||||
this.box = blessed.box({
|
||||
top: 'center',
|
||||
left: 'center',
|
||||
width: 'shrink',
|
||||
height: 'shrink',
|
||||
tags: true,
|
||||
...boxStyle(),
|
||||
});
|
||||
this.box.on('keypress', (evt: {}, key: {full: string}) => {
|
||||
if(key.full === 'escape') {
|
||||
this.emitter.emit('cancel');
|
||||
this.close();
|
||||
} else if(key.full === 'enter') {
|
||||
this.emitter.emit('selected', this.selectedItem.take(this.qty));
|
||||
this.close();
|
||||
} else if(key.full === 'down') {
|
||||
|
||||
}
|
||||
});
|
||||
this.items = Game.current.inv.items.filter(filter);
|
||||
this.open();
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ export class ActionsView extends View {
|
|||
render() {
|
||||
return actions.map((action, idx) => `${(() => {
|
||||
if(this.actionIdx === idx) {
|
||||
return getTheme().selected(' ❯ ' + action.name);
|
||||
return getTheme().bright(' ❯ ' + action.name);
|
||||
} else {
|
||||
return getTheme().normal(' ' + action.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export default class MultiplayerView extends View {
|
|||
render() {
|
||||
if(mdns.players.length === 0) return `{center}${getTheme().normal('No friends online')}{/center}`;
|
||||
return mdns.players.map((player, i) => {
|
||||
if(i === this.selected) return ' ' + getTheme().selected(' ❯ ' + player.toString());
|
||||
if(i === this.selected) return ' ' + getTheme().bright(' ❯ ' + player.toString());
|
||||
else return ' ' + getTheme().normal(player.toString());
|
||||
}).join('\n');
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,36 +6,36 @@ import { panels } from "../UI.js";
|
|||
import { View } from "../View.js";
|
||||
|
||||
export default class PawnsView extends View {
|
||||
constructor() {
|
||||
super();
|
||||
this.name = 'Pawns';
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.name = 'Pawns';
|
||||
}
|
||||
|
||||
keypress(key: { full: string; }) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
keypress(key: { full: string; }) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
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, (panels.right.width - 4) / 2)} \n`;
|
||||
} else {
|
||||
str += ` ${getTheme().normal(pawn.toString())}{|}${pawn.status} `;
|
||||
}
|
||||
return str;
|
||||
})()}`).join('\n')
|
||||
}`;
|
||||
}
|
||||
render() {
|
||||
return `${
|
||||
Game.current.pawns.map(pawn => `${(function() {
|
||||
const selected = pawn === Game.current.selected;
|
||||
let str = '';
|
||||
if(selected) {
|
||||
str += ` ${getTheme().bright(` ❯ ${pawn.toString()}`)}{|}${pawn.status} \n`;
|
||||
str += ` ${getTheme().normal('Energy')}{|}${progressbar(pawn.energy / 100, (panels.right.width - 4) / 2)} \n`;
|
||||
} else {
|
||||
str += ` ${getTheme().normal(pawn.toString())}{|}${pawn.status} `;
|
||||
}
|
||||
return str;
|
||||
})()}`).join('\n')
|
||||
}`;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
"@actions": ["./src/registries/Actions"],
|
||||
"@tasks": ["./src/registries/Tasks"],
|
||||
"@items": ["./src/registries/Items"],
|
||||
"@ui": ["./src/ui/UI"],
|
||||
"@game": ["./src/Game"]
|
||||
},
|
||||
"noImplicitAny": true
|
||||
|
|
|
|||
Loading…
Reference in New Issue