Merge branch 'potion-animations' into 'master'

Consumable Animations

See merge request veloren/veloren!2512
This commit is contained in:
Samuel Keiffer 2021-06-29 16:36:41 +00:00
commit 0151e5aeed
53 changed files with 515 additions and 97 deletions

View File

@ -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 - Players can press H to greet others
- Ability to toggle chat visibility - Ability to toggle chat visibility
- Added gem rings with various stat improvements. - Added gem rings with various stat improvements.
- Animations for using consumables.
### Changed ### Changed

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Potent Potion", name: "Potent Potion",
description: "A potent healing potion.", description: "A potent healing potion.",
kind: Consumable( kind: Consumable(
kind: "Potion", kind: Potion,
effect: [ effect: [
Buff(( Buff((
kind: Potion, kind: Potion,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Large Potion", name: "Large Potion",
description: "", description: "",
kind: Consumable( kind: Consumable(
kind: "PotionLarge", kind: Potion,
effect: [ effect: [
Buff(( Buff((
kind: Potion, kind: Potion,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Medium Potion", name: "Medium Potion",
description: "", description: "",
kind: Consumable( kind: Consumable(
kind: "PotionMed", kind: Potion,
effect: [ effect: [
Buff(( Buff((
kind: Potion, kind: Potion,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Minor Potion", name: "Minor Potion",
description: "", description: "",
kind: Consumable( kind: Consumable(
kind: "PotionMinor", kind: Potion,
effect: [ effect: [
Buff(( Buff((
kind: Potion, kind: Potion,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Apple", name: "Apple",
description: "Red and juicy", description: "Red and juicy",
kind: Consumable( kind: Consumable(
kind: "Apple", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Mushroom Curry", name: "Mushroom Curry",
description: "Who could say no to that?", description: "Who could say no to that?",
kind: Consumable( kind: Consumable(
kind: "AppleShroomCurry", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Apple Stick", name: "Apple Stick",
description: "The stick makes it easier to carry!", description: "The stick makes it easier to carry!",
kind: Consumable( kind: Consumable(
kind: "AppleStick", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Cactus Colada", name: "Cactus Colada",
description: "Giving you that special prickle.", description: "Giving you that special prickle.",
kind: Consumable( kind: Consumable(
kind: "CactusColada", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Carrot", name: "Carrot",
description: "An orange root vegetable. They say it'll improve your vision!", description: "An orange root vegetable. They say it'll improve your vision!",
kind: Consumable( kind: Consumable(
kind: "Carrot", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Dwarven Cheese", name: "Dwarven Cheese",
description: "Aromatic and nutritious", description: "Aromatic and nutritious",
kind: Consumable( kind: Consumable(
kind: "Cheese", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Coconut", name: "Coconut",
description: "Reliable source of water and fat.\n\nNaturally growing at the top of palm trees.", description: "Reliable source of water and fat.\n\nNaturally growing at the top of palm trees.",
kind: Consumable( kind: Consumable(
kind: "Coconut", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Coltsfoot", name: "Coltsfoot",
description: "A daisy-like flower often used in herbal teas.", description: "A daisy-like flower often used in herbal teas.",
kind: Consumable( kind: Consumable(
kind: "Coltsfoot", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Dandelion", name: "Dandelion",
description: "A small, yellow flower. Uses the wind to spread its seeds.", description: "A small, yellow flower. Uses the wind to spread its seeds.",
kind: Consumable( kind: Consumable(
kind: "Dandelion", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Garlic", name: "Garlic",
description: "Make sure to brush your teeth after eating.", description: "Make sure to brush your teeth after eating.",
kind: Consumable( kind: Consumable(
kind: "Garlic", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Lettuce", name: "Lettuce",
description: "A vibrant green leafy vegetable. Lettuce make some salads!", description: "A vibrant green leafy vegetable. Lettuce make some salads!",
kind: Consumable( kind: Consumable(
kind: "Lettuce", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Meat", name: "Meat",
description: "Meat. The lifeblood of mankind.", description: "Meat. The lifeblood of mankind.",
kind: Consumable( kind: Consumable(
kind: "Meat", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Cooked Meat Slab", name: "Cooked Meat Slab",
description: "Medium Rare.", description: "Medium Rare.",
kind: Consumable( kind: Consumable(
kind: "BeastLargeCooked", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Raw Meat Slab", name: "Raw Meat Slab",
description: "Chunk of beastly animal meat, best after cooking.", description: "Chunk of beastly animal meat, best after cooking.",
kind: Consumable( kind: Consumable(
kind: "BeastLargeRaw", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Cooked Meat Sliver", name: "Cooked Meat Sliver",
description: "Medium Rare.", description: "Medium Rare.",
kind: Consumable( kind: Consumable(
kind: "BeastSmallCooked", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Raw Meat Sliver", name: "Raw Meat Sliver",
description: "Small hunk of beastly animal meat, best after cooking.", description: "Small hunk of beastly animal meat, best after cooking.",
kind: Consumable( kind: Consumable(
kind: "BeastSmallRaw", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Cooked Bird Meat", name: "Cooked Bird Meat",
description: "Best enjoyed with one in each hand.", description: "Best enjoyed with one in each hand.",
kind: Consumable( kind: Consumable(
kind: "BirdCooked", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Huge Cooked Drumstick", name: "Huge Cooked Drumstick",
description: "Makes for a legendary meal.", description: "Makes for a legendary meal.",
kind: Consumable( kind: Consumable(
kind: "BirdLargeCooked", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Huge Raw Drumstick", name: "Huge Raw Drumstick",
description: "It's magificent.", description: "It's magificent.",
kind: Consumable( kind: Consumable(
kind: "BirdLargeRaw", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Raw Bird Meat", name: "Raw Bird Meat",
description: "A hefty drumstick.", description: "A hefty drumstick.",
kind: Consumable( kind: Consumable(
kind: "BirdRaw", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Cooked Fish", name: "Cooked Fish",
description: "A fresh cooked seafood steak.", description: "A fresh cooked seafood steak.",
kind: Consumable( kind: Consumable(
kind: "FishCooked", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Raw Fish", name: "Raw Fish",
description: "A steak chopped from a fish, best after cooking.", description: "A steak chopped from a fish, best after cooking.",
kind: Consumable( kind: Consumable(
kind: "FishRaw", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Cooked Tough Meat", name: "Cooked Tough Meat",
description: "Tastes exotic.", description: "Tastes exotic.",
kind: Consumable( kind: Consumable(
kind: "ToughCooked", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Raw Tough Meat", name: "Raw Tough Meat",
description: "Peculiar bit of meat, best after cooking.", description: "Peculiar bit of meat, best after cooking.",
kind: Consumable( kind: Consumable(
kind: "ToughRaw", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Mushroom", name: "Mushroom",
description: "Hopefully this one is not poisonous", description: "Hopefully this one is not poisonous",
kind: Consumable( kind: Consumable(
kind: "Mushroom", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Mushroom Stick", name: "Mushroom Stick",
description: "Roasted mushrooms on a stick for easy carrying", description: "Roasted mushrooms on a stick for easy carrying",
kind: Consumable( kind: Consumable(
kind: "MushroomStick", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Onion", name: "Onion",
description: "A vegetable that's made the toughest men cry.", description: "A vegetable that's made the toughest men cry.",
kind: Consumable( kind: Consumable(
kind: "Onion", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Plain Salad", name: "Plain Salad",
description: "Literally just chopped lettuce. Does this even count as a salad?", description: "Literally just chopped lettuce. Does this even count as a salad?",
kind: Consumable( kind: Consumable(
kind: "PlainSalad", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Sage", name: "Sage",
description: "A herb commonly used in tea.", description: "A herb commonly used in tea.",
kind: Consumable( kind: Consumable(
kind: "Sage", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Sunflower Ice Tea", name: "Sunflower Ice Tea",
description: "Brewed from freshly shelled sunflower seeds", description: "Brewed from freshly shelled sunflower seeds",
kind: Consumable( kind: Consumable(
kind: "SunflowerTea", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Tomato", name: "Tomato",
description: "A red fruit. Not actually a vegetable.", description: "A red fruit. Not actually a vegetable.",
kind: Consumable( kind: Consumable(
kind: "Tomato", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2,7 +2,7 @@ ItemDef(
name: "Tomato Salad", name: "Tomato Salad",
description: "Leafy salad with some chopped, juicy tomatoes mixed in.", description: "Leafy salad with some chopped, juicy tomatoes mixed in.",
kind: Consumable( kind: Consumable(
kind: "TomatoSalad", kind: Food,
effect: [ effect: [
Buff(( Buff((
kind: Saturation, kind: Saturation,

View File

@ -2235,40 +2235,36 @@
"element.items.item_bag_blue", "element.items.item_bag_blue",
), ),
// Consumables // Consumables
Consumable("Apple"): Png( Consumable("common.items.food.apple"): Png(
"element.items.item_apple", "element.items.item_apple",
), ),
Consumable("Coconut"): Png( Consumable("common.items.food.coconut"): Png(
"element.items.item_coconut", "element.items.item_coconut",
), ),
Consumable("CactusColada"): VoxTrans( Consumable("common.items.food.cactus_colada"): VoxTrans(
"voxel.object.cactus_drink", "voxel.object.cactus_drink",
(-1.0, 1.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (-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", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.7, (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", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.5, (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", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9,
), ),
Ingredient("PotionExp"): VoxTrans( Consumable("common.items.boss_drops.potions"): VoxTrans(
"voxel.object.potion_turq", "voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (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", "element.items.item_cheese",
), ),
Consumable("Potion"): VoxTrans( Consumable("common.items.food.mushroom"): VoxTrans(
"voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.0,
),
Consumable("Mushroom"): VoxTrans(
"voxel.sprite.mushrooms.mushroom-10", "voxel.sprite.mushrooms.mushroom-10",
(0.0, 0.0, 0.0), (-50.0, 70.0, 40.0), 1.0, (0.0, 0.0, 0.0), (-50.0, 70.0, 40.0), 1.0,
), ),
@ -2280,83 +2276,83 @@
"voxel.sprite.velorite.velorite_1", "voxel.sprite.velorite.velorite_1",
(0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8, (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", "element.items.item_apple_curry",
), ),
Consumable("AppleStick"): Png( Consumable("common.items.food.apple_stick"): Png(
"element.items.item_apple_stick", "element.items.item_apple_stick",
), ),
Consumable("MushroomStick"): Png( Consumable("common.items.food.mushroom_stick"): Png(
"element.items.item_shroom_stick", "element.items.item_shroom_stick",
), ),
Consumable("SunflowerTea"): Png( Consumable("common.items.food.sunflower_icetea"): Png(
"element.items.item_sunflower_tea", "element.items.item_sunflower_tea",
), ),
Consumable("Carrot"): VoxTrans( Consumable("common.items.food.carrot"): VoxTrans(
"voxel.sprite.carrot.carrot", "voxel.sprite.carrot.carrot",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.tomato.tomato",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (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", "voxel.sprite.cabbage.cabbage",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (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", "voxel.sprite.food.meat.fish_raw",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.food.meat.fish_cooked",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.food.meat.bird_raw",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.food.meat.bird_cooked",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.food.meat.bird_large_raw",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.food.meat.bird_large_cooked",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9, (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", "voxel.sprite.food.meat.beast_small_raw",
(0.0, 0.0, 0.0), (-50.0, 10.0, 0.0), 1.0, (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", "voxel.sprite.food.meat.beast_small_cooked",
(0.0, 0.0, 0.0), (-50.0, 20.0, 0.0), 1.0, (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", "voxel.sprite.food.meat.tough_raw",
(0.0, 0.0, 0.0), (-50.0, 10.0, 0.0), 1.0, (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", "voxel.sprite.food.meat.tough_cooked",
(0.0, 0.0, 0.0), (-50.0, 20.0, 0.0), 1.0, (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", "voxel.sprite.food.meat.beast_large_raw",
(-1.0, 0.0, 0.0), (-80.0, 40.0, 0.0), 0.8, (-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", "voxel.sprite.food.meat.beast_large_cooked",
(-1.0, 0.0, 0.0), (-80.0, 40.0, 0.0), 0.8, (-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", "voxel.sprite.food.salad_plain",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (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", "voxel.sprite.food.salad_tomato",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
), ),

View File

@ -339,7 +339,7 @@ impl CharacterAbility {
match self { match self {
CharacterAbility::Roll { energy_cost, .. } => { CharacterAbility::Roll { energy_cost, .. } => {
data.physics.on_ground.is_some() data.physics.on_ground.is_some()
&& data.vel.0.xy().magnitude_squared() > 0.5 && data.inputs.move_dir.magnitude_squared() > 0.25
&& update && update
.energy .energy
.try_change_by(-(*energy_cost as i32), EnergySource::Ability) .try_change_by(-(*energy_cost as i32), EnergySource::Ability)

View File

@ -105,6 +105,8 @@ pub enum CharacterState {
SelfBuff(self_buff::Data), SelfBuff(self_buff::Data),
/// Creates sprites around the caster /// Creates sprites around the caster
SpriteSummon(sprite_summon::Data), SpriteSummon(sprite_summon::Data),
/// Handles logic for using an item so it is not simply instant
UseItem(use_item::Data),
} }
impl CharacterState { impl CharacterState {
@ -175,6 +177,7 @@ impl CharacterState {
| CharacterState::Shockwave(_) | CharacterState::Shockwave(_)
| CharacterState::BasicBeam(_) | CharacterState::BasicBeam(_)
| CharacterState::Stunned(_) | CharacterState::Stunned(_)
| CharacterState::UseItem(_)
| CharacterState::Wielding | CharacterState::Wielding
| CharacterState::Talk | CharacterState::Talk
| CharacterState::HealingBeam(_) | CharacterState::HealingBeam(_)

View File

@ -251,7 +251,7 @@ pub enum ItemKind {
Armor(armor::Armor), Armor(armor::Armor),
Glider(Glider), Glider(Glider),
Consumable { Consumable {
kind: String, kind: ConsumableKind,
effect: Vec<Effect>, effect: Vec<Effect>,
}, },
Throwable { Throwable {
@ -270,6 +270,12 @@ pub enum ItemKind {
}, },
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ConsumableKind {
Potion,
Food,
}
impl ItemKind { impl ItemKind {
pub fn is_equippable(&self) -> bool { pub fn is_equippable(&self) -> bool {
matches!( matches!(

View File

@ -9,7 +9,10 @@ use vek::Vec3;
use crate::{ use crate::{
comp::{ comp::{
inventory::{ inventory::{
item::{tool::AbilityMap, ItemDef, ItemKind, MaterialStatManifest, TagExampleInfo}, item::{
tool::AbilityMap, ConsumableKind, ItemDef, ItemKind, MaterialStatManifest,
TagExampleInfo,
},
loadout::Loadout, loadout::Loadout,
slot::{EquipSlot, Slot, SlotError}, slot::{EquipSlot, Slot, SlotError},
}, },
@ -803,7 +806,7 @@ impl Component for Inventory {
pub enum InventoryUpdateEvent { pub enum InventoryUpdateEvent {
Init, Init,
Used, Used,
Consumed(String), Consumed(ConsumableKind),
Gave, Gave,
Given, Given,
Swapped, Swapped,

View File

@ -29,5 +29,6 @@ pub mod spin_melee;
pub mod sprite_summon; pub mod sprite_summon;
pub mod stunned; pub mod stunned;
pub mod talk; pub mod talk;
pub mod use_item;
pub mod utils; pub mod utils;
pub mod wielding; pub mod wielding;

View 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));
}
}

View File

@ -2,7 +2,7 @@ use crate::{
combat, combat,
comp::{ comp::{
biped_large, biped_small, biped_large, biped_small,
inventory::slot::EquipSlot, inventory::slot::{EquipSlot, Slot},
item::{Hands, ItemKind, Tool, ToolKind}, item::{Hands, ItemKind, Tool, ToolKind},
quadruped_low, quadruped_medium, quadruped_small, quadruped_low, quadruped_medium, quadruped_small,
skills::{Skill, SwimSkill}, skills::{Skill, SwimSkill},
@ -575,9 +575,45 @@ pub fn handle_manipulate_loadout(
update: &mut StateUpdate, update: &mut StateUpdate,
inv_action: InventoryAction, inv_action: InventoryAction,
) { ) {
update use use_item::ItemUseKind;
.server_events if let InventoryAction::Use(Slot::Inventory(inv_slot)) = inv_action {
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into())); // 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 /// 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)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum StageSection { pub enum StageSection {
Buildup, Buildup,
Swing,
Recover, Recover,
Charge, Charge,
Cast,
Shoot,
Movement, 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)] #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -165,6 +165,14 @@ impl<'a> System<'a> for Sys {
let was_wielded = char_state.get_unchecked().is_wield(); let was_wielded = char_state.get_unchecked().is_wield();
let poise_state = poise.poise_state(); let poise_state = poise.poise_state();
let pos = pos.0; 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 { match poise_state {
PoiseState::Normal => {}, PoiseState::Normal => {},
PoiseState::Interrupted => { PoiseState::Interrupted => {
@ -332,6 +340,7 @@ impl<'a> System<'a> for Sys {
CharacterState::BasicSummon(data) => data.handle_event(&j, action), CharacterState::BasicSummon(data) => data.handle_event(&j, action),
CharacterState::SelfBuff(data) => data.handle_event(&j, action), CharacterState::SelfBuff(data) => data.handle_event(&j, action),
CharacterState::SpriteSummon(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); local_emitter.append(&mut state_update.local_events);
server_emitter.append(&mut state_update.server_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::BasicSummon(data) => data.behavior(&j),
CharacterState::SelfBuff(data) => data.behavior(&j), CharacterState::SelfBuff(data) => data.behavior(&j),
CharacterState::SpriteSummon(data) => data.behavior(&j), CharacterState::SpriteSummon(data) => data.behavior(&j),
CharacterState::UseItem(data) => data.behavior(&j),
}; };
local_emitter.append(&mut state_update.local_events); local_emitter.append(&mut state_update.local_events);

View File

@ -289,7 +289,8 @@ impl<'a> System<'a> for Sys {
CharacterState::Roll { .. } CharacterState::Roll { .. }
| CharacterState::Climb { .. } | CharacterState::Climb { .. }
| CharacterState::Stunned { .. } | CharacterState::Stunned { .. }
| CharacterState::BasicBlock { .. } => {}, | CharacterState::BasicBlock { .. }
| CharacterState::UseItem { .. } => {},
} }
} }

View File

@ -287,7 +287,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
match item.kind() { match item.kind() {
ItemKind::Consumable { kind, effect, .. } => { ItemKind::Consumable { kind, effect, .. } => {
maybe_effect = Some(effect.clone()); maybe_effect = Some(effect.clone());
Some(comp::InventoryUpdateEvent::Consumed(kind.clone())) Some(comp::InventoryUpdateEvent::Consumed(*kind))
}, },
ItemKind::Throwable { kind, .. } => { ItemKind::Throwable { kind, .. } => {
if let Some(pos) = if let Some(pos) =

View 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
}
}

View File

@ -4,6 +4,7 @@ pub mod beta;
pub mod block; pub mod block;
pub mod chargeswing; pub mod chargeswing;
pub mod climb; pub mod climb;
pub mod consume;
pub mod dance; pub mod dance;
pub mod dash; pub mod dash;
pub mod equip; pub mod equip;
@ -32,14 +33,14 @@ pub mod wield;
// Reexports // Reexports
pub use self::{ pub use self::{
alpha::AlphaAnimation, beam::BeamAnimation, beta::BetaAnimation, block::BlockAnimation, alpha::AlphaAnimation, beam::BeamAnimation, beta::BetaAnimation, block::BlockAnimation,
chargeswing::ChargeswingAnimation, climb::ClimbAnimation, dance::DanceAnimation, chargeswing::ChargeswingAnimation, climb::ClimbAnimation, consume::ConsumeAnimation,
dash::DashAnimation, equip::EquipAnimation, glidewield::GlideWieldAnimation, dance::DanceAnimation, dash::DashAnimation, equip::EquipAnimation,
gliding::GlidingAnimation, idle::IdleAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, glidewield::GlideWieldAnimation, gliding::GlidingAnimation, idle::IdleAnimation,
repeater::RepeaterAnimation, roll::RollAnimation, run::RunAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, repeater::RepeaterAnimation,
shockwave::ShockwaveAnimation, shoot::ShootAnimation, sit::SitAnimation, sneak::SneakAnimation, roll::RollAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
spin::SpinAnimation, spinmelee::SpinMeleeAnimation, staggered::StaggeredAnimation, sit::SitAnimation, sneak::SneakAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation,
stand::StandAnimation, stunned::StunnedAnimation, swim::SwimAnimation, staggered::StaggeredAnimation, stand::StandAnimation, stunned::StunnedAnimation,
swimwield::SwimWieldAnimation, talk::TalkAnimation, wield::WieldAnimation, swim::SwimAnimation, swimwield::SwimWieldAnimation, talk::TalkAnimation, wield::WieldAnimation,
}; };
use super::{make_bone, vek::*, FigureBoneData, Skeleton}; use super::{make_bone, vek::*, FigureBoneData, Skeleton};
use common::comp; use common::comp;

View File

@ -92,7 +92,7 @@ use common::{
assets::{self, AssetExt, AssetHandle}, assets::{self, AssetExt, AssetHandle},
comp::{ comp::{
beam, biped_large, biped_small, humanoid, beam, biped_large, biped_small, humanoid,
item::{ItemKind, ToolKind}, item::{ConsumableKind, ItemKind, ToolKind},
object, object,
poise::PoiseState, poise::PoiseState,
quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType, quadruped_low, quadruped_medium, quadruped_small, Body, CharacterAbilityType,
@ -276,7 +276,7 @@ pub enum SfxInventoryEvent {
CollectedTool(ToolKind), CollectedTool(ToolKind),
CollectedItem(String), CollectedItem(String),
CollectFailed, CollectFailed,
Consumed(String), Consumed(ConsumableKind),
Debug, Debug,
Dropped, Dropped,
Given, Given,
@ -308,7 +308,7 @@ impl From<&InventoryUpdateEvent> for SfxEvent {
SfxEvent::Inventory(SfxInventoryEvent::CollectFailed) SfxEvent::Inventory(SfxInventoryEvent::CollectFailed)
}, },
InventoryUpdateEvent::Consumed(consumable) => { InventoryUpdateEvent::Consumed(consumable) => {
SfxEvent::Inventory(SfxInventoryEvent::Consumed(consumable.clone())) SfxEvent::Inventory(SfxInventoryEvent::Consumed(*consumable))
}, },
InventoryUpdateEvent::Debug => SfxEvent::Inventory(SfxInventoryEvent::Debug), InventoryUpdateEvent::Debug => SfxEvent::Inventory(SfxInventoryEvent::Debug),
InventoryUpdateEvent::Dropped => SfxEvent::Inventory(SfxInventoryEvent::Dropped), InventoryUpdateEvent::Dropped => SfxEvent::Inventory(SfxInventoryEvent::Dropped),

View File

@ -49,7 +49,7 @@ impl<T: ItemDesc> From<&T> for ItemKey {
ItemKind::Glider(Glider { kind, .. }) => ItemKey::Glider(kind.clone()), ItemKind::Glider(Glider { kind, .. }) => ItemKey::Glider(kind.clone()),
ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()), ItemKind::Armor(Armor { kind, .. }) => ItemKey::Armor(kind.clone()),
ItemKind::Utility { kind, .. } => ItemKey::Utility(*kind), 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::Throwable { kind, .. } => ItemKey::Throwable(*kind),
ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()), ItemKind::Ingredient { kind, .. } => ItemKey::Ingredient(kind.clone()),
ItemKind::TagExamples { item_ids } => ItemKey::TagExamples( ItemKind::TagExamples { item_ids } => ItemKey::TagExamples(

View File

@ -1422,6 +1422,27 @@ impl FigureMgr {
skeleton_attr, 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 { .. } => { CharacterState::Equipping { .. } => {
anim::character::EquipAnimation::update_skeleton( anim::character::EquipAnimation::update_skeleton(
&target_base, &target_base,