This commit is contained in:
James Melkonian 2022-10-22 18:18:23 -07:00 committed by flo666
parent 586d0f6dd8
commit 6bacb487f3
10 changed files with 181 additions and 2 deletions

View File

@ -121,6 +121,11 @@
(None, "common.abilities.custom.woodgolem.shockwave")
],
),
Custom("Simple Flying Melee"): (
primary: "common.abilities.custom.simpleflyingmelee.singlestrike",
secondary: "common.abilities.custom.simpleflyingmelee.singlestrike",
abilities: [],
),
Custom("Sword Simple"): (
primary: "common.abilities.swordsimple.doublestrike",
secondary: "common.abilities.swordsimple.dash",

View File

@ -0,0 +1,28 @@
ComboMelee(
stage_data: [
(
stage: 1,
base_damage: 4.0,
damage_increase: 0,
base_poise_damage: 0,
poise_damage_increase: 0,
knockback: 0.0,
range: 2.5,
angle: 150.0,
base_buildup_duration: 0.1,
base_swing_duration: 0.07,
hit_timing: 0.5,
base_recover_duration: 0.2,
forward_movement: 0.0,
damage_kind: Piercing,
),
],
initial_energy_gain: 0,
max_energy_gain: 0,
energy_increase: 0,
speed_increase: 0.0,
max_speed_increase: 0.0,
scales_from_combo: 0,
is_interruptible: false,
ori_modifier: 0.6,
)

View File

@ -0,0 +1,21 @@
ItemDef(
name: "Simple Flying Melee",
description: "I believe I can fly!!!!!",
kind: Tool((
kind: Natural,
hands: Two,
stats: (
equip_time_secs: 0.01,
power: 1.0,
effect_power: 1.0,
speed: 1.0,
crit_chance: 0.0625,
range: 1.0,
energy_efficiency: 1.0,
buff_strength: 1.0,
),
)),
quality: Low,
tags: [],
ability_spec: Some(Custom("Simple Flying Melee")),
)

View File

@ -289,6 +289,7 @@ impl<'a> From<&'a Body> for Psyche {
bird_medium::Species::Peacock => 0.4,
bird_medium::Species::Eagle => 0.3,
bird_medium::Species::Parrot => 0.8,
bird_medium::Species::Bat => 0.0,
_ => 0.5,
},
Body::BirdLarge(_) => 0.1,

View File

@ -27,7 +27,7 @@ use specs::{Component, DerefFlaggedStorage};
use strum::Display;
use vek::*;
use super::{BuffKind, Collider, Density, Mass};
use super::{BuffKind, Collider, Density, Mass, Scale};
make_case_elim!(
body,
@ -231,6 +231,17 @@ impl Body {
)
}
pub fn scale(&self) -> Scale {
let s = match self {
Body::BirdMedium(bird_medium) => match bird_medium.species {
bird_medium::Species::Bat => 0.5,
_ => 1.0,
},
_ => 1.0,
};
Scale(s)
}
/// Average density of the body
// Units are based on kg/m³
pub fn density(&self) -> Density {

View File

@ -1,7 +1,7 @@
use crate::{
assets::{self, AssetExt},
comp::{
arthropod, biped_large, biped_small, bird_large, golem,
arthropod, biped_large, biped_small, bird_large, bird_medium, golem,
inventory::{
loadout::Loadout,
slot::{ArmorSlot, EquipSlot},
@ -778,6 +778,12 @@ fn default_main_tool(body: &Body) -> Item {
"common.items.npc_weapons.unique.birdlargebasic",
)),
},
Body::BirdMedium(bird_medium) => match bird_medium.species {
bird_medium::Species::Bat => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.simpleflyingbasic",
)),
_ => None,
},
_ => None,
};

View File

