From f1801560fa90b6a9210ae9235993e3f84c2ba395 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 30 Jan 2022 18:04:09 -0500 Subject: [PATCH] Deadwood ai --- .../common/abilities/ability_set_manifest.ron | 5 +++ .../common/abilities/custom/deadwood/dash.ron | 28 +++++++++++++ .../custom/deadwood/lifestealbeam.ron | 14 +++++++ assets/common/abilities/gnarling/axe/chop.ron | 22 +++++----- .../common/abilities/gnarling/dagger/stab.ron | 22 +++++----- .../entity/dungeon/gnarling/deadwood.ron | 8 ---- .../entity/dungeon/gnarling/mandragora.ron | 9 +--- .../entity/dungeon/gnarling/woodgolem.ron | 5 +-- .../items/npc_weapons/unique/deadwood.ron | 21 ++++++++++ assets/voxygen/shaders/particle-vert.glsl | 2 +- common/src/comp/inventory/loadout_builder.rs | 2 +- server/src/sys/agent.rs | 4 ++ server/src/sys/agent/attack.rs | 41 +++++++++++++++++++ server/src/sys/agent/data.rs | 1 + world/src/site2/plot/dungeon.rs | 18 -------- world/src/site2/plot/gnarling.rs | 21 +++++++++- 16 files changed, 159 insertions(+), 64 deletions(-) create mode 100644 assets/common/abilities/custom/deadwood/dash.ron create mode 100644 assets/common/abilities/custom/deadwood/lifestealbeam.ron delete mode 100644 assets/common/entity/dungeon/gnarling/deadwood.ron create mode 100644 assets/common/items/npc_weapons/unique/deadwood.ron diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index dc5b0c8e3d..b8db252fd0 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -79,6 +79,11 @@ secondary: "common.abilities.gnarling.blowgun.dart", abilities: [], ), + Custom("Deadwood"): ( + primary: "common.abilities.custom.deadwood.lifestealbeam", + secondary: "common.abilities.custom.deadwood.dash", + abilities: [], + ), Custom("Sword Simple"): ( primary: "common.abilities.swordsimple.doublestrike", secondary: "common.abilities.swordsimple.dash", diff --git a/assets/common/abilities/custom/deadwood/dash.ron b/assets/common/abilities/custom/deadwood/dash.ron new file mode 100644 index 0000000000..853c25462e --- /dev/null +++ b/assets/common/abilities/custom/deadwood/dash.ron @@ -0,0 +1,28 @@ +DashMelee( + energy_cost: 0, + melee_constructor: ( + kind: Bash( + damage: 8.0, + poise: 25.0, + knockback: 4.0, + energy_regen: 0.0, + ), + scaled: Some(Bash( + damage: 15.0, + poise: 0.0, + knockback: 17.0, + energy_regen: 0.0, + )), + range: 4, + angle: 45.0, + ), + energy_drain: 0, + forward_speed: 3, + buildup_duration: 0.5, + charge_duration: 1.0, + swing_duration: 0.1, + recover_duration: 1.0, + ori_modifier: 0.1, + charge_through: true, + is_interruptible: false, +) diff --git a/assets/common/abilities/custom/deadwood/lifestealbeam.ron b/assets/common/abilities/custom/deadwood/lifestealbeam.ron new file mode 100644 index 0000000000..9f3964953a --- /dev/null +++ b/assets/common/abilities/custom/deadwood/lifestealbeam.ron @@ -0,0 +1,14 @@ +BasicBeam( + buildup_duration: 0.25, + recover_duration: 0.25, + beam_duration: 1, + damage: 3.0, + tick_rate: 2.0, + range: 25.0, + max_angle: 1.0, + damage_effect: Some(Lifesteal(0.15)), + energy_regen: 2.5, + energy_drain: 0, + ori_rate: 0.3, + specifier: LifestealBeam, +) diff --git a/assets/common/abilities/gnarling/axe/chop.ron b/assets/common/abilities/gnarling/axe/chop.ron index cbbe6ec444..833977ec9b 100644 --- a/assets/common/abilities/gnarling/axe/chop.ron +++ b/assets/common/abilities/gnarling/axe/chop.ron @@ -3,16 +3,14 @@ BasicMelee( buildup_duration: 0.2, swing_duration: 0.05, recover_duration: 0.3, - base_damage: 6, - base_poise_damage: 5, - knockback: ( strength: 0, direction: Away), - range: 3, - max_angle: 30, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10, - strength: DamageFraction(0.1), - chance: 0.1, - ))), - damage_kind: Slashing, + melee_constructor: ( + kind: Slash( + damage: 6, + poise: 5, + knockback: 0, + energy_regen: 0, + ), + range: 3, + angle: 30, + ), ) diff --git a/assets/common/abilities/gnarling/dagger/stab.ron b/assets/common/abilities/gnarling/dagger/stab.ron index 00046bc35b..7c786aa313 100644 --- a/assets/common/abilities/gnarling/dagger/stab.ron +++ b/assets/common/abilities/gnarling/dagger/stab.ron @@ -3,16 +3,14 @@ BasicMelee( buildup_duration: 0.1, swing_duration: 0.05, recover_duration: 0.25, - base_damage: 4, - base_poise_damage: 0, - knockback: ( strength: 0, direction: Away), - range: 2, - max_angle: 15, - damage_effect: Some(Buff(( - kind: Bleeding, - dur_secs: 10, - strength: DamageFraction(0.2), - chance: 0.3, - ))), - damage_kind: Piercing, + melee_constructor: ( + kind: Stab( + damage: 4, + poise: 0, + knockback: 0, + energy_regen: 0, + ), + range: 2, + angle: 15, + ), ) diff --git a/assets/common/entity/dungeon/gnarling/deadwood.ron b/assets/common/entity/dungeon/gnarling/deadwood.ron deleted file mode 100644 index 0268e145e1..0000000000 --- a/assets/common/entity/dungeon/gnarling/deadwood.ron +++ /dev/null @@ -1,8 +0,0 @@ -( - name: Name("Deadwood"), - body: RandomWith("deadwood"), - alignment: Alignment(Enemy), - loadout: FromBody, - loot: LootTable("common.loot_tables.dungeon.tier-0.miniboss"), - meta: [], -) \ No newline at end of file diff --git a/assets/common/entity/dungeon/gnarling/mandragora.ron b/assets/common/entity/dungeon/gnarling/mandragora.ron index a84ccfb7fd..32dc6d62fe 100644 --- a/assets/common/entity/dungeon/gnarling/mandragora.ron +++ b/assets/common/entity/dungeon/gnarling/mandragora.ron @@ -2,12 +2,7 @@ EntityConfig ( name: Name("Mandragora"), body: RandomWith("mandragora"), alignment: Alignment(Enemy), - + loadout: Asset(Loadout("common.loadout.dungeon.gnarling.mandragora")), loot: LootTable("common.loot_tables.dungeon.tier-0.miniboss"), - - hands: Uninit, - - meta: [ - LoadoutAsset("common.loadout.dungeon.gnarling.mandragora"), - ], + meta: [], ) diff --git a/assets/common/entity/dungeon/gnarling/woodgolem.ron b/assets/common/entity/dungeon/gnarling/woodgolem.ron index 914004a643..0b49caf998 100644 --- a/assets/common/entity/dungeon/gnarling/woodgolem.ron +++ b/assets/common/entity/dungeon/gnarling/woodgolem.ron @@ -2,10 +2,7 @@ EntityConfig ( name: Name("Wooden Golem"), body: RandomWith("woodgolem"), alignment: Alignment(Enemy), - + loadout: FromBody, loot: LootTable("common.loot_tables.dungeon.tier-0.miniboss"), - - hands: Uninit, - meta: [], ) diff --git a/assets/common/items/npc_weapons/unique/deadwood.ron b/assets/common/items/npc_weapons/unique/deadwood.ron new file mode 100644 index 0000000000..f99d846845 --- /dev/null +++ b/assets/common/items/npc_weapons/unique/deadwood.ron @@ -0,0 +1,21 @@ +ItemDef( + name: "Deadwood", + description: "testing123", + kind: Tool(( + kind: Natural, + hands: Two, + stats: Direct(( + equip_time_secs: 0.01, + 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("Deadwood")), +) \ No newline at end of file diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 9c4ddba1b6..f0a752c104 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -398,7 +398,7 @@ void main() { attr = Attr( spiral_motion(inst_dir, 0.3 * (floor(2 * rand0 + 0.5) - 0.5) * min(linear_scale(10), 1), lifetime / inst_lifespan, 10.0, inst_time), vec3((1.7 - 0.7 * abs(floor(2 * rand0 - 0.5) + 0.5)) * (1.5 + 0.5 * sin(tick.x * 10 - lifetime * 4))), - vec4(vec3(red_col + purple_col * 0.6, green_col + purple_col * 0.35, purple_col), 1), + vec4(vec3(purple_col, green_col, 0.75 * purple_col), 1), spin_in_axis(inst_dir, tick.z) ); break; diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 4c456a9cba..7bd3e03e4f 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -241,7 +241,7 @@ fn default_main_tool(body: &Body) -> Item { "common.items.npc_weapons.unique.quadlowbreathe", )), quadruped_low::Species::Deadwood => Some(Item::new_from_asset_expect( - "common.items.npc_weapons.unique.quadlowbeam", + "common.items.npc_weapons.unique.deadwood", )), quadruped_low::Species::Basilisk => Some(Item::new_from_asset_expect( "common.items.npc_weapons.unique.basilisk", diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index b8613de660..ae3c1c4752 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -1747,6 +1747,7 @@ impl<'a> AgentData<'a> { "Harvester" => Tactic::Harvester, "Gnarling Dagger" => Tactic::SimpleBackstab, "Gnarling Blowgun" => Tactic::ElevatedRanged, + "Deadwood" => Tactic::Deadwood, _ => Tactic::SimpleMelee, }, AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind), @@ -2124,6 +2125,9 @@ impl<'a> AgentData<'a> { Tactic::ElevatedRanged => { self.handle_elevated_ranged(agent, controller, &attack_data, tgt_data, read_data) }, + Tactic::Deadwood => { + self.handle_deadwood(agent, controller, &attack_data, tgt_data, read_data) + }, } } diff --git a/server/src/sys/agent/attack.rs b/server/src/sys/agent/attack.rs index 2e9d951435..40cacc2a2f 100644 --- a/server/src/sys/agent/attack.rs +++ b/server/src/sys/agent/attack.rs @@ -2103,4 +2103,45 @@ impl<'a> AgentData<'a> { // Always attempt to path towards target self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); } + + pub fn handle_deadwood( + &self, + agent: &mut Agent, + controller: &mut Controller, + attack_data: &AttackData, + tgt_data: &TargetData, + read_data: &ReadData, + ) { + const BEAM_RANGE: f32 = 20.0; + const BEAM_TIME: Duration = Duration::from_secs(3); + // action_state.condition controls whether or not deadwood should beam or dash + if matches!(self.char_state, CharacterState::DashMelee(s) if s.stage_section != StageSection::Recover) + { + // If already dashing, keep dashing and have move_dir set to forward + controller.push_basic_input(InputKind::Secondary); + controller.inputs.move_dir = self.ori.look_vec().xy(); + } else if attack_data.in_min_range() && attack_data.angle < 10.0 { + // If near target, dash at them and through them to get away + controller.push_basic_input(InputKind::Secondary); + } else if matches!(self.char_state, CharacterState::BasicBeam(s) if s.stage_section != StageSection::Recover && s.timer < BEAM_TIME) + { + // If already beaming, keep beaming if not beaming for over 5 seconds + controller.push_basic_input(InputKind::Primary); + } else if attack_data.dist_sqrd < BEAM_RANGE.powi(2) { + // Else if in beam range, beam them + if attack_data.angle < 5.0 { + controller.push_basic_input(InputKind::Primary); + } else { + // If not in angle, apply slight movement so deadwood 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 { + // Otherwise too far, move towards target + self.path_toward_target(agent, controller, tgt_data, read_data, false, false, None); + } + } } diff --git a/server/src/sys/agent/data.rs b/server/src/sys/agent/data.rs index 08f36425cc..7f00020972 100644 --- a/server/src/sys/agent/data.rs +++ b/server/src/sys/agent/data.rs @@ -114,6 +114,7 @@ pub enum Tactic { Yeti, Harvester, StoneGolem, + Deadwood, } #[derive(SystemData)] diff --git a/world/src/site2/plot/dungeon.rs b/world/src/site2/plot/dungeon.rs index 7e25b67895..c92fa70a09 100644 --- a/world/src/site2/plot/dungeon.rs +++ b/world/src/site2/plot/dungeon.rs @@ -285,7 +285,6 @@ impl Room { if tile_pos == miniboss_spawn_tile && tile_wcenter.xy() == wpos2d { let entities = match self.difficulty { - 0 => mini_boss_0(dynamic_rng, tile_wcenter), 1 => mini_boss_1(dynamic_rng, tile_wcenter), 2 => mini_boss_2(dynamic_rng, tile_wcenter), 3 => mini_boss_3(dynamic_rng, tile_wcenter), @@ -319,7 +318,6 @@ impl Room { if tile_pos == boss_spawn_tile && wpos2d == tile_wcenter.xy() { let entities = match self.difficulty { - 0 => boss_0(dynamic_rng, tile_wcenter), 1 => boss_1(dynamic_rng, tile_wcenter), 2 => boss_2(dynamic_rng, tile_wcenter), 3 => boss_3(dynamic_rng, tile_wcenter), @@ -772,13 +770,6 @@ fn turret_5(dynamic_rng: &mut impl Rng, pos: Vec3) -> EntityInfo { EntityInfo::at(pos).with_asset_expect("common.entity.dungeon.tier-5.turret", dynamic_rng) } -fn boss_0(dynamic_rng: &mut impl Rng, tile_wcenter: Vec3) -> Vec { - vec![ - EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_asset_expect("common.entity.dungeon.tier-0.boss", dynamic_rng), - ] -} - fn boss_1(dynamic_rng: &mut impl Rng, tile_wcenter: Vec3) -> Vec { vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) @@ -823,13 +814,6 @@ fn boss_fallback(dynamic_rng: &mut impl Rng, tile_wcenter: Vec3) -> Vec) -> Vec { - vec![ - EntityInfo::at(tile_wcenter.map(|e| e as f32)) - .with_asset_expect("common.entity.dungeon.tier-0.miniboss", dynamic_rng), - ] -} - fn mini_boss_1(dynamic_rng: &mut impl Rng, tile_wcenter: Vec3) -> Vec { let mut entities = Vec::new(); entities.resize_with(8, || { @@ -1440,7 +1424,6 @@ mod tests { fn test_creating_bosses() { let mut dynamic_rng = rand::thread_rng(); let tile_wcenter = Vec3::new(0, 0, 0); - boss_0(&mut dynamic_rng, tile_wcenter); boss_1(&mut dynamic_rng, tile_wcenter); boss_2(&mut dynamic_rng, tile_wcenter); boss_3(&mut dynamic_rng, tile_wcenter); @@ -1467,7 +1450,6 @@ mod tests { fn test_creating_minibosses() { let mut dynamic_rng = rand::thread_rng(); let tile_wcenter = Vec3::new(0, 0, 0); - mini_boss_0(&mut dynamic_rng, tile_wcenter); mini_boss_1(&mut dynamic_rng, tile_wcenter); mini_boss_2(&mut dynamic_rng, tile_wcenter); mini_boss_3(&mut dynamic_rng, tile_wcenter); diff --git a/world/src/site2/plot/gnarling.rs b/world/src/site2/plot/gnarling.rs index a9600435aa..e4c7979482 100644 --- a/world/src/site2/plot/gnarling.rs +++ b/world/src/site2/plot/gnarling.rs @@ -2177,7 +2177,7 @@ fn gnarling_chieftain(pos: Vec3, rng: &mut R) -> EntityInfo { fn deadwood(pos: Vec3, rng: &mut R) -> EntityInfo { EntityInfo::at(pos.map(|x| x as f32)) - .with_asset_expect("common.entity.dungeon.gnarling.deadwood", rng) + .with_asset_expect("common.entity.wild.aggressive.deadwood", rng) } fn mandragora(pos: Vec3, rng: &mut R) -> EntityInfo { @@ -2304,3 +2304,22 @@ where Some((branches, terminals)) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_creating_entities() { + let pos = Vec3::zero(); + + gnarling_mugger(pos); + gnarling_stalker(pos); + gnarling_logger(pos); + gnarling_chieftain(pos); + deadwood(pos); + mandragora(pos); + wood_golem(pos); + harvester_boss(pos); + } +}