import { Agent } from "./agent.ts";
import { Cell } from "./cell.ts";
import { Direction } from "./direction.ts";
import { GameEvent } from "./game-event.ts";
import { isAnimated } from "./animated.ts";
import { Item } from "./item.ts";
/**
* Abstract base class for agent proxies (a kind of decorator class).
*
* Wraps another agent and forwards all behaviour to it, with the exception of
* `onTurn` which is intentionally suppressed so that creature AI is disabled
* for the duration of any proxy effect (giving paralysis for free for
* non-player agents).
*
* Subclasses can override individual callbacks to add effect-specific behaviour.
* The wrapped agent is accessible as `this.agent`.
*
* Mirrors Java's `AgentProxy` abstract class.
*/
export class AgentProxy extends Agent {
protected agent: Agent;
constructor(agent: Agent, flags: number) {
super(agent.name, flags, agent.color, agent.symbol);
this.agent = agent;
}
/**
* Returns true if either the proxy's own flags OR the wrapped agent has the
* given flag. This is critical so that `PLAYER` propagates through
* a `Paralyzed` wrapper.
*/
is(flag: number): boolean {
return this.agent.is(flag) || (this.flags & flag) === flag;
}
/** Returns true only if neither the proxy flags nor the wrapped agent has the given flag. */
not(flag: number): boolean {
return this.agent.not(flag) && (this.flags & flag) !== flag;
}
changeHealth(value: number): number {
return this.agent.changeHealth(value);
}
canEnter(direction: Direction, from: Cell, to: Cell): boolean {
return this.agent.canEnter(direction, from, to);
}
onDie(event: GameEvent, cell: Cell) {
this.agent.onDie(event, cell);
}
onHit(event: GameEvent, attackerCell: Cell, agentLoc: Cell, agent: Agent) {
this.agent.onHit(event, attackerCell, agentLoc, agent);
}
onHitBy(event: GameEvent, agentLoc: Cell, agent: Agent, dir: Direction) {
this.agent.onHitBy(event, agentLoc, agent, dir);
}
onHitByItem(event: GameEvent, itemLoc: Cell, item: Item, dir: Direction) {
this.agent.onHitByItem(event, itemLoc, item, dir);
}
/** Delegates to the wrapped agent's onFrame if it defines one. */
onFrame(event: GameEvent, cell: Cell, frame: number) {
if (isAnimated(this.agent)) {
this.agent.onFrame(event, cell, frame);
}
}
// onTurn is intentionally NOT delegated — suppresses creature AI while any
// proxy effect is active.
}