add ability to move from room to room.
This commit is contained in:
102
Entity.ts
Normal file
102
Entity.ts
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Entity.ts contains the Entity class which is a base class that handles effects and
|
||||
* containing items. It is the base class for Player and Scene.
|
||||
*/
|
||||
|
||||
import type { Conditions, Item, EntityProperties } from "./types.ts";
|
||||
|
||||
export default class Entity<T extends EntityProperties> {
|
||||
protected _conditions: Conditions<T>;
|
||||
protected _properties: T;
|
||||
protected _activeEffects: string[];
|
||||
|
||||
constructor(
|
||||
properties: T,
|
||||
conditions: Conditions<T>,
|
||||
activeEffects: string[] = []
|
||||
) {
|
||||
this._conditions = conditions; // Conditional properties
|
||||
this._properties = properties; // Base properties
|
||||
this._activeEffects = activeEffects;
|
||||
}
|
||||
|
||||
get activeEffects(): string[] {
|
||||
return this._activeEffects;
|
||||
}
|
||||
|
||||
set conditions(conditions: Conditions<T>) {
|
||||
this._conditions = conditions;
|
||||
}
|
||||
|
||||
get properties(): T {
|
||||
return this._properties;
|
||||
}
|
||||
|
||||
set properties(properties: T) {
|
||||
this._properties = properties;
|
||||
}
|
||||
|
||||
addEffect(effect: string): void {
|
||||
this.activeEffects.push(effect);
|
||||
}
|
||||
|
||||
// Player effects should be applied first, then scene effects should be applied.
|
||||
// This will mean that scene effects will take precedence over player effects.
|
||||
// Returns base properties with conditional properties applied.
|
||||
applyEffects(
|
||||
activePlayerEffects: string[],
|
||||
activeSceneEffects: string[]
|
||||
): T {
|
||||
const playerSet = new Set(activePlayerEffects);
|
||||
const sceneSet = new Set(activeSceneEffects);
|
||||
|
||||
const effects = this._conditions.effects.filter(({ name, source }) => {
|
||||
const set = source === "player" ? playerSet : sceneSet;
|
||||
return set.has(name);
|
||||
});
|
||||
|
||||
const appliedProperties = { ...this._properties };
|
||||
|
||||
// for each effect, apply changed properties to the
|
||||
for (const effect of effects) {
|
||||
Object.assign(appliedProperties, effect.properties);
|
||||
}
|
||||
|
||||
return appliedProperties;
|
||||
}
|
||||
|
||||
// Generate a description of the contained items
|
||||
description(items: Item[]): string | null {
|
||||
if (items.length === 0) return null;
|
||||
|
||||
const vowels = ["a", "e", "i", "o", "u"];
|
||||
const description = items
|
||||
.map(({ name }, i) => {
|
||||
let anItem = `${vowels.includes(name[0]) ? "an" : "a"} ${name}`;
|
||||
|
||||
// if we have more than one item, and this is the last item...
|
||||
if (i > 1 && i + 1 === items.length) {
|
||||
anItem = `and ${anItem}`;
|
||||
}
|
||||
|
||||
return anItem;
|
||||
})
|
||||
.join(", ");
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
// Checks if a given effect exists as an active effect on this entity
|
||||
hasActiveEffect(effect: string): boolean {
|
||||
return this._activeEffects.includes(effect);
|
||||
}
|
||||
|
||||
// Removes an effect if it is active on this entity
|
||||
removeEffect(effect: string): void {
|
||||
const idx = this._activeEffects.findIndex((e) => e === effect);
|
||||
|
||||
if (idx >= 0) {
|
||||
this._activeEffects.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user