mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixes to animations and making ability that the animation system thinks is being used more correct
This commit is contained in:
parent
38fb7b8cd5
commit
1cc99c9c4a
@ -6,7 +6,7 @@ FinisherMelee(
|
|||||||
melee_constructor: (
|
melee_constructor: (
|
||||||
kind: Slash(
|
kind: Slash(
|
||||||
damage: 60,
|
damage: 60,
|
||||||
poise: 100,
|
poise: 20,
|
||||||
knockback: 0,
|
knockback: 0,
|
||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
),
|
),
|
||||||
|
@ -6,7 +6,7 @@ FinisherMelee(
|
|||||||
melee_constructor: (
|
melee_constructor: (
|
||||||
kind: Slash(
|
kind: Slash(
|
||||||
damage: 75,
|
damage: 75,
|
||||||
poise: 100,
|
poise: 25,
|
||||||
knockback: 0,
|
knockback: 0,
|
||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
),
|
),
|
||||||
|
@ -9,8 +9,9 @@ ItemDef(
|
|||||||
data: (
|
data: (
|
||||||
strength: 0.4,
|
strength: 0.4,
|
||||||
duration: Some(20),
|
duration: Some(20),
|
||||||
|
secondary_duration: Some(5),
|
||||||
),
|
),
|
||||||
cat_ids: [Natural],
|
cat_ids: [RemoveOnAttack],
|
||||||
)),
|
)),
|
||||||
|
|
||||||
])
|
])
|
||||||
|
@ -9,8 +9,9 @@ ItemDef(
|
|||||||
data: (
|
data: (
|
||||||
strength: 0.4,
|
strength: 0.4,
|
||||||
duration: Some(20),
|
duration: Some(20),
|
||||||
|
secondary_duration: Some(5),
|
||||||
),
|
),
|
||||||
cat_ids: [Natural],
|
cat_ids: [RemoveOnAttack],
|
||||||
)),
|
)),
|
||||||
|
|
||||||
])
|
])
|
||||||
|
@ -10,7 +10,7 @@ ItemDef(
|
|||||||
strength: 0.4,
|
strength: 0.4,
|
||||||
duration: Some(20),
|
duration: Some(20),
|
||||||
),
|
),
|
||||||
cat_ids: [Natural],
|
cat_ids: [RemoveOnAttack],
|
||||||
)),
|
)),
|
||||||
|
|
||||||
])
|
])
|
||||||
|
@ -1172,7 +1172,6 @@ impl CombatBuff {
|
|||||||
BuffData::new(
|
BuffData::new(
|
||||||
self.strength.to_strength(damage, strength_modifier),
|
self.strength.to_strength(damage, strength_modifier),
|
||||||
Some(Secs(self.dur_secs as f64)),
|
Some(Secs(self.dur_secs as f64)),
|
||||||
None,
|
|
||||||
),
|
),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
source,
|
source,
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
character_state::AttackFilters,
|
character_state::AttackFilters,
|
||||||
inventory::{
|
inventory::{
|
||||||
item::{
|
item::{
|
||||||
tool::{AbilityContext, AbilityKind, Stats, ToolKind},
|
tool::{AbilityContext, AbilityItem, AbilityKind, Stats, ToolKind},
|
||||||
ItemKind,
|
ItemKind,
|
||||||
},
|
},
|
||||||
slot::EquipSlot,
|
slot::EquipSlot,
|
||||||
@ -149,7 +149,7 @@ impl ActiveAbilities {
|
|||||||
char_state: Option<&CharacterState>,
|
char_state: Option<&CharacterState>,
|
||||||
contexts: &[AbilityContext],
|
contexts: &[AbilityContext],
|
||||||
// bool is from_offhand
|
// bool is from_offhand
|
||||||
) -> Option<(CharacterAbility, bool)> {
|
) -> Option<(CharacterAbility, bool, SpecifiedAbility)> {
|
||||||
let ability = self.get_ability(input, inv, Some(skill_set));
|
let ability = self.get_ability(input, inv, Some(skill_set));
|
||||||
|
|
||||||
let ability_set = |equip_slot| {
|
let ability_set = |equip_slot| {
|
||||||
@ -167,63 +167,116 @@ impl ActiveAbilities {
|
|||||||
ability.adjusted_by_skills(skill_set, tool_kind)
|
ability.adjusted_by_skills(skill_set, tool_kind)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let spec_ability = |context_index| SpecifiedAbility {
|
||||||
|
ability,
|
||||||
|
context_index,
|
||||||
|
};
|
||||||
|
|
||||||
match ability {
|
match ability {
|
||||||
Ability::ToolGuard => ability_set(EquipSlot::ActiveMainhand)
|
Ability::ToolGuard => ability_set(EquipSlot::ActiveMainhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.guard(Some(skill_set), contexts)
|
.guard(Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
|
})
|
||||||
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveMainhand),
|
||||||
|
true,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), true))
|
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
ability_set(EquipSlot::ActiveOffhand)
|
ability_set(EquipSlot::ActiveOffhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.secondary(Some(skill_set), contexts)
|
.guard(Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
|
})
|
||||||
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveOffhand),
|
||||||
|
false,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveOffhand), false))
|
|
||||||
}),
|
}),
|
||||||
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand)
|
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.primary(Some(skill_set), contexts)
|
.primary(Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false)),
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveMainhand),
|
||||||
|
false,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
|
}),
|
||||||
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.secondary(Some(skill_set), contexts)
|
.secondary(Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
|
})
|
||||||
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveOffhand),
|
||||||
|
true,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveOffhand), true))
|
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
ability_set(EquipSlot::ActiveMainhand)
|
ability_set(EquipSlot::ActiveMainhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.secondary(Some(skill_set), contexts)
|
.secondary(Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
|
})
|
||||||
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveMainhand),
|
||||||
|
false,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false))
|
|
||||||
}),
|
}),
|
||||||
Ability::SpeciesMovement => matches!(body, Some(Body::Humanoid(_)))
|
Ability::SpeciesMovement => matches!(body, Some(Body::Humanoid(_)))
|
||||||
.then(|| CharacterAbility::default_roll(char_state))
|
.then(|| CharacterAbility::default_roll(char_state))
|
||||||
.map(|ability| (ability.adjusted_by_skills(skill_set, None), false)),
|
.map(|ability| {
|
||||||
|
(
|
||||||
|
ability.adjusted_by_skills(skill_set, None),
|
||||||
|
false,
|
||||||
|
spec_ability(None),
|
||||||
|
)
|
||||||
|
}),
|
||||||
Ability::MainWeaponAux(index) => ability_set(EquipSlot::ActiveMainhand)
|
Ability::MainWeaponAux(index) => ability_set(EquipSlot::ActiveMainhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.auxiliary(index, Some(skill_set), contexts)
|
.auxiliary(index, Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false)),
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveMainhand),
|
||||||
|
false,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
|
}),
|
||||||
Ability::OffWeaponAux(index) => ability_set(EquipSlot::ActiveOffhand)
|
Ability::OffWeaponAux(index) => ability_set(EquipSlot::ActiveOffhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.auxiliary(index, Some(skill_set), contexts)
|
.auxiliary(index, Some(skill_set), contexts)
|
||||||
.map(|a| a.ability.clone())
|
.map(|(a, i)| (a.ability.clone(), i))
|
||||||
})
|
})
|
||||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveOffhand), true)),
|
.map(|(ability, i)| {
|
||||||
|
(
|
||||||
|
scale_ability(ability, EquipSlot::ActiveOffhand),
|
||||||
|
true,
|
||||||
|
spec_ability(i),
|
||||||
|
)
|
||||||
|
}),
|
||||||
Ability::Empty => None,
|
Ability::Empty => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,7 +371,7 @@ impl Ability {
|
|||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.guard(skillset, contexts)
|
.guard(skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
abilities
|
abilities
|
||||||
.guard
|
.guard
|
||||||
@ -330,7 +383,7 @@ impl Ability {
|
|||||||
ability_set(EquipSlot::ActiveOffhand).and_then(|abilities| {
|
ability_set(EquipSlot::ActiveOffhand).and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.guard(skillset, contexts)
|
.guard(skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
abilities
|
abilities
|
||||||
.guard
|
.guard
|
||||||
@ -342,21 +395,21 @@ impl Ability {
|
|||||||
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.primary(skillset, contexts)
|
.primary(skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| contextual_id(Some(&abilities.primary)))
|
.or_else(|| contextual_id(Some(&abilities.primary)))
|
||||||
}),
|
}),
|
||||||
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
||||||
.and_then(|abilities| {
|
.and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.secondary(skillset, contexts)
|
.secondary(skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| contextual_id(Some(&abilities.secondary)))
|
.or_else(|| contextual_id(Some(&abilities.secondary)))
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.secondary(skillset, contexts)
|
.secondary(skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| contextual_id(Some(&abilities.secondary)))
|
.or_else(|| contextual_id(Some(&abilities.secondary)))
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
@ -365,7 +418,7 @@ impl Ability {
|
|||||||
ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
ability_set(EquipSlot::ActiveMainhand).and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.auxiliary(index, skillset, contexts)
|
.auxiliary(index, skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| contextual_id(abilities.abilities.get(index)))
|
.or_else(|| contextual_id(abilities.abilities.get(index)))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -373,7 +426,7 @@ impl Ability {
|
|||||||
ability_set(EquipSlot::ActiveOffhand).and_then(|abilities| {
|
ability_set(EquipSlot::ActiveOffhand).and_then(|abilities| {
|
||||||
abilities
|
abilities
|
||||||
.auxiliary(index, skillset, contexts)
|
.auxiliary(index, skillset, contexts)
|
||||||
.map(|a| a.id.as_str())
|
.map(|a| a.0.id.as_str())
|
||||||
.or_else(|| contextual_id(abilities.abilities.get(index)))
|
.or_else(|| contextual_id(abilities.abilities.get(index)))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -396,6 +449,59 @@ impl From<GuardAbility> for Ability {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only use for specifying to the front end what ability is being used, do not
|
||||||
|
// actually use it for any logic in common or server
|
||||||
|
#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
pub struct SpecifiedAbility {
|
||||||
|
pub ability: Ability,
|
||||||
|
pub context_index: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpecifiedAbility {
|
||||||
|
pub fn ability_id(self, inv: Option<&Inventory>) -> Option<&str> {
|
||||||
|
let ability_set = |equip_slot| {
|
||||||
|
inv.and_then(|inv| inv.equipped(equip_slot))
|
||||||
|
.map(|i| &i.item_config_expect().abilities)
|
||||||
|
};
|
||||||
|
|
||||||
|
fn ability_id(spec_ability: SpecifiedAbility, ability: &AbilityKind<AbilityItem>) -> &str {
|
||||||
|
match ability {
|
||||||
|
AbilityKind::Simple(_, a) => a.id.as_str(),
|
||||||
|
AbilityKind::Contextualized {
|
||||||
|
pseudo_id,
|
||||||
|
abilities,
|
||||||
|
} => spec_ability
|
||||||
|
.context_index
|
||||||
|
.and_then(|i| abilities.get(i))
|
||||||
|
.map_or(pseudo_id.as_str(), |(_, (_, a))| a.id.as_str()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.ability {
|
||||||
|
Ability::ToolPrimary => ability_set(EquipSlot::ActiveMainhand)
|
||||||
|
.map(|abilities| ability_id(self, &abilities.primary)),
|
||||||
|
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
||||||
|
.map(|abilities| ability_id(self, &abilities.secondary))
|
||||||
|
.or_else(|| {
|
||||||
|
ability_set(EquipSlot::ActiveMainhand)
|
||||||
|
.map(|abilities| ability_id(self, &abilities.secondary))
|
||||||
|
}),
|
||||||
|
Ability::ToolGuard => ability_set(EquipSlot::ActiveMainhand)
|
||||||
|
.and_then(|abilities| abilities.guard.as_ref().map(|a| ability_id(self, a)))
|
||||||
|
.or_else(|| {
|
||||||
|
ability_set(EquipSlot::ActiveOffhand)
|
||||||
|
.and_then(|abilities| abilities.guard.as_ref().map(|a| ability_id(self, a)))
|
||||||
|
}),
|
||||||
|
Ability::SpeciesMovement => None, // TODO: Make not None
|
||||||
|
Ability::MainWeaponAux(index) => ability_set(EquipSlot::ActiveMainhand)
|
||||||
|
.and_then(|abilities| abilities.abilities.get(index).map(|a| ability_id(self, a))),
|
||||||
|
Ability::OffWeaponAux(index) => ability_set(EquipSlot::ActiveOffhand)
|
||||||
|
.and_then(|abilities| abilities.abilities.get(index).map(|a| ability_id(self, a))),
|
||||||
|
Ability::Empty => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||||
pub enum PrimaryAbility {
|
pub enum PrimaryAbility {
|
||||||
Tool,
|
Tool,
|
||||||
|
@ -158,11 +158,7 @@ impl AuraBuffConstructor {
|
|||||||
) -> Aura {
|
) -> Aura {
|
||||||
let aura_kind = AuraKind::Buff {
|
let aura_kind = AuraKind::Buff {
|
||||||
kind: self.kind,
|
kind: self.kind,
|
||||||
data: BuffData {
|
data: BuffData::new(self.strength, self.duration),
|
||||||
strength: self.strength,
|
|
||||||
duration: self.duration,
|
|
||||||
delay: None,
|
|
||||||
},
|
|
||||||
category: self.category,
|
category: self.category,
|
||||||
source: BuffSource::Character { by: *uid },
|
source: BuffSource::Character { by: *uid },
|
||||||
};
|
};
|
||||||
|
@ -74,6 +74,12 @@ pub enum BuffKind {
|
|||||||
/// Provides immunity to burning and increases movement speed in lava.
|
/// Provides immunity to burning and increases movement speed in lava.
|
||||||
/// Movement speed increases linearly with strength, 1.0 is a 100% increase.
|
/// Movement speed increases linearly with strength, 1.0 is a 100% increase.
|
||||||
// SalamanderAspect, TODO: Readd in second dwarven mine MR
|
// SalamanderAspect, TODO: Readd in second dwarven mine MR
|
||||||
|
/// Inflict burning on your attack
|
||||||
|
Flame,
|
||||||
|
/// Inflict frost on your attack
|
||||||
|
Frigid,
|
||||||
|
/// Gain Lifesteal on your attack
|
||||||
|
Lifesteal,
|
||||||
/// Guarantees that the next attack is a critical hit. Does this kind of
|
/// Guarantees that the next attack is a critical hit. Does this kind of
|
||||||
/// hackily by adding 100% to the crit, will need to be adjusted if we ever
|
/// hackily by adding 100% to the crit, will need to be adjusted if we ever
|
||||||
/// allow double crits instead of treating 100 as a ceiling.
|
/// allow double crits instead of treating 100 as a ceiling.
|
||||||
@ -118,12 +124,6 @@ pub enum BuffKind {
|
|||||||
PotionSickness,
|
PotionSickness,
|
||||||
// Changed into another body.
|
// Changed into another body.
|
||||||
Polymorphed(Body),
|
Polymorphed(Body),
|
||||||
// Inflict burning on your attack
|
|
||||||
Flame,
|
|
||||||
// Inflict frost on your attack
|
|
||||||
Frigid,
|
|
||||||
// Gain Lifesteal on your attack
|
|
||||||
Lifesteal,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuffKind {
|
impl BuffKind {
|
||||||
@ -314,8 +314,8 @@ impl BuffKind {
|
|||||||
None,
|
None,
|
||||||
CombatEffect::Buff(CombatBuff {
|
CombatEffect::Buff(CombatBuff {
|
||||||
kind: BuffKind::Burning,
|
kind: BuffKind::Burning,
|
||||||
dur_secs: 5.0,
|
dur_secs: data.secondary_duration.map_or(5.0, |dur| dur.0 as f32),
|
||||||
strength: CombatBuffStrength::DamageFraction(0.2),
|
strength: CombatBuffStrength::DamageFraction(data.strength),
|
||||||
chance: 1.0,
|
chance: 1.0,
|
||||||
}),
|
}),
|
||||||
))],
|
))],
|
||||||
@ -323,14 +323,14 @@ impl BuffKind {
|
|||||||
None,
|
None,
|
||||||
CombatEffect::Buff(CombatBuff {
|
CombatEffect::Buff(CombatBuff {
|
||||||
kind: BuffKind::Frozen,
|
kind: BuffKind::Frozen,
|
||||||
dur_secs: 5.0,
|
dur_secs: data.secondary_duration.map_or(5.0, |dur| dur.0 as f32),
|
||||||
strength: CombatBuffStrength::DamageFraction(0.2),
|
strength: CombatBuffStrength::DamageFraction(data.strength),
|
||||||
chance: 1.0,
|
chance: 1.0,
|
||||||
}),
|
}),
|
||||||
))],
|
))],
|
||||||
BuffKind::Lifesteal => vec![BuffEffect::BuffOnHit(AttackEffect::new(
|
BuffKind::Lifesteal => vec![BuffEffect::BuffOnHit(AttackEffect::new(
|
||||||
None,
|
None,
|
||||||
CombatEffect::Lifesteal(0.2),
|
CombatEffect::Lifesteal(data.strength),
|
||||||
))],
|
))],
|
||||||
/*BuffKind::SalamanderAspect => vec![
|
/*BuffKind::SalamanderAspect => vec![
|
||||||
BuffEffect::BuffImmunity(BuffKind::Burning),
|
BuffEffect::BuffImmunity(BuffKind::Burning),
|
||||||
@ -358,20 +358,34 @@ impl BuffKind {
|
|||||||
|
|
||||||
// Struct used to store data relevant to a buff
|
// Struct used to store data relevant to a buff
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct BuffData {
|
pub struct BuffData {
|
||||||
pub strength: f32,
|
pub strength: f32,
|
||||||
pub duration: Option<Secs>,
|
pub duration: Option<Secs>,
|
||||||
pub delay: Option<Secs>,
|
pub delay: Option<Secs>,
|
||||||
|
// Used for buffs that have rider buffs (e.g. Flame, Frigid)
|
||||||
|
pub secondary_duration: Option<Secs>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuffData {
|
impl BuffData {
|
||||||
pub fn new(strength: f32, duration: Option<Secs>, delay: Option<Secs>) -> Self {
|
pub fn new(strength: f32, duration: Option<Secs>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
strength,
|
strength,
|
||||||
duration,
|
duration,
|
||||||
delay,
|
delay: None,
|
||||||
|
secondary_duration: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_delay(mut self, delay: Secs) -> Self {
|
||||||
|
self.delay = Some(delay);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_secondary_duration(mut self, sec_dur: Secs) -> Self {
|
||||||
|
self.secondary_duration = Some(sec_dur);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// De/buff category ID.
|
/// De/buff category ID.
|
||||||
|
@ -342,7 +342,11 @@ impl<T> AbilityKind<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ability(&self, skillset: Option<&SkillSet>, contexts: &[AbilityContext]) -> Option<&T> {
|
pub fn ability(
|
||||||
|
&self,
|
||||||
|
skillset: Option<&SkillSet>,
|
||||||
|
contexts: &[AbilityContext],
|
||||||
|
) -> Option<(&T, Option<usize>)> {
|
||||||
let unlocked = |s: Option<Skill>, a| {
|
let unlocked = |s: Option<Skill>, a| {
|
||||||
// If there is a skill requirement and the skillset does not contain the
|
// If there is a skill requirement and the skillset does not contain the
|
||||||
// required skill, return None
|
// required skill, return None
|
||||||
@ -351,18 +355,21 @@ impl<T> AbilityKind<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
AbilityKind::Simple(s, a) => unlocked(*s, a),
|
AbilityKind::Simple(s, a) => unlocked(*s, a).map(|a| (a, None)),
|
||||||
AbilityKind::Contextualized {
|
AbilityKind::Contextualized {
|
||||||
pseudo_id: _,
|
pseudo_id: _,
|
||||||
abilities,
|
abilities,
|
||||||
} => abilities
|
} => abilities
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(req_contexts, (s, a))| unlocked(*s, a).map(|a| (req_contexts, a)))
|
.enumerate()
|
||||||
.find_map(|(req_contexts, a)| {
|
.filter_map(|(i, (req_contexts, (s, a)))| {
|
||||||
|
unlocked(*s, a).map(|a| (i, (req_contexts, a)))
|
||||||
|
})
|
||||||
|
.find_map(|(i, (req_contexts, a))| {
|
||||||
req_contexts
|
req_contexts
|
||||||
.iter()
|
.iter()
|
||||||
.all(|req| req.fulfilled_by(contexts))
|
.all(|req| req.fulfilled_by(contexts))
|
||||||
.then_some(a)
|
.then_some((a, Some(i)))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,13 +472,21 @@ impl<T> AbilitySet<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn guard(&self, skillset: Option<&SkillSet>, contexts: &[AbilityContext]) -> Option<&T> {
|
pub fn guard(
|
||||||
|
&self,
|
||||||
|
skillset: Option<&SkillSet>,
|
||||||
|
contexts: &[AbilityContext],
|
||||||
|
) -> Option<(&T, Option<usize>)> {
|
||||||
self.guard
|
self.guard
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|g| g.ability(skillset, contexts))
|
.and_then(|g| g.ability(skillset, contexts))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary(&self, skillset: Option<&SkillSet>, contexts: &[AbilityContext]) -> Option<&T> {
|
pub fn primary(
|
||||||
|
&self,
|
||||||
|
skillset: Option<&SkillSet>,
|
||||||
|
contexts: &[AbilityContext],
|
||||||
|
) -> Option<(&T, Option<usize>)> {
|
||||||
self.primary.ability(skillset, contexts)
|
self.primary.ability(skillset, contexts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,7 +494,7 @@ impl<T> AbilitySet<T> {
|
|||||||
&self,
|
&self,
|
||||||
skillset: Option<&SkillSet>,
|
skillset: Option<&SkillSet>,
|
||||||
contexts: &[AbilityContext],
|
contexts: &[AbilityContext],
|
||||||
) -> Option<&T> {
|
) -> Option<(&T, Option<usize>)> {
|
||||||
self.secondary.ability(skillset, contexts)
|
self.secondary.ability(skillset, contexts)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +503,7 @@ impl<T> AbilitySet<T> {
|
|||||||
index: usize,
|
index: usize,
|
||||||
skillset: Option<&SkillSet>,
|
skillset: Option<&SkillSet>,
|
||||||
contexts: &[AbilityContext],
|
contexts: &[AbilityContext],
|
||||||
) -> Option<&T> {
|
) -> Option<(&T, Option<usize>)> {
|
||||||
self.abilities
|
self.abilities
|
||||||
.get(index)
|
.get(index)
|
||||||
.and_then(|a| a.ability(skillset, contexts))
|
.and_then(|a| a.ability(skillset, contexts))
|
||||||
|
@ -82,11 +82,10 @@ impl CharacterBehavior for Data {
|
|||||||
// Creates buff
|
// Creates buff
|
||||||
let buff = Buff::new(
|
let buff = Buff::new(
|
||||||
self.static_data.buff_kind,
|
self.static_data.buff_kind,
|
||||||
BuffData {
|
BuffData::new(
|
||||||
strength: self.static_data.buff_strength * scaling_factor,
|
self.static_data.buff_strength * scaling_factor,
|
||||||
duration: self.static_data.buff_duration,
|
self.static_data.buff_duration,
|
||||||
delay: None,
|
),
|
||||||
},
|
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::Character { by: *data.uid },
|
BuffSource::Character { by: *data.uid },
|
||||||
*data.time,
|
*data.time,
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
astar::Astar,
|
astar::Astar,
|
||||||
combat,
|
combat,
|
||||||
comp::{
|
comp::{
|
||||||
ability::{Ability, AbilityInitEvent, AbilityInput, AbilityMeta, Capability, Stance},
|
ability::{AbilityInitEvent, AbilityMeta, Capability, SpecifiedAbility, Stance},
|
||||||
arthropod, biped_large, biped_small, bird_medium,
|
arthropod, biped_large, biped_small, bird_medium,
|
||||||
character_state::OutputEvents,
|
character_state::OutputEvents,
|
||||||
controller::InventoryManip,
|
controller::InventoryManip,
|
||||||
@ -1206,7 +1206,7 @@ fn handle_ability(
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
let contexts = AbilityContext::from(data.stance, data.inventory, data.combo);
|
let contexts = AbilityContext::from(data.stance, data.inventory, data.combo);
|
||||||
if let Some(ability_input) = input.into() {
|
if let Some(ability_input) = input.into() {
|
||||||
if let Some((ability, from_offhand)) = data
|
if let Some((ability, from_offhand, spec_ability)) = data
|
||||||
.active_abilities
|
.active_abilities
|
||||||
.and_then(|a| {
|
.and_then(|a| {
|
||||||
a.activate_ability(
|
a.activate_ability(
|
||||||
@ -1218,11 +1218,17 @@ fn handle_ability(
|
|||||||
&contexts,
|
&contexts,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.filter(|(ability, _)| ability.requirements_paid(data, update))
|
.filter(|(ability, _, _)| ability.requirements_paid(data, update))
|
||||||
{
|
{
|
||||||
update.character = CharacterState::from((
|
update.character = CharacterState::from((
|
||||||
&ability,
|
&ability,
|
||||||
AbilityInfo::from_input(data, from_offhand, input, ability.ability_meta()),
|
AbilityInfo::new(
|
||||||
|
data,
|
||||||
|
from_offhand,
|
||||||
|
input,
|
||||||
|
Some(spec_ability),
|
||||||
|
ability.ability_meta(),
|
||||||
|
),
|
||||||
data,
|
data,
|
||||||
));
|
));
|
||||||
if let Some(init_event) = ability.ability_meta().init_event {
|
if let Some(init_event) = ability.ability_meta().init_event {
|
||||||
@ -1508,14 +1514,15 @@ pub struct AbilityInfo {
|
|||||||
pub input: InputKind,
|
pub input: InputKind,
|
||||||
pub input_attr: Option<InputAttr>,
|
pub input_attr: Option<InputAttr>,
|
||||||
pub ability_meta: AbilityMeta,
|
pub ability_meta: AbilityMeta,
|
||||||
pub ability: Option<Ability>,
|
pub ability: Option<SpecifiedAbility>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityInfo {
|
impl AbilityInfo {
|
||||||
pub fn from_input(
|
pub fn new(
|
||||||
data: &JoinData<'_>,
|
data: &JoinData<'_>,
|
||||||
from_offhand: bool,
|
from_offhand: bool,
|
||||||
input: InputKind,
|
input: InputKind,
|
||||||
|
ability: Option<SpecifiedAbility>,
|
||||||
ability_meta: AbilityMeta,
|
ability_meta: AbilityMeta,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let tool_data = if from_offhand {
|
let tool_data = if from_offhand {
|
||||||
@ -1529,9 +1536,6 @@ impl AbilityInfo {
|
|||||||
Some(HandInfo::from_main_tool(hands, from_offhand)),
|
Some(HandInfo::from_main_tool(hands, from_offhand)),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let ability = Option::<AbilityInput>::from(input)
|
|
||||||
.zip(data.active_abilities)
|
|
||||||
.map(|(i, a)| a.get_ability(i, data.inventory, Some(data.skill_set)));
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
tool,
|
tool,
|
||||||
|
@ -142,7 +142,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Ensnared,
|
BuffKind::Ensnared,
|
||||||
BuffData::new(1.0, Some(Secs(1.0)), None),
|
BuffData::new(1.0, Some(Secs(1.0))),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -160,7 +160,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Bleeding,
|
BuffKind::Bleeding,
|
||||||
BuffData::new(1.0, Some(Secs(6.0)), None),
|
BuffData::new(1.0, Some(Secs(6.0))),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -178,7 +178,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Bleeding,
|
BuffKind::Bleeding,
|
||||||
BuffData::new(5.0, Some(Secs(3.0)), None),
|
BuffData::new(5.0, Some(Secs(3.0))),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -196,7 +196,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Burning,
|
BuffKind::Burning,
|
||||||
BuffData::new(10.0, None, None),
|
BuffData::new(10.0, None),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -214,7 +214,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Bleeding,
|
BuffKind::Bleeding,
|
||||||
BuffData::new(15.0, Some(Secs(0.1)), None),
|
BuffData::new(15.0, Some(Secs(0.1))),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -227,7 +227,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Frozen,
|
BuffKind::Frozen,
|
||||||
BuffData::new(0.2, Some(Secs(1.0)), None),
|
BuffData::new(0.2, Some(Secs(1.0))),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -245,7 +245,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Burning,
|
BuffKind::Burning,
|
||||||
BuffData::new(20.0, None, None),
|
BuffData::new(20.0, None),
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
@ -266,7 +266,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
buff_change: BuffChange::Add(Buff::new(
|
buff_change: BuffChange::Add(Buff::new(
|
||||||
BuffKind::Burning,
|
BuffKind::Burning,
|
||||||
BuffData::new(20.0, None, None),
|
BuffData::new(20.0, None),
|
||||||
vec![BuffCategory::Natural],
|
vec![BuffCategory::Natural],
|
||||||
BuffSource::World,
|
BuffSource::World,
|
||||||
*read_data.time,
|
*read_data.time,
|
||||||
|
@ -1370,8 +1370,7 @@ impl<'a> AgentData<'a> {
|
|||||||
Some(self.char_state),
|
Some(self.char_state),
|
||||||
&contexts,
|
&contexts,
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.map_or(Default::default(), |a| a.0)
|
||||||
.0
|
|
||||||
};
|
};
|
||||||
let (flamethrower, shockwave) = (
|
let (flamethrower, shockwave) = (
|
||||||
extract_ability(AbilityInput::Secondary),
|
extract_ability(AbilityInput::Secondary),
|
||||||
|
@ -220,8 +220,7 @@ impl<'a> AgentData<'a> {
|
|||||||
Some(self.char_state),
|
Some(self.char_state),
|
||||||
&context,
|
&context,
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.map_or(Default::default(), |a| a.0),
|
||||||
.0,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1856,7 +1856,7 @@ fn handle_spawn_campfire(
|
|||||||
Aura::new(
|
Aura::new(
|
||||||
AuraKind::Buff {
|
AuraKind::Buff {
|
||||||
kind: BuffKind::CampfireHeal,
|
kind: BuffKind::CampfireHeal,
|
||||||
data: BuffData::new(0.02, Some(Secs(1.0)), None),
|
data: BuffData::new(0.02, Some(Secs(1.0))),
|
||||||
category: BuffCategory::Natural,
|
category: BuffCategory::Natural,
|
||||||
source: BuffSource::World,
|
source: BuffSource::World,
|
||||||
},
|
},
|
||||||
@ -1868,7 +1868,7 @@ fn handle_spawn_campfire(
|
|||||||
Aura::new(
|
Aura::new(
|
||||||
AuraKind::Buff {
|
AuraKind::Buff {
|
||||||
kind: BuffKind::Burning,
|
kind: BuffKind::Burning,
|
||||||
data: BuffData::new(2.0, Some(Secs(10.0)), None),
|
data: BuffData::new(2.0, Some(Secs(10.0))),
|
||||||
category: BuffCategory::Natural,
|
category: BuffCategory::Natural,
|
||||||
source: BuffSource::World,
|
source: BuffSource::World,
|
||||||
},
|
},
|
||||||
@ -3960,7 +3960,7 @@ fn handle_buff(
|
|||||||
if let (Some(buff), strength, duration) = parse_cmd_args!(args, String, f32, f64) {
|
if let (Some(buff), strength, duration) = parse_cmd_args!(args, String, f32, f64) {
|
||||||
let strength = strength.unwrap_or(0.01);
|
let strength = strength.unwrap_or(0.01);
|
||||||
let duration = duration.unwrap_or(1.0);
|
let duration = duration.unwrap_or(1.0);
|
||||||
let buffdata = BuffData::new(strength, Some(Secs(duration)), None);
|
let buffdata = BuffData::new(strength, Some(Secs(duration)));
|
||||||
if buff != "all" {
|
if buff != "all" {
|
||||||
cast_buff(&buff, buffdata, server, target)
|
cast_buff(&buff, buffdata, server, target)
|
||||||
} else {
|
} else {
|
||||||
|
@ -394,7 +394,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
|
|||||||
Aura::new(
|
Aura::new(
|
||||||
AuraKind::Buff {
|
AuraKind::Buff {
|
||||||
kind: BuffKind::CampfireHeal,
|
kind: BuffKind::CampfireHeal,
|
||||||
data: BuffData::new(0.02, Some(Secs(1.0)), None),
|
data: BuffData::new(0.02, Some(Secs(1.0))),
|
||||||
category: BuffCategory::Natural,
|
category: BuffCategory::Natural,
|
||||||
source: BuffSource::World,
|
source: BuffSource::World,
|
||||||
},
|
},
|
||||||
@ -406,7 +406,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
|
|||||||
Aura::new(
|
Aura::new(
|
||||||
AuraKind::Buff {
|
AuraKind::Buff {
|
||||||
kind: BuffKind::Burning,
|
kind: BuffKind::Burning,
|
||||||
data: BuffData::new(2.0, Some(Secs(10.0)), None),
|
data: BuffData::new(2.0, Some(Secs(10.0))),
|
||||||
category: BuffCategory::Natural,
|
category: BuffCategory::Natural,
|
||||||
source: BuffSource::World,
|
source: BuffSource::World,
|
||||||
},
|
},
|
||||||
|
@ -1399,7 +1399,7 @@ pub fn handle_parry_hook(
|
|||||||
if let Some(attacker) = attacker && matches!(source, AttackSource::Melee){
|
if let Some(attacker) = attacker && matches!(source, AttackSource::Melee){
|
||||||
// When attacker is parried, add the parried debuff for 2 seconds, which slows
|
// When attacker is parried, add the parried debuff for 2 seconds, which slows
|
||||||
// them
|
// them
|
||||||
let data = buff::BuffData::new(1.0, Some(Secs(2.0)), None);
|
let data = buff::BuffData::new(1.0, Some(Secs(2.0)));
|
||||||
let source = if let Some(uid) = ecs.read_storage::<Uid>().get(defender) {
|
let source = if let Some(uid) = ecs.read_storage::<Uid>().get(defender) {
|
||||||
BuffSource::Character { by: *uid }
|
BuffSource::Character { by: *uid }
|
||||||
} else {
|
} else {
|
||||||
|
@ -511,7 +511,7 @@ impl StateExt for State {
|
|||||||
.with(Auras::new(vec![Aura::new(
|
.with(Auras::new(vec![Aura::new(
|
||||||
AuraKind::Buff {
|
AuraKind::Buff {
|
||||||
kind: BuffKind::Invulnerability,
|
kind: BuffKind::Invulnerability,
|
||||||
data: BuffData::new(1.0, Some(Secs(1.0)), None),
|
data: BuffData::new(1.0, Some(Secs(1.0))),
|
||||||
category: BuffCategory::Natural,
|
category: BuffCategory::Natural,
|
||||||
source: BuffSource::World,
|
source: BuffSource::World,
|
||||||
},
|
},
|
||||||
|
@ -264,7 +264,7 @@ impl Animation for ChargeswingAnimation {
|
|||||||
next.control.orientation =
|
next.control.orientation =
|
||||||
Quaternion::rotation_x(s_a.ac.3 + move1 * -1.0 + tension / 30.0)
|
Quaternion::rotation_x(s_a.ac.3 + move1 * -1.0 + tension / 30.0)
|
||||||
* Quaternion::rotation_y(s_a.ac.4)
|
* Quaternion::rotation_y(s_a.ac.4)
|
||||||
* Quaternion::rotation_z(s_a.ac.5);
|
* Quaternion::rotation_z(s_a.ac.5 - move1 * PI);
|
||||||
|
|
||||||
next.control.orientation.rotate_x(move2 * -3.0);
|
next.control.orientation.rotate_x(move2 * -3.0);
|
||||||
next.control.position += Vec3::new(0.0, move2 * 8.0, move2 * -30.0);
|
next.control.position += Vec3::new(0.0, move2 * 8.0, move2 * -30.0);
|
||||||
|
@ -912,7 +912,7 @@ impl Animation for ComboAnimation {
|
|||||||
next.control.orientation =
|
next.control.orientation =
|
||||||
Quaternion::rotation_x(s_a.ac.3 + move1 * -1.5)
|
Quaternion::rotation_x(s_a.ac.3 + move1 * -1.5)
|
||||||
* Quaternion::rotation_y(s_a.ac.4)
|
* Quaternion::rotation_y(s_a.ac.4)
|
||||||
* Quaternion::rotation_z(s_a.ac.5 + move1 * 0.4);
|
* Quaternion::rotation_z(s_a.ac.5 + move1 * (0.4 - PI));
|
||||||
|
|
||||||
next.chest.orientation.rotate_z(move1 * 0.4);
|
next.chest.orientation.rotate_z(move1 * 0.4);
|
||||||
next.head.orientation.rotate_z(move1 * -0.2);
|
next.head.orientation.rotate_z(move1 * -0.2);
|
||||||
@ -925,7 +925,7 @@ impl Animation for ComboAnimation {
|
|||||||
next.shorts.orientation.rotate_z(move2 * 0.2);
|
next.shorts.orientation.rotate_z(move2 * 0.2);
|
||||||
next.control.orientation = next.control.orientation
|
next.control.orientation = next.control.orientation
|
||||||
* Quaternion::rotation_z(move2 * -0.5)
|
* Quaternion::rotation_z(move2 * -0.5)
|
||||||
* Quaternion::rotation_x(move2 * -2.0);
|
* Quaternion::rotation_x(move2 * 2.0);
|
||||||
next.control.orientation.rotate_y(move2 * -0.7);
|
next.control.orientation.rotate_y(move2 * -0.7);
|
||||||
next.control.position += Vec3::new(move2 * 15.0, 0.0, move2 * -4.0);
|
next.control.position += Vec3::new(move2 * 15.0, 0.0, move2 * -4.0);
|
||||||
},
|
},
|
||||||
@ -944,7 +944,7 @@ impl Animation for ComboAnimation {
|
|||||||
next.shorts.orientation.rotate_z(move2 * -0.2);
|
next.shorts.orientation.rotate_z(move2 * -0.2);
|
||||||
next.control.orientation = next.control.orientation
|
next.control.orientation = next.control.orientation
|
||||||
* Quaternion::rotation_z(move2 * 0.5)
|
* Quaternion::rotation_z(move2 * 0.5)
|
||||||
* Quaternion::rotation_x(move2 * -2.0);
|
* Quaternion::rotation_x(move2 * 2.0);
|
||||||
next.control.orientation.rotate_y(move2 * 0.7);
|
next.control.orientation.rotate_y(move2 * 0.7);
|
||||||
next.control.position += Vec3::new(move2 * -15.0, 0.0, move2 * -4.0);
|
next.control.position += Vec3::new(move2 * -15.0, 0.0, move2 * -4.0);
|
||||||
},
|
},
|
||||||
@ -985,7 +985,7 @@ impl Animation for ComboAnimation {
|
|||||||
Vec3::new(s_a.ac.0 + move1 * -1.0, s_a.ac.1 + move1 * -4.0, s_a.ac.2);
|
Vec3::new(s_a.ac.0 + move1 * -1.0, s_a.ac.1 + move1 * -4.0, s_a.ac.2);
|
||||||
next.control.orientation = Quaternion::rotation_x(s_a.ac.3 + move1 * -0.4)
|
next.control.orientation = Quaternion::rotation_x(s_a.ac.3 + move1 * -0.4)
|
||||||
* Quaternion::rotation_y(s_a.ac.4 + move1 * -0.5)
|
* Quaternion::rotation_y(s_a.ac.4 + move1 * -0.5)
|
||||||
* Quaternion::rotation_z(s_a.ac.5 + move1 * 1.5);
|
* Quaternion::rotation_z(s_a.ac.5 + move1 * (1.5 - PI));
|
||||||
|
|
||||||
next.control.orientation.rotate_z(move2 * -3.5);
|
next.control.orientation.rotate_z(move2 * -3.5);
|
||||||
next.control.position += Vec3::new(move2 * 12.0, move2 * 4.0, 0.0);
|
next.control.position += Vec3::new(move2 * 12.0, move2 * 4.0, 0.0);
|
||||||
@ -1012,7 +1012,7 @@ impl Animation for ComboAnimation {
|
|||||||
Vec3::new(s_a.ac.0 + move1 * -1.0, s_a.ac.1 + move1 * -4.0, s_a.ac.2);
|
Vec3::new(s_a.ac.0 + move1 * -1.0, s_a.ac.1 + move1 * -4.0, s_a.ac.2);
|
||||||
next.control.orientation = Quaternion::rotation_x(s_a.ac.3 + move1 * 0.6)
|
next.control.orientation = Quaternion::rotation_x(s_a.ac.3 + move1 * 0.6)
|
||||||
* Quaternion::rotation_y(s_a.ac.4 + move1 * -0.5)
|
* Quaternion::rotation_y(s_a.ac.4 + move1 * -0.5)
|
||||||
* Quaternion::rotation_z(s_a.ac.5 + move1 * 3.0);
|
* Quaternion::rotation_z(s_a.ac.5 + move1 * (3.0 - PI));
|
||||||
|
|
||||||
next.chest.orientation = Quaternion::rotation_z(move1 * 0.6);
|
next.chest.orientation = Quaternion::rotation_z(move1 * 0.6);
|
||||||
next.head.orientation = Quaternion::rotation_z(move1 * -0.2);
|
next.head.orientation = Quaternion::rotation_z(move1 * -0.2);
|
||||||
|
@ -161,7 +161,7 @@ impl Animation for FinisherMeleeAnimation {
|
|||||||
next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
|
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)
|
next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
|
||||||
* Quaternion::rotation_y(s_a.ac.4)
|
* Quaternion::rotation_y(s_a.ac.4)
|
||||||
* Quaternion::rotation_z(s_a.ac.5);
|
* Quaternion::rotation_z(s_a.ac.5 - move1 * PI);
|
||||||
|
|
||||||
next.control.orientation.rotate_x(move1 * 0.9);
|
next.control.orientation.rotate_x(move1 * 0.9);
|
||||||
next.chest.orientation.rotate_z(move1 * 1.2);
|
next.chest.orientation.rotate_z(move1 * 1.2);
|
||||||
@ -199,7 +199,7 @@ impl Animation for FinisherMeleeAnimation {
|
|||||||
next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
|
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)
|
next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
|
||||||
* Quaternion::rotation_y(s_a.ac.4)
|
* Quaternion::rotation_y(s_a.ac.4)
|
||||||
* Quaternion::rotation_z(s_a.ac.5);
|
* Quaternion::rotation_z(s_a.ac.5 - move1 * PI);
|
||||||
|
|
||||||
next.control.orientation.rotate_x(move1 * 0.9);
|
next.control.orientation.rotate_x(move1 * 0.9);
|
||||||
next.chest.orientation.rotate_z(move1 * 1.2);
|
next.chest.orientation.rotate_z(move1 * 1.2);
|
||||||
|
@ -3,6 +3,7 @@ use super::{
|
|||||||
CharacterSkeleton, SkeletonAttr,
|
CharacterSkeleton, SkeletonAttr,
|
||||||
};
|
};
|
||||||
use common::states::utils::{AbilityInfo, StageSection};
|
use common::states::utils::{AbilityInfo, StageSection};
|
||||||
|
use core::f32::consts::PI;
|
||||||
|
|
||||||
pub struct SelfBuffAnimation;
|
pub struct SelfBuffAnimation;
|
||||||
impl Animation for SelfBuffAnimation {
|
impl Animation for SelfBuffAnimation {
|
||||||
@ -188,7 +189,7 @@ impl Animation for SelfBuffAnimation {
|
|||||||
* Quaternion::rotation_z(s_a.ac.5);
|
* Quaternion::rotation_z(s_a.ac.5);
|
||||||
|
|
||||||
next.control.orientation.rotate_z(move1 * -2.0);
|
next.control.orientation.rotate_z(move1 * -2.0);
|
||||||
next.control.orientation.rotate_x(move1 * -3.5);
|
next.control.orientation.rotate_x(move1 * 3.5);
|
||||||
next.control.position += Vec3::new(move1 * 14.0, move1 * -6.0, move1 * 15.0);
|
next.control.position += Vec3::new(move1 * 14.0, move1 * -6.0, move1 * 15.0);
|
||||||
|
|
||||||
next.head.orientation.rotate_x(move2 * 0.6);
|
next.head.orientation.rotate_x(move2 * 0.6);
|
||||||
@ -248,7 +249,7 @@ impl Animation for SelfBuffAnimation {
|
|||||||
next.control.position = Vec3::new(s_a.ac.0, s_a.ac.1, s_a.ac.2);
|
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)
|
next.control.orientation = Quaternion::rotation_x(s_a.ac.3)
|
||||||
* Quaternion::rotation_y(s_a.ac.4)
|
* Quaternion::rotation_y(s_a.ac.4)
|
||||||
* Quaternion::rotation_z(s_a.ac.5);
|
* Quaternion::rotation_z(s_a.ac.5 - move1 * PI);
|
||||||
|
|
||||||
next.control.orientation.rotate_z(move1 * -1.8);
|
next.control.orientation.rotate_z(move1 * -1.8);
|
||||||
next.control.orientation.rotate_y(move1 * 1.5);
|
next.control.orientation.rotate_y(move1 * 1.5);
|
||||||
|
@ -1169,7 +1169,7 @@ impl<'a> Skillbar<'a> {
|
|||||||
self.contexts,
|
self.contexts,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map_or(false, |(a, _)| {
|
.map_or(false, |(a, _, _)| {
|
||||||
self.energy.current() >= a.energy_cost()
|
self.energy.current() >= a.energy_cost()
|
||||||
&& self.combo.map_or(false, |c| c.counter() >= a.combo_cost())
|
&& self.combo.map_or(false, |c| c.counter() >= a.combo_cost())
|
||||||
&& a.ability_meta().requirements.requirements_met(self.stance)
|
&& a.ability_meta().requirements.requirements_met(self.stance)
|
||||||
|
@ -186,7 +186,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
|||||||
contexts,
|
contexts,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|(ability, _)| {
|
.map(|(ability, _, _)| {
|
||||||
(
|
(
|
||||||
image,
|
image,
|
||||||
if energy.current() >= ability.energy_cost()
|
if energy.current() >= ability.energy_cost()
|
||||||
|
@ -37,11 +37,11 @@ use anim::{
|
|||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
inventory::slot::EquipSlot,
|
inventory::slot::EquipSlot,
|
||||||
item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
|
item::{Hands, ItemKind, ToolKind},
|
||||||
ship::{self, figuredata::VOXEL_COLLIDER_MANIFEST},
|
ship::{self, figuredata::VOXEL_COLLIDER_MANIFEST},
|
||||||
Body, CharacterActivity, CharacterState, Collider, Combo, Controller, Health, Inventory,
|
Body, CharacterActivity, CharacterState, Collider, Controller, Health, Inventory, Item,
|
||||||
Item, ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState,
|
ItemKey, Last, LightAnimation, LightEmitter, Object, Ori, PhysicsState, PoiseState, Pos,
|
||||||
Pos, Scale, SkillSet, Stance, Vel,
|
Scale, Vel,
|
||||||
},
|
},
|
||||||
link::Is,
|
link::Is,
|
||||||
mounting::{Rider, VolumeRider},
|
mounting::{Rider, VolumeRider},
|
||||||
@ -853,7 +853,7 @@ impl FigureMgr {
|
|||||||
inventory,
|
inventory,
|
||||||
item,
|
item,
|
||||||
light_emitter,
|
light_emitter,
|
||||||
(is_rider, is_volume_rider, collider, stance, skillset, combo),
|
(is_rider, is_volume_rider, collider),
|
||||||
),
|
),
|
||||||
) in (
|
) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
@ -875,9 +875,6 @@ impl FigureMgr {
|
|||||||
ecs.read_storage::<Is<Rider>>().maybe(),
|
ecs.read_storage::<Is<Rider>>().maybe(),
|
||||||
ecs.read_storage::<Is<VolumeRider>>().maybe(),
|
ecs.read_storage::<Is<VolumeRider>>().maybe(),
|
||||||
ecs.read_storage::<Collider>().maybe(),
|
ecs.read_storage::<Collider>().maybe(),
|
||||||
ecs.read_storage::<Stance>().maybe(),
|
|
||||||
ecs.read_storage::<SkillSet>().maybe(),
|
|
||||||
ecs.read_storage::<Combo>().maybe(),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
@ -1038,12 +1035,10 @@ impl FigureMgr {
|
|||||||
let second_tool_spec = second_tool_spec.as_deref();
|
let second_tool_spec = second_tool_spec.as_deref();
|
||||||
let hands = (active_tool_hand, second_tool_hand);
|
let hands = (active_tool_hand, second_tool_hand);
|
||||||
|
|
||||||
let contexts = AbilityContext::from(stance, inventory, combo);
|
|
||||||
|
|
||||||
let ability_id = character.and_then(|c| {
|
let ability_id = character.and_then(|c| {
|
||||||
c.ability_info()
|
c.ability_info()
|
||||||
.and_then(|a| a.ability)
|
.and_then(|a| a.ability)
|
||||||
.and_then(|a| a.ability_id(inventory, skillset, &contexts))
|
.and_then(|a| a.ability_id(inventory))
|
||||||
});
|
});
|
||||||
|
|
||||||
let move_dir = {
|
let move_dir = {
|
||||||
|
Loading…
Reference in New Issue
Block a user