Merge branch 'sam/agent-combat-state' into 'master'

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

See merge request veloren/veloren!4183
This commit is contained in:
Samuel Keiffer 2023-11-12 18:19:07 +00:00
commit a4ff592547
6 changed files with 300 additions and 298 deletions

View File

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

View File

@ -229,15 +229,15 @@ impl<'a> AgentData<'a> {
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;
}
} else {
agent.action_state.timers[ActionTimers::TimerIdle as usize] = 0.01;
agent.behavior_state.timers[ActionTimers::TimerIdle as usize] = 0.01;
return;
}
agent.action_state.timers[ActionTimers::TimerIdle as usize] = 0.0;
agent.behavior_state.timers[ActionTimers::TimerIdle as usize] = 0.0;
'activity: {
match agent.rtsim_controller.activity {
@ -791,7 +791,7 @@ impl<'a> AgentData<'a> {
enum ActionStateTimers {
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;
// 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,
) -> bool {
if let Some(health) = agent_data.health {
agent.action_state.int_counters[icounter_action_mode_index] = if health.fraction() < 0.1 {
agent.action_state.positions[position_guarded_cover_index] = None;
agent.combat_state.int_counters[icounter_action_mode_index] = if health.fraction() < 0.1 {
agent.combat_state.positions[position_guarded_cover_index] = None;
ActionMode::Fleeing as u8
} 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
} else {
agent.action_state.positions[position_guarded_cover_index] = None;
agent.action_state.positions[position_flee_index] = None;
agent.combat_state.positions[position_guarded_cover_index] = None;
agent.combat_state.positions[position_flee_index] = None;
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
// path positions if occurs for too long
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 {
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 {
agent.action_state.positions[position_guarded_cover_index] = None;
agent.action_state.positions[position_flee_index] = None;
agent.action_state.timers[timer_pos_timeout_index] = 0.0;
if agent.combat_state.timers[timer_pos_timeout_index] > 2.0 {
agent.combat_state.positions[position_guarded_cover_index] = None;
agent.combat_state.positions[position_flee_index] = None;
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::Guarded => {
agent.action_state.timers[timer_guarded_cycle_index] += read_data.dt.0;
if agent.action_state.timers[timer_guarded_cycle_index]
> agent.action_state.counters[fcounter_guarded_timer_index]
agent.combat_state.timers[timer_guarded_cycle_index] += read_data.dt.0;
if agent.combat_state.timers[timer_guarded_cycle_index]
> agent.combat_state.counters[fcounter_guarded_timer_index]
{
agent.action_state.timers[timer_guarded_cycle_index] = 0.0;
agent.action_state.conditions[condition_guarded_defend_index] ^= true;
agent.action_state.counters[fcounter_guarded_timer_index] =
if agent.action_state.conditions[condition_guarded_defend_index] {
agent.combat_state.timers[timer_guarded_cycle_index] = 0.0;
agent.combat_state.conditions[condition_guarded_defend_index] ^= true;
agent.combat_state.counters[fcounter_guarded_timer_index] =
if agent.combat_state.conditions[condition_guarded_defend_index] {
rng.gen_range(3.0..6.0)
} else {
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) {
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] {
agent.action_state.positions[position_guarded_cover_index] = None;
if !agent.combat_state.conditions[condition_guarded_defend_index] {
agent.combat_state.positions[position_guarded_cover_index] = None;
true
} else {
if attack_data.dist_sqrd > 10_f32.powi(2) {
// Choose random point to either side when looking at target and move
// 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) {
agent.action_state.positions[position_guarded_cover_index] = None;
agent.combat_state.positions[position_guarded_cover_index] = None;
}
agent_data.path_toward_target(
agent,
@ -316,7 +316,7 @@ pub fn handle_attack_aggression(
None,
);
} else {
agent.action_state.positions[position_guarded_cover_index] = {
agent.combat_state.positions[position_guarded_cover_index] = {
let rand_dir = {
let dir = (tgt_data.pos.0 - agent_data.pos.0)
.try_normalized()
@ -344,7 +344,7 @@ pub fn handle_attack_aggression(
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,
@ -354,15 +354,15 @@ pub fn handle_attack_aggression(
Path::Separate,
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);
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()) {
controller.push_basic_input(InputKind::Block);
}
} 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)
.try_normalized()
.unwrap_or(Vec3::unit_x())
@ -380,7 +380,7 @@ pub fn handle_attack_aggression(
{
agent_data.pos.0 + backwards * 5.0
} else {
agent.action_state.conditions[condition_rolling_breakthrough_index] =
agent.combat_state.conditions[condition_rolling_breakthrough_index] =
true;
agent_data.pos.0
- backwards
@ -403,16 +403,16 @@ pub fn handle_attack_aggression(
}
},
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);
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) {
controller.inputs.look_dir = dir;
}
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,
@ -423,7 +423,7 @@ pub fn handle_attack_aggression(
None,
);
} else {
agent.action_state.positions[position_flee_index] = {
agent.combat_state.positions[position_flee_index] = {
let rand_dir = {
let dir = (agent_data.pos.0 - tgt_data.pos.0)
.try_normalized()
@ -453,7 +453,7 @@ pub fn handle_attack_aggression(
.cast()
.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)
} else {
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
.heal_self(bdata.agent, bdata.controller, false)
{
bdata.agent.action_state.timers
bdata.agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.01;
return true;
}
@ -767,18 +767,18 @@ fn do_combat(bdata: &mut BehaviorData) -> bool {
let aggro_on = *aggro_on;
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]
> FLEE_DURATION;
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.
if agent.action_state.timers
if agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize]
== 0.0
{
agent_data.cry_out(agent, event_emitter, read_data);
agent.action_state.timers
agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.01;
agent.flee_from_pos = {
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.action_state.timers
agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] +=
read_data.dt.0;
} else {
agent.action_state.timers
agent.behavior_state.timers
[ActionStateBehaviorTreeTimers::TimerBehaviorTree as usize] = 0.0;
agent.target = 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 => {},
}
} else {
bdata.agent.action_state.timers
bdata.agent.behavior_state.timers
[ActionStateInteractionTimers::TimerInteraction as usize] = 0.1;
}
}
@ -63,9 +63,9 @@ pub fn process_inbox_interaction(bdata: &mut BehaviorData) -> bool {
false
}
/// Increment agent's action_state timer
/// Increment agent's behavior_state timer
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;
false
}