Helm Crusher

This commit is contained in:
Sam 2024-02-25 14:58:09 -05:00
parent 38c74bf182
commit b8de5e414b
24 changed files with 129 additions and 20 deletions

View File

@ -234,7 +234,7 @@
),
Simple(Hammer(PileDriver), "common.abilities.hammer.pile_driver"),
Simple(Hammer(LungPummel), "common.abilities.hammer.lung_pummel"),
// Simple(Hammer(HelmCrusher), "common.abilities.hammer.helm_crusher"),
Simple(Hammer(HelmCrusher), "common.abilities.hammer.helm_crusher"),
// Simple(Hammer(Rampart), "common.abilities.hammer.rampart"),
// Simple(Hammer(Tenacity), "common.abilities.hammer.tenacity"),
// Simple(Hammer(Earthshaker), "common.abilities.hammer.earthshaker"),

View File

@ -0,0 +1,26 @@
FinisherMelee(
energy_cost: 0,
buildup_duration: 0.2,
swing_duration: 0.1,
recover_duration: 0.2,
melee_constructor: (
kind: Bash(
damage: 20,
poise: 20,
knockback: 12,
energy_regen: 0,
),
range: 4.0,
angle: 60.0,
damage_effect: Some(Buff((
kind: Concussion,
dur_secs: 8,
strength: Value(1.0),
chance: 1.0,
))),
precision_flank_multipliers: (front: 1.5, side: 1.0, back: 1.0),
precision_flank_invert: true,
),
minimum_combo: 10,
combo_consumption: Cost,
)

View File

@ -20,6 +20,6 @@ FinisherMelee(
))),
precision_flank_multipliers: (front: 1.0, side: 2.0, back: 1.0),
),
minimum_combo: 0,
minimum_combo: 10,
combo_consumption: Cost,
)

BIN
assets/voxygen/element/de_buffs/debuff_concussion.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/skills/hammer/helm_crusher.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -130,6 +130,9 @@ buff-rooted = Rooted
## Winded
buff-winded = Winded
.desc = You can barely breathe hampering how much energy you can recover and how quickly you can move.
## Concussion
buff-concussion = Concussion
.desc = You have been hit hard on the head and have trouble focusing, preventing you from using some of your more complex attacks.
## Util
buff-text-over_seconds = over { $dur_secs } seconds
buff-text-for_seconds = for { $dur_secs } seconds

View File

@ -419,3 +419,6 @@ common-abilities-hammer-pile_driver = Pile Driver
common-abilities-hammer-lung_pummel = Lung Pummel
.desc =
Swipe your hammer into your foe's side, winding them.
common-abilities-hammer-helm_crusher = Helm Crusher
.dsc =
Bash your enemy's head with your hammer, concussing them.

View File

