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 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(),
|
||||||
|
@ -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
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user