Skip to content

Commit

Permalink
feat(state): remove verbs by setting script name to empty (fixes #75)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jun 3, 2021
1 parent 97bfb3e commit 7932c5c
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 30 deletions.
4 changes: 4 additions & 0 deletions data/base.yml
Expand Up @@ -396,6 +396,10 @@ worlds:
data: !map {}
name:
base: room-step
verbs.common.move:
data: !map {}
name:
base: ''
verbs.world.slog:
data: !map {}
name:
Expand Down
4 changes: 2 additions & 2 deletions src/script/signal/actor/ActorStep.ts
Expand Up @@ -4,7 +4,7 @@ import { ActorType, isActor } from '../../../model/entity/Actor';
import { ScriptContext, ScriptTarget } from '../../../service/script';
import { getKey } from '../../../util/collection/map';
import { STAT_HEALTH } from '../../../util/constants';
import { getScripts } from '../../../util/state';
import { getVerbScripts } from '../../../util/state';

export async function ActorStep(this: ScriptTarget, context: ScriptContext): Promise<void> {
context.logger.debug({
Expand Down Expand Up @@ -32,7 +32,7 @@ export async function ActorStep(this: ScriptTarget, context: ScriptContext): Pro

const { command } = context;

const scripts = getScripts(context.state, this);
const scripts = getVerbScripts(context.state, this);
if (scripts.has(command.verb) === false) {
await context.stateHelper.show('actor.step.command.unknown', { actor: this, command });
context.logger.warn({ command }, 'unknown verb');
Expand Down
4 changes: 2 additions & 2 deletions src/service/script/LocalScript.ts
Expand Up @@ -19,7 +19,7 @@ import {
ActorStepUse,
ActorStepWait,
} from '../../script/verb/common';
import { getScripts, SearchParams, searchState } from '../../util/state';
import { getVerbScripts, SearchParams, searchState } from '../../util/state';

/**
* Common scripts, built into the engine and always available.
Expand Down Expand Up @@ -61,7 +61,7 @@ export class LocalScriptService implements ScriptService {
public async invoke(target: ScriptTarget, slot: string, scope: SuppliedScope): Promise<void> {
this.logger.debug({ slot, target }, 'trying to invoke slot on target');

const scripts = getScripts(scope.state, target);
const scripts = getVerbScripts(scope.state, target);
const scriptRef = scripts.get(slot);

if (isNil(scriptRef)) {
Expand Down
12 changes: 8 additions & 4 deletions src/service/state/TurnState.ts
Expand Up @@ -33,12 +33,13 @@ import {
META_LOAD,
META_QUIT,
META_SAVE,
META_VERBS,
META_WORLDS,
SLOT_STEP,
VERB_PREFIX,
VERB_WAIT,
} from '../../util/constants';
import { getScripts } from '../../util/state';
import { getVerbScripts } from '../../util/state';
import { debugState, graphState } from '../../util/state/debug';
import { StateEntityGenerator } from '../../util/state/EntityGenerator';
import { StateEntityTransfer } from '../../util/state/EntityTransfer';
Expand Down Expand Up @@ -365,9 +366,12 @@ export class LocalStateService implements StateService {
}

public async doHelp(actor: Optional<Actor>): Promise<void> {
const scripts = getScripts(this.state, actor);
const verbs = Array.from(scripts.keys())
.filter((it) => it.startsWith(VERB_PREFIX))
const scripts = getVerbScripts(this.state, actor);
const worldVerbs = Array.from(scripts.keys()).filter((it) => it.startsWith(VERB_PREFIX));
const verbs = [
...worldVerbs,
...META_VERBS,
].sort()
.map((it) => `$t(${it})`)
.join(', ');

Expand Down
39 changes: 19 additions & 20 deletions src/util/state/index.ts
Expand Up @@ -141,18 +141,22 @@ export function findContainer(state: WorldState, search: Partial<SearchParams>,
/**
* @todo remove existing verbs
*/
export function getScripts(state: Optional<Immutable<WorldState>>, target: Optional<WorldEntity>): ScriptMap {
export function getVerbScripts(state: Optional<Immutable<WorldState>>, target: Optional<WorldEntity>): ScriptMap {
const scripts: ScriptMap = new Map();

// TODO: this should only be in getVerbs, not getScripts
for (const verb of META_VERBS) {
scripts.set(verb, {
data: new Map(),
name: '',
});
}

if (doesExist(target)) {
mergeMap(scripts, target.scripts);

if (!isItem(target)) {
for (const item of target.items) {
for (const [name, script] of item.scripts) {
if (name.startsWith(VERB_PREFIX)) {
scripts.set(name, script);
}
}
}
}

// TODO: bad cast
if (!isRoom(target)) {
const [room] = findRoom(mustExist(state) as WorldState, {
Expand All @@ -169,19 +173,14 @@ export function getScripts(state: Optional<Immutable<WorldState>>, target: Optio
}
}
}
}

if (!isItem(target)) {
for (const item of target.items) {
for (const [name, script] of item.scripts) {
if (name.startsWith(VERB_PREFIX)) {
scripts.set(name, script);
}
}
}
const scriptNames = Array.from(scripts.keys()); // needs to be pulled AOT since the Map will be mutated
for (const name of scriptNames) {
const script = scripts.get(name);
if (doesExist(script) && script.name.length === 0) {
scripts.delete(name);
}

// merge everything, including signals, from the target
mergeMap(scripts, target.scripts);
}

return scripts;
Expand Down
8 changes: 6 additions & 2 deletions src/util/template/SplitChain.ts
@@ -1,5 +1,5 @@
import { InvalidArgumentError } from '@apextoaster/js-utils';
import { alt, createLanguage, regexp, string } from 'parsimmon';
import { alt, createLanguage, regexp, string, empty } from 'parsimmon';

import { InputChain } from '.';

Expand All @@ -13,16 +13,20 @@ export interface SplitOptions {

export function splitChain(input: string, options: SplitOptions): InputChain {
const lang = createLanguage<{
Empty: string,
List: InputChain;
Token: string;
Top: InputChain;
Value: InputChain;
}>({
Empty: () => regexp(/^$/),
List: (r) => string(options.group.start).then(r.Value.sepBy(string(options.split))).skip(string(options.group.end)),
Token: () => regexp(/[-a-zA-Z ]+/),
Top: (r) => alt(r.Value, r.Empty),
Value: (r) => alt(r.List, r.Token),
});

const parse = lang.Value.tryParse(input);
const parse = lang.Top.tryParse(input);
if (typeof parse === 'string') {
return [parse];
}
Expand Down

0 comments on commit 7932c5c

Please sign in to comment.