@ -322,6 +322,44 @@ impl<'a> AgentData<'a> {
}
}
} else {
// Bats should fly
// Use a proportional controller as the bouncing effect mimics bat flight
if self.traversal_config.can_fly
&& self
.inventory
.equipped(EquipSlot::ActiveMainhand)
.as_ref()
.map_or(false, |item| {
item.ability_spec().map_or(false, |a_s| match &*a_s {
AbilitySpec::Custom(spec) => match spec.as_str() {
"Simple Flying Melee" => true,
_ => false,
},
_ => false,
})
})
{
// Bats don't like the ground, so make sure they are always flying
controller.push_basic_input(InputKind::Fly);
if read_data
.terrain
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 5.0))
.until(Block::is_solid)
.cast()
.1
.map_or(true, |b| b.is_some())
{
// Fly up
controller.inputs.move_z = 1.0;
// If on the ground, jump
if self.physics_state.on_ground.is_some() {
controller.push_basic_input(InputKind::Jump);
}
} else {
// Fly down
controller.inputs.move_z = -1.0;
}
}
agent.bearing += Vec2::new(rng.gen::<f32>() - 0.5, rng.gen::<f32>() - 0.5) * 0.1
- agent.bearing * 0.003
- agent.patrol_origin.map_or(Vec2::zero(), |patrol_origin| {
@ -768,6 +806,7 @@ impl<'a> AgentData<'a> {
AbilitySpec::Custom(spec) => match spec.as_str() {
"Oni" | "Sword Simple" => Tactic::Sword,
"Staff Simple" => Tactic::Staff,
"Simple Flying Melee" => Tactic::SimpleFlyingMelee,
"Bow Simple" => Tactic::Bow,
"Stone Golem" => Tactic::StoneGolem,
"Quad Med Quick" => Tactic::CircleCharge {
@ -1000,6 +1039,14 @@ impl<'a> AgentData<'a> {
// Match on tactic. Each tactic has different controls depending on the distance
// from the agent to the target.
match tactic {
Tactic::SimpleFlyingMelee => self.handle_simple_flying_melee(
agent,
controller,
&attack_data,
tgt_data,
read_data,
rng,
),
Tactic::SimpleMelee => {
self.handle_simple_melee(agent, controller, &attack_data, tgt_data, read_data, rng)
},

View File

@ -53,6 +53,64 @@ impl<'a> AgentData<'a> {
}
}
// Intended for any agent that has one attack, that attack is a melee attack,
// and the agent is able to freely fly around
pub fn handle_simple_flying_melee(
&self,
agent: &mut Agent,
controller: &mut Controller,
attack_data: &AttackData,
tgt_data: &TargetData,
read_data: &ReadData,
rng: &mut impl Rng,
) {
// Fly to target
let dir_to_target = ((tgt_data.pos.0 + Vec3::unit_z() * 1.5) - self.pos.0)
.try_normalized()
.unwrap_or_else(Vec3::zero);
let speed = 1.0;
controller.inputs.move_dir = dir_to_target.xy() * speed;
// Always fly! If the floor can't touch you, it can't hurt you...
controller.push_basic_input(InputKind::Fly);
// Flee from the ground! The internet told me it was lava!
// If on the ground, jump with every last ounce of energy, holding onto all that
// is dear in life and straining for the wide open skies.
if self.physics_state.on_ground.is_some() {
controller.push_basic_input(InputKind::Jump);
} else {
// Only fly down if close enough to target in the xy plane
// Otherwise fly towards the target bouncing around a 5 block altitude
let mut maintain_altitude = |altitude| {
if read_data
.terrain
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * altitude))
.until(Block::is_solid)
.cast()
.1
.map_or(true, |b| b.is_some())
{
// Fly up
controller.inputs.move_z = 1.0;
} else {
// Fly down
controller.inputs.move_z = -1.0;
}
};
if (tgt_data.pos.0 - self.pos.0).xy().magnitude_squared() > (5.0_f32).powi(2) {
// If above 5 blocks, fly down
maintain_altitude(5.0);
} else {
maintain_altitude(2.0);
// Attack if in range
if attack_data.dist_sqrd < 3.5_f32.powi(2) && attack_data.angle < 150.0 {
controller.push_basic_input(InputKind::Primary);
}
}
}
}
// Intended for any agent that has one attack, that attack is a melee attack,
// the agent is able to freely walk around, and the agent is trying to attack
// from behind its target

View File

@ -74,6 +74,7 @@ impl AttackData {
pub enum Tactic {
// General tactics
SimpleMelee,
SimpleFlyingMelee,
SimpleBackstab,
ElevatedRanged,
Turret,

View File

@ -1212,6 +1212,7 @@ fn handle_spawn(
body,
)
.with(comp::Vel(vel))
.with(body.scale())
.with(alignment);
if ai {