mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Sword AI now randomly rolls again
This commit is contained in:
parent
d60839010a
commit
7022350693
@ -23,6 +23,5 @@ ComboMelee(
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
is_interruptible: false,
|
||||
ori_modifier: 0.6,
|
||||
)
|
||||
|
@ -547,7 +547,9 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
|
||||
let advance = |agent: &mut Agent, controller: &mut Controller, dist: f32, angle: f32| {
|
||||
if attack_data.dist_sqrd > dist.powi(2) || attack_data.angle > angle {
|
||||
if attack_data.dist_sqrd > (dist + self.body.map_or(0.0, |b| b.max_radius())).powi(2)
|
||||
|| attack_data.angle > angle
|
||||
{
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
@ -559,6 +561,30 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
const AVERAGE_ROLL_FREQUENCY: f32 = 12.0;
|
||||
const TIMER_LAST_ROLL: usize = 0;
|
||||
const CONDITION_RANDOM_ROLL: usize = 0;
|
||||
const MIN_ENERGY_FOR_ROLL: f32 = 30.0;
|
||||
if self.energy.current() > MIN_ENERGY_FOR_ROLL {
|
||||
agent.action_state.timers[TIMER_LAST_ROLL] += read_data.dt.0;
|
||||
}
|
||||
if (-agent.action_state.timers[TIMER_LAST_ROLL] / AVERAGE_ROLL_FREQUENCY).exp()
|
||||
< rng.gen::<f32>() / std::f32::consts::E
|
||||
{
|
||||
agent.action_state.conditions[CONDITION_RANDOM_ROLL] = true;
|
||||
}
|
||||
if agent.action_state.conditions[CONDITION_RANDOM_ROLL] {
|
||||
controller.push_basic_input(InputKind::Roll);
|
||||
advance(agent, controller, 1.0, 30.0);
|
||||
let random_angle = rng.gen_range(-PI..PI) / 4.0;
|
||||
controller.inputs.move_dir.rotated_z(random_angle);
|
||||
}
|
||||
if matches!(self.char_state, CharacterState::Roll(c) if c.stage_section == StageSection::Recover)
|
||||
{
|
||||
agent.action_state.timers[TIMER_LAST_ROLL] = 0.0;
|
||||
agent.action_state.conditions[CONDITION_RANDOM_ROLL] = false;
|
||||
}
|
||||
|
||||
// Called when out of energy, or the situation is not right to use another
|
||||
// ability. Only contains tactics for using M1 and M2
|
||||
let fallback_rng_1 = rng.gen::<f32>() < 0.67;
|
||||
@ -728,7 +754,10 @@ impl<'a> AgentData<'a> {
|
||||
energy: 2.5,
|
||||
};
|
||||
const DESIRED_ENERGY: f32 = 50.0;
|
||||
const CONDITION_HOLD: usize = 0;
|
||||
const CONDITION_HOLD: usize = 1;
|
||||
const COUNTER_ANGLE: usize = 1;
|
||||
const TIMER_HOLD_TIMEOUT: usize = 1;
|
||||
const HOLD_TIMEOUT: f32 = 3.0;
|
||||
|
||||
let mut try_block = || {
|
||||
if let Some(char_state) = tgt_data.char_state {
|
||||
@ -749,14 +778,20 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
if agent.action_state.conditions[CONDITION_HOLD] {
|
||||
agent.action_state.timers[TIMER_HOLD_TIMEOUT] += read_data.dt.0;
|
||||
}
|
||||
|
||||
if read_data.time.0
|
||||
- self
|
||||
.health
|
||||
.map_or(read_data.time.0, |h| h.last_change.time.0)
|
||||
< read_data.dt.0 as f64 * 2.0
|
||||
|| agent.action_state.timers[TIMER_HOLD_TIMEOUT] > HOLD_TIMEOUT
|
||||
{
|
||||
// If attacked in last couple ticks, stop standing still
|
||||
agent.action_state.conditions[CONDITION_HOLD] = false;
|
||||
agent.action_state.timers[TIMER_HOLD_TIMEOUT] = 0.0;
|
||||
} else if matches!(
|
||||
self.char_state.ability_info().and_then(|info| info.input),
|
||||
Some(InputKind::Ability(1))
|
||||
@ -795,7 +830,11 @@ impl<'a> AgentData<'a> {
|
||||
DEFENSIVE_COMBO.angle,
|
||||
);
|
||||
}
|
||||
} else if !agent.action_state.conditions[CONDITION_HOLD] {
|
||||
} else if agent.action_state.conditions[CONDITION_HOLD] {
|
||||
agent.action_state.counters[COUNTER_ANGLE] += rng.gen::<f32>() * read_data.dt.0;
|
||||
controller.inputs.move_dir =
|
||||
Vec2::unit_x().rotated_z(agent.action_state.counters[COUNTER_ANGLE]) * 0.25;
|
||||
} else {
|
||||
advance(
|
||||
agent,
|
||||
controller,
|
||||
@ -891,7 +930,7 @@ impl<'a> AgentData<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
const CONDITION_FEINT_DIR: usize = 0;
|
||||
const CONDITION_FEINT_DIR: usize = 1;
|
||||
|
||||
if rng.gen::<f32>() < read_data.dt.0 {
|
||||
agent.action_state.conditions[CONDITION_FEINT_DIR] =
|
||||
@ -1033,8 +1072,8 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
const CONDITION_SELF_ROLLING: usize = 0;
|
||||
const TIMER_DIVE_TIMEOUT: usize = 0;
|
||||
const CONDITION_SELF_ROLLING: usize = 1;
|
||||
const TIMER_DIVE_TIMEOUT: usize = 1;
|
||||
|
||||
if matches!(self.char_state, CharacterState::Roll(_)) {
|
||||
agent.action_state.conditions[CONDITION_SELF_ROLLING] = true;
|
||||
@ -1225,8 +1264,8 @@ impl<'a> AgentData<'a> {
|
||||
};
|
||||
const DESIRED_ENERGY: f32 = 50.0;
|
||||
|
||||
const CONDITION_POISE_DMG: usize = 0;
|
||||
const TIMER_POMMELSTRIKE: usize = 0;
|
||||
const CONDITION_POISE_DMG: usize = 1;
|
||||
const TIMER_POMMELSTRIKE: usize = 1;
|
||||
|
||||
agent.action_state.conditions[CONDITION_POISE_DMG] = self
|
||||
.poise
|
||||
|
@ -192,8 +192,10 @@ pub struct ComboMeleeData {
|
||||
|
||||
impl ComboMeleeData {
|
||||
pub fn could_use(&self, attack_data: &AttackData, agent_data: &AgentData) -> bool {
|
||||
attack_data.dist_sqrd < self.max_range.powi(2)
|
||||
&& attack_data.dist_sqrd > self.min_range.powi(2)
|
||||
attack_data.dist_sqrd
|
||||
< (self.max_range + agent_data.body.map_or(0.0, |b| b.max_radius())).powi(2)
|
||||
&& attack_data.dist_sqrd
|
||||
> (self.min_range + agent_data.body.map_or(0.0, |b| b.max_radius())).powi(2)
|
||||
&& attack_data.angle < self.angle
|
||||
&& agent_data.energy.current() >= self.energy
|
||||
}
|
||||
@ -208,7 +210,8 @@ pub struct FinisherMeleeData {
|
||||
|
||||
impl FinisherMeleeData {
|
||||
pub fn could_use(&self, attack_data: &AttackData, agent_data: &AgentData) -> bool {
|
||||
attack_data.dist_sqrd < self.range.powi(2)
|
||||
attack_data.dist_sqrd
|
||||
< (self.range + agent_data.body.map_or(0.0, |b| b.max_radius())).powi(2)
|
||||
&& attack_data.angle < self.angle
|
||||
&& agent_data.energy.current() >= self.energy
|
||||
&& agent_data
|
||||
@ -258,8 +261,10 @@ impl DiveMeleeData {
|
||||
agent_data.energy.current() > self.energy
|
||||
&& agent_data.physics_state.on_ground.is_some()
|
||||
&& agent_data.pos.0.z >= tgt_data.pos.0.z
|
||||
&& dist_sqrd_2d > (self.range / 2.0).powi(2)
|
||||
&& dist_sqrd_2d < (self.range + 5.0).powi(2)
|
||||
&& dist_sqrd_2d
|
||||
> ((self.range + agent_data.body.map_or(0.0, |b| b.max_radius())) / 2.0).powi(2)
|
||||
&& dist_sqrd_2d
|
||||
< (self.range + agent_data.body.map_or(0.0, |b| b.max_radius()) + 5.0).powi(2)
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +277,8 @@ pub struct BlockData {
|
||||
|
||||
impl BlockData {
|
||||
pub fn could_use(&self, attack_data: &AttackData, agent_data: &AgentData) -> bool {
|
||||
attack_data.dist_sqrd < self.range.powi(2)
|
||||
attack_data.dist_sqrd
|
||||
< (self.range + agent_data.body.map_or(0.0, |b| b.max_radius())).powi(2)
|
||||
&& attack_data.angle < self.angle
|
||||
&& agent_data.energy.current() >= self.energy
|
||||
}
|
||||
@ -296,7 +302,8 @@ impl DashMeleeData {
|
||||
pub fn could_use(&self, attack_data: &AttackData, agent_data: &AgentData) -> bool {
|
||||
let charge_dur = self.charge_dur(agent_data);
|
||||
let charge_dist = charge_dur * self.speed * Self::BASE_SPEED;
|
||||
let attack_dist = charge_dist + self.range;
|
||||
let attack_dist =
|
||||
charge_dist + self.range + agent_data.body.map_or(0.0, |b| b.max_radius());
|
||||
let ori_gap = Self::ORI_RATE * charge_dur;
|
||||
attack_data.dist_sqrd < attack_dist.powi(2)
|
||||
&& attack_data.angle < self.angle + ori_gap
|
||||
@ -323,7 +330,8 @@ pub struct RapidMeleeData {
|
||||
|
||||
impl RapidMeleeData {
|
||||
pub fn could_use(&self, attack_data: &AttackData, agent_data: &AgentData) -> bool {
|
||||
attack_data.dist_sqrd < self.range.powi(2)
|
||||
attack_data.dist_sqrd
|
||||
< (self.range + agent_data.body.map_or(0.0, |b| b.max_radius())).powi(2)
|
||||
&& attack_data.angle < self.angle
|
||||
&& agent_data.energy.current() > self.energy * self.strikes as f32
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user