//! The write side of the behavior engine. Everything a behavior wants to DO beyond mutating
//! its own projectile and the one enemy it hit becomes a `Command`. Pushed during a pass,
//! drained and applied after. Payoffs: no borrow conflict, one deterministic apply point, and
//! the ability to affect entities you only have READ access to.
use macroquad::math::Vec2;
use crate::{
animations::Animation,
behavior::status::StatusBehavior,
context::DamageMap,
enemy::Enemy,
pool::GroundPool,
types::{DamageDelivery, GameEvent, ResourceKind, Source},
world::{EntityId, Projectile},
};
pub enum TransformEntity {
Enemy,
}
pub struct Transform {
pub entity: TransformEntity,
pub id: EntityId,
pub location: Vec2,
}
pub enum Command {
SpawnProjectile(Projectile),
SpawnPool(GroundPool),
SpawnEnemy(Enemy), // e.g. an enemy that s plits on death
Damage {
target: EntityId,
amount: DamageMap,
source: Source,
delivery: DamageDelivery,
},
ApplyStatus {
target: EntityId,
status: Box<dyn StatusBehavior>,
},
Despawn(EntityId),
GrantResource {
kind: ResourceKind,
amount: u32,
},
Emit(GameEvent), // feeds the SP PassiveEffect bus + UI
SpawnAnimation(Animation),
Replicate(Transform),
}
#[derive(Default)]
pub struct CommandBuffer {
pub cmds: Vec<Command>,
}
impl CommandBuffer {
pub fn spawn_projectile(&mut self, p: Projectile) {
self.cmds.push(Command::SpawnProjectile(p));
}
pub fn spawn_pool(&mut self, p: GroundPool) {
self.cmds.push(Command::SpawnPool(p));
}
pub fn spawn_enemy(&mut self, e: Enemy) {
self.cmds.push(Command::SpawnEnemy(e));
}
pub fn damage(
&mut self,
t: EntityId,
amount: DamageMap,
source: Source,
delivery: DamageDelivery,
) {
self.cmds.push(Command::Damage {
target: t,
amount,
source,
delivery,
});
}
pub fn apply_status(&mut self, t: EntityId, status: Box<dyn StatusBehavior>) {
self.cmds.push(Command::ApplyStatus { target: t, status });
}
pub fn grant_resource(&mut self, kind: ResourceKind, amount: u32) {
self.cmds.push(Command::GrantResource { kind, amount });
}
pub fn despawn(&mut self, t: EntityId) {
self.cmds.push(Command::Despawn(t));
}
pub fn emit(&mut self, e: GameEvent) {
self.cmds.push(Command::Emit(e));
}
pub fn spawn_animation(&mut self, a: Animation) {
self.cmds.push(Command::SpawnAnimation(a));
}
pub fn replicate(&mut self, t: Transform) {
self.cmds.push(Command::Replicate(t));
}
}