@ -192,6 +192,7 @@ lazy_static! {
BuffKind::ScornfulTaunt => "scornful_taunt",
BuffKind::Rooted => "rooted",
BuffKind::Winded => "winded",
BuffKind::Concussion => "concussion",
};
let mut buff_parser = HashMap::new();
for kind in BuffKind::iter() {

View File

@ -167,18 +167,24 @@ impl ActiveAbilities {
input: AbilityInput,
inventory: Option<&Inventory>,
skill_set: Option<&SkillSet>,
stats: Option<&comp::Stats>,
) -> Ability {
match input {
AbilityInput::Guard => self.guard.into(),
AbilityInput::Primary => self.primary.into(),
AbilityInput::Secondary => self.secondary.into(),
AbilityInput::Movement => self.movement.into(),
AbilityInput::Auxiliary(index) => self
.auxiliary_set(inventory, skill_set)
.get(index)
.copied()
.map(|a| a.into())
.unwrap_or(Ability::Empty),
AbilityInput::Auxiliary(index) => {
if stats.map_or(false, |s| s.disable_auxiliary_abilities) {
Ability::Empty
} else {
self.auxiliary_set(inventory, skill_set)
.get(index)
.copied()
.map(|a| a.into())
.unwrap_or(Ability::Empty)
}
},
}
}
@ -192,9 +198,10 @@ impl ActiveAbilities {
body: Option<&Body>,
char_state: Option<&CharacterState>,
context: &AbilityContext,
stats: Option<&comp::Stats>,
// bool is from_offhand
) -> Option<(CharacterAbility, bool, SpecifiedAbility)> {
let ability = self.get_ability(input, inv, Some(skill_set));
let ability = self.get_ability(input, inv, Some(skill_set), stats);
let ability_set = |equip_slot| {
inv.and_then(|inv| inv.equipped(equip_slot))

View File

@ -190,6 +190,9 @@ pub enum BuffKind {
/// energy reward and 33% reduction of move speed. 1.0 leads to 67%
/// reduction of energy reward and 50% reduction of move speed.
Winded,
/// Prevents use of auxiliary abilities.
/// Does not scale with strength
Concussion,
// Complex, non-obvious buffs
/// Changed into another body.
Polymorphed,
@ -254,7 +257,8 @@ impl BuffKind {
| BuffKind::PotionSickness
| BuffKind::Heatstroke
| BuffKind::Rooted
| BuffKind::Winded => BuffDescriptor::SimpleNegative,
| BuffKind::Winded
| BuffKind::Concussion => BuffDescriptor::SimpleNegative,
BuffKind::Polymorphed => BuffDescriptor::Complex,
}
}
@ -502,6 +506,7 @@ impl BuffKind {
BuffEffect::MovementSpeed(1.0 - nn_scaling2(data.strength)),
BuffEffect::EnergyReward(1.0 - nn_scaling(data.strength)),
],
BuffKind::Concussion => vec![BuffEffect::DisableAuxiliaryAbilities],
}
}
@ -673,6 +678,8 @@ pub enum BuffEffect {
DamagedEffect(DamagedEffect),
/// Add an effect to the entity when killed
DeathEffect(DeathEffect),
/// Prevents use of auxiliary abilities
DisableAuxiliaryAbilities,
}
/// Actual de/buff.

View File

@ -77,6 +77,7 @@ pub struct Stats {
pub effects_on_damaged: Vec<DamagedEffect>,
/// This creates effects when the entity is killed
pub effects_on_death: Vec<DeathEffect>,
pub disable_auxiliary_abilities: bool,
}
impl Stats {
@ -103,6 +104,7 @@ impl Stats {
energy_reward_modifier: 1.0,
effects_on_damaged: Vec::new(),
effects_on_death: Vec::new(),
disable_auxiliary_abilities: false,
}
}

View File

@ -1298,6 +1298,7 @@ fn handle_ability(
Some(data.body),
Some(data.character),
&context,
Some(data.stats),
)
})
.map(|(mut a, f, s)| {

View File

@ -816,5 +816,6 @@ fn execute_effect(
},
BuffEffect::DamagedEffect(effect) => stat.effects_on_damaged.push(effect.clone()),
BuffEffect::DeathEffect(effect) => stat.effects_on_death.push(effect.clone()),
BuffEffect::DisableAuxiliaryAbilities => stat.disable_auxiliary_abilities = true,
};
}

View File

@ -1584,6 +1584,7 @@ impl<'a> AgentData<'a> {
self.body,
Some(self.char_state),
&context,
self.stats,
)
.map_or(Default::default(), |a| a.0)
};

View File

@ -219,6 +219,7 @@ impl<'a> AgentData<'a> {
self.body,
Some(self.char_state),
&context,
self.stats,
)
.map_or(Default::default(), |a| a.0),
)

View File

