use npc_engine_core::{
impl_task_boxed_methods, AgentId, StateDiffRef, StateDiffRefMut, Task, TaskDuration,
};
use npc_engine_utils::OptionDiffDomain;
use crate::{
constants::MAP,
domain::{CaptureDomain, DisplayAction},
map::Location,
};
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct StartMoving {
pub to: Location,
}
impl Task<CaptureDomain> for StartMoving {
fn duration(
&self,
_tick: u64,
_state_diff: StateDiffRef<CaptureDomain>,
_agent: AgentId,
) -> TaskDuration {
0
}
fn execute(
&self,
_tick: u64,
state_diff: StateDiffRefMut<CaptureDomain>,
agent: AgentId,
) -> Option<Box<dyn Task<CaptureDomain>>> {
let diff = CaptureDomain::get_cur_state_mut(state_diff);
let agent_state = diff.agents.get_mut(&agent).unwrap();
let to = self.to;
agent_state.next_location = Some(to);
let from = agent_state.cur_or_last_location;
Some(Box::new(Moving { from, to }))
}
fn display_action(&self) -> DisplayAction {
DisplayAction::StartMoving(self.to)
}
fn is_valid(
&self,
_tick: u64,
state_diff: StateDiffRef<CaptureDomain>,
agent: AgentId,
) -> bool {
let state = CaptureDomain::get_cur_state(state_diff);
state.agents.get(&agent).map_or(false, |agent_state| {
let location = agent_state.cur_or_last_location;
agent_state.next_location.is_none() &&
MAP.is_path(location, self.to)
})
}
impl_task_boxed_methods!(CaptureDomain);
}
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct Moving {
from: Location,
to: Location,
}
impl Task<CaptureDomain> for Moving {
fn duration(
&self,
_tick: u64,
_state_diff: StateDiffRef<CaptureDomain>,
_agent: AgentId,
) -> TaskDuration {
MAP.path_len(self.from, self.to).unwrap()
}
fn execute(
&self,
_tick: u64,
state_diff: StateDiffRefMut<CaptureDomain>,
agent: AgentId,
) -> Option<Box<dyn Task<CaptureDomain>>> {
let diff = CaptureDomain::get_cur_state_mut(state_diff);
let agent_state = diff.agents.get_mut(&agent).unwrap();
agent_state.cur_or_last_location = self.to;
agent_state.next_location = None;
None
}
fn display_action(&self) -> DisplayAction {
DisplayAction::Moving(self.to)
}
fn is_valid(
&self,
_tick: u64,
state_diff: StateDiffRef<CaptureDomain>,
agent: AgentId,
) -> bool {
let state = CaptureDomain::get_cur_state(state_diff);
state.agents.get(&agent).is_some()
}
impl_task_boxed_methods!(CaptureDomain);
}