use npc_engine_core::{
impl_task_boxed_methods, AgentId, StateDiffRef, StateDiffRefMut, Task, TaskDuration,
};
use npc_engine_utils::OptionDiffDomain;
use crate::{
constants::{RESPAWN_AMMO_DURATION, RESPAWN_MEDKIT_DURATION},
domain::{CaptureDomain, DisplayAction},
state::CapturePointState,
};
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct WorldStep;
impl Task<CaptureDomain> for WorldStep {
fn duration(
&self,
_tick: u64,
_state_diff: StateDiffRef<CaptureDomain>,
_agent: AgentId,
) -> TaskDuration {
1
}
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);
for capture_point in &diff.capture_points {
if let CapturePointState::Captured(agent) = capture_point {
if let Some(agent_state) = diff.agents.get_mut(agent) {
agent_state.acc_capture += 1;
}
}
}
let now = (tick & 0xff) as u8;
if respawn_timeout_ammo(now, diff.ammo_tick) {
diff.ammo = 1;
diff.ammo_tick = now;
}
if respawn_timeout_medkit(now, diff.medkit_tick) {
diff.medkit = 1;
diff.medkit_tick = now;
}
Some(Box::new(WorldStep))
}
fn display_action(&self) -> DisplayAction {
DisplayAction::WorldStep
}
fn is_valid(
&self,
_tick: u64,
_state_diff: StateDiffRef<CaptureDomain>,
_agent: AgentId,
) -> bool {
true
}
impl_task_boxed_methods!(CaptureDomain);
}
fn respawn_timeout_ammo(now: u8, before: u8) -> bool {
now.wrapping_sub(before) > RESPAWN_AMMO_DURATION
}
fn respawn_timeout_medkit(now: u8, before: u8) -> bool {
now.wrapping_sub(before) > RESPAWN_MEDKIT_DURATION
}