import { Color } from "./color.ts";
import { Piece } from "./piece.ts";
import { Sym } from "./sym.ts";
import { TRANSIENT } from "./flags.ts";
/**
* Base class for all effect types.
*
* Effects are transient pieces (not saved with the board) used to animate
* thrown items, projectiles, fire, clouds, etc. Unlike terrain/items/agents,
* effects are NOT immutable — they maintain frame state as they animate.
*
* Effects implement `onFrame(event, cell, frame)` and are registered with the
* board's AnimationProxy list when added to a cell (mirrors Java's EffectBag
* registering Animated effects via board.addAnimated). Each effect gets its
* own proxy with a frame counter starting at 0 (randomSeed = false).
*
* Effects self-remove by calling cell.removeEffect(this) inside onFrame when
* their animation is complete, matching Java's cell.getEffects().remove(this).
*/
export class Effect extends Piece {
frames: Sym[];
frameIndex: number;
done: boolean;
constructor(name: string, frames: Sym[], color: Color) {
if (frames.length === 0) {
throw new Error("Effect must have at least one frame");
}
// Effects always have the TRANSIENT flag
super(name, TRANSIENT, color, frames[0]);
this.frames = frames;
this.frameIndex = 0;
this.done = false;
}
/**
* Effects always start at frame 0 (not a random seed). Mirrors Java where
* all effects return randomSeed() = false.
*/
randomSeed(): boolean {
return false;
}
/** Current animation frame symbol. */
get currentSymbol(): Sym {
return this.frames[this.frameIndex];
}
/** True if this effect has finished animating and should be removed. */
get isExpired(): boolean {
return this.done;
}
/**
* Should this effect render above an agent that occupies the same cell?
* Override to return true for effects that should appear on top.
*/
isAboveAgent(): boolean {
return false;
}
}