use npc_engine_core::{
impl_task_boxed_methods, AgentId, StateDiffRef, StateDiffRefMut, Task, TaskDuration,
};
use npc_engine_utils::Direction;
use crate::{
constants::MOVE_WEIGHT,
domain::{DisplayAction, EcosystemDomain},
map::DirConv,
state::{Access, AccessMut},
};
#[derive(Hash, Clone, Eq, PartialEq, Debug)]
pub struct Move(pub Direction);
impl Task<EcosystemDomain> for Move {
fn weight(
&self,
_tick: u64,
_state_diff: StateDiffRef<EcosystemDomain>,
_agent: AgentId,
) -> f32 {
MOVE_WEIGHT
}
fn duration(
&self,
_tick: u64,
_state_diff: StateDiffRef<EcosystemDomain>,
_agent: AgentId,
) -> TaskDuration {
0
}
fn execute(
&self,
_tick: u64,
mut state_diff: StateDiffRefMut<EcosystemDomain>,
agent: AgentId,
) -> Option<Box<dyn Task<EcosystemDomain>>> {
let agent_state = state_diff.get_agent_mut(agent).unwrap();
let target_pos = DirConv::apply(self.0, agent_state.position);
agent_state.position = target_pos;
None
}
fn is_valid(
&self,
_tick: u64,
state_diff: StateDiffRef<EcosystemDomain>,
agent: AgentId,
) -> bool {
let agent_state = state_diff.get_agent(agent).unwrap();
debug_assert!(
agent_state.alive,
"Task validity check called on a dead agent"
);
if !agent_state.alive {
return false;
}
let target_pos = DirConv::apply(self.0, agent_state.position);
state_diff.is_position_free(target_pos)
}
fn display_action(&self) -> DisplayAction {
DisplayAction::Move(self.0)
}
impl_task_boxed_methods!(EcosystemDomain);
}