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",
|
secondary: "common.abilities.custom.mandragora.scream",
|
||||||
abilities: [],
|
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"): (
|
Custom("Sword Simple"): (
|
||||||
primary: "common.abilities.swordsimple.doublestrike",
|
primary: "common.abilities.swordsimple.doublestrike",
|
||||||
secondary: "common.abilities.swordsimple.dash",
|
secondary: "common.abilities.swordsimple.dash",
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 5.0,
|
range: 5.0,
|
||||||
angle: 120.0,
|
angle: 120.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 4.0,
|
range: 4.0,
|
||||||
angle: 45.0,
|
angle: 45.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 4.0,
|
range: 4.0,
|
||||||
angle: 60.0,
|
angle: 60.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 3,
|
range: 3,
|
||||||
angle: 30,
|
angle: 30,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 5.0,
|
range: 5.0,
|
||||||
angle: 60.0,
|
angle: 60.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 0.8,
|
range: 0.8,
|
||||||
angle: 50.0,
|
angle: 50.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 5.0,
|
range: 5.0,
|
||||||
angle: 60.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,
|
range: 4.0,
|
||||||
angle: 20.0,
|
angle: 20.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 3.5,
|
range: 3.5,
|
||||||
angle: 20.0,
|
angle: 20.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 3.5,
|
range: 3.5,
|
||||||
angle: 15.0,
|
angle: 15.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 3.5,
|
range: 3.5,
|
||||||
angle: 20.0,
|
angle: 20.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 3,
|
range: 3,
|
||||||
angle: 30,
|
angle: 30,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 2,
|
range: 2,
|
||||||
angle: 15,
|
angle: 15,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 4.5,
|
range: 4.5,
|
||||||
angle: 20.0,
|
angle: 20.0,
|
||||||
),
|
),
|
||||||
|
ori_modifier: 1.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,5 @@ BasicMelee(
|
|||||||
range: 3.0,
|
range: 3.0,
|
||||||
angle: 90.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,
|
swing_duration: f32,
|
||||||
recover_duration: f32,
|
recover_duration: f32,
|
||||||
melee_constructor: MeleeConstructor,
|
melee_constructor: MeleeConstructor,
|
||||||
|
ori_modifier: f32,
|
||||||
},
|
},
|
||||||
BasicRanged {
|
BasicRanged {
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
@ -610,6 +611,7 @@ impl Default for CharacterAbility {
|
|||||||
angle: 15.0,
|
angle: 15.0,
|
||||||
damage_effect: None,
|
damage_effect: None,
|
||||||
},
|
},
|
||||||
|
ori_modifier: 1.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -697,6 +699,7 @@ impl CharacterAbility {
|
|||||||
ref mut swing_duration,
|
ref mut swing_duration,
|
||||||
ref mut recover_duration,
|
ref mut recover_duration,
|
||||||
ref mut melee_constructor,
|
ref mut melee_constructor,
|
||||||
|
ori_modifier: _,
|
||||||
} => {
|
} => {
|
||||||
*buildup_duration /= stats.speed;
|
*buildup_duration /= stats.speed;
|
||||||
*swing_duration /= stats.speed;
|
*swing_duration /= stats.speed;
|
||||||
@ -1696,6 +1699,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
swing_duration,
|
swing_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
melee_constructor,
|
melee_constructor,
|
||||||
|
ori_modifier,
|
||||||
energy_cost: _,
|
energy_cost: _,
|
||||||
} => CharacterState::BasicMelee(basic_melee::Data {
|
} => CharacterState::BasicMelee(basic_melee::Data {
|
||||||
static_data: basic_melee::StaticData {
|
static_data: basic_melee::StaticData {
|
||||||
@ -1703,6 +1707,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
swing_duration: Duration::from_secs_f32(*swing_duration),
|
swing_duration: Duration::from_secs_f32(*swing_duration),
|
||||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||||
melee_constructor: *melee_constructor,
|
melee_constructor: *melee_constructor,
|
||||||
|
ori_modifier: *ori_modifier,
|
||||||
ability_info,
|
ability_info,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
|
@ -180,6 +180,9 @@ fn default_main_tool(body: &Body) -> Item {
|
|||||||
golem::Species::ClayGolem => Some(Item::new_from_asset_expect(
|
golem::Species::ClayGolem => Some(Item::new_from_asset_expect(
|
||||||
"common.items.npc_weapons.unique.clay_golem_fist",
|
"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,
|
_ => None,
|
||||||
},
|
},
|
||||||
Body::QuadrupedMedium(quadruped_medium) => match quadruped_medium.species {
|
Body::QuadrupedMedium(quadruped_medium) => match quadruped_medium.species {
|
||||||
@ -465,6 +468,7 @@ impl LoadoutBuilder {
|
|||||||
},
|
},
|
||||||
Body::Golem(body) => match body.species {
|
Body::Golem(body) => match body.species {
|
||||||
golem::Species::ClayGolem => Some("common.items.npc_armor.golem.claygolem"),
|
golem::Species::ClayGolem => Some("common.items.npc_armor.golem.claygolem"),
|
||||||
|
golem::Species::WoodGolem => Some("common.items.npc_armor.golem.woodgolem"),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Body::QuadrupedLow(body) => match body.species {
|
Body::QuadrupedLow(body) => match body.species {
|
||||||
|
@ -23,6 +23,8 @@ pub struct StaticData {
|
|||||||
pub recover_duration: Duration,
|
pub recover_duration: Duration,
|
||||||
/// Used to construct the Melee attack
|
/// Used to construct the Melee attack
|
||||||
pub melee_constructor: MeleeConstructor,
|
pub melee_constructor: MeleeConstructor,
|
||||||
|
/// Adjusts turning rate during the attack
|
||||||
|
pub ori_modifier: f32,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_info: AbilityInfo,
|
pub ability_info: AbilityInfo,
|
||||||
}
|
}
|
||||||
@ -44,7 +46,7 @@ impl CharacterBehavior for Data {
|
|||||||
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||||
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, self.static_data.ori_modifier, None);
|
||||||
handle_move(data, &mut update, 0.7);
|
handle_move(data, &mut update, 0.7);
|
||||||
handle_jump(data, output_events, &mut update, 1.0);
|
handle_jump(data, output_events, &mut update, 1.0);
|
||||||
|
|
||||||
|
@ -1749,6 +1749,7 @@ impl<'a> AgentData<'a> {
|
|||||||
"Gnarling Blowgun" => Tactic::ElevatedRanged,
|
"Gnarling Blowgun" => Tactic::ElevatedRanged,
|
||||||
"Deadwood" => Tactic::Deadwood,
|
"Deadwood" => Tactic::Deadwood,
|
||||||
"Mandragora" => Tactic::Mandragora,
|
"Mandragora" => Tactic::Mandragora,
|
||||||
|
"Wood Golem" => Tactic::WoodGolem,
|
||||||
_ => Tactic::SimpleMelee,
|
_ => Tactic::SimpleMelee,
|
||||||
},
|
},
|
||||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||||
@ -2132,6 +2133,9 @@ impl<'a> AgentData<'a> {
|
|||||||
Tactic::Mandragora => {
|
Tactic::Mandragora => {
|
||||||
self.handle_mandragora(agent, controller, &attack_data, tgt_data, read_data)
|
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,
|
StoneGolem,
|
||||||
Deadwood,
|
Deadwood,
|
||||||
Mandragora,
|
Mandragora,
|
||||||
|
WoodGolem,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(SystemData)]
|
#[derive(SystemData)]
|
||||||
|
@ -87,6 +87,7 @@ fn maps_basic_melee() {
|
|||||||
angle: 15.0,
|
angle: 15.0,
|
||||||
damage_effect: None,
|
damage_effect: None,
|
||||||
},
|
},
|
||||||
|
ori_modifier: 1.0,
|
||||||
ability_info: empty_ability_info(),
|
ability_info: empty_ability_info(),
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
|
Loading…
Reference in New Issue
Block a user