mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Mandragora attacks and ai
This commit is contained in:
parent
f1801560fa
commit
e044bf5091
@ -84,6 +84,11 @@
|
||||
secondary: "common.abilities.custom.deadwood.dash",
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Mandragora"): (
|
||||
primary: "common.abilities.custom.mandragora.basic",
|
||||
secondary: "common.abilities.custom.mandragora.scream",
|
||||
abilities: [],
|
||||
),
|
||||
Custom("Sword Simple"): (
|
||||
primary: "common.abilities.swordsimple.doublestrike",
|
||||
secondary: "common.abilities.swordsimple.dash",
|
||||
|
16
assets/common/abilities/custom/mandragora/basic.ron
Normal file
16
assets/common/abilities/custom/mandragora/basic.ron
Normal file
@ -0,0 +1,16 @@
|
||||
BasicMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.2,
|
||||
swing_duration: 0.05,
|
||||
recover_duration: 0.3,
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 4,
|
||||
poise: 5,
|
||||
knockback: 0,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3,
|
||||
angle: 30,
|
||||
),
|
||||
)
|
21
assets/common/abilities/custom/mandragora/scream.ron
Normal file
21
assets/common/abilities/custom/mandragora/scream.ron
Normal file
@ -0,0 +1,21 @@
|
||||
SpinMelee(
|
||||
buildup_duration: 0.5,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 0.5,
|
||||
melee_constructor: (
|
||||
kind: SonicWave(
|
||||
damage: 5,
|
||||
poise: 100,
|
||||
knockback: 20,
|
||||
),
|
||||
range: 10,
|
||||
angle: 360.0,
|
||||
),
|
||||
energy_cost: 0.0,
|
||||
is_infinite: false,
|
||||
movement_behavior: Stationary,
|
||||
is_interruptible: false,
|
||||
forward_speed: 0.0,
|
||||
num_spins: 1,
|
||||
specifier: None,
|
||||
)
|
@ -2,7 +2,11 @@ EntityConfig (
|
||||
name: Name("Mandragora"),
|
||||
body: RandomWith("mandragora"),
|
||||
alignment: Alignment(Enemy),
|
||||
loadout: Asset(Loadout("common.loadout.dungeon.gnarling.mandragora")),
|
||||
loadout: Extended(
|
||||
hands: TwoHanded(Item("common.items.npc_weapons.biped_small.mandragora")),
|
||||
base_asset: Loadout("common.loadout.dungeon.gnarling.mandragora"),
|
||||
inventory: [],
|
||||
),
|
||||
loot: LootTable("common.loot_tables.dungeon.tier-0.miniboss"),
|
||||
meta: [],
|
||||
)
|
||||
|
21
assets/common/items/npc_weapons/biped_small/mandragora.ron
Normal file
21
assets/common/items/npc_weapons/biped_small/mandragora.ron
Normal file
@ -0,0 +1,21 @@
|
||||
ItemDef(
|
||||
name: "Mandragora",
|
||||
description: "Testing",
|
||||
kind: Tool((
|
||||
kind: Natural,
|
||||
hands: Two,
|
||||
stats: Direct((
|
||||
equip_time_secs: 0.0,
|
||||
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("Mandragora")),
|
||||
)
|
@ -1179,4 +1179,8 @@
|
||||
vox_spec: ("weapon.biped_small.axe.strategian", (-0.5, -6.0, -4.0)),
|
||||
color: None
|
||||
),
|
||||
"common.items.npc_weapons.biped_small.mandragora": (
|
||||
vox_spec: ("armor.empty", (0.0, 0.0, 0.0)),
|
||||
color: None
|
||||
),
|
||||
})
|
||||
|
@ -483,6 +483,7 @@ pub struct ActionState {
|
||||
pub counter: f32,
|
||||
pub condition: bool,
|
||||
pub int_counter: u8,
|
||||
pub initialized: bool,
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
|
@ -232,6 +232,43 @@ impl MeleeConstructor {
|
||||
.with_effect(knockback)
|
||||
.with_combo_increment()
|
||||
},
|
||||
SonicWave {
|
||||
damage,
|
||||
poise,
|
||||
knockback,
|
||||
} => {
|
||||
let mut damage = AttackDamage::new(
|
||||
Damage {
|
||||
source: DamageSource::Melee,
|
||||
kind: DamageKind::Energy,
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
);
|
||||
|
||||
if let Some(damage_effect) = self.damage_effect {
|
||||
damage = damage.with_effect(damage_effect);
|
||||
}
|
||||
|
||||
let poise =
|
||||
AttackEffect::new(Some(GroupTarget::OutOfGroup), CombatEffect::Poise(poise))
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let knockback = AttackEffect::new(
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
CombatEffect::Knockback(Knockback {
|
||||
strength: knockback,
|
||||
direction: KnockbackDir::Away,
|
||||
}),
|
||||
)
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
|
||||
Attack::default()
|
||||
.with_damage(damage)
|
||||
.with_crit(crit_chance, crit_mult)
|
||||
.with_effect(poise)
|
||||
.with_effect(knockback)
|
||||
.with_combo_increment()
|
||||
},
|
||||
};
|
||||
|
||||
Melee {
|
||||
@ -324,6 +361,22 @@ impl MeleeConstructor {
|
||||
pull: scale_values(a_pull, b_pull),
|
||||
lifesteal: scale_values(a_lifesteal, b_lifesteal),
|
||||
},
|
||||
(
|
||||
SonicWave {
|
||||
damage: a_damage,
|
||||
poise: a_poise,
|
||||
knockback: a_knockback,
|
||||
},
|
||||
SonicWave {
|
||||
damage: b_damage,
|
||||
poise: b_poise,
|
||||
knockback: b_knockback,
|
||||
},
|
||||
) => SonicWave {
|
||||
damage: scale_values(a_damage, b_damage),
|
||||
poise: scale_values(a_poise, b_poise),
|
||||
knockback: scale_values(a_knockback, b_knockback),
|
||||
},
|
||||
_ => {
|
||||
dev_panic!(
|
||||
"Attempted to scale on a melee attack between two different kinds of \
|
||||
@ -382,6 +435,11 @@ pub enum MeleeConstructorKind {
|
||||
pull: f32,
|
||||
lifesteal: f32,
|
||||
},
|
||||
SonicWave {
|
||||
damage: f32,
|
||||
poise: f32,
|
||||
knockback: f32,
|
||||
},
|
||||
}
|
||||
|
||||
impl MeleeConstructorKind {
|
||||
@ -426,6 +484,14 @@ impl MeleeConstructorKind {
|
||||
} => {
|
||||
*damage *= stats.power;
|
||||
},
|
||||
SonicWave {
|
||||
ref mut damage,
|
||||
ref mut poise,
|
||||
knockback: _,
|
||||
} => {
|
||||
*damage *= stats.power;
|
||||
*poise *= stats.effect_power;
|
||||
},
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1748,6 +1748,7 @@ impl<'a> AgentData<'a> {
|
||||
"Gnarling Dagger" => Tactic::SimpleBackstab,
|
||||
"Gnarling Blowgun" => Tactic::ElevatedRanged,
|
||||
"Deadwood" => Tactic::Deadwood,
|
||||
"Mandragora" => Tactic::Mandragora,
|
||||
_ => Tactic::SimpleMelee,
|
||||
},
|
||||
AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind),
|
||||
@ -2128,6 +2129,9 @@ impl<'a> AgentData<'a> {
|
||||
Tactic::Deadwood => {
|
||||
self.handle_deadwood(agent, controller, &attack_data, tgt_data, read_data)
|
||||
},
|
||||
Tactic::Mandragora => {
|
||||
self.handle_mandragora(agent, controller, &attack_data, tgt_data, read_data)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2144,4 +2144,52 @@ impl<'a> AgentData<'a> {
|
||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_mandragora(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
) {
|
||||
const SCREAM_RANGE: f32 = 10.0;
|
||||
|
||||
if !agent.action_state.initialized {
|
||||
agent.action_state.counter = self.health.map_or(0.0, |h| h.maximum());
|
||||
agent.action_state.initialized = true;
|
||||
}
|
||||
|
||||
if !agent.action_state.condition {
|
||||
// If mandragora is still "sleeping" and hasn't screamed yet, do nothing until
|
||||
// target in range or until it's taken damage
|
||||
if self
|
||||
.health
|
||||
.map_or(false, |h| h.current() < agent.action_state.counter)
|
||||
|| attack_data.dist_sqrd < SCREAM_RANGE.powi(2)
|
||||
{
|
||||
agent.action_state.condition = true;
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
}
|
||||
} else {
|
||||
// Once mandragora has woken, move towards target and attack
|
||||
if attack_data.in_min_range() {
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2)
|
||||
&& can_see_tgt(
|
||||
&read_data.terrain,
|
||||
self.pos,
|
||||
tgt_data.pos,
|
||||
attack_data.dist_sqrd,
|
||||
)
|
||||
{
|
||||
// If in pathing range and can see target, move towards them
|
||||
self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None);
|
||||
} else {
|
||||
// Otherwise, go back to sleep
|
||||
agent.action_state.condition = false;
|
||||
agent.action_state.counter = self.health.map_or(0.0, |h| h.maximum());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ pub enum Tactic {
|
||||
Harvester,
|
||||
StoneGolem,
|
||||
Deadwood,
|
||||
Mandragora,
|
||||
}
|
||||
|
||||
#[derive(SystemData)]
|
||||
|
Loading…
Reference in New Issue
Block a user