diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 67ce8b6ded..2c5015f94c 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -258,6 +258,13 @@ secondary: "common.abilities.custom.quadmedbasic.triplestrike", abilities: [], ), + Custom("Roshwalr"): ( + primary: "common.abilities.custom.roshwalr.doublehusk", + secondary: "common.abilities.custom.roshwalr.slowcharge", + abilities: [ + Simple(None, "common.abilities.custom.roshwalr.freezeshockwave"), + ], + ), Custom("Basilisk"): ( primary: "common.abilities.custom.basilisk.petrify", secondary: "common.abilities.custom.basilisk.triplestrike", diff --git a/assets/common/abilities/custom/roshwalr/doublehusk.ron b/assets/common/abilities/custom/roshwalr/doublehusk.ron new file mode 100644 index 0000000000..8184536ac6 --- /dev/null +++ b/assets/common/abilities/custom/roshwalr/doublehusk.ron @@ -0,0 +1,43 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 28.0, + damage_increase: 0, + base_poise_damage: 15, + poise_damage_increase: 0, + knockback: 3.0, + range: 2.2, + angle: 30.0, + base_buildup_duration: 1.2, + base_swing_duration: 0.07, + hit_timing: 0.5, + base_recover_duration: 0.3, + forward_movement: 0.5, + damage_kind: Crushing, + ), + ( + stage: 2, + base_damage: 28.0, + damage_increase: 0, + base_poise_damage: 18, + poise_damage_increase: 0, + knockback: 3.0, + range: 2.2, + angle: 30.0, + base_buildup_duration: 0.2, + base_swing_duration: 0.07, + hit_timing: 0.5, + base_recover_duration: 0.6, + forward_movement: 0.5, + damage_kind: Crushing, + ), + ], + initial_energy_gain: 0, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 0.0, + scales_from_combo: 0, + ori_modifier: 0.65, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/roshwalr/freezeshockwave.ron b/assets/common/abilities/custom/roshwalr/freezeshockwave.ron new file mode 100644 index 0000000000..e504dadc12 --- /dev/null +++ b/assets/common/abilities/custom/roshwalr/freezeshockwave.ron @@ -0,0 +1,23 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 0.9, + swing_duration: 0.15, + recover_duration: 2.0, + damage: 15.0, + poise_damage: 10, + knockback: (strength: 18.0, direction: Up), + shockwave_angle: 75.0, + shockwave_vertical_angle: 15.0, + shockwave_speed: 20.0, + shockwave_duration: 0.5, + requires_ground: true, + move_efficiency: 0.2, + damage_kind: Piercing, + specifier: IceSpikes, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 4.0, + strength: DamageFraction(0.1), + chance: 1, + ))), +) diff --git a/assets/common/abilities/custom/roshwalr/slowcharge.ron b/assets/common/abilities/custom/roshwalr/slowcharge.ron new file mode 100644 index 0000000000..ac862cb06a --- /dev/null +++ b/assets/common/abilities/custom/roshwalr/slowcharge.ron @@ -0,0 +1,27 @@ +DashMelee( + energy_cost: 0, + melee_constructor: ( + kind: Bash( + damage: 14.0, + poise: 28.0, + knockback: 8.0, + energy_regen: 0.0, + ), + scaled: Some(Bash( + damage: 65.0, + poise: 35.0, + knockback: 14.0, + energy_regen: 0.0, + )), + range: 2.5, + angle: 45.0, + ), + energy_drain: 0, + forward_speed: 1.0, + buildup_duration: 1.0, + charge_duration: 5, + swing_duration: 0.1, + recover_duration: 2.2, + ori_modifier: 0.3, + charge_through: false, +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/unique/roshwalr.ron b/assets/common/items/npc_weapons/unique/roshwalr.ron new file mode 100644 index 0000000000..ab45b58b5f --- /dev/null +++ b/assets/common/items/npc_weapons/unique/roshwalr.ron @@ -0,0 +1,21 @@ +ItemDef( + name: "Roshwalr", + description: "testing123", + 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("Roshwalr")), +) \ No newline at end of file diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 401f4fe850..bb18365a1d 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -556,13 +556,15 @@ fn default_main_tool(body: &Body) -> Item { "common.items.npc_weapons.unique.quadmedjump", )), quadruped_medium::Species::Tuskram - | quadruped_medium::Species::Roshwalr | quadruped_medium::Species::Moose | quadruped_medium::Species::Dreadhorn | quadruped_medium::Species::Mammoth | quadruped_medium::Species::Ngoubou => Some(Item::new_from_asset_expect( "common.items.npc_weapons.unique.quadmedcharge", )), + quadruped_medium::Species::Roshwalr => Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.roshwalr", + )), quadruped_medium::Species::Highland | quadruped_medium::Species::Cattle | quadruped_medium::Species::Yak => Some(Item::new_from_asset_expect( diff --git a/server/agent/src/action_nodes.rs b/server/agent/src/action_nodes.rs index d1fb00c29f..0403660ee5 100644 --- a/server/agent/src/action_nodes.rs +++ b/server/agent/src/action_nodes.rs @@ -824,6 +824,7 @@ impl<'a> AgentData<'a> { circle_time: 1, }, "Quad Med Basic" => Tactic::QuadMedBasic, + "Roshwalr" => Tactic::Roshwalr, "Asp" | "Maneater" => Tactic::QuadLowRanged, "Quad Low Breathe" | "Quad Low Beam" | "Basilisk" => { Tactic::QuadLowBeam @@ -1139,6 +1140,13 @@ impl<'a> AgentData<'a> { tgt_data, read_data, ), + Tactic::Roshwalr => self.handle_roshwalr_attack( + agent, + controller, + &attack_data, + tgt_data, + read_data, + ), Tactic::OrganAura => { self.handle_organ_aura_attack(agent, controller, &attack_data, tgt_data, read_data) }, diff --git a/server/agent/src/attack.rs b/server/agent/src/attack.rs index 10741060c7..2b8b06f493 100644 --- a/server/agent/src/attack.rs +++ b/server/agent/src/attack.rs @@ -3507,6 +3507,63 @@ impl<'a> AgentData<'a> { ); } + pub fn handle_roshwalr_attack( + &self, + agent: &mut Agent, + controller: &mut Controller, + attack_data: &AttackData, + tgt_data: &TargetData, + read_data: &ReadData, + ) { + const SLOW_CHARGE_RANGE: f32 = 20.0; + const SHOCKWAVE_RANGE: f32 = 12.5; + const SHOCKWAVE_TIMER: f32 = 10.0; + + enum ActionStateFCounters { + FCounterRoshwalrAttack = 0, + } + + agent.action_state.counters[ActionStateFCounters::FCounterRoshwalrAttack as usize] += + read_data.dt.0; + if matches!(self.char_state, CharacterState::DashMelee(c) if !matches!(c.stage_section, StageSection::Recover)) + { + // If already charging, keep charging if not in recover + controller.push_basic_input(InputKind::Ability(0)); + } else if attack_data.dist_sqrd < SHOCKWAVE_RANGE.powi(2) { + if agent.action_state.counters[ActionStateFCounters::FCounterRoshwalrAttack as usize] + > SHOCKWAVE_TIMER + { + // Use shockwave if timer has gone for long enough + controller.push_basic_input(InputKind::Ability(0)); + + if matches!(self.char_state, CharacterState::Shockwave(_)) { + // Resets action counter when using shockwave + agent.action_state.counters + [ActionStateFCounters::FCounterRoshwalrAttack as usize] = 0.0; + } + } else if attack_data.in_min_range() { + // Basic attack if on top of them + controller.push_basic_input(InputKind::Primary); + } else { + // Use slow charge if too far for other abilities + controller.push_basic_input(InputKind::Secondary); + } + } else if attack_data.dist_sqrd < SLOW_CHARGE_RANGE.powi(2) { + // Use slow charge if in range + controller.push_basic_input(InputKind::Secondary); + } + + // Always attempt to path towards target + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Partial, + None, + ); + } + pub fn handle_harvester_attack( &self, agent: &mut Agent, diff --git a/server/agent/src/data.rs b/server/agent/src/data.rs index 5fd5205994..99779dca22 100644 --- a/server/agent/src/data.rs +++ b/server/agent/src/data.rs @@ -137,6 +137,7 @@ pub enum Tactic { OrganAura, Dagon, Cardinal, + Roshwalr, } #[derive(SystemData)]