this kid, wants me to watch a movie and shit

master
Valerie 2021-06-25 20:28:29 -04:00
parent 204e5bdad6
commit d11741dc02
15 changed files with 316 additions and 235 deletions

View File

@ -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: {}
})
});

View File

@ -1,2 +0,0 @@
import { registerAction } from '@actions';
import { Game } from '@game';

View File

@ -1,2 +0,0 @@
import { registerAction } from '@actions';
import { Game } from '@game';

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);
});

View File

@ -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);

View File

@ -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';
}
});

View File

@ -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"
}
}

View File

@ -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');
}

View File

@ -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<any>;
awake: boolean;
sex: number;
@ -108,7 +108,7 @@ export class Pawn extends Serializable implements Tickable {
}
}
assignJob(task: Task) {
assignJob(task: TaskState<any>) {
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() {

View File

@ -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<any>[] = [];
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<any>) {
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
}

View File

@ -36,6 +36,7 @@ export class Item extends Serializable {
setProperty(prop: ItemProperty, value: any) {
this.props[prop.name] = value;
return this;
}
getProperty(prop: ItemProperty) {

View File

@ -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<string, typeof Task> = new Map();
const tasks: Map<string, Task<any>> = new Map();
export type TaskCategory = "self" | "work" | "craft" | "idle";
export class Task {
progress = 0;
worker: Pawn;
data: any;
export class Task<Data> {
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<T> 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<T>) {
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;
}
}