Maelstrom

This commit is contained in:
Sam 2023-05-18 19:33:47 -04:00
parent 0e771c9082
commit ff15780c22
14 changed files with 150 additions and 100 deletions

View File

@ -147,24 +147,30 @@
primary: Simple(None, "common.abilities.axe.triple_chop"),
secondary: Simple(None, "common.abilities.axe.cleave"),
abilities: [
Simple(Some(Axe(BrutalSwing)), "common.abilities.axe.brutal_swing"),
Simple(Some(Axe(Berserk)), "common.abilities.axe.berserk"),
Simple(Some(Axe(RisingTide)), "common.abilities.axe.rising_tide"),
Simple(Some(Axe(SavageSense)), "common.abilities.axe.savage_sense"),
Simple(Some(Axe(AdrenalineRush)), "common.abilities.axe.adrenaline_rush"),
Simple(Some(Axe(Execute)), "common.abilities.axe.execute"),
Simple(Some(Axe(Rake)), "common.abilities.axe.rake"),
Simple(Some(Axe(Bloodfeast)), "common.abilities.axe.bloodfeast"),
Simple(Some(Axe(FierceRaze)), "common.abilities.axe.fierce_raze"),
Simple(Some(Axe(Furor)), "common.abilities.axe.furor"),
Simple(Some(Axe(Fracture)), "common.abilities.axe.fracture"),
Simple(Some(Axe(Lacerate)), "common.abilities.axe.lacerate"),
Simple(Some(Axe(SkullBash)), "common.abilities.axe.skull_bash"),
Simple(Some(Axe(Sunder)), "common.abilities.axe.sunder"),
Simple(Some(Axe(Plunder)), "common.abilities.axe.plunder"),
Simple(Some(Axe(Defiance)), "common.abilities.axe.defiance"),
Simple(Some(Axe(Keelhaul)), "common.abilities.axe.keelhaul"),
Simple(Some(Axe(Bulkhead)), "common.abilities.axe.bulkhead"),
Simple(Axe(BrutalSwing), "common.abilities.axe.brutal_swing"),
Simple(Axe(Berserk), "common.abilities.axe.berserk"),
Simple(Axe(RisingTide), "common.abilities.axe.rising_tide"),
Simple(Axe(SavageSense), "common.abilities.axe.savage_sense"),
Simple(Axe(AdrenalineRush), "common.abilities.axe.adrenaline_rush"),
Contextualized(
pseudo_id: "common.abilities.axe.execute",
abilities: [
([Combo(50)], (Axe(Maelstrom), "common.abilities.axe.maelstrom")),
([], (Axe(Execute), "common.abilities.axe.execute")),
],
),
Simple(Axe(Rake), "common.abilities.axe.rake"),
Simple(Axe(Bloodfeast), "common.abilities.axe.bloodfeast"),
Simple(Axe(FierceRaze), "common.abilities.axe.fierce_raze"),
Simple(Axe(Furor), "common.abilities.axe.furor"),
Simple(Axe(Fracture), "common.abilities.axe.fracture"),
Simple(Axe(Lacerate), "common.abilities.axe.lacerate"),
Simple(Axe(SkullBash), "common.abilities.axe.skull_bash"),
Simple(Axe(Sunder), "common.abilities.axe.sunder"),
Simple(Axe(Plunder), "common.abilities.axe.plunder"),
Simple(Axe(Defiance), "common.abilities.axe.defiance"),
Simple(Axe(Keelhaul), "common.abilities.axe.keelhaul"),
Simple(Axe(Bulkhead), "common.abilities.axe.bulkhead"),
],
),
Tool(Hammer): (

View File

@ -1,6 +1,6 @@
FinisherMelee(
energy_cost: 0,
buildup_duration: 0.6,
buildup_duration: 0.5,
swing_duration: 0.2,
recover_duration: 0.4,
melee_constructor: (

View File

@ -1,22 +1,18 @@
ComboMelee2(
strikes: [
(
melee_constructor: (
kind: Slash(
damage: 4,
poise: 5,
knockback: 0,
energy_regen: 5,
),
range: 3.0,
angle: 45.0,
),
buildup_duration: 0.15,
swing_duration: 0.05,
hit_timing: 0.5,
recover_duration: 0.1,
ori_modifier: 0.6,
FinisherMelee(
energy_cost: 0,
buildup_duration: 0.5,
swing_duration: 0.4,
recover_duration: 0.2,
melee_constructor: (
kind: Slash(
damage: 75,
poise: 100,
knockback: 0,
energy_regen: 0,
),
],
energy_cost_per_strike: 0,
range: 3.0,
angle: 360.0,
multi_target: Some(Normal),
),
minimum_combo: 50,
)

View File

@ -11,7 +11,7 @@ use crate::{
Inventory,
},
skills::Skill,
CharacterAbility, SkillSet,
CharacterAbility, Combo, SkillSet,
},
};
use hashbrown::HashMap;
@ -361,7 +361,7 @@ impl<T> AbilityKind<T> {
.find_map(|(req_contexts, a)| {
req_contexts
.iter()
.all(|req| contexts.contains(req))
.all(|req| req.fulfilled_by(contexts))
.then_some(a)
}),
}
@ -376,10 +376,15 @@ pub enum AbilityContext {
/// files(s).
Stance(Stance),
DualWieldingSameKind,
Combo(u32),
}
impl AbilityContext {
pub fn from(stance: Option<&Stance>, inv: Option<&Inventory>) -> Vec<Self> {
pub fn from(
stance: Option<&Stance>,
inv: Option<&Inventory>,
combo: Option<&Combo>,
) -> Vec<Self> {
let mut contexts = Vec::new();
match stance {
Some(Stance::None) => {},
@ -400,8 +405,29 @@ impl AbilityContext {
contexts.push(AbilityContext::DualWieldingSameKind)
}
}
if let Some(combo) = combo {
contexts.push(AbilityContext::Combo(combo.counter()));
}
contexts
}
fn fulfilled_by(&self, contexts: &[AbilityContext]) -> bool {
match self {
basic_context @ Self::Stance(_) | basic_context @ Self::DualWieldingSameKind => {
contexts.contains(basic_context)
},
Self::Combo(required) => contexts
.iter()
.filter_map(|context| {
if let Self::Combo(combo) = context {
Some(combo)
} else {
None
}
})
.any(|combo| combo >= required),
}
}
}
impl AbilitySet<AbilityItem> {

View File

@ -1204,7 +1204,7 @@ fn handle_ability(
output_events: &mut OutputEvents,
input: InputKind,
) -> bool {
let contexts = AbilityContext::from(data.stance, data.inventory);
let contexts = AbilityContext::from(data.stance, data.inventory, data.combo);
if let Some(ability_input) = input.into() {
if let Some((ability, from_offhand)) = data
.active_abilities

View File

@ -1359,7 +1359,7 @@ impl<'a> AgentData<'a> {
enum ActionStateConditions {
ConditionStaffCanShockwave = 0,
}
let contexts = AbilityContext::from(self.stance, Some(self.inventory));
let contexts = AbilityContext::from(self.stance, Some(self.inventory), self.combo);
let extract_ability = |input: AbilityInput| {
self.active_abilities
.activate_ability(

View File

@ -208,7 +208,7 @@ impl<'a> AgentData<'a> {
}
pub fn extract_ability(&self, input: AbilityInput) -> Option<AbilityData> {
let context = AbilityContext::from(self.stance, Some(self.inventory));
let context = AbilityContext::from(self.stance, Some(self.inventory), self.combo);
AbilityData::from_ability(
&self
.active_abilities

View File

@ -37,10 +37,12 @@ impl Animation for ChargeswingAnimation {
next.main.position = Vec3::new(0.0, 0.0, 0.0);
next.main.orientation = Quaternion::rotation_z(0.0);
next.main_weapon_trail = true;
next.second.position = Vec3::new(0.0, 0.0, 0.0);
next.second.orientation = Quaternion::rotation_z(0.0);
next.off_weapon_trail = true;
if matches!(stage_section, Some(StageSection::Action)) {
next.main_weapon_trail = true;
next.off_weapon_trail = true;
}
match ability_id {
Some(
@ -237,16 +239,10 @@ impl Animation for ChargeswingAnimation {
Some("common.abilities.axe.cleave") => {
let (move1, move2, move3, tension) = match stage_section {
Some(StageSection::Charge) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(anim_time.min(1.0), 0.0, 0.0, (anim_time * 20.0).sin())
},
Some(StageSection::Action) => (1.0, anim_time.powi(2), 0.0, 0.0),
Some(StageSection::Recover) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(1.0, 1.0, anim_time, 0.0)
},
Some(StageSection::Recover) => (1.0, 1.0, anim_time, 0.0),
_ => (0.0, 0.0, 0.0, 0.0),
};
let pullback = 1.0 - move3;

View File

@ -32,10 +32,12 @@ impl Animation for ComboAnimation {
next.main.position = Vec3::new(0.0, 0.0, 0.0);
next.main.orientation = Quaternion::rotation_z(0.0);
next.main_weapon_trail = true;
next.second.position = Vec3::new(0.0, 0.0, 0.0);
next.second.orientation = Quaternion::rotation_z(0.0);
next.off_weapon_trail = true;
if matches!(stage_section, Some(StageSection::Action)) {
next.main_weapon_trail = true;
next.off_weapon_trail = true;
}
let multi_strike_pullback = 1.0
- if matches!(stage_section, Some(StageSection::Recover)) {
anim_time.powi(4)
@ -882,17 +884,9 @@ impl Animation for ComboAnimation {
Some("common.abilities.axe.triple_chop") => {
let (move1, move2) = if strike == current_strike {
match stage_section {
Some(StageSection::Buildup) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(anim_time, 0.0)
},
Some(StageSection::Buildup) => (anim_time, 0.0),
Some(StageSection::Action) => (1.0, anim_time),
Some(StageSection::Recover) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(1.0, 1.0)
},
Some(StageSection::Recover) => (1.0, 1.0),
_ => (0.0, 0.0),
}
} else {
@ -972,17 +966,9 @@ impl Animation for ComboAnimation {
},
Some("common.abilities.axe.brutal_swing") => {
let (move1, move2_raw) = match stage_section {
Some(StageSection::Buildup) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(anim_time, 0.0)
},
Some(StageSection::Buildup) => (anim_time, 0.0),
Some(StageSection::Action) => (1.0, anim_time),
Some(StageSection::Recover) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(1.0, 1.0)
},
Some(StageSection::Recover) => (1.0, 1.0),
_ => (0.0, 0.0),
};
let move1 = move1 * multi_strike_pullback;
@ -1007,17 +993,9 @@ impl Animation for ComboAnimation {
},
Some("common.abilities.axe.rising_tide") => {
let (move1, move2_raw) = match stage_section {
Some(StageSection::Buildup) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(anim_time, 0.0)
},
Some(StageSection::Buildup) => (anim_time, 0.0),
Some(StageSection::Action) => (1.0, anim_time),
Some(StageSection::Recover) => {
next.main_weapon_trail = false;
next.off_weapon_trail = false;
(1.0, 1.0)
},
Some(StageSection::Recover) => (1.0, 1.0),
_ => (0.0, 0.0),
};
let move1 = move1 * multi_strike_pullback;

View File

@ -26,10 +26,12 @@ impl Animation for FinisherMeleeAnimation {
next.main.position = Vec3::new(0.0, 0.0, 0.0);
next.main.orientation = Quaternion::rotation_z(0.0);
next.main_weapon_trail = true;
next.second.position = Vec3::new(0.0, 0.0, 0.0);
next.second.orientation = Quaternion::rotation_z(0.0);
next.off_weapon_trail = true;
if matches!(stage_section, Some(StageSection::Action)) {
next.main_weapon_trail = true;
next.off_weapon_trail = true;
}
match ability_id {
Some("common.abilities.sword.basic_mighty_strike") => {
@ -176,6 +178,46 @@ impl Animation for FinisherMeleeAnimation {
next.control.position += Vec3::new(move2 * -3.0, move2 * 12.0, move2 * -17.0);
next.control.orientation.rotate_z(move2 * 0.7);
},
Some("common.abilities.axe.maelstrom") => {
let (move1, move2_raw, move3) = match stage_section {
Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
Some(StageSection::Action) => (1.0, anim_time, 0.0),
Some(StageSection::Recover) => (1.0, 1.0, anim_time),
_ => (0.0, 0.0, 0.0),
};
let pullback = 1.0 - move3;
let move1 = move1 * pullback;
let move2 = move2_raw * pullback;
next.hand_l.position = Vec3::new(s_a.ahl.0, s_a.ahl.1, s_a.ahl.2);
next.hand_l.orientation =
Quaternion::rotation_x(s_a.ahl.3) * Quaternion::rotation_y(s_a.ahl.4);
next.hand_r.position = Vec3::new(s_a.ahr.0, s_a.ahr.1, s_a.ahr.2);
next.hand_r.orientation =
Quaternion::rotation_x(s_a.ahr.3) * Quaternion::rotation_z(s_a.ahr.5);
next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
* Quaternion::rotation_y(s_a.ac.4)
* Quaternion::rotation_z(s_a.ac.5);
next.control.orientation.rotate_x(move1 * 0.9);
next.chest.orientation.rotate_z(move1 * 1.2);
next.head.orientation.rotate_z(move1 * -0.5);
next.belt.orientation.rotate_z(move1 * -0.3);
next.shorts.orientation.rotate_z(move1 * -0.7);
next.control.position += Vec3::new(move1 * 4.0, move1 * -12.0, move1 * 11.0);
next.chest.orientation.rotate_z(move2 * -2.0);
next.head.orientation.rotate_z(move2 * 0.9);
next.belt.orientation.rotate_z(move2 * 0.4);
next.shorts.orientation.rotate_z(move2 * 1.1);
next.control.orientation.rotate_x(move2 * -5.0);
next.control.position += Vec3::new(move2 * 5.0, move2 * 12.0, move2 * -17.0);
next.control.orientation.rotate_y(move2 * -2.0);
next.control.orientation.rotate_z(move2 * -1.0);
next.torso.orientation.rotate_z(move2_raw * -4.0 * PI);
},
_ => {},
}

View File

@ -34,10 +34,12 @@ impl Animation for RapidMeleeAnimation {
next.main.position = Vec3::new(0.0, 0.0, 0.0);
next.main.orientation = Quaternion::rotation_z(0.0);
next.main_weapon_trail = true;
next.second.position = Vec3::new(0.0, 0.0, 0.0);
next.second.orientation = Quaternion::rotation_z(0.0);
next.off_weapon_trail = true;
if matches!(stage_section, Some(StageSection::Action)) {
next.main_weapon_trail = true;
next.off_weapon_trail = true;
}
match ability_id {
Some(

View File

@ -25,10 +25,12 @@ impl Animation for RiposteMeleeAnimation {
next.main.position = Vec3::new(0.0, 0.0, 0.0);
next.main.orientation = Quaternion::rotation_z(0.0);
next.main_weapon_trail = true;
next.second.position = Vec3::new(0.0, 0.0, 0.0);
next.second.orientation = Quaternion::rotation_z(0.0);
next.off_weapon_trail = true;
if matches!(stage_section, Some(StageSection::Action)) {
next.main_weapon_trail = true;
next.off_weapon_trail = true;
}
match ability_id {
Some("common.abilities.sword.defensive_riposte") => {

View File

@ -3047,6 +3047,7 @@ impl Hud {
let bodies = ecs.read_storage::<comp::Body>();
let poises = ecs.read_storage::<comp::Poise>();
let combos = ecs.read_storage::<comp::Combo>();
let combo = combos.get(entity);
let time = ecs.read_resource::<Time>();
let stances = ecs.read_storage::<comp::Stance>();
let char_states = ecs.read_storage::<comp::CharacterState>();
@ -3073,7 +3074,7 @@ impl Hud {
bodies.get(entity),
) {
let stance = stances.get(entity);
let contexts = AbilityContext::from(stance, Some(inventory));
let contexts = AbilityContext::from(stance, Some(inventory), combo);
match Skillbar::new(
client,
&info,
@ -3100,7 +3101,7 @@ impl Hud {
&msm,
self.floaters.combo_floater,
&contexts,
combos.get(entity),
combo,
char_states.get(entity),
stance,
)
@ -3581,7 +3582,7 @@ impl Hud {
bodies.get(entity),
poises.get(entity),
) {
let contexts = AbilityContext::from(stances.get(entity), Some(inventory));
let contexts = AbilityContext::from(stances.get(entity), Some(inventory), combo);
for event in Diary::new(
&self.show,
client,

View File

@ -39,9 +39,9 @@ use common::{
inventory::slot::EquipSlot,
item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
ship::{self, figuredata::VOXEL_COLLIDER_MANIFEST},
Body, CharacterActivity, CharacterState, Collider, Controller, Health, Inventory, Item,
ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState, Pos,
Scale, SkillSet, Stance, Vel,
Body, CharacterActivity, CharacterState, Collider, Combo, Controller, Health, Inventory,
Item, ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState,
Pos, Scale, SkillSet, Stance, Vel,
},
link::Is,
mounting::{Rider, VolumeRider},
@ -853,7 +853,7 @@ impl FigureMgr {
inventory,
item,
light_emitter,
(is_rider, is_volume_rider, collider, stance, skillset),
(is_rider, is_volume_rider, collider, stance, skillset, combo),
),
) in (
&ecs.entities(),
@ -877,6 +877,7 @@ impl FigureMgr {
ecs.read_storage::<Collider>().maybe(),
ecs.read_storage::<Stance>().maybe(),
ecs.read_storage::<SkillSet>().maybe(),
ecs.read_storage::<Combo>().maybe(),
),
)
.join()
@ -1037,7 +1038,7 @@ impl FigureMgr {
let second_tool_spec = second_tool_spec.as_deref();
let hands = (active_tool_hand, second_tool_hand);
let contexts = AbilityContext::from(stance, inventory);
let contexts = AbilityContext::from(stance, inventory, combo);
let ability_id = character.and_then(|c| {
c.ability_info()