mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'potion-animations' into 'master'
Consumable Animations See merge request veloren/veloren!2512
This commit is contained in:
commit
0151e5aeed
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Players can press H to greet others
|
||||
- Ability to toggle chat visibility
|
||||
- Added gem rings with various stat improvements.
|
||||
- Animations for using consumables.
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Potent Potion",
|
||||
description: "A potent healing potion.",
|
||||
kind: Consumable(
|
||||
kind: "Potion",
|
||||
kind: Potion,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Potion,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Large Potion",
|
||||
description: "",
|
||||
kind: Consumable(
|
||||
kind: "PotionLarge",
|
||||
kind: Potion,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Potion,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Medium Potion",
|
||||
description: "",
|
||||
kind: Consumable(
|
||||
kind: "PotionMed",
|
||||
kind: Potion,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Potion,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Minor Potion",
|
||||
description: "",
|
||||
kind: Consumable(
|
||||
kind: "PotionMinor",
|
||||
kind: Potion,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Potion,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Apple",
|
||||
description: "Red and juicy",
|
||||
kind: Consumable(
|
||||
kind: "Apple",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Mushroom Curry",
|
||||
description: "Who could say no to that?",
|
||||
kind: Consumable(
|
||||
kind: "AppleShroomCurry",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Apple Stick",
|
||||
description: "The stick makes it easier to carry!",
|
||||
kind: Consumable(
|
||||
kind: "AppleStick",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Cactus Colada",
|
||||
description: "Giving you that special prickle.",
|
||||
kind: Consumable(
|
||||
kind: "CactusColada",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Carrot",
|
||||
description: "An orange root vegetable. They say it'll improve your vision!",
|
||||
kind: Consumable(
|
||||
kind: "Carrot",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Dwarven Cheese",
|
||||
description: "Aromatic and nutritious",
|
||||
kind: Consumable(
|
||||
kind: "Cheese",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Coconut",
|
||||
description: "Reliable source of water and fat.\n\nNaturally growing at the top of palm trees.",
|
||||
kind: Consumable(
|
||||
kind: "Coconut",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Coltsfoot",
|
||||
description: "A daisy-like flower often used in herbal teas.",
|
||||
kind: Consumable(
|
||||
kind: "Coltsfoot",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Dandelion",
|
||||
description: "A small, yellow flower. Uses the wind to spread its seeds.",
|
||||
kind: Consumable(
|
||||
kind: "Dandelion",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Garlic",
|
||||
description: "Make sure to brush your teeth after eating.",
|
||||
kind: Consumable(
|
||||
kind: "Garlic",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Lettuce",
|
||||
description: "A vibrant green leafy vegetable. Lettuce make some salads!",
|
||||
kind: Consumable(
|
||||
kind: "Lettuce",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Meat",
|
||||
description: "Meat. The lifeblood of mankind.",
|
||||
kind: Consumable(
|
||||
kind: "Meat",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Cooked Meat Slab",
|
||||
description: "Medium Rare.",
|
||||
kind: Consumable(
|
||||
kind: "BeastLargeCooked",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Raw Meat Slab",
|
||||
description: "Chunk of beastly animal meat, best after cooking.",
|
||||
kind: Consumable(
|
||||
kind: "BeastLargeRaw",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Cooked Meat Sliver",
|
||||
description: "Medium Rare.",
|
||||
kind: Consumable(
|
||||
kind: "BeastSmallCooked",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Raw Meat Sliver",
|
||||
description: "Small hunk of beastly animal meat, best after cooking.",
|
||||
kind: Consumable(
|
||||
kind: "BeastSmallRaw",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Cooked Bird Meat",
|
||||
description: "Best enjoyed with one in each hand.",
|
||||
kind: Consumable(
|
||||
kind: "BirdCooked",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Huge Cooked Drumstick",
|
||||
description: "Makes for a legendary meal.",
|
||||
kind: Consumable(
|
||||
kind: "BirdLargeCooked",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Huge Raw Drumstick",
|
||||
description: "It's magificent.",
|
||||
kind: Consumable(
|
||||
kind: "BirdLargeRaw",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Raw Bird Meat",
|
||||
description: "A hefty drumstick.",
|
||||
kind: Consumable(
|
||||
kind: "BirdRaw",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Cooked Fish",
|
||||
description: "A fresh cooked seafood steak.",
|
||||
kind: Consumable(
|
||||
kind: "FishCooked",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Raw Fish",
|
||||
description: "A steak chopped from a fish, best after cooking.",
|
||||
kind: Consumable(
|
||||
kind: "FishRaw",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Cooked Tough Meat",
|
||||
description: "Tastes exotic.",
|
||||
kind: Consumable(
|
||||
kind: "ToughCooked",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Raw Tough Meat",
|
||||
description: "Peculiar bit of meat, best after cooking.",
|
||||
kind: Consumable(
|
||||
kind: "ToughRaw",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Mushroom",
|
||||
description: "Hopefully this one is not poisonous",
|
||||
kind: Consumable(
|
||||
kind: "Mushroom",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Mushroom Stick",
|
||||
description: "Roasted mushrooms on a stick for easy carrying",
|
||||
kind: Consumable(
|
||||
kind: "MushroomStick",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Onion",
|
||||
description: "A vegetable that's made the toughest men cry.",
|
||||
kind: Consumable(
|
||||
kind: "Onion",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Plain Salad",
|
||||
description: "Literally just chopped lettuce. Does this even count as a salad?",
|
||||
kind: Consumable(
|
||||
kind: "PlainSalad",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Sage",
|
||||
description: "A herb commonly used in tea.",
|
||||
kind: Consumable(
|
||||
kind: "Sage",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Sunflower Ice Tea",
|
||||
description: "Brewed from freshly shelled sunflower seeds",
|
||||
kind: Consumable(
|
||||
kind: "SunflowerTea",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Tomato",
|
||||
description: "A red fruit. Not actually a vegetable.",
|
||||
kind: Consumable(
|
||||
kind: "Tomato",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Tomato Salad",
|
||||
description: "Leafy salad with some chopped, juicy tomatoes mixed in.",
|
||||
kind: Consumable(
|
||||
kind: "TomatoSalad",
|
||||
kind: Food,
|
||||
effect: [
|
||||
Buff((
|
||||
kind: Saturation,
|
||||
|
@ -2235,40 +2235,36 @@
|
||||
"element.items.item_bag_blue",
|
||||
),
|
||||
// Consumables
|
||||
Consumable("Apple"): Png(
|
||||
Consumable("common.items.food.apple"): Png(
|
||||
"element.items.item_apple",
|
||||
),
|
||||
Consumable("Coconut"): Png(
|
||||
Consumable("common.items.food.coconut"): Png(
|
||||
"element.items.item_coconut",
|
||||
),
|
||||
Consumable("CactusColada"): VoxTrans(
|
||||
Consumable("common.items.food.cactus_colada"): VoxTrans(
|
||||
"voxel.object.cactus_drink",
|
||||
(-1.0, 1.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
|
||||
),
|
||||
Consumable("PotionMed"): VoxTrans(
|
||||
Consumable("common.items.consumable.potion_med"): VoxTrans(
|
||||
"voxel.object.potion_red",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.7,
|
||||
),
|
||||
Consumable("PotionMinor"): VoxTrans(
|
||||
Consumable("common.items.consumable.potion_minor"): VoxTrans(
|
||||
"voxel.object.potion_red",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.5,
|
||||
),
|
||||
Consumable("PotionLarge"): VoxTrans(
|
||||
Consumable("common.items.consumable.potion_big"): VoxTrans(
|
||||
"voxel.object.potion_red",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9,
|
||||
),
|
||||
Ingredient("PotionExp"): VoxTrans(
|
||||
"voxel.object.potion_turq",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
|
||||
Consumable("common.items.boss_drops.potions"): VoxTrans(
|
||||
"voxel.object.potion_red",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("Cheese"): Png(
|
||||
Consumable("common.items.food.cheese"): Png(
|
||||
"element.items.item_cheese",
|
||||
),
|
||||
Consumable("Potion"): VoxTrans(
|
||||
"voxel.object.potion_red",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.0,
|
||||
),
|
||||
Consumable("Mushroom"): VoxTrans(
|
||||
Consumable("common.items.food.mushroom"): VoxTrans(
|
||||
"voxel.sprite.mushrooms.mushroom-10",
|
||||
(0.0, 0.0, 0.0), (-50.0, 70.0, 40.0), 1.0,
|
||||
),
|
||||
@ -2280,83 +2276,83 @@
|
||||
"voxel.sprite.velorite.velorite_1",
|
||||
(0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
||||
),
|
||||
Consumable("AppleShroomCurry"): Png(
|
||||
Consumable("common.items.food.apple_mushroom_curry"): Png(
|
||||
"element.items.item_apple_curry",
|
||||
),
|
||||
Consumable("AppleStick"): Png(
|
||||
Consumable("common.items.food.apple_stick"): Png(
|
||||
"element.items.item_apple_stick",
|
||||
),
|
||||
Consumable("MushroomStick"): Png(
|
||||
Consumable("common.items.food.mushroom_stick"): Png(
|
||||
"element.items.item_shroom_stick",
|
||||
),
|
||||
Consumable("SunflowerTea"): Png(
|
||||
Consumable("common.items.food.sunflower_icetea"): Png(
|
||||
"element.items.item_sunflower_tea",
|
||||
),
|
||||
Consumable("Carrot"): VoxTrans(
|
||||
Consumable("common.items.food.carrot"): VoxTrans(
|
||||
"voxel.sprite.carrot.carrot",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("Tomato"): VoxTrans(
|
||||
Consumable("common.items.food.tomato"): VoxTrans(
|
||||
"voxel.sprite.tomato.tomato",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
|
||||
),
|
||||
Consumable("Lettuce"): VoxTrans(
|
||||
Consumable("common.items.food.lettuce"): VoxTrans(
|
||||
"voxel.sprite.cabbage.cabbage",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
|
||||
),
|
||||
Consumable("FishRaw"): VoxTrans(
|
||||
Consumable("common.items.food.meat.fish_raw"): VoxTrans(
|
||||
"voxel.sprite.food.meat.fish_raw",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("FishCooked"): VoxTrans(
|
||||
Consumable("common.items.food.meat.fish_cooked"): VoxTrans(
|
||||
"voxel.sprite.food.meat.fish_cooked",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("BirdRaw"): VoxTrans(
|
||||
Consumable("common.items.food.meat.bird_raw"): VoxTrans(
|
||||
"voxel.sprite.food.meat.bird_raw",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("BirdCooked"): VoxTrans(
|
||||
Consumable("common.items.food.meat.bird_cooked"): VoxTrans(
|
||||
"voxel.sprite.food.meat.bird_cooked",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("BirdLargeRaw"): VoxTrans(
|
||||
Consumable("common.items.food.meat.bird_large_raw"): VoxTrans(
|
||||
"voxel.sprite.food.meat.bird_large_raw",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("BirdLargeCooked"): VoxTrans(
|
||||
Consumable("common.items.food.meat.bird_large_cooked"): VoxTrans(
|
||||
"voxel.sprite.food.meat.bird_large_cooked",
|
||||
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
|
||||
),
|
||||
Consumable("BeastSmallRaw"): VoxTrans(
|
||||
Consumable("common.items.food.meat.beast_small_raw"): VoxTrans(
|
||||
"voxel.sprite.food.meat.beast_small_raw",
|
||||
(0.0, 0.0, 0.0), (-50.0, 10.0, 0.0), 1.0,
|
||||
),
|
||||
Consumable("BeastSmallCooked"): VoxTrans(
|
||||
Consumable("common.items.food.meat.beast_small_cooked"): VoxTrans(
|
||||
"voxel.sprite.food.meat.beast_small_cooked",
|
||||
(0.0, 0.0, 0.0), (-50.0, 20.0, 0.0), 1.0,
|
||||
),
|
||||
Consumable("ToughRaw"): VoxTrans(
|
||||
Consumable("common.items.food.meat.tough_raw"): VoxTrans(
|
||||
"voxel.sprite.food.meat.tough_raw",
|
||||
(0.0, 0.0, 0.0), (-50.0, 10.0, 0.0), 1.0,
|
||||
),
|
||||
Consumable("ToughCooked"): VoxTrans(
|
||||
Consumable("common.items.food.meat.tough_cooked"): VoxTrans(
|
||||
"voxel.sprite.food.meat.tough_cooked",
|
||||
(0.0, 0.0, 0.0), (-50.0, 20.0, 0.0), 1.0,
|
||||
),
|
||||
Consumable("BeastLargeRaw"): VoxTrans(
|
||||
Consumable("common.items.food.meat.beast_large_raw"): VoxTrans(
|
||||
"voxel.sprite.food.meat.beast_large_raw",
|
||||
(-1.0, 0.0, 0.0), (-80.0, 40.0, 0.0), 0.8,
|
||||
),
|
||||
Consumable("BeastLargeCooked"): VoxTrans(
|
||||
Consumable("common.items.food.meat.beast_large_cooked"): VoxTrans(
|
||||
"voxel.sprite.food.meat.beast_large_cooked",
|
||||
(-1.0, 0.0, 0.0), (-80.0, 40.0, 0.0), 0.8,
|
||||
),
|
||||
Consumable("PlainSalad"): VoxTrans(
|
||||
Consumable("common.items.food.plainsalad"): VoxTrans(
|
||||
"voxel.sprite.food.salad_plain",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
|
||||
),
|
||||
Consumable("TomatoSalad"): VoxTrans(
|
||||
Consumable("common.items.food.tomatosalad"): VoxTrans(
|
||||
"voxel.sprite.food.salad_tomato",
|
||||
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
|
||||
),
|
||||
|
@ -339,7 +339,7 @@ impl CharacterAbility {
|
||||
match self {
|
||||
CharacterAbility::Roll { energy_cost, .. } => {
|
||||
data.physics.on_ground.is_some()
|
||||
&& data.vel.0.xy().magnitude_squared() > 0.5
|
||||
&& data.inputs.move_dir.magnitude_squared() > 0.25
|
||||
&& update
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
|
@ -105,6 +105,8 @@ pub enum CharacterState {
|
||||
SelfBuff(self_buff::Data),
|
||||
/// Creates sprites around the caster
|
||||
SpriteSummon(sprite_summon::Data),
|
||||
/// Handles logic for using an item so it is not simply instant
|
||||
UseItem(use_item::Data),
|
||||
}
|
||||
|
||||
impl CharacterState {
|
||||
@ -175,6 +177,7 @@ impl CharacterState {
|
||||
| CharacterState::Shockwave(_)
|
||||
| CharacterState::BasicBeam(_)
|
||||
| CharacterState::Stunned(_)
|
||||
| CharacterState::UseItem(_)
|
||||
| CharacterState::Wielding
|
||||
| CharacterState::Talk
|
||||
| CharacterState::HealingBeam(_)
|
||||
|
@ -251,7 +251,7 @@ pub enum ItemKind {
|
||||
Armor(armor::Armor),
|
||||
Glider(Glider),
|
||||
Consumable {
|
||||
kind: String,
|
||||
kind: ConsumableKind,
|
||||
effect: Vec<Effect>,
|
||||
},
|
||||
Throwable {
|
||||
@ -270,6 +270,12 @@ pub enum ItemKind {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum ConsumableKind {
|
||||
Potion,
|
||||
Food,
|
||||
}
|
||||
|
||||
impl ItemKind {
|
||||
pub fn is_equippable(&self) -> bool {
|
||||
matches!(
|
||||
|
@ -9,7 +9,10 @@ use vek::Vec3;
|
||||
use crate::{
|
||||
comp::{
|
||||
inventory::{
|
||||
item::{tool::AbilityMap, ItemDef, ItemKind, MaterialStatManifest, TagExampleInfo},
|
||||
item::{
|
||||
tool::AbilityMap, ConsumableKind, ItemDef, ItemKind, MaterialStatManifest,
|
||||
TagExampleInfo,
|
||||
},
|
||||
loadout::Loadout,
|
||||
slot::{EquipSlot, Slot, SlotError},
|
||||
},
|
||||
@ -803,7 +806,7 @@ impl Component for Inventory {
|
||||
pub enum InventoryUpdateEvent {
|
||||
Init,
|
||||
Used,
|
||||
Consumed(String),
|
||||
Consumed(ConsumableKind),
|
||||
Gave,
|
||||
Given,
|
||||
Swapped,
|
||||
|
@ -29,5 +29,6 @@ pub mod spin_melee;
|
||||
pub mod sprite_summon;
|
||||
pub mod stunned;
|
||||
pub mod talk;
|
||||
pub mod use_item;
|
||||
pub mod utils;
|
||||
pub mod wielding;
|
||||
|
208
common/src/states/use_item.rs
Normal file
208
common/src/states/use_item.rs
Normal file
@ -0,0 +1,208 @@
|
||||
use super::utils::*;
|
||||
use crate::{
|
||||
comp::{
|
||||
buff::{BuffChange, BuffKind},
|
||||
inventory::{
|
||||
item::{ConsumableKind, ItemKind},
|
||||
slot::{InvSlotId, Slot},
|
||||
},
|
||||
CharacterState, InventoryManip, StateUpdate,
|
||||
},
|
||||
event::ServerEvent,
|
||||
states::behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Separated out to condense update portions of character state
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct StaticData {
|
||||
/// Buildup to item use
|
||||
pub buildup_duration: Duration,
|
||||
/// Duration of item use
|
||||
pub use_duration: Duration,
|
||||
/// Recovery after item use
|
||||
pub recover_duration: Duration,
|
||||
/// Inventory slot to use item from
|
||||
pub inv_slot: InvSlotId,
|
||||
/// Item definition id, used to verify that slot still has the correct item
|
||||
pub item_definition_id: String,
|
||||
/// Kind of item used
|
||||
pub item_kind: ItemUseKind,
|
||||
/// Had weapon wielded
|
||||
pub was_wielded: bool,
|
||||
/// Was sneaking
|
||||
pub was_sneak: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
/// Struct containing data that does not change over the course of the
|
||||
/// character state
|
||||
pub static_data: StaticData,
|
||||
/// Timer for each stage
|
||||
pub timer: Duration,
|
||||
/// What section the character stage is in
|
||||
pub stage_section: StageSection,
|
||||
}
|
||||
|
||||
impl CharacterBehavior for Data {
|
||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||
let mut update = StateUpdate::from(data);
|
||||
|
||||
match self.static_data.item_kind {
|
||||
ItemUseKind::Consumable(ConsumableKind::Potion) => {
|
||||
handle_orientation(data, &mut update, 1.0);
|
||||
handle_move(data, &mut update, 1.0);
|
||||
},
|
||||
ItemUseKind::Consumable(ConsumableKind::Food) => {
|
||||
handle_orientation(data, &mut update, 0.0);
|
||||
handle_move(data, &mut update, 0.0);
|
||||
},
|
||||
}
|
||||
|
||||
let use_point = match self.static_data.item_kind {
|
||||
ItemUseKind::Consumable(ConsumableKind::Potion) => UsePoint::BuildupUse,
|
||||
ItemUseKind::Consumable(ConsumableKind::Food) => UsePoint::UseRecover,
|
||||
};
|
||||
|
||||
match self.stage_section {
|
||||
StageSection::Buildup => {
|
||||
if self.timer < self.static_data.buildup_duration {
|
||||
// Build up
|
||||
update.character = CharacterState::UseItem(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Transitions to use section of stage
|
||||
update.character = CharacterState::UseItem(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Use,
|
||||
});
|
||||
if let UsePoint::BuildupUse = use_point {
|
||||
// Create inventory manipulation event
|
||||
use_item(data, &mut update, self);
|
||||
}
|
||||
}
|
||||
},
|
||||
StageSection::Use => {
|
||||
if self.timer < self.static_data.use_duration {
|
||||
// Item use
|
||||
update.character = CharacterState::UseItem(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Transitions to recover section of stage
|
||||
update.character = CharacterState::UseItem(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Recover,
|
||||
});
|
||||
if let UsePoint::UseRecover = use_point {
|
||||
// Create inventory manipulation event
|
||||
use_item(data, &mut update, self);
|
||||
}
|
||||
}
|
||||
},
|
||||
StageSection::Recover => {
|
||||
if self.timer < self.static_data.recover_duration {
|
||||
// Recovery
|
||||
update.character = CharacterState::UseItem(Data {
|
||||
static_data: self.static_data.clone(),
|
||||
timer: tick_attack_or_default(data, self.timer, None),
|
||||
..*self
|
||||
});
|
||||
} else {
|
||||
// Done
|
||||
if self.static_data.was_wielded {
|
||||
update.character = CharacterState::Wielding;
|
||||
} else if self.static_data.was_sneak {
|
||||
update.character = CharacterState::Sneak;
|
||||
} else {
|
||||
update.character = CharacterState::Idle;
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
// If it somehow ends up in an incorrect stage section
|
||||
update.character = CharacterState::Idle;
|
||||
},
|
||||
}
|
||||
|
||||
// At end of state logic so an interrupt isn't overwritten
|
||||
handle_state_interrupt(data, &mut update, false);
|
||||
|
||||
if matches!(update.character, CharacterState::Roll(_)) {
|
||||
// Remove potion effect if left the use item state early by rolling
|
||||
update.server_events.push_front(ServerEvent::Buff {
|
||||
entity: data.entity,
|
||||
buff_change: BuffChange::RemoveByKind(BuffKind::Potion),
|
||||
});
|
||||
}
|
||||
|
||||
update
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to control effects based off of the type of item used
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ItemUseKind {
|
||||
Consumable(ConsumableKind),
|
||||
}
|
||||
|
||||
impl From<&ItemKind> for Option<ItemUseKind> {
|
||||
fn from(item_kind: &ItemKind) -> Self {
|
||||
match item_kind {
|
||||
ItemKind::Consumable { kind, .. } => Some(ItemUseKind::Consumable(*kind)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemUseKind {
|
||||
/// Returns (buildup, use, recover)
|
||||
pub fn durations(&self) -> (Duration, Duration, Duration) {
|
||||
match self {
|
||||
Self::Consumable(ConsumableKind::Potion) => (
|
||||
Duration::from_secs_f32(0.1),
|
||||
Duration::from_secs_f32(1.1),
|
||||
Duration::from_secs_f32(0.1),
|
||||
),
|
||||
Self::Consumable(ConsumableKind::Food) => (
|
||||
Duration::from_secs_f32(1.0),
|
||||
Duration::from_secs_f32(5.0),
|
||||
Duration::from_secs_f32(0.5),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to control when the item is used in the state
|
||||
enum UsePoint {
|
||||
/// Between buildup and use
|
||||
BuildupUse,
|
||||
/// Between use and recover
|
||||
UseRecover,
|
||||
}
|
||||
|
||||
fn use_item(data: &JoinData, update: &mut StateUpdate, state: &Data) {
|
||||
// Check if the same item is in the slot
|
||||
let item_is_same = data
|
||||
.inventory
|
||||
.get(state.static_data.inv_slot)
|
||||
.map_or(false, |item| {
|
||||
item.item_definition_id() == state.static_data.item_definition_id
|
||||
});
|
||||
if item_is_same {
|
||||
// Create inventory manipulation event
|
||||
let inv_manip = InventoryManip::Use(Slot::Inventory(state.static_data.inv_slot));
|
||||
update
|
||||
.server_events
|
||||
.push_front(ServerEvent::InventoryManip(data.entity, inv_manip));
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ use crate::{
|
||||
combat,
|
||||
comp::{
|
||||
biped_large, biped_small,
|
||||
inventory::slot::EquipSlot,
|
||||
inventory::slot::{EquipSlot, Slot},
|
||||
item::{Hands, ItemKind, Tool, ToolKind},
|
||||
quadruped_low, quadruped_medium, quadruped_small,
|
||||
skills::{Skill, SwimSkill},
|
||||
@ -575,9 +575,45 @@ pub fn handle_manipulate_loadout(
|
||||
update: &mut StateUpdate,
|
||||
inv_action: InventoryAction,
|
||||
) {
|
||||
update
|
||||
.server_events
|
||||
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
|
||||
use use_item::ItemUseKind;
|
||||
if let InventoryAction::Use(Slot::Inventory(inv_slot)) = inv_action {
|
||||
// If inventory action is using a slot, and slot is in the inventory
|
||||
// TODO: Do some non lazy way of handling the possibility that items equipped in
|
||||
// the loadout will have effects that are desired to be non-instantaneous
|
||||
if let Some((item_kind, item)) = data
|
||||
.inventory
|
||||
.get(inv_slot)
|
||||
.and_then(|item| Option::<ItemUseKind>::from(item.kind()).zip(Some(item)))
|
||||
{
|
||||
let (buildup_duration, use_duration, recover_duration) = item_kind.durations();
|
||||
// If item returns a valid kind for item use, do into use item character state
|
||||
update.character = CharacterState::UseItem(use_item::Data {
|
||||
static_data: use_item::StaticData {
|
||||
buildup_duration,
|
||||
use_duration,
|
||||
recover_duration,
|
||||
inv_slot,
|
||||
item_kind,
|
||||
item_definition_id: item.item_definition_id().to_string(),
|
||||
was_wielded: matches!(data.character, CharacterState::Wielding),
|
||||
was_sneak: matches!(data.character, CharacterState::Sneak),
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
});
|
||||
} else {
|
||||
// Else emit inventory action instantnaneously
|
||||
update
|
||||
.server_events
|
||||
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
|
||||
}
|
||||
} else {
|
||||
// Else if inventory action is not item use, or if slot is in loadout, just do
|
||||
// event instantaneously
|
||||
update
|
||||
.server_events
|
||||
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks that player can wield the glider and updates `CharacterState` if so
|
||||
@ -836,12 +872,15 @@ pub fn tick_attack_or_default(
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum StageSection {
|
||||
Buildup,
|
||||
Swing,
|
||||
Recover,
|
||||
Charge,
|
||||
Cast,
|
||||
Shoot,
|
||||
Movement,
|
||||
// TODO: Consolidate these to `Action`
|
||||
// Code reviewers: comment here to remind me to open beginner issue
|
||||
Swing,
|
||||
Shoot,
|
||||
Cast,
|
||||
Use,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -165,6 +165,14 @@ impl<'a> System<'a> for Sys {
|
||||
let was_wielded = char_state.get_unchecked().is_wield();
|
||||
let poise_state = poise.poise_state();
|
||||
let pos = pos.0;
|
||||
// Remove potion buff if knocked into poise state
|
||||
if !matches!(poise_state, PoiseState::Normal) {
|
||||
use comp::buff::{BuffChange, BuffKind};
|
||||
server_emitter.emit(ServerEvent::Buff {
|
||||
entity,
|
||||
buff_change: BuffChange::RemoveByKind(BuffKind::Potion),
|
||||
});
|
||||
}
|
||||
match poise_state {
|
||||
PoiseState::Normal => {},
|
||||
PoiseState::Interrupted => {
|
||||
@ -332,6 +340,7 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::BasicSummon(data) => data.handle_event(&j, action),
|
||||
CharacterState::SelfBuff(data) => data.handle_event(&j, action),
|
||||
CharacterState::SpriteSummon(data) => data.handle_event(&j, action),
|
||||
CharacterState::UseItem(data) => data.handle_event(&j, action),
|
||||
};
|
||||
local_emitter.append(&mut state_update.local_events);
|
||||
server_emitter.append(&mut state_update.server_events);
|
||||
@ -388,6 +397,7 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::BasicSummon(data) => data.behavior(&j),
|
||||
CharacterState::SelfBuff(data) => data.behavior(&j),
|
||||
CharacterState::SpriteSummon(data) => data.behavior(&j),
|
||||
CharacterState::UseItem(data) => data.behavior(&j),
|
||||
};
|
||||
|
||||
local_emitter.append(&mut state_update.local_events);
|
||||
|
@ -289,7 +289,8 @@ impl<'a> System<'a> for Sys {
|
||||
CharacterState::Roll { .. }
|
||||
| CharacterState::Climb { .. }
|
||||
| CharacterState::Stunned { .. }
|
||||
| CharacterState::BasicBlock { .. } => {},
|
||||
| CharacterState::BasicBlock { .. }
|
||||
| CharacterState::UseItem { .. } => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
match item.kind() {
|
||||
ItemKind::Consumable { kind, effect, .. } => {
|
||||
maybe_effect = Some(effect.clone());
|
||||
Some(comp::InventoryUpdateEvent::Consumed(kind.clone()))
|
||||
Some(comp::InventoryUpdateEvent::Consumed(*kind))
|
||||
},
|
||||
ItemKind::Throwable { kind, .. } => {
|
||||
if let Some(pos) =
|
||||
|
128
voxygen/anim/src/character/consume.rs
Normal file
128
voxygen/anim/src/character/consume.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
CharacterSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::ConsumableKind,
|
||||
states::{use_item::ItemUseKind, utils::StageSection},
|
||||
};
|
||||
|
||||
pub struct ConsumeAnimation;
|
||||
|
||||
impl Animation for ConsumeAnimation {
|
||||
type Dependency<'a> = (f32, Option<StageSection>, Option<ItemUseKind>);
|
||||
type Skeleton = CharacterSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"character_consume\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "character_consume")]
|
||||
fn update_skeleton_inner<'a>(
|
||||
skeleton: &Self::Skeleton,
|
||||
(_global_time, stage_section, item_kind): Self::Dependency<'a>,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
match item_kind {
|
||||
Some(ItemUseKind::Consumable(ConsumableKind::Potion)) => {
|
||||
let (move1, move2, move3) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
|
||||
Some(StageSection::Use) => (1.0, (anim_time * 8.0).sin(), 0.0),
|
||||
Some(StageSection::Recover) => (1.0, 1.0, anim_time.powf(0.25)),
|
||||
_ => (0.0, 0.0, 0.0),
|
||||
};
|
||||
let pullback = 1.0 - move3;
|
||||
let move2 = move2 * pullback;
|
||||
let move1 = move1 * pullback;
|
||||
next.head.orientation = Quaternion::rotation_x(move1 * 0.5 + move2 * -0.05);
|
||||
|
||||
next.hand_r.position = Vec3::new(
|
||||
s_a.hand.0 + move1 * -4.0,
|
||||
s_a.hand.1 + move1 * 6.0,
|
||||
s_a.hand.2 + move1 * 10.0 + move2 * -1.0,
|
||||
);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(move1 * 2.3 + move2 * -0.2)
|
||||
* Quaternion::rotation_y(move1 * 1.2);
|
||||
next.chest.orientation = Quaternion::rotation_x(move1 * 0.25);
|
||||
next.hand_l.position = Vec3::new(
|
||||
-s_a.hand.0 + move1 * 3.0,
|
||||
s_a.hand.1 + move1 * 2.0,
|
||||
s_a.hand.2,
|
||||
);
|
||||
|
||||
next.hand_l.orientation =
|
||||
Quaternion::rotation_x(move1 * 0.8) * Quaternion::rotation_y(move1 * -0.5);
|
||||
},
|
||||
Some(ItemUseKind::Consumable(ConsumableKind::Food)) => {
|
||||
let (move1, move2, move3) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time, 0.0, 0.0),
|
||||
Some(StageSection::Use) => (1.0, (anim_time * 12.0).sin(), 0.0),
|
||||
Some(StageSection::Recover) => (1.0, 1.0, anim_time.powf(0.25)),
|
||||
_ => (0.0, 0.0, 0.0),
|
||||
};
|
||||
let pullback = 1.0 - move3;
|
||||
let move2 = move2 * pullback;
|
||||
let move1 = move1 * pullback;
|
||||
next.head.position =
|
||||
Vec3::new(0.0, s_a.head.0 + move1 * 2.0, s_a.head.1 + move1 * 1.0);
|
||||
next.head.orientation =
|
||||
Quaternion::rotation_x(move1 * -0.3) * Quaternion::rotation_z(move2 * -0.15);
|
||||
|
||||
next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + move1 * -3.0);
|
||||
next.chest.orientation =
|
||||
Quaternion::rotation_x(move1 * 0.3) * Quaternion::rotation_z(move2 * 0.05);
|
||||
|
||||
next.belt.position = Vec3::new(0.0, s_a.belt.0 + move1 * 1.0, s_a.belt.1);
|
||||
next.belt.orientation = Quaternion::rotation_x(move1 * 0.2);
|
||||
|
||||
next.back.position = Vec3::new(0.0, s_a.back.0, s_a.back.1);
|
||||
|
||||
next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + move1 * 3.0, s_a.shorts.1);
|
||||
next.shorts.orientation = Quaternion::rotation_x(move1 * 0.7);
|
||||
|
||||
next.hand_l.position = Vec3::new(
|
||||
-s_a.hand.0 + move1 * 3.0 + move2 * -1.0,
|
||||
s_a.hand.1 + move1 * 5.0,
|
||||
s_a.hand.2 + move1 * 3.0 + move2 * -2.0,
|
||||
);
|
||||
|
||||
next.hand_l.orientation = Quaternion::rotation_x(move1 * 1.2)
|
||||
* Quaternion::rotation_y(move1 * -0.5 + move2 * 0.3);
|
||||
|
||||
next.hand_r.position = Vec3::new(
|
||||
s_a.hand.0 + move1 * -3.0 + move2 * -1.0,
|
||||
s_a.hand.1 + move1 * 5.0,
|
||||
s_a.hand.2 + move1 * 3.0 + move2 * 2.0,
|
||||
);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(move1 * 1.2)
|
||||
* Quaternion::rotation_y(move1 * 0.5 + move2 * 0.3);
|
||||
|
||||
next.foot_l.position = Vec3::new(
|
||||
-s_a.foot.0,
|
||||
s_a.foot.1 + move1 * 5.0,
|
||||
s_a.foot.2 + move1 * 2.0,
|
||||
);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(move1 * 1.2);
|
||||
|
||||
next.foot_r.position = Vec3::new(
|
||||
s_a.foot.0,
|
||||
s_a.foot.1 + move1 * 5.0,
|
||||
s_a.foot.2 + move1 * 2.0,
|
||||
);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(move1 * 1.2);
|
||||
|
||||
next.shoulder_l.position =
|
||||
Vec3::new(-s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2);
|
||||
|
||||
next.shoulder_r.position =
|
||||
Vec3::new(s_a.shoulder.0, s_a.shoulder.1, s_a.shoulder.2);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ pub mod beta;
|
||||
pub mod block;
|
||||
pub mod chargeswing;
|
||||
pub mod climb;
|
||||
pub mod consume;
|
||||
pub mod dance;
|
||||
pub mod dash;
|
||||
pub mod equip;
|
||||
@ -32,14 +33,14 @@ pub mod wield;
|
||||
// Reexports
|
||||
pub use self::{
|
||||
alpha::AlphaAnimation, beam::BeamAnimation, beta::BetaAnimation, block::BlockAnimation,
|
||||
chargeswing::ChargeswingAnimation, climb::ClimbAnimation, dance::DanceAnimation,
|
||||
dash::DashAnimation, equip::EquipAnimation, glidewield::GlideWieldAnimation,
|
||||
gliding::GlidingAnimation, idle::IdleAnimation, jump::JumpAnimation, leapmelee::LeapAnimation,
|
||||
repeater::RepeaterAnimation, roll::RollAnimation, run::RunAnimation,
|
||||
shockwave::ShockwaveAnimation, shoot::ShootAnimation, sit::SitAnimation, sneak::SneakAnimation,
|
||||
spin::SpinAnimation, spinmelee::SpinMeleeAnimation, staggered::StaggeredAnimation,
|
||||
stand::StandAnimation, stunned::StunnedAnimation, swim::SwimAnimation,
|
||||
swimwield::SwimWieldAnimation, talk::TalkAnimation, wield::WieldAnimation,
|
||||
chargeswing::ChargeswingAnimation, climb::ClimbAnimation, consume::ConsumeAnimation,
|
||||
dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation,
|
||||
glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation,
|
||||
jump::JumpAnimation, leapmelee::LeapAnimation, repeater::RepeaterAnimation,
|
||||
roll::RollAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
|
||||
sit::SitAnimation, sneak::SneakAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation,
|
||||
staggered::StaggeredAnimation, stand::StandAnimation, stunned::StunnedAnimation,
|
||||
swim::SwimAnimation, swimwield::SwimWieldAnimation, talk::TalkAnimation, wield::WieldAnimation,
|
||||
};
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp;
|
||||
|
@ -92,7 +92,7 @@ use common::{
|
||||
assets::{self, AssetExt, AssetHandle},
|
||||
comp::{
|
||||
beam, biped_large, biped_small, humanoid,
|
||||
item::{ItemKind, ToolKind},
|
||||
item::{ConsumableKind, ItemKind, ToolKind},
|
||||
object,
|
||||
poise::PoiseState,
|
||||
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType,
|
||||
@ -276,7 +276,7 @@ pub enum SfxInventoryEvent {
|
||||
CollectedTool(ToolKind),
|
||||
CollectedItem(String),
|
||||
CollectFailed,
|
||||
Consumed(String),
|
||||
Consumed(ConsumableKind),
|
||||
Debug,
|
||||
Dropped,
|
||||
Given,
|
||||
@ -308,7 +308,7 @@ impl From<&InventoryUpdateEvent> for SfxEvent {
|
||||
SfxEvent::Inventory(SfxInventoryEvent::CollectFailed)
|
||||
},
|
||||
InventoryUpdateEvent::Consumed(consumable) => {
|
||||
SfxEvent::Inventory(SfxInventoryEvent::Consumed(consumable.clone()))
|
||||
SfxEvent::Inventory(SfxInventoryEvent::Consumed(*consumable))
|
||||
},
|
||||
InventoryUpdateEvent::Debug => SfxEvent::Inventory(SfxInventoryEvent::Debug),
|
||||
InventoryUpdateEvent::Dropped => SfxEvent::Inventory(SfxInventoryEvent::Dropped),
|
||||
|
@ -49,7 +49,7 @@ impl<T: ItemDesc> From<&T> for ItemKey {
|
||||
ItemKind::Glider(Glider { kind, .. }) => ItemKey::Glider(kind.clone()),
|
||||
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
|
||||
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind),
|
||||
ItemKind::Consumable { kind, .. } => ItemKey::Consumable(kind.clone()),
|
||||
ItemKind::Consumable { .. } => ItemKey::Consumable(item_definition_id.to_owned()),
|
||||
ItemKind::Throwable { kind, .. } => ItemKey::Throwable(*kind),
|
||||
ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()),
|
||||
ItemKind::TagExamples { item_ids } => ItemKey::TagExamples(
|
||||
|
@ -1422,6 +1422,27 @@ impl FigureMgr {
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::UseItem(s) => {
|
||||
let stage_time = s.timer.as_secs_f32();
|
||||
let item_kind = s.static_data.item_kind;
|
||||
let stage_progress = match s.stage_section {
|
||||
StageSection::Buildup => {
|
||||
stage_time / s.static_data.buildup_duration.as_secs_f32()
|
||||
},
|
||||
StageSection::Use => stage_time,
|
||||
StageSection::Recover => {
|
||||
stage_time / s.static_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
anim::character::ConsumeAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(time, Some(s.stage_section), Some(item_kind)),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::Equipping { .. } => {
|
||||
anim::character::EquipAnimation::update_skeleton(
|
||||
&target_base,
|
||||
|
Loading…
Reference in New Issue
Block a user