Split action state into two sets of state, one each for combat and behavior.

This commit is contained in:
Sam 2023-11-12 12:45:03 -05:00
parent ef858ef72b
commit a4df3f8ad5
6 changed files with 300 additions and 298 deletions

View File

@ -589,7 +589,8 @@ pub struct Agent {
pub behavior: Behavior, pub behavior: Behavior,
pub psyche: Psyche, pub psyche: Psyche,
pub inbox: VecDeque<AgentEvent>, pub inbox: VecDeque<AgentEvent>,
pub action_state: ActionState, pub combat_state: ActionState,
pub behavior_state: ActionState,
pub timer: Timer, pub timer: Timer,
pub bearing: Vec2<f32>, pub bearing: Vec2<f32>,
pub sounds_heard: Vec<Sound>, pub sounds_heard: Vec<Sound>,
@ -699,7 +700,8 @@ impl Agent {
behavior: Behavior::default(), behavior: Behavior::default(),
psyche: Psyche::from(body), psyche: Psyche::from(body),
inbox: VecDeque::new(), inbox: VecDeque::new(),
action_state: ActionState::default(), combat_state: ActionState::default(),
behavior_state: ActionState::default(),
timer: Timer::default(), timer: Timer::default(),
bearing: Vec2::zero(), bearing: Vec2::zero(),
sounds_heard: Vec::new(), sounds_heard: Vec::new(),

View File

@ -229,15 +229,15 @@ impl<'a> AgentData<'a> {
true true
}; };
if attempt_heal && self.heal_self(agent, controller, true) { if attempt_heal && self.heal_self(agent, controller, true) {
agent.action_state.timers[ActionTimers::TimerIdle as usize] = 0.01; agent.behavior_state.timers[ActionTimers::TimerIdle as usize] = 0.01;
return; return;
} }
} else { } else {
agent.action_state.timers[ActionTimers::TimerIdle as usize] = 0.01; agent.behavior_state.timers[ActionTimers::TimerIdle as usize] = 0.01;
return; return;
} }
agent.action_state.timers[ActionTimers::TimerIdle as usize] = 0.0; agent.behavior_state.timers[ActionTimers::TimerIdle as usize] = 0.0;
'activity: { 'activity: {
match agent.rtsim_controller.activity { match agent.rtsim_controller.activity {
@ -791,7 +791,7 @@ impl<'a> AgentData<'a> {
enum ActionStateTimers { enum ActionStateTimers {
TimerChooseTarget = 0, TimerChooseTarget = 0,
} }
agent.action_state.timers[ActionStateTimers::TimerChooseTarget as usize] = 0.0; agent.behavior_state.timers[ActionStateTimers::TimerChooseTarget as usize] = 0.0;
let mut aggro_on = false; let mut aggro_on = false;
// Search the area. // Search the area.

File diff suppressed because it is too large Load Diff

View File

@ -248,15 +248,15 @@ pub fn handle_attack_aggression(
position_flee_index: usize, position_flee_index: usize,
) -> bool { ) -> bool {
if let Some(health) = agent_data.health { if let Some(health) = agent_data.health {
agent.action_state.int_counters[icounter_action_mode_index] = if health.fraction() < 0.1 { agent.combat_state.int_counters[icounter_action_mode_index] = if health.fraction() < 0.1 {
agent.action_state.positions[position_guarded_cover_index] = None; agent.combat_state.positions[position_guarded_cover_index] = None;
ActionMode::Fleeing as u8 ActionMode::Fleeing as u8
} else if health.fraction() < 0.9 { } else if health.fraction() < 0.9 {
agent.action_state.positions[position_flee_index] = None; agent.combat_state.positions[position_flee_index] = None;
ActionMode::Guarded as u8 ActionMode::Guarded as u8
} else { } else {
agent.action_state.positions[position_guarded_cover_index] = None; agent.combat_state.positions[position_guarded_cover_index] = None;
agent.action_state.positions[position_flee_index] = None; agent.combat_state.positions[position_flee_index] = None;
ActionMode::Reckless as u8 ActionMode::Reckless as u8
}; };
} }
@ -264,48 +264,48 @@ pub fn handle_attack_aggression(
// If agent has not moved, assume agent was unable to move and reset attempted // If agent has not moved, assume agent was unable to move and reset attempted
// path positions if occurs for too long // path positions if occurs for too long
if agent_data.vel.0.magnitude_squared() < 1_f32.powi(2) { if agent_data.vel.0.magnitude_squared() < 1_f32.powi(2) {
agent.action_state.timers[timer_pos_timeout_index] += read_data.dt.0; agent.combat_state.timers[timer_pos_timeout_index] += read_data.dt.0;
} else { } else {
agent.action_state.timers[timer_pos_timeout_index] = 0.0; agent.combat_state.timers[timer_pos_timeout_index] = 0.0;
} }
if agent.action_state.timers[timer_pos_timeout_index] > 2.0 { if agent.combat_state.timers[timer_pos_timeout_index] > 2.0 {
agent.action_state.positions[position_guarded_cover_index] = None; agent.combat_state.positions[position_guarded_cover_index] = None;
agent.action_state.positions[position_flee_index] = None; agent.combat_state.positions[position_flee_index] = None;
agent.action_state.timers[timer_pos_timeout_index] = 0.0; agent.combat_state.timers[timer_pos_timeout_index] = 0.0;
} }
match ActionMode::from_u8(agent.action_state.int_counters[icounter_action_mode_index]) { match ActionMode::from_u8(agent.combat_state.int_counters[icounter_action_mode_index]) {
ActionMode::Reckless => true, ActionMode::Reckless => true,
ActionMode::Guarded => { ActionMode::Guarded => {
agent.action_state.timers[timer_guarded_cycle_index] += read_data.dt.0; agent.combat_state.timers[timer_guarded_cycle_index] += read_data.dt.0;
if agent.action_state.timers[timer_guarded_cycle_index] if agent.combat_state.timers[timer_guarded_cycle_index]
> agent.action_state.counters[fcounter_guarded_timer_index] > agent.combat_state.counters[fcounter_guarded_timer_index]
{ {
agent.action_state.timers[timer_guarded_cycle_index] = 0.0; agent.combat_state.timers[timer_guarded_cycle_index] = 0.0;
agent.action_state.conditions[condition_guarded_defend_index] ^= true; agent.combat_state.conditions[condition_guarded_defend_index] ^= true;
agent.action_state.counters[fcounter_guarded_timer_index] = agent.combat_state.counters[fcounter_guarded_timer_index] =
if agent.action_state.conditions[condition_guarded_defend_index] { if agent.combat_state.conditions[condition_guarded_defend_index] {
rng.gen_range(3.0..6.0) rng.gen_range(3.0..6.0)
} else { } else {
rng.gen_range(6.0..10.0) rng.gen_range(6.0..10.0)
}; };
} }
if let Some(pos) = agent.action_state.positions[position_guarded_cover_index] { if let Some(pos) = agent.combat_state.positions[position_guarded_cover_index] {
if pos.distance_squared(agent_data.pos.0) < 3_f32.powi(2) { if pos.distance_squared(agent_data.pos.0) < 3_f32.powi(2) {
agent.action_state.positions[position_guarded_cover_index] = None; agent.combat_state.positions[position_guarded_cover_index] = None;
} }
} }
if !agent.action_state.conditions[condition_guarded_defend_index] { if !agent.combat_state.conditions[condition_guarded_defend_index] {
agent.action_state.positions[position_guarded_cover_index] = None; agent.combat_state.positions[position_guarded_cover_index] = None;
true true
} else { } else {
if attack_data.dist_sqrd > 10_f32.powi(2) { if attack_data.dist_sqrd > 10_f32.powi(2) {
// Choose random point to either side when looking at target and move // Choose random point to either side when looking at target and move
// towards it // towards it
if let Some(pos) = agent.action_state.positions[position_guarded_cover_index] { if let Some(pos) = agent.combat_state.positions[position_guarded_cover_index] {
if pos.distance_squared(agent_data.pos.0) < 5_f32.powi(2) { if pos.distance_squared(agent_data.pos.0) < 5_f32.powi(2) {
agent.action_state.positions[position_guarded_cover_index] = None; agent.combat_state.positions[position_guarded_cover_index] = None;
} }
agent_data.path_toward_target( agent_data.path_toward_target(
agent, agent,
@ -316,7 +316,7 @@ pub fn handle_attack_aggression(
None, None,
); );
} else { } else {
agent.action_state.positions[position_guarded_cover_index] = { agent.combat_state.positions[position_guarded_cover_index] = {
let rand_dir = { let rand_dir = {
let dir = (tgt_data.pos.0 - agent_data.pos.0) let dir = (tgt_data.pos.0 - agent_data.pos.0)
.try_normalized() .try_normalized()
@ -344,7 +344,7 @@ pub fn handle_attack_aggression(
Some(agent_data.pos.0 + rand_dir * actual_dist) Some(agent_data.pos.0 + rand_dir * actual_dist)
}; };
} }
} else if let Some(pos) = agent.action_state.positions[position_guarded_cover_index] } else if let Some(pos) = agent.combat_state.positions[position_guarded_cover_index]
{ {
agent_data.path_toward_target( agent_data.path_toward_target(
agent, agent,
@ -354,15 +354,15 @@ pub fn handle_attack_aggression(
Path::Separate, Path::Separate,
None, None,
); );
if agent.action_state.conditions[condition_rolling_breakthrough_index] { if agent.combat_state.conditions[condition_rolling_breakthrough_index] {
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
agent.action_state.conditions[condition_rolling_breakthrough_index] = false; agent.combat_state.conditions[condition_rolling_breakthrough_index] = false;
} }
if tgt_data.char_state.map_or(false, |cs| cs.is_melee_attack()) { if tgt_data.char_state.map_or(false, |cs| cs.is_melee_attack()) {
controller.push_basic_input(InputKind::Block); controller.push_basic_input(InputKind::Block);
} }
} else { } else {
agent.action_state.positions[position_guarded_cover_index] = { agent.combat_state.positions[position_guarded_cover_index] = {
let backwards = (agent_data.pos.0 - tgt_data.pos.0) let backwards = (agent_data.pos.0 - tgt_data.pos.0)
.try_normalized() .try_normalized()
.unwrap_or(Vec3::unit_x()) .unwrap_or(Vec3::unit_x())
@ -380,7 +380,7 @@ pub fn handle_attack_aggression(
{ {
agent_data.pos.0 + backwards * 5.0 agent_data.pos.0 + backwards * 5.0
} else { } else {
agent.action_state.conditions[condition_rolling_breakthrough_index] = agent.combat_state.conditions[condition_rolling_breakthrough_index] =
true; true;
agent_data.pos.0 agent_data.pos.0
- backwards - backwards
@ -403,16 +403,16 @@ pub fn handle_attack_aggression(
} }
}, },
ActionMode::Fleeing => { ActionMode::Fleeing => {
if agent.action_state.conditions[condition_rolling_breakthrough_index] { if agent.combat_state.conditions[condition_rolling_breakthrough_index] {
controller.push_basic_input(InputKind::Roll); controller.push_basic_input(InputKind::Roll);
agent.action_state.conditions[condition_rolling_breakthrough_index] = false; agent.combat_state.conditions[condition_rolling_breakthrough_index] = false;
} }
if let Some(pos) = agent.action_state.positions[position_flee_index] { if let Some(pos) = agent.combat_state.positions[position_flee_index] {
if let Some(dir) = Dir::from_unnormalized(pos - agent_data.pos.0) { if let Some(dir) = Dir::from_unnormalized(pos - agent_data.pos.0) {
controller.inputs.look_dir = dir; controller.inputs.look_dir = dir;
} }
if pos.distance_squared(agent_data.pos.0) < 5_f32.powi(2) { if pos.distance_squared(agent_data.pos.0) < 5_f32.powi(2) {
agent.action_state.positions[position_flee_index] = None; agent.combat_state.positions[position_flee_index] = None;
} }
agent_data.path_toward_target( agent_data.path_toward_target(
agent, agent,
@ -423,7 +423,7 @@ pub fn handle_attack_aggression(
None, None,
); );
} else { } else {
agent.action_state.positions[position_flee_index] = { agent.combat_state.positions[position_flee_index] = {
let rand_dir = { let rand_dir = {
let dir = (agent_data.pos.0 - tgt_data.pos.0) let dir = (agent_data.pos.0 - tgt_data.pos.0)
.try_normalized() .try_normalized()
@ -453,7 +453,7 @@ pub fn handle_attack_aggression(
.cast() .cast()
.0 .0
- 1.0; - 1.0;
agent.action_state.conditions[condition_rolling_breakthrough_index] = true; agent.combat_state.conditions[condition_rolling_breakthrough_index] = true;
Some(agent_data.pos.0 - rand_dir * dist) Some(agent_data.pos.0 - rand_dir * dist)
} else { } else {
Some(agent_data.pos.0 + rand_dir * actual_dist) Some(agent_data.pos.0 + rand_dir * actual_dist)

View File

@ -642,7 +642,7 @@ fn heal_self_if_hurt(bdata: &mut BehaviorData) -> bool {
.agent_data .agent_data
.heal_self(bdata.agent, bdata.controller, false) .heal_self(bdata.agent, bdata.controller, false)
{ {
bdata.agent.action_state.timers bdata.agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.01; [ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.01;
return true; return true;
} }
@ -767,18 +767,18 @@ fn do_combat(bdata: &mut BehaviorData) -> bool {
let aggro_on = *aggro_on; let aggro_on = *aggro_on;
if agent_data.below_flee_health(agent) { if agent_data.below_flee_health(agent) {
let flee_timer_done = agent.action_state.timers let flee_timer_done = agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] [ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize]
> FLEE_DURATION; > FLEE_DURATION;
let within_normal_flee_dir_dist = dist_sqrd < NORMAL_FLEE_DIR_DIST.powi(2); let within_normal_flee_dir_dist = dist_sqrd < NORMAL_FLEE_DIR_DIST.powi(2);
// FIXME: Using action state timer to see if allowed to speak is a hack. // FIXME: Using action state timer to see if allowed to speak is a hack.
if agent.action_state.timers if agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] [ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize]
== 0.0 == 0.0
{ {
agent_data.cry_out(agent, event_emitter, read_data); agent_data.cry_out(agent, event_emitter, read_data);
agent.action_state.timers agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.01; [ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.01;
agent.flee_from_pos = { agent.flee_from_pos = {
let random = || thread_rng().gen_range(-1.0..1.0); let random = || thread_rng().gen_range(-1.0..1.0);
@ -795,11 +795,11 @@ fn do_combat(bdata: &mut BehaviorData) -> bool {
agent_data.flee(agent, controller, read_data, tgt_pos); agent_data.flee(agent, controller, read_data, tgt_pos);
} }
agent.action_state.timers agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] += [ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] +=
read_data.dt.0; read_data.dt.0;
} else { } else {
agent.action_state.timers agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.0; [ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.0;
agent.target = None; agent.target = None;
agent.flee_from_pos = None; agent.flee_from_pos = None;

View File

@ -45,7 +45,7 @@ pub fn process_inbox_sound_and_hurt(bdata: &mut BehaviorData) -> bool {
Some(_) | None => {}, Some(_) | None => {},
} }
} else { } else {
bdata.agent.action_state.timers bdata.agent.behavior_state.timers
[ActionStateInteractionTimers::TimerInteraction as usize] = 0.1; [ActionStateInteractionTimers::TimerInteraction as usize] = 0.1;
} }
} }
@ -63,9 +63,9 @@ pub fn process_inbox_interaction(bdata: &mut BehaviorData) -> bool {
false false
} }
/// Increment agent's action_state timer /// Increment agent's behavior_state timer
pub fn increment_timer_deltatime(bdata: &mut BehaviorData) -> bool { pub fn increment_timer_deltatime(bdata: &mut BehaviorData) -> bool {
bdata.agent.action_state.timers[ActionStateInteractionTimers::TimerInteraction as usize] += bdata.agent.behavior_state.timers[ActionStateInteractionTimers::TimerInteraction as usize] +=
bdata.read_data.dt.0; bdata.read_data.dt.0;
false false
} }