import { Piece } from "./piece.js";
import { TRANSIENT } from "./flags.js";
/**
* 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.
*
* An effect has an array of animation frames (Symbols). The AnimationManager
* calls onTick() each frame to advance the effect.
*/
export class Effect extends Piece {
/**
* @param {string} name
* @param {Symbol[]} frames - animation frame symbols
* @param {string} color
*/
constructor(name, frames, color) {
if (!frames || 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;
}
/** Current animation frame symbol. */
get currentSymbol() {
return this.frames[this.frameIndex];
}
/** True if this effect has finished animating and should be removed. */
get isExpired() {
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.
* @returns {boolean}
*/
isAboveAgent() {
return false;
}
/**
* Advance the effect by one tick. Called by AnimationManager each animation frame.
* Override in subclasses to implement movement, spreading, damage, etc.
* @param {GameEvent} event
* @param {Board} board
* @param {Cell} cell
*/
onTick(event, board, cell) {
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
}
}