mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Wood golem attacks and ai
This commit is contained in:
parent
e044bf5091
commit
fcb0f8d8f0
@ -89,6 +89,13 @@
|
||||
secondary: "common.abilities.custom.mandragora.scream",
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Wood Golem"): (
|
||||
primary: "common.abilities.custom.woodgolem.strike",
|
||||
secondary: "common.abilities.custom.woodgolem.spin",
|
||||
abilities: [
|
||||
(None, "common.abilities.custom.woodgolem.shockwave")
|
||||
],
|
||||
),
|
||||
Custom("Sword Simple"): (
|
||||
primary: "common.abilities.swordsimple.doublestrike",
|
||||
secondary: "common.abilities.swordsimple.dash",
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 5.0,
|
||||
angle: 120.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 4.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 4.0,
|
||||
angle: 60.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 3,
|
||||
angle: 30,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 5.0,
|
||||
angle: 60.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 0.8,
|
||||
angle: 50.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 5.0,
|
||||
angle: 60.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
17
assets/common/abilities/custom/woodgolem/shockwave.ron
Normal file
17
assets/common/abilities/custom/woodgolem/shockwave.ron
Normal file
@ -0,0 +1,17 @@
|
||||
Shockwave(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.5,
|
||||
swing_duration: 0.12,
|
||||
recover_duration: 1.2,
|
||||
damage: 20.0,
|
||||
poise_damage: 30,
|
||||
knockback: (strength: 30.0, direction: TowardsUp),
|
||||
shockwave_angle: 90.0,
|
||||
shockwave_vertical_angle: 90.0,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Ground,
|
||||
)
|
22
assets/common/abilities/custom/woodgolem/spin.ron
Normal file
22
assets/common/abilities/custom/woodgolem/spin.ron
Normal file
@ -0,0 +1,22 @@
|
||||
SpinMelee(
|
||||
buildup_duration: 0.1,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 0.1,
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 15.0,
|
||||
poise: 30.0,
|
||||
knockback: 20.0,
|
||||
energy_regen: 0.0,
|
||||
),
|
||||
range: 7.5,
|
||||
angle: 360.0,
|
||||
),
|
||||
energy_cost: 0,
|
||||
is_infinite: false,
|
||||
movement_behavior: Stationary,
|
||||
is_interruptible: false,
|
||||
forward_speed: 0.0,
|
||||
num_spins: 1,
|
||||
specifier: None,
|
||||
)
|
17
assets/common/abilities/custom/woodgolem/strike.ron
Normal file
17
assets/common/abilities/custom/woodgolem/strike.ron
Normal file
@ -0,0 +1,17 @@
|
||||
BasicMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.5,
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 10.0,
|
||||
poise: 25.0,
|
||||
knockback: 15.0,
|
||||
energy_regen: 0.0,
|
||||
),
|
||||
range: 4.0,
|
||||
angle: 45.0,
|
||||
),
|
||||
ori_modifier: 0.4,
|
||||
)
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 4.0,
|
||||
angle: 20.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 3.5,
|
||||
angle: 20.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 3.5,
|
||||
angle: 15.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 3.5,
|
||||
angle: 20.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 3,
|
||||
angle: 30,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 2,
|
||||
angle: 15,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 4.5,
|
||||
angle: 20.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
||||
range: 3.0,
|
||||
angle: 90.0,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
)
|
||||
|
13
assets/common/items/npc_armor/golem/woodgolem.ron
Normal file
13
assets/common/items/npc_armor/golem/woodgolem.ron
Normal file
@ -0,0 +1,13 @@
|
||||
ItemDef(
|
||||
name: "Wood Golem Armor",
|
||||
description: "Yeet",
|
||||
kind: Armor((
|
||||
kind: Chest("Wood Golem"),
|
||||
stats: (
|
||||
protection: Some(Normal(60.0)),
|
||||
poise_resilience: Some(Normal(60.0)),
|
||||
),
|
||||
)),
|
||||
quality: Common,
|
||||
tags: [],
|
||||
)
|
21
assets/common/items/npc_weapons/unique/wood_golem_fist.ron
Normal file
21
assets/common/items/npc_weapons/unique/wood_golem_fist.ron
Normal file
@ -0,0 +1,21 @@
|
||||
ItemDef(
|
||||
name: "Wood Golem Fists",
|
||||
description: "Yeet",
|
||||
kind: Tool((
|
||||
kind: Natural,
|
||||
hands: Two,
|
||||
stats: Direct((
|
||||
equip_time_secs: 0.001,
|
||||
power: 1.0,
|
||||
effect_power: 1.0,
|
||||
speed: 1.0,
|
||||
crit_chance: 0.1,
|
||||
range: 1.0,
|
||||
energy_efficiency: 1.0,
|
||||
buff_strength: 1.0,
|
||||
)),
|
||||
)),
|
||||
quality: Low,
|
||||
tags: [],
|
||||
ability_spec: Some(Custom("Wood Golem")),
|
||||
)
|
@ -394,6 +394,7 @@ pub enum CharacterAbility {
|
||||
swing_duration: f32,
|
||||
recover_duration: f32,
|
||||
melee_constructor: MeleeConstructor,
|
||||
ori_modifier: f32,
|
||||
},
|
||||
BasicRanged {
|
||||
energy_cost: f32,
|
||||
@ -610,6 +611,7 @@ impl Default for CharacterAbility {
|
||||
angle: 15.0,
|
||||
damage_effect: None,
|
||||
},
|
||||
ori_modifier: 1.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -697,6 +699,7 @@ impl CharacterAbility {
|
||||
ref mut swing_duration,
|
||||
ref mut recover_duration,
|
||||
ref mut melee_constructor,
|
||||
ori_modifier: _,
|
||||
} => {
|
||||
*buildup_duration /= stats.speed;
|
||||
*swing_duration /= stats.speed;
|
||||
@ -1696,6 +1699,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
swing_duration,
|
||||
recover_duration,
|
||||
melee_constructor,
|
||||
ori_modifier,
|
||||
energy_cost: _,
|
||||
} => CharacterState::BasicMelee(basic_melee::Data {
|
||||
static_data: basic_melee::StaticData {
|
||||
@ -1703,6 +1707,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
||||
swing_duration: Duration::from_secs_f32(*swing_duration),
|
||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||
melee_constructor: *melee_constructor,
|
||||
ori_modifier: *ori_modifier,
|
||||
ability_info,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
|
@ -180,6 +180,9 @@ fn default_main_tool(body: &Body) -> Item {
|
||||
golem::Species::ClayGolem => Some(Item::new_from_asset_expect(
|
||||
"common.items.npc_weapons.unique.clay_golem_fist",
|
||||
)),
|
||||
golem::Species::WoodGolem => Some(Item::new_from_asset_expect(
|
||||
"common.items.npc_weapons.unique.wood_golem_fist",
|
||||
)),
|
||||
_ => None,
|
||||
},
|
||||
Body::QuadrupedMedium(quadruped_medium) => match quadruped_medium.species {
|
||||
@ -465,6 +468,7 @@ impl LoadoutBuilder {
|
||||
},
|
||||
Body::Golem(body) => match body.species {
|
||||
golem::Species::ClayGolem => Some("common.items.npc_armor.golem.claygolem"),
|
||||
golem::Species::WoodGolem => Some("common.items.npc_armor.golem.woodgolem"),
|
||||
_ => None,
|
||||
},
|
||||
Body::QuadrupedLow(body) => match body.species {
|
||||
|
@ -23,6 +23,8 @@ pub struct StaticData {
|
||||
pub recover_duration: Duration,
|
||||
/// Used to construct the Melee attack
|
||||
pub melee_constructor: MeleeConstructor,
|
||||
/// Adjusts turning rate during the attack
|
||||
pub ori_modifier: f32,
|
||||
/// What key is used to press ability
|
||||
pub ability_info: AbilityInfo,
|
||||
}
|
||||
@ -44,7 +46,7 @@ impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
handle_orientation(data, &mut update, 1.0, None);
|
||||
handle_orientation(data, &mut update, self.static_data.ori_modifier, None);
|
||||
handle_move(data, &mut update, 0.7);
|
||||
handle_jump(data, output_events, &mut update, 1.0);
|
||||
|
||||
|
@ -1749,6 +1749,7 @@ impl<'a> AgentData<'a> {
|
||||
"Gnarling Blowgun" => Tactic::ElevatedRanged,
|
||||
"Deadwood" => Tactic::Deadwood,
|
||||
"Mandragora" => Tactic::Mandragora,
|
||||
"Wood Golem" => Tactic::WoodGolem,
|
||||
_ => Tactic::SimpleMelee,
|
||||
},
|
||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||
@ -2132,6 +2133,9 @@ impl<'a> AgentData<'a> {
|
||||
Tactic::Mandragora => {
|
||||
self.handle_mandragora(agent, controller, &attack_data, tgt_data, read_data)
|
||||
},
|
||||
Tactic::WoodGolem => {
|
||||
self.handle_wood_golem(agent, controller, &attack_data, tgt_data, read_data)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2192,4 +2192,58 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_wood_golem(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
) {
|
||||
const SHOCKWAVE_RANGE: f32 = 25.0;
|
||||
const SHOCKWAVE_WAIT_TIME: f32 = 7.5;
|
||||
const SPIN_WAIT_TIME: f32 = 3.0;
|
||||
|
||||
// After spinning, reset timer
|
||||
if matches!(self.char_state, CharacterState::SpinMelee(s) if s.stage_section == StageSection::Recover)
|
||||
{
|
||||
agent.action_state.timer = 0.0;
|
||||
}
|
||||
|
||||
if attack_data.in_min_range() {
|
||||
// If in minimum range
|
||||
if agent.action_state.timer > SPIN_WAIT_TIME {
|
||||
// If it's been too long since able to hit target, spin
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
} else if attack_data.angle < 30.0 {
|
||||
// Else if in angle to strike, strike
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
} else {
|
||||
// Else increment spin timer
|
||||
agent.action_state.timer += read_data.dt.0;
|
||||
// If not in angle, apply slight movement so golem orients itself correctly
|
||||
controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0)
|
||||
.xy()
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec2::zero)
|
||||
* 0.01;
|
||||
}
|
||||
} else {
|
||||
// Else if too far for melee
|
||||
if attack_data.dist_sqrd < SHOCKWAVE_RANGE.powi(2) && attack_data.angle < 45.0 {
|
||||
// Shockwave if close enough and haven't shockwaved too recently
|
||||
if agent.action_state.counter > SHOCKWAVE_WAIT_TIME {
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
}
|
||||
if matches!(self.char_state, CharacterState::Shockwave(_)) {
|
||||
agent.action_state.counter = 0.0;
|
||||
} else {
|
||||
agent.action_state.counter += read_data.dt.0;
|
||||
}
|
||||
}
|
||||
// And always try to path towards target
|
||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ pub enum Tactic {
|
||||
StoneGolem,
|
||||
Deadwood,
|
||||
Mandragora,
|
||||
WoodGolem,
|
||||
}
|
||||
|
||||
#[derive(SystemData)]
|
||||
|
@ -87,6 +87,7 @@ fn maps_basic_melee() {
|
||||
angle: 15.0,
|
||||
damage_effect: None,
|
||||
},
|
||||
ori_modifier: 1.0,
|
||||
ability_info: empty_ability_info(),
|
||||
},
|
||||
timer: Duration::default(),
|
||||
|
Loading…
Reference in New Issue
Block a user