Move component decorator to all decorators
This commit is contained in:
parent
b549193a3b
commit
6568e1e8d9
|
|
@ -1,5 +1,5 @@
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { Component } from "../core/world";
|
import { Component } from "../core/world";
|
||||||
|
import { component } from "../utils/decorators";
|
||||||
import { Stat } from "./stat";
|
import { Stat } from "./stat";
|
||||||
|
|
||||||
@component
|
@component
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { Component } from "../core/world";
|
import { Component } from "../core/world";
|
||||||
import { action, variable } from "../utils/decorators";
|
import { action, component, variable } from "../utils/decorators";
|
||||||
|
|
||||||
@component
|
@component
|
||||||
export class Cooldown extends Component<{
|
export class Cooldown extends Component<{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { Component, type EvalContext } from "../core/world";
|
import { Component, type EvalContext } from "../core/world";
|
||||||
import { evaluateCondition } from "../utils/conditions";
|
import { evaluateCondition } from "../utils/conditions";
|
||||||
import { action, variable } from "../utils/decorators";
|
import { action, component, variable } from "../utils/decorators";
|
||||||
import { Stat } from "./stat";
|
import { Stat } from "./stat";
|
||||||
|
|
||||||
@component
|
@component
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { Component } from "../core/world";
|
import { Component } from "../core/world";
|
||||||
import { action } from "../utils/decorators";
|
|
||||||
import type { RPGVariables } from "../types";
|
import type { RPGVariables } from "../types";
|
||||||
|
import { action, component } from "../utils/decorators";
|
||||||
import { Effect } from "./effect";
|
import { Effect } from "./effect";
|
||||||
import { Damage } from "./combat";
|
|
||||||
|
|
||||||
// ── Equippable ────────────────────────────────────────────────────────────────
|
// ── Equippable ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { Component } from "../core/world";
|
import { Component } from "../core/world";
|
||||||
import { action, variable } from "../utils/decorators";
|
import { action, component, variable } from "../utils/decorators";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How much XP is required to advance from level N to N+1.
|
* How much XP is required to advance from level N to N+1.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { Component, type Entity } from "../core/world";
|
import { Component, type Entity } from "../core/world";
|
||||||
import type { RPGVariables } from "../types";
|
import type { RPGVariables } from "../types";
|
||||||
import { action } from "../utils/decorators";
|
import { action, component } from "../utils/decorators";
|
||||||
|
|
||||||
// ── FactionMember ─────────────────────────────────────────────────────────────
|
// ── FactionMember ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import type { InventorySlotInput, RPGVariables, SlotId } from "../types";
|
|
||||||
import { action } from "../utils/decorators";
|
|
||||||
import { Component, type EvalContext } from "../core/world";
|
import { Component, type EvalContext } from "../core/world";
|
||||||
import { component } from "../core/registry";
|
import type { InventorySlotInput, RPGVariables, SlotId } from "../types";
|
||||||
import { Stackable, Usable } from "./item";
|
import { action, component } from "../utils/decorators";
|
||||||
import { Equipment, Equippable } from "./equipment";
|
|
||||||
import { resolveVariables } from "../utils/variables";
|
import { resolveVariables } from "../utils/variables";
|
||||||
|
import { Equipment, Equippable } from "./equipment";
|
||||||
|
import { Stackable, Usable } from "./item";
|
||||||
|
|
||||||
interface SlotRecord {
|
interface SlotRecord {
|
||||||
slotId: SlotId;
|
slotId: SlotId;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Component, type EvalContext, type World } from "../core/world";
|
import { Component, type EvalContext, type World } from "../core/world";
|
||||||
import { component } from "../core/registry";
|
|
||||||
import type { RPGAction } from "../types";
|
import type { RPGAction } from "../types";
|
||||||
import { action, variable } from "../utils/decorators";
|
import { action, component, variable } from "../utils/decorators";
|
||||||
import { executeAction } from "../utils/variables";
|
import { executeAction } from "../utils/variables";
|
||||||
import { Equippable } from "./equipment";
|
import { Equippable } from "./equipment";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Component } from "../core/world";
|
||||||
|
import { component } from "../utils/decorators";
|
||||||
|
|
||||||
|
@component({ variables: ['x', 'y', 'z'] })
|
||||||
|
export class Position extends Component<{ x: number, y: number, z: number }> {
|
||||||
|
constructor(x = 0, y = 0, z = 0) {
|
||||||
|
super({ x, y, z });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Component, type EvalContext } from "../core/world";
|
import { Component, type EvalContext } from "../core/world";
|
||||||
import { component } from "../core/registry";
|
|
||||||
import { isQuest, type Quest, type QuestStage, type RPGVariables } from "../types";
|
import { isQuest, type Quest, type QuestStage, type RPGVariables } from "../types";
|
||||||
import { evaluateCondition } from "../utils/conditions";
|
import { evaluateCondition } from "../utils/conditions";
|
||||||
|
import { component } from "../utils/decorators";
|
||||||
|
|
||||||
export type QuestStatus = 'inactive' | 'active' | 'completed' | 'failed';
|
export type QuestStatus = 'inactive' | 'active' | 'completed' | 'failed';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { action, variable } from "../utils/decorators";
|
|
||||||
import { Component } from "../core/world";
|
import { Component } from "../core/world";
|
||||||
import { component } from "../core/registry";
|
import { action, component, variable } from "../utils/decorators";
|
||||||
|
|
||||||
interface StatState {
|
interface StatState {
|
||||||
base: number;
|
base: number;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import type { RPGVariables } from "../types";
|
|
||||||
import { action } from "../utils/decorators";
|
|
||||||
import { Component } from "../core/world";
|
import { Component } from "../core/world";
|
||||||
import { component } from "../core/registry";
|
import type { RPGVariables } from "../types";
|
||||||
|
import { action, component } from "../utils/decorators";
|
||||||
|
|
||||||
interface Var {
|
interface Var {
|
||||||
key: string;
|
key: string;
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
import type { Component } from './world';
|
|
||||||
|
|
||||||
type ComponentConstructor = abstract new (...args: any[]) => Component<any>;
|
|
||||||
type MigrationFn = (state: Record<string, unknown>) => Record<string, unknown>;
|
|
||||||
|
|
||||||
interface ComponentMeta {
|
|
||||||
ctor: ComponentConstructor;
|
|
||||||
version: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MigrationEntry {
|
|
||||||
toVersion: number;
|
|
||||||
fn: MigrationFn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const registry = new Map<string, ComponentMeta>();
|
|
||||||
const reverseRegistry = new Map<ComponentConstructor, string>();
|
|
||||||
/** migrations[name][fromVersion] → { toVersion, fn } */
|
|
||||||
const migrations = new Map<string, Map<number, MigrationEntry>>();
|
|
||||||
|
|
||||||
function register(name: string, ctor: ComponentConstructor, version: number): void {
|
|
||||||
registry.set(name, { ctor, version });
|
|
||||||
reverseRegistry.set(ctor, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getComponentMeta(name: string): ComponentMeta | undefined {
|
|
||||||
return registry.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getComponentName(ctor: Function): string | undefined {
|
|
||||||
return reverseRegistry.get(ctor as ComponentConstructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a migration that upgrades component state from `fromVersion` to `toVersion`.
|
|
||||||
* Migrations are chained automatically: registering 0→1 and 1→2 handles saves at version 0.
|
|
||||||
*/
|
|
||||||
export function registerMigration(
|
|
||||||
name: string,
|
|
||||||
fromVersion: number,
|
|
||||||
toVersion: number,
|
|
||||||
fn: MigrationFn,
|
|
||||||
): void {
|
|
||||||
if (!migrations.has(name)) migrations.set(name, new Map());
|
|
||||||
migrations.get(name)!.set(fromVersion, { toVersion, fn });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply all registered migrations to bring `state` from `fromVersion` up to the current
|
|
||||||
* registered version. Returns the migrated state (may be the same object if no migrations ran).
|
|
||||||
*/
|
|
||||||
export function migrateState(
|
|
||||||
name: string,
|
|
||||||
state: Record<string, unknown>,
|
|
||||||
fromVersion: number,
|
|
||||||
): Record<string, unknown> {
|
|
||||||
const meta = registry.get(name);
|
|
||||||
if (!meta) return state;
|
|
||||||
const chain = migrations.get(name);
|
|
||||||
if (!chain) return state;
|
|
||||||
let current = fromVersion;
|
|
||||||
let s = state;
|
|
||||||
while (current < meta.version) {
|
|
||||||
const entry = chain.get(current);
|
|
||||||
if (!entry) throw new Error(
|
|
||||||
`[registry] No migration for '${name}' from version ${current} to ${meta.version}. ` +
|
|
||||||
`Register one with registerMigration('${name}', ${current}, ...).`
|
|
||||||
);
|
|
||||||
s = entry.fn(s);
|
|
||||||
current = entry.toVersion;
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ComponentOptions {
|
|
||||||
name?: string;
|
|
||||||
version?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ComponentDecorator = (target: ComponentConstructor, ctx: ClassDecoratorContext) => void;
|
|
||||||
|
|
||||||
export function component(target: ComponentConstructor, ctx: ClassDecoratorContext): void;
|
|
||||||
export function component(name: string): ComponentDecorator;
|
|
||||||
export function component(options: ComponentOptions): ComponentDecorator;
|
|
||||||
export function component(
|
|
||||||
nameOrTargetOrOptions: string | ComponentConstructor | ComponentOptions,
|
|
||||||
ctx?: ClassDecoratorContext,
|
|
||||||
): void | ComponentDecorator {
|
|
||||||
if (typeof nameOrTargetOrOptions === 'string') {
|
|
||||||
const name = nameOrTargetOrOptions;
|
|
||||||
return (target: ComponentConstructor) => register(name, target, 0);
|
|
||||||
}
|
|
||||||
if (typeof nameOrTargetOrOptions === 'object') {
|
|
||||||
const { name, version = 0 } = nameOrTargetOrOptions;
|
|
||||||
return (target: ComponentConstructor, ctx: ClassDecoratorContext) =>
|
|
||||||
register(name ?? String(ctx.name), target, version);
|
|
||||||
}
|
|
||||||
// Used as bare @component
|
|
||||||
register(String(ctx!.name), nameOrTargetOrOptions, 0);
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { World, Entity, Component, WORLD_ENTITY_COUNTER } from './world';
|
import { World, Entity, Component, WORLD_ENTITY_COUNTER } from './world';
|
||||||
import { getComponentMeta, getComponentName, migrateState } from './registry';
|
import { getComponentMeta, getComponentName, migrateState } from '../utils/decorators';
|
||||||
|
|
||||||
/** Increment this when the WorldData/EntityData structure itself changes incompatibly. */
|
/** Increment this when the WorldData/EntityData structure itself changes incompatibly. */
|
||||||
const SCHEMA_VERSION = 1;
|
const SCHEMA_VERSION = 1;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { ACTION_KEYS, VARIABLE_KEYS } from '../utils/decorators';
|
|
||||||
import type { RPGActions, RPGVariables } from '../types';
|
import type { RPGActions, RPGVariables } from '../types';
|
||||||
import { getComponentName } from './registry';
|
import { ACTION_KEYS, getComponentName, STATE_KEYS, VARIABLE_KEYS } from '../utils/decorators';
|
||||||
|
|
||||||
interface EntityEvent<T = unknown> {
|
interface EntityEvent<T = unknown> {
|
||||||
target: Entity;
|
target: Entity;
|
||||||
|
|
@ -59,14 +58,24 @@ export abstract class Component<TState = Record<string, unknown>> {
|
||||||
getVariables(): RPGVariables {
|
getVariables(): RPGVariables {
|
||||||
const meta = (this.constructor as Function)[Symbol.metadata];
|
const meta = (this.constructor as Function)[Symbol.metadata];
|
||||||
const keys = meta?.[VARIABLE_KEYS] as Map<string | symbol, string> | undefined;
|
const keys = meta?.[VARIABLE_KEYS] as Map<string | symbol, string> | undefined;
|
||||||
if (!keys) return {};
|
const stateKeys = meta?.[STATE_KEYS] as Set<string> | undefined;
|
||||||
const vars: RPGVariables = {};
|
const vars: RPGVariables = {};
|
||||||
|
if (keys) {
|
||||||
for (const [methodKey, exportName] of keys) {
|
for (const [methodKey, exportName] of keys) {
|
||||||
const v = (this as Record<string, unknown>)[String(methodKey)];
|
const v = (this as Record<string, unknown>)[String(methodKey)];
|
||||||
if (typeof v === 'number' || typeof v === 'string' || typeof v === 'boolean') {
|
if (typeof v === 'number' || typeof v === 'string' || typeof v === 'boolean') {
|
||||||
vars[exportName] = v;
|
vars[exportName] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (stateKeys) {
|
||||||
|
for (const key of stateKeys) {
|
||||||
|
const v = (this._state as Record<string, unknown>)[String(key)];
|
||||||
|
if (typeof v === 'number' || typeof v === 'string' || typeof v === 'boolean') {
|
||||||
|
vars[key] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Component } from "../core/world";
|
||||||
import type { RPGVariables } from "../types";
|
import type { RPGVariables } from "../types";
|
||||||
|
|
||||||
// TC39 stage-3 decorators use Symbol.metadata; polyfill for runtimes that lack it (e.g. Bun).
|
// TC39 stage-3 decorators use Symbol.metadata; polyfill for runtimes that lack it (e.g. Bun).
|
||||||
|
|
@ -5,6 +6,7 @@ import type { RPGVariables } from "../types";
|
||||||
|
|
||||||
export const ACTION_KEYS = Symbol('rpg.actions');
|
export const ACTION_KEYS = Symbol('rpg.actions');
|
||||||
export const VARIABLE_KEYS = Symbol('rpg.variables');
|
export const VARIABLE_KEYS = Symbol('rpg.variables');
|
||||||
|
export const STATE_KEYS = Symbol('rpg.state_variables');
|
||||||
|
|
||||||
export function action<T extends (arg?: any, ctx?: any) => unknown>(
|
export function action<T extends (arg?: any, ctx?: any) => unknown>(
|
||||||
target: T,
|
target: T,
|
||||||
|
|
@ -19,11 +21,16 @@ export function action<T extends (arg?: any, ctx?: any) => unknown>(
|
||||||
|
|
||||||
type VariableContext<T extends RPGVariables[string]> =
|
type VariableContext<T extends RPGVariables[string]> =
|
||||||
| ClassFieldDecoratorContext<unknown, T>
|
| ClassFieldDecoratorContext<unknown, T>
|
||||||
| ClassGetterDecoratorContext<unknown, T>;
|
| ClassGetterDecoratorContext<unknown, T>
|
||||||
|
| ClassDecoratorContext;
|
||||||
|
|
||||||
function registerVariable(context: VariableContext<RPGVariables[string]>, exportName: string): void {
|
function registerVariable(context: VariableContext<RPGVariables[string]>, exportName: string, name?: string): void {
|
||||||
const prev = context.metadata[VARIABLE_KEYS] as Map<string | symbol, string> | undefined;
|
const prev = context.metadata[VARIABLE_KEYS] as Map<string | symbol, string> | undefined;
|
||||||
context.metadata[VARIABLE_KEYS] = new Map(prev).set(context.name, exportName);
|
context.metadata[VARIABLE_KEYS] = new Map(prev).set(name ?? context.name ?? exportName, exportName);
|
||||||
|
}
|
||||||
|
function registerStateVariable(context: VariableContext<RPGVariables[string]>, name: string): void {
|
||||||
|
const prev = context.metadata[STATE_KEYS] as Set<string> | undefined;
|
||||||
|
context.metadata[STATE_KEYS] = new Set(prev).add(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function variable(name: string): <T extends RPGVariables[string]>(target: undefined | (() => T), context: VariableContext<T>) => void;
|
export function variable(name: string): <T extends RPGVariables[string]>(target: undefined | (() => T), context: VariableContext<T>) => void;
|
||||||
|
|
@ -41,3 +48,107 @@ export function variable(
|
||||||
}
|
}
|
||||||
registerVariable(context!, String(context!.name));
|
registerVariable(context!, String(context!.name));
|
||||||
}
|
}
|
||||||
|
type ComponentConstructor<T> = abstract new (...args: any[]) => Component<T>;
|
||||||
|
type MigrationFn = (state: Record<string, unknown>) => Record<string, unknown>;
|
||||||
|
|
||||||
|
interface ComponentMeta<T> {
|
||||||
|
ctor: ComponentConstructor<T>;
|
||||||
|
version: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MigrationEntry {
|
||||||
|
toVersion: number;
|
||||||
|
fn: MigrationFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
const registry = new Map<string, ComponentMeta<any>>();
|
||||||
|
const reverseRegistry = new Map<ComponentConstructor<any>, string>();
|
||||||
|
/** migrations[name][fromVersion] → { toVersion, fn } */
|
||||||
|
const migrations = new Map<string, Map<number, MigrationEntry>>();
|
||||||
|
|
||||||
|
function register<T>(name: string, ctor: ComponentConstructor<T>, version: number): void {
|
||||||
|
registry.set(name, { ctor, version });
|
||||||
|
reverseRegistry.set(ctor, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getComponentMeta<T>(name: string): ComponentMeta<T> | undefined {
|
||||||
|
return registry.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getComponentName(ctor: Function): string | undefined {
|
||||||
|
return reverseRegistry.get(ctor as ComponentConstructor<any>);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a migration that upgrades component state from `fromVersion` to `toVersion`.
|
||||||
|
* Migrations are chained automatically: registering 0→1 and 1→2 handles saves at version 0.
|
||||||
|
*/
|
||||||
|
export function registerMigration(
|
||||||
|
name: string,
|
||||||
|
fromVersion: number,
|
||||||
|
toVersion: number,
|
||||||
|
fn: MigrationFn,
|
||||||
|
): void {
|
||||||
|
if (!migrations.has(name)) migrations.set(name, new Map());
|
||||||
|
migrations.get(name)!.set(fromVersion, { toVersion, fn });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all registered migrations to bring `state` from `fromVersion` up to the current
|
||||||
|
* registered version. Returns the migrated state (may be the same object if no migrations ran).
|
||||||
|
*/
|
||||||
|
export function migrateState(
|
||||||
|
name: string,
|
||||||
|
state: Record<string, unknown>,
|
||||||
|
fromVersion: number,
|
||||||
|
): Record<string, unknown> {
|
||||||
|
const meta = registry.get(name);
|
||||||
|
if (!meta) return state;
|
||||||
|
const chain = migrations.get(name);
|
||||||
|
if (!chain) return state;
|
||||||
|
let current = fromVersion;
|
||||||
|
let s = state;
|
||||||
|
while (current < meta.version) {
|
||||||
|
const entry = chain.get(current);
|
||||||
|
if (!entry) throw new Error(
|
||||||
|
`[registry] No migration for '${name}' from version ${current} to ${meta.version}. ` +
|
||||||
|
`Register one with registerMigration('${name}', ${current}, ...).`
|
||||||
|
);
|
||||||
|
s = entry.fn(s);
|
||||||
|
current = entry.toVersion;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ComponentOptions<T> {
|
||||||
|
name?: string;
|
||||||
|
version?: number;
|
||||||
|
variables?: (keyof T)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComponentDecorator<T> = (target: ComponentConstructor<T>, ctx: ClassDecoratorContext) => void;
|
||||||
|
|
||||||
|
export function component<T>(target: ComponentConstructor<T>, ctx: ClassDecoratorContext): void;
|
||||||
|
export function component<T>(name: string): ComponentDecorator<T>;
|
||||||
|
export function component<T>(options: ComponentOptions<T>): ComponentDecorator<T>;
|
||||||
|
export function component<T>(
|
||||||
|
nameOrTargetOrOptions: string | ComponentConstructor<T> | ComponentOptions<T>,
|
||||||
|
ctx?: ClassDecoratorContext,
|
||||||
|
): void | ComponentDecorator<T> {
|
||||||
|
if (typeof nameOrTargetOrOptions === 'string') {
|
||||||
|
const name = nameOrTargetOrOptions;
|
||||||
|
return (target: ComponentConstructor<T>) => register(name, target, 0);
|
||||||
|
}
|
||||||
|
if (typeof nameOrTargetOrOptions === 'object') {
|
||||||
|
const { name, version = 0, variables = [] } = nameOrTargetOrOptions;
|
||||||
|
return (target: ComponentConstructor<T>, ctx: ClassDecoratorContext) => {
|
||||||
|
register(name ?? String(ctx.name), target, version);
|
||||||
|
|
||||||
|
for (const key of variables) {
|
||||||
|
registerStateVariable(ctx, String(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Used as bare @component
|
||||||
|
register(String(ctx!.name), nameOrTargetOrOptions, 0);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
import type { Entity, EvalContext } from "../core/world";
|
||||||
|
import { World } from "../core/world";
|
||||||
import type { RPGAction, RPGActions, RPGVariables } from "../types";
|
import type { RPGAction, RPGActions, RPGVariables } from "../types";
|
||||||
import { isEvalContext, World } from "../core/world";
|
import { getComponentName } from "./decorators";
|
||||||
import type { EvalContext, Entity } from "../core/world";
|
|
||||||
import { getComponentName } from "../core/registry";
|
|
||||||
|
|
||||||
export function resolveVariables(target: Entity | World): RPGVariables {
|
export function resolveVariables(target: Entity | World): RPGVariables {
|
||||||
const result: RPGVariables = {};
|
const result: RPGVariables = {};
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import { Serialization } from "@common/rpg/core/serialization";
|
||||||
import { Factions } from "@common/rpg/components/faction";
|
import { Factions } from "@common/rpg/components/faction";
|
||||||
import { Effect } from "@common/rpg/components/effect";
|
import { Effect } from "@common/rpg/components/effect";
|
||||||
import { Equipment } from "@common/rpg/components/equipment";
|
import { Equipment } from "@common/rpg/components/equipment";
|
||||||
|
import { Position } from "@common/rpg/components/position";
|
||||||
|
|
||||||
export default async function main() {
|
export default async function main() {
|
||||||
const world = new World();
|
const world = new World();
|
||||||
|
|
@ -35,6 +36,7 @@ export default async function main() {
|
||||||
}]));
|
}]));
|
||||||
player.add('str', new Stat({ value: 100 }));
|
player.add('str', new Stat({ value: 100 }));
|
||||||
player.add('agl', new Stat({ value: 100 }));
|
player.add('agl', new Stat({ value: 100 }));
|
||||||
|
player.add(new Position(42, 69));
|
||||||
|
|
||||||
Factions.join(player, 'boobs');
|
Factions.join(player, 'boobs');
|
||||||
Factions.adjustReputation(player, 'guards', 10);
|
Factions.adjustReputation(player, 'guards', 10);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue