Skip to content

Commit

Permalink
feat(util): add state search helper for name or id
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed May 16, 2021
1 parent b823475 commit 2266380
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 61 deletions.
51 changes: 6 additions & 45 deletions src/service/script/LocalScriptController.ts
@@ -1,11 +1,10 @@
import { doesExist, isNil } from '@apextoaster/js-utils';
import { BaseOptions, Inject, Logger } from 'noicejs';

import { ScriptController, ScriptFunction, ScriptTarget, ScriptTargetFilter, SuppliedScope } from '.';
import { Metadata } from '../../model/meta/Metadata';
import { ScriptController, ScriptFunction, ScriptTarget, SuppliedScope } from '.';
import { State } from '../../model/State';
import { INJECT_LOGGER } from '../../module';
import { matchMetadata } from '../../util/state';
import { matchMetadata, SearchParams, searchState } from '../../util/state';
import { ActorHit } from './common/ActorHit';
import { ActorStep } from './common/ActorStep';
import { ItemStep } from './common/ItemStep';
Expand Down Expand Up @@ -60,49 +59,11 @@ export class LocalScriptController implements ScriptController {
});
}

/**
* @todo use searchState to find target entities once it supports room filter
*/
async broadcast(state: State, filter: ScriptTargetFilter, slot: string, scope: SuppliedScope): Promise<void> {
for (const room of state.rooms) {
if (doesExist(filter.room)) {
if (matchMetadata(room, filter.room) === false) {
// skip rooms that do not match
continue;
}
}
async broadcast(state: State, filter: Partial<SearchParams>, slot: string, scope: SuppliedScope): Promise<void> {
const targets = searchState(state, filter);

if (this.match(room, filter)) {
await this.invoke(room, slot, scope);
}

for (const actor of room.actors) {
if (this.match(actor, filter)) {
await this.invoke(actor, slot, scope);
}

for (const item of actor.items) {
if (this.match(item, filter)) {
await this.invoke(item, slot, scope);
}
}
}

for (const item of room.items) {
if (this.match(item, filter)) {
await this.invoke(item, slot, scope);
}
}
}
}

match(target: ScriptTarget, filter: ScriptTargetFilter): boolean {
let matched = true;

if (doesExist(filter.meta)) {
matched = matched && matchMetadata(target, filter.meta);
for (const target of targets) {
await this.invoke(target, slot, scope);
}

return matched;
}
}
2 changes: 1 addition & 1 deletion src/service/script/common/RoomStep.ts
Expand Up @@ -16,7 +16,7 @@ export async function RoomStep(this: ScriptTarget, scope: ScriptScope): Promise<
// TODO: remove
await scope.script.broadcast(scope.state, {
meta: {
id: 'bon',
id: 'actor-goblin',
},
room: {
id: this.meta.id,
Expand Down
9 changes: 2 additions & 7 deletions src/service/script/index.ts
Expand Up @@ -4,8 +4,8 @@ import { WorldEntity } from '../../model/entity';
import { Actor } from '../../model/entity/Actor';
import { Item } from '../../model/entity/Item';
import { Room } from '../../model/entity/Room';
import { Metadata } from '../../model/meta/Metadata';
import { State } from '../../model/State';
import { SearchParams } from '../../util/state';
import { Immutable, ScriptData } from '../../util/types';
import { Command } from '../input';

Expand Down Expand Up @@ -78,12 +78,7 @@ export interface ScriptScope extends SuppliedScope {
script: ScriptController;
}

export type ScriptTargetFilter = {
meta?: Partial<Metadata>;
room?: Partial<Metadata>;
};

export interface ScriptController {
broadcast(state: Immutable<State>, filter: ScriptTargetFilter, slot: string, scope: SuppliedScope): Promise<void>;
broadcast(state: Immutable<State>, search: Partial<SearchParams>, slot: string, scope: SuppliedScope): Promise<void>;
invoke(target: ScriptTarget, slot: string, scope: SuppliedScope): Promise<void>;
}
10 changes: 3 additions & 7 deletions src/service/state/LocalStateController.ts
Expand Up @@ -19,7 +19,7 @@ import {
} from '../../module';
import { PORTAL_DEPTH, SLOT_ENTER, SLOT_STEP } from '../../util/constants';
import { Counter } from '../../util/counter';
import { searchState } from '../../util/state';
import { searchState, searchStateString } from '../../util/state';
import { findByTemplateId } from '../../util/template';
import { ActorInputMapper } from '../input/ActorInputMapper';
import { RandomGenerator } from '../random';
Expand Down Expand Up @@ -188,15 +188,11 @@ export class LocalStateController implements StateController {
});

// find target item
const [target] = searchState(state, {
meta: {
id,
},
type: ITEM_TYPE,
});
const [target] = searchStateString(state, id);

// ensure source and dest are both actor/room (types are greatly narrowed after these guards)
if (isItem(source) || isItem(dest) || !isItem(target)) {
this.logger.debug({ dest, source, target }, 'invalid entity type for item transfer');
return;
}

Expand Down
23 changes: 22 additions & 1 deletion src/util/state/index.ts
Expand Up @@ -7,14 +7,20 @@ import { State } from '../../model/State';

export interface SearchParams {
meta: Partial<Metadata>;
// TODO: match room: Partial<Metadata>
room: Partial<Metadata>
type: WorldEntityType;
}

export function searchState(state: State, search: Partial<SearchParams>): Array<WorldEntity> {
const results: Array<WorldEntity> = [];

for (const room of state.rooms) {
if (doesExist(search.room)) {
if (matchMetadata(room, search.room) === false) {
continue;
}
}

if (matchEntity(room, search)) {
results.push(room);
}
Expand All @@ -41,6 +47,21 @@ export function searchState(state: State, search: Partial<SearchParams>): Array<
return results;
}

export function searchStateString(state: State, value: string): Array<WorldEntity> {
return [
...searchState(state, {
meta: {
id: value,
},
}),
...searchState(state, {
meta: {
name: value,
},
}),
];
}

export function matchEntity(entity: Entity, search: Partial<SearchParams>): boolean {
let matched = true;

Expand Down

0 comments on commit 2266380

Please sign in to comment.