Skip to content

Commit

Permalink
fix(world): remove redundant lookup from transfer helpers, since clie…
Browse files Browse the repository at this point in the history
…nts already have target info
  • Loading branch information
ssube committed May 19, 2021
1 parent dd03793 commit 518d94c
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 40 deletions.
24 changes: 18 additions & 6 deletions src/service/script/common/ActorStep.ts
Expand Up @@ -64,8 +64,20 @@ export async function ActorStepDrop(this: Actor, context: ScriptContext): Promis
const cmd = mustExist(context.command);
const room = mustExist(context.room);

const [moving] = searchStateString(context.state, {
meta: cmd.target,
room: {
id: room.meta.id,
},
});

if (!isItem(moving)) {
await context.focus.show(`${moving.meta.name} is not an item`);
return;
}

await context.transfer.moveItem({
moving: cmd.target,
moving,
source: this.meta.id,
target: room.meta.id,
}, context);
Expand Down Expand Up @@ -157,7 +169,7 @@ export async function ActorStepMove(this: Actor, context: ScriptContext): Promis
// move the actor and focus
await context.focus.show(`${this.meta.name} moved to ${targetPortal.name}`);
await context.transfer.moveActor({
moving: this.meta.id,
moving: this,
source: currentRoom.meta.id,
target: targetPortal.dest
}, context);
Expand All @@ -172,20 +184,20 @@ export async function ActorStepTake(this: Actor, context: ScriptContext): Promis
const room = mustExist(context.room);
context.logger.debug({ cmd, room }, 'taking item from room');

const [target] = searchStateString(context.state, {
const [moving] = searchStateString(context.state, {
meta: cmd.target,
room: {
id: room.meta.id,
},
});

if (!isItem(target)) {
await context.focus.show(`${target.meta.name} is not an item`);
if (!isItem(moving)) {
await context.focus.show(`${moving.meta.name} is not an item`);
return;
}

await context.transfer.moveItem({
moving: target.meta.id,
moving,
source: room.meta.id,
target: this.meta.id
}, context);
Expand Down
8 changes: 4 additions & 4 deletions src/service/script/index.ts
Expand Up @@ -28,11 +28,11 @@ export interface ScriptFocus {
show(msg: string, source?: WorldEntity): Promise<void>;
}

export interface TransferParams {
export interface TransferParams<TEntity extends WorldEntity> {
/**
* The entity to transfer.
*/
moving: string;
moving: TEntity;

/**
* The source container from which `id` will be transferred.
Expand All @@ -51,12 +51,12 @@ export interface ScriptTransfer {
/**
* Move an actor from one room to another.
*/
moveActor(transfer: TransferParams, context: ScriptContext): Promise<void>;
moveActor(transfer: TransferParams<Actor>, context: ScriptContext): Promise<void>;

/**
* Move an item from one actor or room to another.
*/
moveItem(transfer: TransferParams, context: ScriptContext): Promise<void>;
moveItem(transfer: TransferParams<Item>, context: ScriptContext): Promise<void>;
}

export type ScriptTarget = WorldEntity;
Expand Down
64 changes: 34 additions & 30 deletions src/util/state/transfer.ts
@@ -1,14 +1,14 @@
import { Logger } from 'noicejs';

import { isActor } from '../../model/entity/Actor';
import { isItem } from '../../model/entity/Item';
import { Actor, isActor } from '../../model/entity/Actor';
import { isItem, Item } from '../../model/entity/Item';
import { isRoom, ROOM_TYPE } from '../../model/entity/Room';
import { State } from '../../model/State';
import { ScriptContext, TransferParams } from '../../service/script';
import { ScriptContext, ScriptTransfer, TransferParams } from '../../service/script';
import { SLOT_ENTER, SLOT_GET } from '../constants';
import { searchState, searchStateString } from './search';

export class StateEntityTransfer {
export class StateEntityTransfer implements ScriptTransfer {
protected logger: Logger;
protected state: State;

Expand All @@ -17,43 +17,47 @@ export class StateEntityTransfer {
this.state = state;
}

public async moveActor(transfer: TransferParams, context: ScriptContext): Promise<void> {
const [targetRoom] = searchState(this.state, {
public async moveActor(transfer: TransferParams<Actor>, context: ScriptContext): Promise<void> {
if (!isActor(transfer.moving)) {
this.logger.warn(transfer, 'moving entity is not an actor');
return;
}

const [target] = searchState(this.state, {
meta: {
id: transfer.target,
},
type: ROOM_TYPE,
});
if (!isRoom(targetRoom)) {
if (!isRoom(target)) {
this.logger.warn(transfer, 'destination room does not exist');
return;
}

const [currentRoom] = searchState(this.state, {
const [source] = searchState(this.state, {
meta: {
id: transfer.source,
},
type: ROOM_TYPE,
});

if (!isRoom(currentRoom)) {
if (!isRoom(source)) {
this.logger.warn(transfer, 'source room does not exist');
return;
}

const targetActor = currentRoom.actors.find((it) => it.meta.id === transfer.moving);
if (!isActor(targetActor)) {
this.logger.warn(transfer, 'target actor does not exist');
const idx = source.actors.indexOf(transfer.moving);
if (idx < 0) {
this.logger.warn({ source, transfer }, 'source does not directly contain moving entity');
return;
}

// move the actor
this.logger.debug(transfer, 'moving actor between rooms');
currentRoom.actors.splice(currentRoom.actors.indexOf(targetActor), 1);
targetRoom.actors.push(targetActor);
source.actors.splice(idx, 1);
target.actors.push(transfer.moving);

await context.script.invoke(targetRoom, SLOT_ENTER, {
actor: targetActor,
await context.script.invoke(target, SLOT_ENTER, {
actor: transfer.moving,
data: {
source: transfer.source,
},
Expand All @@ -63,7 +67,12 @@ export class StateEntityTransfer {
});
}

public async moveItem(transfer: TransferParams, context: ScriptContext): Promise<void> {
public async moveItem(transfer: TransferParams<Item>, context: ScriptContext): Promise<void> {
if (!isItem(transfer.moving)) {
this.logger.warn(transfer, 'moving entity is not an item');
return;
}

if (transfer.source === transfer.target) {
this.logger.debug(transfer, 'cannot transfer item between the same source and target');
return;
Expand All @@ -83,34 +92,29 @@ export class StateEntityTransfer {
},
});

// find moving item
const [moving] = searchStateString(this.state, {
meta: transfer.moving,
});

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

const idx = source.items.indexOf(moving);
const idx = source.items.indexOf(transfer.moving);
if (idx < 0) {
this.logger.warn({ moving, source }, 'source does not directly contain moving entity');
this.logger.warn({ source, transfer }, 'source does not directly contain moving entity');
return;
}

// move target from source to dest
this.logger.debug({
moving,
source,
target,
transfer,
}, 'moving item between entities');
source.items.splice(idx, 1);
target.items.push(moving);
target.items.push(transfer.moving);

await context.script.invoke(target, SLOT_GET, {
item: moving,
item: transfer.moving,
data: {
source: transfer.source,
},
Expand Down

0 comments on commit 518d94c

Please sign in to comment.