mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Split action state into two sets of state, one each for combat and behavior.
This commit is contained in:
parent
ef858ef72b
commit
a4df3f8ad5
@ -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(),
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user