@ -4553,7 +4553,8 @@ fn build_buff(
| BuffKind::Heatstroke
| BuffKind::ScornfulTaunt
| BuffKind::Rooted
| BuffKind::Winded => {
| BuffKind::Winded
| BuffKind::Concussion => {
if buff_kind.is_simple() {
unreachable!("is_simple() above")
} else {

View File

@ -483,6 +483,30 @@ impl Animation for FinisherMeleeAnimation {
next.control.orientation.rotate_z(move2 * -4.0);
next.control.position += Vec3::new(12.0, 0.0, 14.0) * move2;
},
Some("common.abilities.hammer.helm_crusher") => {
hammer_start(&mut next, s_a);
let (move1, move2, 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 * pullback;
twist_back(&mut next, move1, 0.8, 0.3, 0.1, 0.5);
next.control.orientation.rotate_x(move1 * -0.8);
next.control.orientation.rotate_z(move1 * -1.6);
next.control.orientation.rotate_x(move1 * 2.8);
next.control.position += Vec3::new(-9.0, 0.0, 8.0) * move1;
next.control.orientation.rotate_z(move1 * -0.4);
twist_forward(&mut next, move2, 1.8, 0.7, 0.4, 1.1);
next.control.orientation.rotate_x(move2 * -5.0);
next.control.orientation.rotate_z(move2 * -1.0);
next.control.position += Vec3::new(-12.0, 0.0, -8.0) * move2;
},
_ => {},
}

View File

@ -408,7 +408,8 @@ fn get_buff_ident(buff: BuffKind) -> &'static str {
| BuffKind::Polymorphed
| BuffKind::Heatstroke
| BuffKind::Rooted
| BuffKind::Winded => {
| BuffKind::Winded
| BuffKind::Concussion => {
tracing::error!("Player was killed by a debuff that doesn't do damage!");
"mysterious"
},

View File

@ -37,7 +37,7 @@ use common::{
StaffSkill, SwimSkill, SwordSkill, SKILL_MODIFIERS,
},
skillset::{SkillGroupKind, SkillSet},
Body, CharacterState, Energy, Health, Inventory, Poise,
Body, CharacterState, Energy, Health, Inventory, Poise, Stats,
},
};
use conrod_core::{
@ -210,6 +210,7 @@ pub struct Diary<'a> {
slot_manager: &'a mut SlotManager,
pulse: f32,
context: &'a AbilityContext,
stats: Option<&'a Stats>,
#[conrod(common_builder)]
common: widget::CommonBuilder,
@ -257,6 +258,7 @@ impl<'a> Diary<'a> {
slot_manager: &'a mut SlotManager,
pulse: f32,
context: &'a AbilityContext,
stats: Option<&'a Stats>,
) -> Self {
Self {
show,
@ -280,6 +282,7 @@ impl<'a> Diary<'a> {
slot_manager,
pulse,
context,
stats,
common: widget::CommonBuilder::default(),
created_btns_top_l: 0,
created_btns_top_r: 0,
@ -825,6 +828,7 @@ impl<'a> Widget for Diary<'a> {
self.skill_set,
self.context,
Some(self.char_state),
self.stats,
),
image_source: self.imgs,
slot_manager: Some(self.slot_manager),
@ -838,6 +842,7 @@ impl<'a> Widget for Diary<'a> {
AbilityInput::Auxiliary(i),
Some(self.inventory),
Some(self.skill_set),
self.stats,
)
.ability_id(
Some(self.char_state),
@ -1022,6 +1027,7 @@ impl<'a> Widget for Diary<'a> {
self.skill_set,
self.context,
Some(self.char_state),
self.stats,
),
image_source: self.imgs,
slot_manager: Some(self.slot_manager),

View File

@ -327,6 +327,7 @@ image_ids! {
hammer_breach: "voxygen.element.skills.hammer.breach",
hammer_pile_driver: "voxygen.element.skills.hammer.pile_driver",
hammer_lung_pummel: "voxygen.element.skills.hammer.lung_pummel",
hammer_helm_crusher: "voxygen.element.skills.hammer.helm_crusher",
// Skilltree Icons
health_plus_skill: "voxygen.element.skills.skilltree.health_plus",
energy_plus_skill: "voxygen.element.skills.skilltree.energy_plus",
@ -818,6 +819,7 @@ image_ids! {
debuff_heatstroke_0: "voxygen.element.de_buffs.debuff_heatstroke_0",
debuff_rooted: "voxygen.element.de_buffs.debuff_rooted",
debuff_winded: "voxygen.element.de_buffs.debuff_winded",
debuff_concussion: "voxygen.element.de_buffs.debuff_concussion",
// Animation Frames
// Buff Frame

View File

@ -3201,6 +3201,7 @@ impl Hud {
combo,
char_states.get(entity),
stance,
stats.get(entity),
)
.set(self.ids.skillbar, ui_widgets)
{
@ -3731,6 +3732,7 @@ impl Hud {
&mut self.slot_manager,
self.pulse,
&context,
stats.get(entity),
)
.set(self.ids.diary, ui_widgets)
{
@ -5277,6 +5279,7 @@ pub fn get_buff_image(buff: BuffKind, imgs: &Imgs) -> conrod_core::image::Id {
BuffKind::Heatstroke => imgs.debuff_heatstroke_0,
BuffKind::Rooted => imgs.debuff_rooted,
BuffKind::Winded => imgs.debuff_winded,
BuffKind::Concussion => imgs.debuff_concussion,
}
}

View File

@ -30,7 +30,7 @@ use common::comp::{
},
skillset::SkillGroupKind,
Ability, ActiveAbilities, Body, CharacterState, Combo, Energy, Health, Inventory, Poise,
PoiseState, SkillSet,
PoiseState, SkillSet, Stats,
};
use conrod_core::{
color,
@ -317,6 +317,7 @@ pub struct Skillbar<'a> {
combo: Option<&'a Combo>,
char_state: Option<&'a CharacterState>,
stance: Option<&'a Stance>,
stats: Option<&'a Stats>,
}
impl<'a> Skillbar<'a> {
@ -351,6 +352,7 @@ impl<'a> Skillbar<'a> {
combo: Option<&'a Combo>,
char_state: Option<&'a CharacterState>,
stance: Option<&'a Stance>,
stats: Option<&'a Stats>,
) -> Self {
Self {
client,
@ -383,6 +385,7 @@ impl<'a> Skillbar<'a> {
combo,
char_state,
stance,
stats,
}
}
@ -946,6 +949,7 @@ impl<'a> Skillbar<'a> {
self.combo,
self.char_state,
self.stance,
self.stats,
);
let image_source = (self.item_imgs, self.imgs);
@ -1028,7 +1032,7 @@ impl<'a> Skillbar<'a> {
// Helper
let tooltip_text = |slot| {
let (hotbar, inventory, _, skill_set, active_abilities, _, contexts, _, _, _) =
let (hotbar, inventory, _, skill_set, active_abilities, _, contexts, ..) =
content_source;
hotbar.get(slot).and_then(|content| match content {
hotbar::SlotContents::Inventory(i, _) => inventory.get_by_hash(i).map(|item| {
@ -1176,6 +1180,7 @@ impl<'a> Skillbar<'a> {
Some(self.body),
self.char_state,
self.context,
self.stats,
)
})
.map_or(false, |(a, _, _)| {

View File

@ -11,7 +11,7 @@ use common::{
item::tool::{AbilityContext, ToolKind},
slot::{InvSlotId, Slot},
ActiveAbilities, Body, CharacterState, Combo, Energy, Inventory, Item, ItemKey, SkillSet,
Stance,
Stance, Stats,
},
recipe::ComponentRecipeBook,
};
@ -133,6 +133,7 @@ type HotbarSource<'a> = (
Option<&'a Combo>,
Option<&'a CharacterState>,
Option<&'a Stance>,
Option<&'a Stats>,
);
type HotbarImageSource<'a> = (&'a ItemImgs, &'a img_ids::Imgs);
@ -152,6 +153,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
combo,
char_state,
stance,
stats,
): &HotbarSource<'a>,
) -> Option<(Self::ImageKey, Option<Color>)> {
const GREYED_OUT: Color = Color::Rgba(0.3, 0.3, 0.3, 0.8);
@ -189,6 +191,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
Some(body),
*char_state,
contexts,
*stats,
)
})
.map(|(ability, _, _)| {
@ -247,6 +250,7 @@ type AbilitiesSource<'a> = (
&'a SkillSet,
&'a AbilityContext,
Option<&'a CharacterState>,
Option<&'a Stats>,
);
impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
@ -254,7 +258,7 @@ impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
fn image_key(
&self,
(active_abilities, inventory, skillset, contexts, char_state): &AbilitiesSource<'a>,
(active_abilities, inventory, skillset, contexts, char_state, stats): &AbilitiesSource<'a>,
) -> Option<(Self::ImageKey, Option<Color>)> {
let ability_id = match self {
Self::Slot(index) => active_abilities
@ -262,6 +266,7 @@ impl<'a> SlotKey<AbilitiesSource<'a>, img_ids::Imgs> for AbilitySlot {
AbilityInput::Auxiliary(*index),
Some(inventory),
Some(skillset),
*stats,
)
.ability_id(*char_state, Some(inventory), Some(skillset), contexts),
Self::Ability(ability) => Ability::from(*ability).ability_id(

View File

@ -211,8 +211,8 @@ fn buff_key(buff: BuffKind) -> &'static str {
BuffKind::PotionSickness => "buff-potionsickness",
BuffKind::Heatstroke => "buff-heatstroke",
BuffKind::Rooted => "buff-rooted",
BuffKind::Winded => "buff-winded",
BuffKind::Concussion => "buff-concussion",
// Neutral
BuffKind::Polymorphed => "buff-polymorphed",
}
@ -325,7 +325,8 @@ pub fn consumable_desc(effects: &Effects, i18n: &Localization) -> Vec<String> {
| BuffKind::Heatstroke
| BuffKind::ScornfulTaunt
| BuffKind::Rooted
| BuffKind::Winded => Cow::Borrowed(""),
| BuffKind::Winded
| BuffKind::Concussion => Cow::Borrowed(""),
};
write!(&mut description, "{}", buff_desc).unwrap();
@ -378,7 +379,8 @@ pub fn consumable_desc(effects: &Effects, i18n: &Localization) -> Vec<String> {
| BuffKind::Heatstroke
| BuffKind::ScornfulTaunt
| BuffKind::Rooted
| BuffKind::Winded => Cow::Borrowed(""),
| BuffKind::Winded
| BuffKind::Concussion => Cow::Borrowed(""),
}
} else if let BuffKind::Saturation
| BuffKind::Regeneration
@ -643,6 +645,7 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id {
"common.abilities.hammer.breach" => imgs.hammer_breach,
"common.abilities.hammer.pile_driver" => imgs.hammer_pile_driver,
"common.abilities.hammer.lung_pummel" => imgs.hammer_lung_pummel,
"common.abilities.hammer.helm_crusher" => imgs.hammer_helm_crusher,
// Bow
"common.abilities.bow.charged" => imgs.bow_m1,
"common.abilities.bow.repeater" => imgs.bow_m2,