mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Adlet elder AI
This commit is contained in:
parent
38a6cc67f9
commit
8c3b1f23ee
@ -5,7 +5,7 @@ ComboMelee2(
|
||||
kind: Bash(
|
||||
damage: 10,
|
||||
poise: 15,
|
||||
knockback: 5.0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 2.5,
|
||||
|
@ -1029,6 +1029,7 @@ impl<'a> AgentData<'a> {
|
||||
secondary: 1,
|
||||
abilities: [4, 0, 0, 0, 0],
|
||||
},
|
||||
"Adlet Elder" => Tactic::AdletElder,
|
||||
_ => Tactic::SimpleMelee,
|
||||
},
|
||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||
@ -1499,6 +1500,9 @@ impl<'a> AgentData<'a> {
|
||||
secondary,
|
||||
abilities,
|
||||
),
|
||||
Tactic::AdletElder => {
|
||||
self.handle_adlet_elder(agent, controller, &attack_data, tgt_data, read_data)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4716,6 +4716,59 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_adlet_elder(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
) {
|
||||
const TRAP_TIMER: usize = 0;
|
||||
agent.action_state.timers[TRAP_TIMER] -= read_data.dt.0;
|
||||
if matches!(self.char_state, CharacterState::BasicRanged(_)) {
|
||||
agent.action_state.timers[TRAP_TIMER] = 15.0;
|
||||
}
|
||||
let primary = self.extract_ability(AbilityInput::Primary);
|
||||
let secondary = self.extract_ability(AbilityInput::Secondary);
|
||||
let could_use_input = |input| match input {
|
||||
InputKind::Primary => primary.as_ref().map_or(false, |p| {
|
||||
p.could_use(attack_data, self, tgt_data, read_data, 0.0)
|
||||
}),
|
||||
InputKind::Secondary => secondary.as_ref().map_or(false, |s| {
|
||||
s.could_use(attack_data, self, tgt_data, read_data, 0.0)
|
||||
}),
|
||||
_ => false,
|
||||
};
|
||||
let move_forwards = if matches!(self.char_state, CharacterState::DashMelee(s) if s.stage_section != StageSection::Recover)
|
||||
{
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
false
|
||||
} else if agent.action_state.timers[TRAP_TIMER] < 0.0 && !tgt_data.considered_ranged() {
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
false
|
||||
} else if could_use_input(InputKind::Primary) {
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
false
|
||||
} else if could_use_input(InputKind::Secondary) {
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if move_forwards && attack_data.dist_sqrd > 2_f32.powi(2) {
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Separate,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_icedrake(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
|
@ -5,7 +5,10 @@ use common::{
|
||||
buff::{BuffKind, Buffs},
|
||||
character_state::AttackFilters,
|
||||
group,
|
||||
item::MaterialStatManifest,
|
||||
inventory::{
|
||||
item::{tool::ToolKind, ItemKind, MaterialStatManifest},
|
||||
slot::EquipSlot,
|
||||
},
|
||||
ActiveAbilities, Alignment, Body, CharacterState, Combo, Energy, Health, Inventory,
|
||||
LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Presence, PresenceKind, Scale,
|
||||
SkillSet, Stance, Stats, Vel,
|
||||
@ -66,6 +69,7 @@ pub struct TargetData<'a> {
|
||||
pub char_state: Option<&'a CharacterState>,
|
||||
pub health: Option<&'a Health>,
|
||||
pub buffs: Option<&'a Buffs>,
|
||||
pub drawn_weapons: (Option<ToolKind>, Option<ToolKind>),
|
||||
}
|
||||
|
||||
impl<'a> TargetData<'a> {
|
||||
@ -77,8 +81,55 @@ impl<'a> TargetData<'a> {
|
||||
char_state: read_data.char_states.get(target),
|
||||
health: read_data.healths.get(target),
|
||||
buffs: read_data.buffs.get(target),
|
||||
drawn_weapons: {
|
||||
let slotted_tool = |inv: &Inventory, slot| {
|
||||
if let Some(ItemKind::Tool(tool)) =
|
||||
inv.equipped(slot).map(|i| i.kind()).as_deref()
|
||||
{
|
||||
Some(tool.kind)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
read_data
|
||||
.inventories
|
||||
.get(target)
|
||||
.map_or((None, None), |inv| {
|
||||
(
|
||||
slotted_tool(inv, EquipSlot::ActiveMainhand),
|
||||
slotted_tool(inv, EquipSlot::ActiveOffhand),
|
||||
)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn considered_ranged(&self) -> bool {
|
||||
let is_ranged_tool = |tool| match tool {
|
||||
Some(
|
||||
ToolKind::Sword
|
||||
| ToolKind::Axe
|
||||
| ToolKind::Hammer
|
||||
| ToolKind::Dagger
|
||||
| ToolKind::Shield
|
||||
| ToolKind::Spear
|
||||
| ToolKind::Farming
|
||||
| ToolKind::Pick
|
||||
| ToolKind::Natural
|
||||
| ToolKind::Empty,
|
||||
)
|
||||
| None => false,
|
||||
Some(
|
||||
ToolKind::Bow
|
||||
| ToolKind::Staff
|
||||
| ToolKind::Sceptre
|
||||
| ToolKind::Blowgun
|
||||
| ToolKind::Debug
|
||||
| ToolKind::Instrument,
|
||||
) => true,
|
||||
};
|
||||
is_ranged_tool(self.drawn_weapons.0) || is_ranged_tool(self.drawn_weapons.1)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AttackData {
|
||||
@ -188,6 +239,7 @@ pub enum Tactic {
|
||||
AdletHunter,
|
||||
AdletIcepicker,
|
||||
AdletTracker,
|
||||
AdletElder,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
Loading…
Reference in New Issue
Block a user