Mandragora attacks and ai

This commit is contained in:
Sam 2022-02-02 00:17:06 -05:00
parent f1801560fa
commit e044bf5091
11 changed files with 192 additions and 1 deletions

View File

@ -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",

View 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,
),
)

View 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,
)

View File

@ -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: [],
)

View 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")),
)

View File

@ -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
),
})

View File

@ -483,6 +483,7 @@ pub struct ActionState {
pub counter: f32,
pub condition: bool,
pub int_counter: u8,
pub initialized: bool,
}
impl Agent {

View File

@ -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
}

View File

@ -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)
},
}
}

View File

@ -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());
}
}
}
}

View File

@ -115,6 +115,7 @@ pub enum Tactic {
Harvester,
StoneGolem,
Deadwood,
Mandragora,
}
#[derive(SystemData)]