mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Adlet hunter AI
This commit is contained in:
parent
92e28f09fc
commit
680d987e11
@ -748,23 +748,23 @@
|
|||||||
// Adlets
|
// Adlets
|
||||||
// TODO: Do we want to eventually convert these to simple variants of weapons?
|
// TODO: Do we want to eventually convert these to simple variants of weapons?
|
||||||
Custom("Adlet Hunter"): (
|
Custom("Adlet Hunter"): (
|
||||||
primary: "common.abilities.adlet.hunter.stab",
|
primary: Simple(None, "common.abilities.adlet.hunter.stab"),
|
||||||
secondary: "common.abilities.adlet.hunter.throw",
|
secondary: Simple(None, "common.abilities.adlet.hunter.throw"),
|
||||||
abilities: [],
|
abilities: [],
|
||||||
),
|
),
|
||||||
Custom("Adlet Icepicker"): (
|
Custom("Adlet Icepicker"): (
|
||||||
primary: "common.abilities.adlet.icepicker.spike",
|
primary: Simple(None, "common.abilities.adlet.icepicker.spike"),
|
||||||
secondary: "common.abilities.adlet.icepicker.leap",
|
secondary: Simple(None, "common.abilities.adlet.icepicker.leap"),
|
||||||
abilities: [],
|
abilities: [],
|
||||||
),
|
),
|
||||||
Custom("Adlet Tracker"): (
|
Custom("Adlet Tracker"): (
|
||||||
primary: "common.abilities.adlet.tracker.arrow",
|
primary: Simple(None, "common.abilities.adlet.tracker.arrow"),
|
||||||
secondary: "common.abilities.adlet.tracker.trap",
|
secondary: Simple(None, "common.abilities.adlet.tracker.trap"),
|
||||||
abilities: [],
|
abilities: [],
|
||||||
),
|
),
|
||||||
// Custom("Adlet Alpha"): (
|
// Custom("Adlet Alpha"): (
|
||||||
// primary: "common.abilities.adlet.alpha",
|
// primary: Simple(None, "common.abilities.adlet.alpha"),
|
||||||
// secondary: "common.abilities.adlet.alpha",
|
// secondary: Simple(None, "common.abilities.adlet.alpha"),
|
||||||
// abilities: [],
|
// abilities: [],
|
||||||
// ),
|
// ),
|
||||||
})
|
})
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 40.0,
|
projectile_speed: 40.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -9,4 +9,5 @@ BasicRanged(
|
|||||||
projectile_speed: 10.0,
|
projectile_speed: 10.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_speed: 80.0,
|
projectile_speed: 80.0,
|
||||||
num_projectiles: 5,
|
num_projectiles: 5,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 260.0,
|
projectile_speed: 260.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.3,
|
projectile_spread: 0.3,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 70.0,
|
projectile_speed: 70.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -18,4 +18,5 @@ BasicRanged(
|
|||||||
strength: DamageFraction(0.1),
|
strength: DamageFraction(0.1),
|
||||||
chance: 1.0,
|
chance: 1.0,
|
||||||
))),
|
))),
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
@ -13,4 +13,5 @@ BasicRanged(
|
|||||||
projectile_speed: 30.0,
|
projectile_speed: 30.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicRanged(
|
|||||||
projectile_speed: 20.0,
|
projectile_speed: 20.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 25.0,
|
projectile_speed: 25.0,
|
||||||
num_projectiles: 5,
|
num_projectiles: 5,
|
||||||
projectile_spread: 0.07,
|
projectile_spread: 0.07,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
@ -13,4 +13,5 @@ BasicRanged(
|
|||||||
projectile_speed: 30.0,
|
projectile_speed: 30.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 70.0,
|
projectile_speed: 70.0,
|
||||||
num_projectiles: 3,
|
num_projectiles: 3,
|
||||||
projectile_spread: 0.2,
|
projectile_spread: 0.2,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -11,5 +11,6 @@ BasicRanged(
|
|||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 70.0,
|
projectile_speed: 70.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 130.0,
|
projectile_speed: 130.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -15,4 +15,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -11,4 +11,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -11,4 +11,5 @@ BasicRanged(
|
|||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 80.0,
|
projectile_speed: 80.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 25,
|
projectile_speed: 25,
|
||||||
num_projectiles: 8,
|
num_projectiles: 8,
|
||||||
projectile_spread: 0.125,
|
projectile_spread: 0.125,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -16,4 +16,5 @@ BasicRanged(
|
|||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
num_projectiles: 1,
|
num_projectiles: 1,
|
||||||
projectile_spread: 0.0,
|
projectile_spread: 0.0,
|
||||||
|
move_efficiency: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -11,6 +11,6 @@
|
|||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
meta: [
|
meta: [
|
||||||
SkillSetAsset("common.skillset.preset.rank1.fullskill"),
|
SkillSetAsset("common.skillset.preset.rank1.general"),
|
||||||
],
|
],
|
||||||
)
|
)
|
@ -11,6 +11,6 @@
|
|||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
meta: [
|
meta: [
|
||||||
SkillSetAsset("common.skillset.preset.rank1.fullskill"),
|
SkillSetAsset("common.skillset.preset.rank1.general"),
|
||||||
],
|
],
|
||||||
)
|
)
|
@ -11,6 +11,6 @@
|
|||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
meta: [
|
meta: [
|
||||||
SkillSetAsset("common.skillset.preset.rank1.fullskill"),
|
SkillSetAsset("common.skillset.preset.rank1.general"),
|
||||||
],
|
],
|
||||||
)
|
)
|
@ -502,6 +502,7 @@ pub enum CharacterAbility {
|
|||||||
num_projectiles: u32,
|
num_projectiles: u32,
|
||||||
projectile_spread: f32,
|
projectile_spread: f32,
|
||||||
damage_effect: Option<CombatEffect>,
|
damage_effect: Option<CombatEffect>,
|
||||||
|
move_efficiency: f32,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
meta: AbilityMeta,
|
meta: AbilityMeta,
|
||||||
},
|
},
|
||||||
@ -1019,6 +1020,7 @@ impl CharacterAbility {
|
|||||||
num_projectiles: _,
|
num_projectiles: _,
|
||||||
projectile_spread: _,
|
projectile_spread: _,
|
||||||
damage_effect: _,
|
damage_effect: _,
|
||||||
|
move_efficiency: _,
|
||||||
meta: _,
|
meta: _,
|
||||||
} => {
|
} => {
|
||||||
*buildup_duration /= stats.speed;
|
*buildup_duration /= stats.speed;
|
||||||
@ -2169,6 +2171,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
num_projectiles,
|
num_projectiles,
|
||||||
projectile_spread,
|
projectile_spread,
|
||||||
damage_effect,
|
damage_effect,
|
||||||
|
move_efficiency,
|
||||||
meta: _,
|
meta: _,
|
||||||
} => CharacterState::BasicRanged(basic_ranged::Data {
|
} => CharacterState::BasicRanged(basic_ranged::Data {
|
||||||
static_data: basic_ranged::StaticData {
|
static_data: basic_ranged::StaticData {
|
||||||
@ -2182,6 +2185,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
projectile_spread: *projectile_spread,
|
projectile_spread: *projectile_spread,
|
||||||
ability_info,
|
ability_info,
|
||||||
damage_effect: *damage_effect,
|
damage_effect: *damage_effect,
|
||||||
|
move_efficiency: *move_efficiency,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Buildup,
|
stage_section: StageSection::Buildup,
|
||||||
|
@ -34,8 +34,8 @@ pub struct StaticData {
|
|||||||
pub num_projectiles: u32,
|
pub num_projectiles: u32,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_info: AbilityInfo,
|
pub ability_info: AbilityInfo,
|
||||||
///
|
|
||||||
pub damage_effect: Option<CombatEffect>,
|
pub damage_effect: Option<CombatEffect>,
|
||||||
|
pub move_efficiency: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@ -56,7 +56,7 @@ impl CharacterBehavior for Data {
|
|||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
handle_orientation(data, &mut update, 1.0, None);
|
handle_orientation(data, &mut update, 1.0, None);
|
||||||
handle_move(data, &mut update, 0.3);
|
handle_move(data, &mut update, self.static_data.move_efficiency);
|
||||||
handle_jump(data, output_events, &mut update, 1.0);
|
handle_jump(data, output_events, &mut update, 1.0);
|
||||||
|
|
||||||
match self.stage_section {
|
match self.stage_section {
|
||||||
|
@ -1014,6 +1014,9 @@ impl<'a> AgentData<'a> {
|
|||||||
"Gnarling Chieftain" => Tactic::GnarlingChieftain,
|
"Gnarling Chieftain" => Tactic::GnarlingChieftain,
|
||||||
"Frost Gigas" => Tactic::FrostGigas,
|
"Frost Gigas" => Tactic::FrostGigas,
|
||||||
"Boreal Hammer" => Tactic::BorealHammer,
|
"Boreal Hammer" => Tactic::BorealHammer,
|
||||||
|
"Adlet Hunter" => Tactic::AdletHunter,
|
||||||
|
"Adlet Icepicker" => Tactic::AdletIcepicker,
|
||||||
|
"Adlet Tracker" => Tactic::AdletTracker,
|
||||||
_ => Tactic::SimpleMelee,
|
_ => Tactic::SimpleMelee,
|
||||||
},
|
},
|
||||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||||
@ -1457,6 +1460,20 @@ impl<'a> AgentData<'a> {
|
|||||||
tgt_data,
|
tgt_data,
|
||||||
read_data,
|
read_data,
|
||||||
),
|
),
|
||||||
|
Tactic::AdletHunter => {
|
||||||
|
self.handle_adlet_hunter(agent, controller, &attack_data, tgt_data, read_data, rng)
|
||||||
|
},
|
||||||
|
Tactic::AdletIcepicker => self.handle_adlet_icepicker(
|
||||||
|
agent,
|
||||||
|
controller,
|
||||||
|
&attack_data,
|
||||||
|
tgt_data,
|
||||||
|
read_data,
|
||||||
|
rng,
|
||||||
|
),
|
||||||
|
Tactic::AdletTracker => {
|
||||||
|
self.handle_adlet_tracker(agent, controller, &attack_data, tgt_data, read_data, rng)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,41 +757,24 @@ impl<'a> AgentData<'a> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let attack_failed = if attempt_attack {
|
let attack_failed = if attempt_attack {
|
||||||
let contexts = AbilityContext::from(self.stance, Some(self.inventory));
|
let primary = self.extract_ability(AbilityInput::Primary);
|
||||||
let extract_ability = |input: AbilityInput| {
|
let secondary = self.extract_ability(AbilityInput::Secondary);
|
||||||
AbilityData::from_ability(
|
|
||||||
&self
|
|
||||||
.active_abilities
|
|
||||||
.activate_ability(
|
|
||||||
input,
|
|
||||||
Some(self.inventory),
|
|
||||||
self.skill_set,
|
|
||||||
self.body,
|
|
||||||
Some(self.char_state),
|
|
||||||
&contexts,
|
|
||||||
)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.0,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let primary = extract_ability(AbilityInput::Primary);
|
|
||||||
let secondary = extract_ability(AbilityInput::Secondary);
|
|
||||||
let abilities = [
|
let abilities = [
|
||||||
extract_ability(AbilityInput::Auxiliary(0)),
|
self.extract_ability(AbilityInput::Auxiliary(0)),
|
||||||
extract_ability(AbilityInput::Auxiliary(1)),
|
self.extract_ability(AbilityInput::Auxiliary(1)),
|
||||||
extract_ability(AbilityInput::Auxiliary(2)),
|
self.extract_ability(AbilityInput::Auxiliary(2)),
|
||||||
extract_ability(AbilityInput::Auxiliary(3)),
|
self.extract_ability(AbilityInput::Auxiliary(3)),
|
||||||
extract_ability(AbilityInput::Auxiliary(4)),
|
self.extract_ability(AbilityInput::Auxiliary(4)),
|
||||||
];
|
];
|
||||||
let could_use_input = |input, desired_energy| match input {
|
let could_use_input = |input, desired_energy| match input {
|
||||||
InputKind::Primary => primary.as_ref().map_or(false, |p| {
|
InputKind::Primary => primary.as_ref().map_or(false, |p| {
|
||||||
p.could_use(attack_data, self, tgt_data, desired_energy)
|
p.could_use(attack_data, self, tgt_data, read_data, desired_energy)
|
||||||
}),
|
}),
|
||||||
InputKind::Secondary => secondary.as_ref().map_or(false, |s| {
|
InputKind::Secondary => secondary.as_ref().map_or(false, |s| {
|
||||||
s.could_use(attack_data, self, tgt_data, desired_energy)
|
s.could_use(attack_data, self, tgt_data, read_data, desired_energy)
|
||||||
}),
|
}),
|
||||||
InputKind::Ability(x) => abilities[x].as_ref().map_or(false, |a| {
|
InputKind::Ability(x) => abilities[x].as_ref().map_or(false, |a| {
|
||||||
a.could_use(attack_data, self, tgt_data, desired_energy)
|
a.could_use(attack_data, self, tgt_data, read_data, desired_energy)
|
||||||
}),
|
}),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
@ -4585,4 +4568,68 @@ impl<'a> AgentData<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_adlet_hunter(
|
||||||
|
&self,
|
||||||
|
agent: &mut Agent,
|
||||||
|
controller: &mut Controller,
|
||||||
|
attack_data: &AttackData,
|
||||||
|
tgt_data: &TargetData,
|
||||||
|
read_data: &ReadData,
|
||||||
|
rng: &mut impl Rng,
|
||||||
|
) {
|
||||||
|
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 could_use_input(InputKind::Primary) {
|
||||||
|
controller.push_basic_input(InputKind::Primary);
|
||||||
|
false
|
||||||
|
} else if could_use_input(InputKind::Secondary) && attack_data.dist_sqrd > 8_f32.powi(2) {
|
||||||
|
controller.push_basic_input(InputKind::Secondary);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
if move_forwards && attack_data.dist_sqrd > 3_f32.powi(2) {
|
||||||
|
self.path_toward_target(
|
||||||
|
agent,
|
||||||
|
controller,
|
||||||
|
tgt_data.pos.0,
|
||||||
|
read_data,
|
||||||
|
Path::Separate,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_adlet_icepicker(
|
||||||
|
&self,
|
||||||
|
agent: &mut Agent,
|
||||||
|
controller: &mut Controller,
|
||||||
|
attack_data: &AttackData,
|
||||||
|
tgt_data: &TargetData,
|
||||||
|
read_data: &ReadData,
|
||||||
|
rng: &mut impl Rng,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_adlet_tracker(
|
||||||
|
&self,
|
||||||
|
agent: &mut Agent,
|
||||||
|
controller: &mut Controller,
|
||||||
|
attack_data: &AttackData,
|
||||||
|
tgt_data: &TargetData,
|
||||||
|
read_data: &ReadData,
|
||||||
|
rng: &mut impl Rng,
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::util::*;
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
ability::CharacterAbility,
|
ability::CharacterAbility,
|
||||||
@ -9,6 +10,7 @@ use common::{
|
|||||||
LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Presence, PresenceKind, Scale,
|
LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Presence, PresenceKind, Scale,
|
||||||
SkillSet, Stance, Stats, Vel,
|
SkillSet, Stance, Stats, Vel,
|
||||||
},
|
},
|
||||||
|
consts::GRAVITY,
|
||||||
link::Is,
|
link::Is,
|
||||||
mounting::{Mount, Rider, VolumeRider},
|
mounting::{Mount, Rider, VolumeRider},
|
||||||
path::TraversalConfig,
|
path::TraversalConfig,
|
||||||
@ -171,6 +173,11 @@ pub enum Tactic {
|
|||||||
BorealHammer,
|
BorealHammer,
|
||||||
Dullahan,
|
Dullahan,
|
||||||
Cyclops,
|
Cyclops,
|
||||||
|
|
||||||
|
// Adlets
|
||||||
|
AdletHunter,
|
||||||
|
AdletIcepicker,
|
||||||
|
AdletTracker,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -331,6 +338,15 @@ pub enum AbilityData {
|
|||||||
blocked_attacks: AttackFilters,
|
blocked_attacks: AttackFilters,
|
||||||
angle: f32,
|
angle: f32,
|
||||||
},
|
},
|
||||||
|
BasicRanged {
|
||||||
|
energy: f32,
|
||||||
|
projectile_speed: f32,
|
||||||
|
},
|
||||||
|
BasicMelee {
|
||||||
|
energy: f32,
|
||||||
|
range: f32,
|
||||||
|
angle: f32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityData {
|
impl AbilityData {
|
||||||
@ -453,6 +469,23 @@ impl AbilityData {
|
|||||||
angle: *max_angle,
|
angle: *max_angle,
|
||||||
blocked_attacks: *blocked_attacks,
|
blocked_attacks: *blocked_attacks,
|
||||||
},
|
},
|
||||||
|
BasicRanged {
|
||||||
|
energy_cost,
|
||||||
|
projectile_speed,
|
||||||
|
..
|
||||||
|
} => Self::BasicRanged {
|
||||||
|
energy: *energy_cost,
|
||||||
|
projectile_speed: *projectile_speed,
|
||||||
|
},
|
||||||
|
BasicMelee {
|
||||||
|
energy_cost,
|
||||||
|
melee_constructor,
|
||||||
|
..
|
||||||
|
} => Self::BasicMelee {
|
||||||
|
energy: *energy_cost,
|
||||||
|
range: melee_constructor.range,
|
||||||
|
angle: melee_constructor.angle,
|
||||||
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
Some(inner)
|
Some(inner)
|
||||||
@ -463,6 +496,7 @@ impl AbilityData {
|
|||||||
attack_data: &AttackData,
|
attack_data: &AttackData,
|
||||||
agent_data: &AgentData,
|
agent_data: &AgentData,
|
||||||
tgt_data: &TargetData,
|
tgt_data: &TargetData,
|
||||||
|
read_data: &ReadData,
|
||||||
desired_energy: f32,
|
desired_energy: f32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let melee_check = |range: f32, angle, forced_movement: Option<ForcedMovement>| {
|
let melee_check = |range: f32, angle, forced_movement: Option<ForcedMovement>| {
|
||||||
@ -487,6 +521,22 @@ impl AbilityData {
|
|||||||
.and_then(|cs| cs.attack_kind())
|
.and_then(|cs| cs.attack_kind())
|
||||||
.map_or(false, |ak| attacks.applies(ak))
|
.map_or(false, |ak| attacks.applies(ak))
|
||||||
};
|
};
|
||||||
|
let ranged_check = |proj_speed| {
|
||||||
|
let max_horiz_dist: f32 = {
|
||||||
|
let flight_time = proj_speed * 2_f32.sqrt() / GRAVITY;
|
||||||
|
proj_speed * 2_f32.sqrt() / 2.0 * flight_time
|
||||||
|
};
|
||||||
|
attack_data.dist_sqrd < max_horiz_dist.powi(2)
|
||||||
|
&& entities_have_line_of_sight(
|
||||||
|
agent_data.pos,
|
||||||
|
agent_data.body,
|
||||||
|
agent_data.scale,
|
||||||
|
tgt_data.pos,
|
||||||
|
tgt_data.body,
|
||||||
|
tgt_data.scale,
|
||||||
|
read_data,
|
||||||
|
)
|
||||||
|
};
|
||||||
use AbilityData::*;
|
use AbilityData::*;
|
||||||
match self {
|
match self {
|
||||||
ComboMelee {
|
ComboMelee {
|
||||||
@ -587,6 +637,15 @@ impl AbilityData {
|
|||||||
.and_then(|cs| cs.stage_section())
|
.and_then(|cs| cs.stage_section())
|
||||||
.map_or(false, |ss| !matches!(ss, StageSection::Recover))
|
.map_or(false, |ss| !matches!(ss, StageSection::Recover))
|
||||||
},
|
},
|
||||||
|
BasicRanged {
|
||||||
|
energy,
|
||||||
|
projectile_speed,
|
||||||
|
} => ranged_check(*projectile_speed) && energy_check(*energy),
|
||||||
|
BasicMelee {
|
||||||
|
energy,
|
||||||
|
range,
|
||||||
|
angle,
|
||||||
|
} => melee_check(*range, *angle, None) && energy_check(*energy),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use crate::data::{ActionMode, AgentData, AttackData, Path, ReadData, TargetData};
|
use crate::data::{AbilityData, ActionMode, AgentData, AttackData, Path, ReadData, TargetData};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
agent::Psyche, buff::BuffKind, inventory::item::ItemTag, item::ItemDesc, Agent, Alignment,
|
ability::AbilityInput,
|
||||||
Body, Controller, InputKind, Pos, Scale,
|
agent::Psyche,
|
||||||
|
buff::BuffKind,
|
||||||
|
item::{tool::AbilityContext, ItemDesc, ItemTag},
|
||||||
|
Agent, Alignment, Body, Controller, InputKind, Pos, Scale,
|
||||||
},
|
},
|
||||||
consts::GRAVITY,
|
consts::GRAVITY,
|
||||||
terrain::Block,
|
terrain::Block,
|
||||||
@ -205,6 +208,24 @@ impl<'a> AgentData<'a> {
|
|||||||
.get(*self.entity)
|
.get(*self.entity)
|
||||||
.map_or(false, |b| b.kinds.contains_key(&buff))
|
.map_or(false, |b| b.kinds.contains_key(&buff))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn extract_ability(&self, input: AbilityInput) -> Option<AbilityData> {
|
||||||
|
let context = AbilityContext::from(self.stance, Some(self.inventory));
|
||||||
|
AbilityData::from_ability(
|
||||||
|
&self
|
||||||
|
.active_abilities
|
||||||
|
.activate_ability(
|
||||||
|
input,
|
||||||
|
Some(self.inventory),
|
||||||
|
self.skill_set,
|
||||||
|
self.body,
|
||||||
|
Some(self.char_state),
|
||||||
|
&context,
|
||||||
|
)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.0,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probably works best for melee (or maybe only for melee considering its
|
// Probably works best for melee (or maybe only for melee considering its
|
||||||
|
@ -113,7 +113,7 @@ impl Animation for AlphaAnimation {
|
|||||||
next.tail.orientation = Quaternion::rotation_x(0.05 * fastalt * speednormcancel)
|
next.tail.orientation = Quaternion::rotation_x(0.05 * fastalt * speednormcancel)
|
||||||
* Quaternion::rotation_z(fast * 0.15 * speednormcancel);
|
* Quaternion::rotation_z(fast * 0.15 * speednormcancel);
|
||||||
},
|
},
|
||||||
Some(ToolKind::Axe) | Some(ToolKind::Hammer) => {
|
Some(ToolKind::Axe) | Some(ToolKind::Hammer) | Some(ToolKind::Pick) => {
|
||||||
next.head.orientation = Quaternion::rotation_z(move1abs * 0.3 + move2abs * -0.6);
|
next.head.orientation = Quaternion::rotation_z(move1abs * 0.3 + move2abs * -0.6);
|
||||||
next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
|
next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
|
||||||
next.control_r.position = Vec3::new(
|
next.control_r.position = Vec3::new(
|
||||||
|
@ -39,7 +39,7 @@ impl Animation for LeapAnimation {
|
|||||||
_ => (0.0, 0.0, 0.0, 0.0),
|
_ => (0.0, 0.0, 0.0, 0.0),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ToolKind::Hammer) = active_tool_kind {
|
if let Some(ToolKind::Hammer | ToolKind::Pick) = active_tool_kind {
|
||||||
next.hand_l.position = Vec3::new(s_a.grip.0 * 2.0, 0.0, s_a.grip.2);
|
next.hand_l.position = Vec3::new(s_a.grip.0 * 2.0, 0.0, s_a.grip.2);
|
||||||
next.hand_r.position = Vec3::new(-s_a.grip.0 * 2.0, 0.0, s_a.grip.2);
|
next.hand_r.position = Vec3::new(-s_a.grip.0 * 2.0, 0.0, s_a.grip.2);
|
||||||
next.hand_l.orientation = Quaternion::rotation_x(0.0);
|
next.hand_l.orientation = Quaternion::rotation_x(0.0);
|
||||||
|
@ -167,7 +167,7 @@ impl Animation for WieldAnimation {
|
|||||||
* Quaternion::rotation_y(-0.2 * speednorm)
|
* Quaternion::rotation_y(-0.2 * speednorm)
|
||||||
* Quaternion::rotation_z(0.5);
|
* Quaternion::rotation_z(0.5);
|
||||||
},
|
},
|
||||||
Some(ToolKind::Axe) | Some(ToolKind::Hammer) => {
|
Some(ToolKind::Axe) | Some(ToolKind::Hammer | ToolKind::Pick) => {
|
||||||
next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
|
next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0);
|
||||||
next.control_r.position =
|
next.control_r.position =
|
||||||
Vec3::new(9.0 + s_a.grip.0 * 2.0, -1.0, -2.0 + speednorm * -3.0);
|
Vec3::new(9.0 + s_a.grip.0 * 2.0, -1.0, -2.0 + speednorm * -3.0);
|
||||||
|
Loading…
Reference in New Issue
Block a user