From d11741dc02ed1ad2c599711e1bbd682335c8664e Mon Sep 17 00:00:00 2001 From: Valerie Date: Fri, 25 Jun 2021 20:28:29 -0400 Subject: [PATCH] this kid, wants me to watch a movie and shit --- content/core/actions/CoreActions.ts | 42 +++++--- content/core/actions/FetchSticksAction.ts | 2 - content/core/actions/GatherRocksAction.ts | 2 - content/core/items/CoreItems.ts | 110 ++++++++++++++++++++ content/core/items/Items.ts | 39 -------- content/core/tasks/ChopTreeTask.ts | 25 ----- content/core/tasks/CoreTasks.ts | 39 ++++++++ content/core/tasks/FetchSticksTask.ts | 21 ---- content/core/tasks/GatherRocksTask.ts | 36 ------- package.json | 3 +- src/Inventory.ts | 43 +++++--- src/Pawn.ts | 10 +- src/TaskList.ts | 62 +++++------- src/registries/Items.ts | 1 + src/registries/Tasks.ts | 116 +++++++++++++++------- 15 files changed, 316 insertions(+), 235 deletions(-) delete mode 100644 content/core/actions/FetchSticksAction.ts delete mode 100644 content/core/actions/GatherRocksAction.ts create mode 100644 content/core/items/CoreItems.ts delete mode 100644 content/core/items/Items.ts delete mode 100644 content/core/tasks/ChopTreeTask.ts create mode 100644 content/core/tasks/CoreTasks.ts delete mode 100644 content/core/tasks/FetchSticksTask.ts delete mode 100644 content/core/tasks/GatherRocksTask.ts diff --git a/content/core/actions/CoreActions.ts b/content/core/actions/CoreActions.ts index e60a699..3fd98eb 100644 --- a/content/core/actions/CoreActions.ts +++ b/content/core/actions/CoreActions.ts @@ -1,23 +1,35 @@ import { registerAction } from '@actions'; import { Game } from '@game'; +import { ItemState } from '@items'; +import { TaskState } from '@tasks'; +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', +// options: {} +// }) +// }); registerAction('Gather Flint', (qty) => { - Game.current.board.addTask({ - taskId: 'core:gather-flint', - options: {} - }) + const taskState = new TaskState(GATHER_FLINT); + Game.current.board.addTask(taskState); }); -registerAction('Gather Slate', (qty) => { - Game.current.board.addTask({ - taskId: 'core:gather-slate', - options: {} - }) +registerAction('Create Arrowhead', (qty) => { + const rock = new ItemState(FLINT_NORMAL, 1, null); + const task = new TaskState(MAKE_ARROWHEAD).setData({ + baseMaterial: rock + }); + + Game.current.board.addTask(task); }); -registerAction('Fetch Sticks', (qty) => { - Game.current.board.addTask({ - taskId: "core:fetch-sticks", - options: {} - }) -}); \ No newline at end of file diff --git a/content/core/actions/FetchSticksAction.ts b/content/core/actions/FetchSticksAction.ts deleted file mode 100644 index fe9ee92..0000000 --- a/content/core/actions/FetchSticksAction.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { registerAction } from '@actions'; -import { Game } from '@game'; \ No newline at end of file diff --git a/content/core/actions/GatherRocksAction.ts b/content/core/actions/GatherRocksAction.ts deleted file mode 100644 index 0183670..0000000 --- a/content/core/actions/GatherRocksAction.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { registerAction } from '@actions'; -import { Game } from '@game'; diff --git a/content/core/items/CoreItems.ts b/content/core/items/CoreItems.ts new file mode 100644 index 0000000..c39514e --- /dev/null +++ b/content/core/items/CoreItems.ts @@ -0,0 +1,110 @@ +import { Item, ItemFilter, ItemProperty, ItemState } from '@items' + +// #region properties! +export const ROCK = new ItemProperty('core:rock') +export const ROCK_HARDNESS = new ItemProperty('core:mohs-hardness') +export const SEDIMENTARY = new ItemProperty('core:sedimentary') +export const IGNEOUS = new ItemProperty('core:igneous') +export const METAMORPHIC = new ItemProperty('core:metamorphic') +// #endregion + +// #region tree-y stuff +export const LOG = new Item() + .setName("Log") + .setId('core:resources/log') + +export const STICK = new Item() + .setName("Stick") + .setId('core:resources/stick') + +export const PLANT_FIBRES = new Item() + .setName("Plant Fibres") + .setId('core:plant-fibres') +// #endregion + +// #region normal ass rocks +export const FLINT_NORMAL = new Item() + .setName("Flint") + .setId('core:flint') + .setProperty(ROCK_HARDNESS, 7) + +export const SANDSTONE_NORMAL = new Item() + .setName("Sandstone") + .setId('core:sandstone') + +export const SANDSTONE_PEBBLE = new Item() + .setName("Sandstone Pebble") + .setId('core:sandstone-pebble') + +export const SLATE_NORMAL = new Item() + .setName("Slate") + .setId('core:slate') + +export const LIMESTONE_NORMAL = new Item() + .setName("Limestone") + .setId('core:limestone') + +export const LIMESTONE_PEBBLE = new Item() + .setName("Limestone Pebble") + .setId('core:limestone-pebble') + +export const SHALE_NORMAL = new Item() + .setName("Shale") + .setId('core:shale') + +export const SHALE_PEBBLE = new Item() + .setName("Shale Pebble") + .setId('core:shale-pebble') + +export const OBSIDIAN_NORMAL = new Item() + .setName("Obsidian") + .setId('core:obsidian') + +// #endregion + +// #region tools n shit + +export const FLINT_HATCHET = new Item() + .setName("Flint Hatchet") + .setId('core:flint-hatchet') + +export const FLINT_ARROWHEAD = new Item() + .setName("Flint Arrowhead") + .setId('core:flint-arrowhead') + +export const FLINT_SPEAR = new Item() + .setName("Flint Spear") + .setId('core:flint-spear') + +export const SLATE_HATCHET = new Item() + .setName("Slate Hatchet") + .setId('core:slate-hatchet') + +export const SLATE_ARROWHEAD = new Item() + .setName("Slate Arrowhead") + .setId('core:slate-arrowhead') + +export const SLATE_SPEAR = new Item() + .setName("Slate Spear") + .setId('core:slate-spear') + +export const OBSIDIAN_HATCHET = new Item() + .setName("Obsidian Hatchet") + .setId('core:obsidian-hatchet') + +export const OBSIDIAN_ARROWHEAD = new Item() + .setName("Obsidian Arrowhead") + .setId('core:obsidian-arrowhead') + +export const OBSIDIAN_SPEAR = new Item() + .setName("Obsidian Spear") + .setId('core:obsidian-spear') + +// #endregion + +export function FILTER_CRAFTABLE_ROCK(item: ItemState) { + return +} + +// tools: plant fibres = rope, flint hatchet +// shale - igneous. metamorphasis => slate \ No newline at end of file diff --git a/content/core/items/Items.ts b/content/core/items/Items.ts deleted file mode 100644 index e309666..0000000 --- a/content/core/items/Items.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Item, ItemFilter, ItemProperty, ItemState } from '@items'; - -export const LOG = new Item().setName("Log").setId('core:resources/log'); -export const STICK = new Item().setName("Stick").setId('core:resources/stick'); -export const PLANT_FIBRES = new Item().setName("Plant Fibres").setId('core:plant-fibres'); - -export const FLINT_NORMAL = new Item().setName("Flint").setId('core:flint'); -export const FLINT_FLAKE = new Item().setName("Flint Flake").setId('core:flint-flake'); -export const SANDSTONE_NORMAL = new Item().setName("Sandstone").setId('core:sandstone'); -export const SANDSTONE_PEBBLE = new Item().setName("Sandstone Pebble").setId('core:sandstone-pebble'); -export const SLATE_NORMAL = new Item().setName("Slate").setId('core:slate'); -export const SLATE_FLAKE = new Item().setName("Slate Flake").setId('core:slate-flake'); -export const LIMESTONE_NORMAL = new Item().setName("Limestone").setId('core:limestone'); -export const LIMESTONE_PEBBLE = new Item().setName("Limestone Pebble").setId('core:limestone-pebble'); -export const SHALE_NORMAL = new Item().setName("Shale").setId('core:shale'); -export const SHALE_PEBBLE = new Item().setName("Shale Pebble").setId('core:shale-pebble'); -export const OBSIDIAN_NORMAL = new Item().setName("Obsidian").setId('core:obsidian') -export const OBSIDIAN_FLAKE = new Item().setName("Obsidian Flake").setId('core:obsidian-flake'); - -export const FLINT_HATCHET = new Item().setName("Flint Hatchet").setId('core:flint-hatchet'); -export const FLINT_ARROWHEAD = new Item().setName("Flint Arrowhead").setId('core:flint-arrowhead'); -export const FLINT_SPEAR = new Item().setName("Flint Spear").setId('core:flint-spear'); -export const SLATE_HATCHET = new Item().setName("Slate Hatchet").setId('core:slate-hatchet'); -export const SLATE_ARROWHEAD = new Item().setName("Slate Arrowhead").setId('core:slate-arrowhead'); -export const SLATE_SPEAR = new Item().setName("Slate Spear").setId('core:slate-spear'); -export const OBSIDIAN_HATCHET = new Item().setName("Obsidian Hatchet").setId('core:obsidian-hatchet'); -export const OBSIDIAN_ARROWHEAD = new Item().setName("Obsidian Arrowhead").setId('core:obsidian-arrowhead'); -export const OBSIDIAN_SPEAR = new Item().setName("Obsidian Spear").setId('core:obsidian-spear'); - -// tools: plant fibres = rope, flint hatchet -// shale - igneous. metamorphasis => slate - -export const SHARPNESS = new ItemProperty('core:sharpness'); - -export function minSharpness(min: number) { - return function(itemState: ItemState): boolean { - return itemState.item.getProperty(SHARPNESS) >= min; - } -} \ No newline at end of file diff --git a/content/core/tasks/ChopTreeTask.ts b/content/core/tasks/ChopTreeTask.ts deleted file mode 100644 index 8e97a5c..0000000 --- a/content/core/tasks/ChopTreeTask.ts +++ /dev/null @@ -1,25 +0,0 @@ -import chalk from 'chalk'; -import { Game } from '@game'; -import { registerTask, Task } from '@tasks'; -import { LOG } from '../items/Items.js'; - -// TODO cleanup imports, use aliases - -class ChopTreeTask extends Task { - work = 100; - - reward() { - Game.current.inv.add(LOG, 1); - } - - get title() { - return chalk.yellow('Chop Trees'); - } - - get status() { - return chalk.yellow('LOGGING'); - } -} - - -registerTask('core:chop-trees', ChopTreeTask); \ No newline at end of file diff --git a/content/core/tasks/CoreTasks.ts b/content/core/tasks/CoreTasks.ts new file mode 100644 index 0000000..0259102 --- /dev/null +++ b/content/core/tasks/CoreTasks.ts @@ -0,0 +1,39 @@ +import { Task } from "@tasks"; +import { Game } from '@game'; +import { FLINT_NORMAL, SLATE_NORMAL } from '../items/CoreItems.js'; +import { ItemState } from "@items"; + +export const GATHER_FLINT = new Task('core:gather-flint') + .setName('Gather Flint') + .setStatus('SCAVENGING') + .setWork(1000) + .setTasklistVisibility(true) + .setCategory("work") + .setCompletionEvent(() => { + const qty = Math.floor(Math.random() * 5) + 1; + Game.current.inv.add(new ItemState(FLINT_NORMAL, 1, null)); + }) + +// export const GATHER_SLATE = new Task('core:gather-slate') +// .setName('Gather Slate') +// .setStatus('SCAVENGING') +// .setWork(1000) +// .setTasklistVisibility(true) +// .setCategory("work") +// .setCompletionEvent(() => { +// const qty = Math.floor(Math.random() * 5) + 1; +// Game.current.inv.add(SLATE_NORMAL, qty); +// }); + +export const MAKE_ARROWHEAD = new Task<{ + baseMaterial: ItemState +}>('core:gather-slate') + .setName('Gather Slate') + .setStatus('SCAVENGING') + .setWork(1000) + .setTasklistVisibility(true) + .setCategory("work") + .setCompletionEvent((data) => { + const qty = Math.floor(Math.random() * 5) + 1; + Game.current.inv.add(SLATE_NORMAL, qty); + }); \ No newline at end of file diff --git a/content/core/tasks/FetchSticksTask.ts b/content/core/tasks/FetchSticksTask.ts deleted file mode 100644 index 5440356..0000000 --- a/content/core/tasks/FetchSticksTask.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Task, registerTask } from "@tasks"; -import chalk from 'chalk'; -import { Game } from '@game'; -import { LOG, STICK } from '../items/Items.js'; - -class FetchSticksTask extends Task { - work = 100; - reward(): void { - Game.current.inv.add(STICK, 1); - } - - get title() { - return chalk.yellow('Chop Trees'); - } - - get status() { - return chalk.yellow('LOGGING'); - } -} - -registerTask('core:fetch-sticks', FetchSticksTask); \ No newline at end of file diff --git a/content/core/tasks/GatherRocksTask.ts b/content/core/tasks/GatherRocksTask.ts deleted file mode 100644 index 794fdf7..0000000 --- a/content/core/tasks/GatherRocksTask.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Task, registerTask } from "@tasks"; -import chalk from 'chalk'; -import { Game } from '@game'; -import { FLINT_NORMAL, SLATE_NORMAL } from '../items/Items.js'; - -registerTask('core:gather-flint', class GatherFlintTask extends Task { - work = 1000; - - reward(): void { - Game.current.inv.add(FLINT_NORMAL, 1); - } - - get title() { - return 'Gather Flint'; - } - - get status() { - return 'SCAVENGING'; - } -}); - -registerTask('core:gather-slate', class GatherSlateTask extends Task { - work = 1000; - - reward(): void { - Game.current.inv.add(SLATE_NORMAL, 1); - } - - get title() { - return 'Gather Slate'; - } - - get status() { - return 'SCAVENGING'; - } -}); \ No newline at end of file diff --git a/package.json b/package.json index f1cc8b2..ece3991 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "dev": "supervisor -w out -n exit -t -k --exec yarn -- start", "prod": "git fetch && git pull && yarn && tsc && yarn start", "test": "mocha", - "lint": "eslint src/**/*.ts" + "lint": "eslint src/**/*.ts", + "profile": "node --inspect --no-warnings --loader ./lib/aliases.mjs --enable-source-maps out/src/index.js" } } diff --git a/src/Inventory.ts b/src/Inventory.ts index 137ff65..40db636 100644 --- a/src/Inventory.ts +++ b/src/Inventory.ts @@ -36,23 +36,36 @@ export class Inventory extends Serializable implements Renderable { this.items = this.items.filter(test => test !== 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(); + add(itemState: ItemState) { + this.items.push(itemState); + this.reduceInv(); } + 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) + } + + // 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(); + // } + render() { return this.items.map(item => item.render()).join('\n'); } diff --git a/src/Pawn.ts b/src/Pawn.ts index 237fc8f..0ea6b23 100644 --- a/src/Pawn.ts +++ b/src/Pawn.ts @@ -1,6 +1,6 @@ import { Serializable } from 'frigid'; import faker from 'faker'; -import { Task } from './registries/Tasks.js'; +import { TaskState } from './registries/Tasks.js'; import Time, { Tickable } from './Time.js'; import { Game } from './Game.js'; import { render } from './ui/UI.js'; @@ -21,7 +21,7 @@ export class Pawn extends Serializable implements Tickable { first: string, last: string }; - job: Task; + job: TaskState; awake: boolean; sex: number; @@ -108,7 +108,7 @@ export class Pawn extends Serializable implements Tickable { } } - assignJob(task: Task) { + assignJob(task: TaskState) { this.job?.stopJob() this.job = task; this.job.claim(this); @@ -116,14 +116,14 @@ export class Pawn extends Serializable implements Tickable { get status() { if(this.job) { - return this.job.status; + return this.job.task.status; } else { return this.awake ? getTheme().status.idle('IDLE') : getTheme().status.self('RESTING') } } static serializationDependencies() { - return [Task] + return [TaskState] } toString() { diff --git a/src/TaskList.ts b/src/TaskList.ts index 1e27348..40c3fe7 100644 --- a/src/TaskList.ts +++ b/src/TaskList.ts @@ -1,54 +1,38 @@ import { Serializable } from 'frigid'; -import { Task, taskClasses } from './registries/Tasks.js'; +import { Task, TaskState } from './registries/Tasks.js'; import { render, Renderable, panels } from './ui/UI.js'; export class TaskList extends Serializable implements Renderable { - tasks: Task[] = []; + tasks: TaskState[] = []; - clear() { - for(const task of this.tasks) { - this.removeTask(task); - } - } + clear() { + for(const task of this.tasks) { + this.removeTask(task); + } + } - static serializationDependencies() { - let a = Array.from(taskClasses.values()) - return a as unknown as (typeof Serializable)[]; - } + static serializationDependencies() { + return [TaskState] + } - addTask({taskId, options}: TaskOptions) { - if(!taskClasses.has(taskId)) - throw new Error('unknown task: ' + taskId); + addTask(task: TaskState) { + this.tasks = [...this.tasks, task]; + } - // this is any because TS doesnt understand that - // static references and constructors are the - // SAME THING. - // in TS, they're MAGICALLY incompatible... - const taskClass: any = taskClasses.get(taskId); - const task = new taskClass(); - - this.tasks = [...this.tasks, task]; - } + removeTask(task) { + this.tasks = this.tasks.filter(v => v !== task); + } - removeTask(task) { - this.tasks = this.tasks.filter(v => v !== task); - } - - render() { - // const width = tasksPanel.width; - panels.left.setContent(`${this.tasks.map(task => { - return task.toString(); - }).join('\n')}`); - // return this.tasks.map(task => task.toString()).join('\n'); - } + render() { + // const width = tasksPanel.width; + panels.left.setContent(`${this.tasks.map(task => { + return task.toString(); + }).join('\n')}`); + // return this.tasks.map(task => task.toString()).join('\n'); + } } const taskTypes = {}; export function registerTask(name, clazz) { taskTypes[name] = clazz; -} - -export type TaskOptions = { - taskId: string, - options: any } \ No newline at end of file diff --git a/src/registries/Items.ts b/src/registries/Items.ts index 76a764f..6acd310 100644 --- a/src/registries/Items.ts +++ b/src/registries/Items.ts @@ -36,6 +36,7 @@ export class Item extends Serializable { setProperty(prop: ItemProperty, value: any) { this.props[prop.name] = value; + return this; } getProperty(prop: ItemProperty) { diff --git a/src/registries/Tasks.ts b/src/registries/Tasks.ts index cc07c36..0d8f96f 100644 --- a/src/registries/Tasks.ts +++ b/src/registries/Tasks.ts @@ -6,24 +6,79 @@ import { Game } from '../Game.js'; import { panels } from '../ui/UI.js'; import { progressbar, ProgressbarStyle } from '../Progressbar.js'; -export const taskClasses: Map = new Map(); +const tasks: Map> = new Map(); +export type TaskCategory = "self" | "work" | "craft" | "idle"; -export class Task { - progress = 0; - worker: Pawn; - data: any; +export class Task { id: string; + work: number; + name: string; + status: string; + tasklistVisibility: boolean; + category: TaskCategory; + completionEvent: (data: Data) => void; + + setTasklistVisibility(b: boolean) { + this.tasklistVisibility = b; + return this; + } + + setName(name: string) { + this.name = name; + return this; + } + + setStatus(s: string) { + this.status = s; + return this; + } + + setCategory(c: TaskCategory) { + this.category = c; + return this; + } + + setWork(n: number) { + this.work = n; + return this; + } + + setCompletionEvent(fn: (data: any) => void) { + this.completionEvent = fn; + return this; + } + + constructor(id: string) { + this.id = id; + this.tasklistVisibility = true; + this.category = "work"; + tasks.set(this.id, this); + } +} + +export class TaskState extends Serializable { + taskId: string; + progress: number; + worker: Pawn; + data: T; ctor() { - this.worker ??= null; + // retest completion when loaded, JUST IN CASE this.testCompletion(); } - abstract reward(): void; - abstract work: number; + constructor(task: Task) { + super(); + this.taskId = task.id; + this.progress = 0; + this.worker = null; + // preset the data to nothing JIC + this.data = {} as T; + } - get completed() { - return this.completion >= 1; + setData(data: T) { + this.data = data; + return this; } stopJob() { @@ -37,47 +92,38 @@ export class Task { } testCompletion() { - if (this.progress >= this.work) { - this.reward(); + if (this.completed) { + this.task.completionEvent(this.data); Game.current.board.removeTask(this); } } + free() { + this.worker = null; + } + claim(pawn: Pawn) { this.worker = pawn; } get completion() { - return Math.min(1, this.progress / this.work); + return Math.min(1, this.progress / this.task.work); + } + + get task() { + return tasks.get(this.taskId); + } + + get completed() { + return this.completion >= 1; } toString() { // HACK magic number 2 here, is the border // of the panel const width = panels.left.width - 2; - const left = ' ' + this.title + ' ' + (this.worker?.toString() || chalk.bold.black('Queued')); + const left = ' ' + this.task.name + ' ' + (this.worker?.toString() || chalk.bold.black('Queued')); const bar = width - 2; return `${left}\n ${progressbar(this.completion, bar, ProgressbarStyle.progress)}\n`; } - - get title() { - return chalk.bgRedBright.black('[Abstract Task]'); - } - - get status() { - return chalk.bgRedBright.black('DOING A TASK'); - } - - setId(id: string) { - this.id = id; - return this; - } -} - -export class TaskState extends Serializable { - - constructor(task: Task) { - super(); - this._taskId = task.id; - } } \ No newline at end of file