Add sprite_behavior_manifest, and make a few more kinds of sprites collectable. Also fix certain crops not appearing properly in farms.

This commit is contained in:
Avi Weinstock 2021-04-12 21:12:36 -04:00 committed by Monty
parent 695ffa96b9
commit 16df594eab
21 changed files with 385 additions and 161 deletions

View File

@ -0,0 +1,9 @@
ItemDef(
name: "Flax",
description: "A stalk of flax.",
kind: Ingredient(
kind: "Flax",
),
quality: Common,
tags: [],
)

View File

@ -0,0 +1,9 @@
ItemDef(
name: "Wheat",
description: "A stalk of wheat.",
kind: Ingredient(
kind: "Wheat",
),
quality: Common,
tags: [],
)

View File

@ -0,0 +1,22 @@
ItemDef(
name: "Blueberries",
description: "Some blueberries.",
kind: Consumable(
kind: "Blueberries",
effect: [
Buff((
kind: Saturation,
data: (
strength: 5.0,
duration: Some((
secs: 10,
nanos: 0,
)),
),
cat_ids: [Natural],
)),
]
),
quality: Common,
tags: [Food],
)

View File

@ -0,0 +1,22 @@
ItemDef(
name: "Corn",
description: "An ear of corn.",
kind: Consumable(
kind: "Corn",
effect: [
Buff((
kind: Saturation,
data: (
strength: 5.0,
duration: Some((
secs: 10,
nanos: 0,
)),
),
cat_ids: [Natural],
)),
]
),
quality: Common,
tags: [Food],
)

View File

@ -0,0 +1,22 @@
ItemDef(
name: "Pumpkin",
description: "A pumpkin.",
kind: Consumable(
kind: "Pumpkin",
effect: [
Buff((
kind: Saturation,
data: (
strength: 5.0,
duration: Some((
secs: 10,
nanos: 0,
)),
),
cat_ids: [Natural],
)),
]
),
quality: Common,
tags: [Food],
)

View File

@ -0,0 +1,22 @@
ItemDef(
name: "Radish",
description: "A radish.",
kind: Consumable(
kind: "Radish",
effect: [
Buff((
kind: Saturation,
data: (
strength: 5.0,
duration: Some((
secs: 10,
nanos: 0,
)),
),
cat_ids: [Natural],
)),
]
),
quality: Common,
tags: [Food],
)

View File

@ -0,0 +1,22 @@
ItemDef(
name: "Turnip",
description: "A turnip.",
kind: Consumable(
kind: "Turnip",
effect: [
Buff((
kind: Saturation,
data: (
strength: 5.0,
duration: Some((
secs: 10,
nanos: 0,
)),
),
cat_ids: [Natural],
)),
]
),
quality: Common,
tags: [Food],
)

View File

@ -0,0 +1,119 @@
SpriteBehaviorManifest(
solid_height: {
// Beware: the height *must* be <= `MAX_HEIGHT` or the collision system will not
// properly detect it!
Tomato: 1.65,
LargeCactus: 2.5,
Scarecrow: 3.0,
Turnip: 0.36,
Pumpkin: 0.81,
Cabbage: 0.45,
Chest: 1.09,
StreetLamp: 2.65,
Carrot: 0.18,
Radish: 0.18,
FireBowlGround: 0.55,
// TODO: Uncomment this when we have a way to open doors
// Door: 3.0,
Bed: 1.54,
Bench: 0.5,
ChairSingle: 0.5,
ChairDouble: 0.5,
CoatRack: 2.36,
Crate: 0.90,
DrawerSmall: 1.0,
DrawerMedium: 2.0,
DrawerLarge: 2.0,
DungeonWallDecor: 1.0,
Planter: 1.09,
TableSide: 1.27,
TableDining: 1.45,
TableDouble: 1.45,
WardrobeSingle: 3.0,
WardrobeDouble: 3.0,
Pot: 0.90,
Mud: 0.36,
ChestBuried: 0.91,
StonyCoral: 1.4,
// TODO: Find suitable heights.
BarrelCactus: 1.0,
RoundCactus: 1.0,
ShortCactus: 1.0,
MedFlatCactus: 1.0,
ShortFlatCactus: 1.0,
Apple: 1.0,
Velorite: 1.0,
VeloriteFrag: 1.0,
Coconut: 1.0,
StreetLampTall: 1.0,
Window1: 1.0,
Window2: 1.0,
Window3: 1.0,
Window4: 1.0,
DropGate: 1.0,
// TODO: Figure out if this should be solid or not.
Shelf: 1.0,
Lantern: 0.9,
CraftingBench: 1.18,
Forge: 2.7,
Cauldron: 1.27,
Anvil: 1.1,
CookingPot: 1.36,
},
collectible_id: {
Apple: Item("common.items.food.apple"),
Mushroom: Item("common.items.food.mushroom"),
CaveMushroom: Item("common.items.food.mushroom"),
Velorite: Item("common.items.ore.velorite"),
VeloriteFrag: Item("common.items.ore.veloritefrag"),
//BlueFlower: Item("common.items.flowers.blue"),
//PinkFlower: Item("common.items.flowers.pink"),
//PurpleFlower: Item("common.items.flowers.purple"),
RedFlower: Item("common.items.flowers.red"),
//WhiteFlower: Item("common.items.flowers.white"),
//YellowFlower: Item("common.items.flowers.yellow"),
Sunflower: Item("common.items.flowers.sunflower"),
Tomato: Item("common.items.food.tomato"),
Cabbage: Item("common.items.food.lettuce"),
Carrot: Item("common.items.food.carrot"),
Corn: Item("common.items.food.corn"),
Garlic: Item("common.items.food.garlic"),
Onion: Item("common.items.food.onion"),
Turnip: Item("common.items.food.turnip"),
Radish: Item("common.items.food.radish"),
Blueberry: Item("common.items.food.blueberries"),
Pumpkin: Item("common.items.food.pumpkin"),
WheatYellow: Item("common.items.crafting_ing.wheat"),
WheatGreen: Item("common.items.crafting_ing.wheat"),
Flax: Item("common.items.crafting_ing.flax"),
//LongGrass: Item("common.items.grasses.long"),
//MediumGrass: Item("common.items.grasses.medium"),
//ShortGrass: Item("common.items.grasses.short"),
Coconut: Item("common.items.food.coconut"),
Beehive: Item("common.items.crafting_ing.honey"),
Stones: Item("common.items.crafting_ing.stones"),
Twigs: Item("common.items.crafting_ing.twigs"),
VialEmpty: Item("common.items.crafting_ing.empty_vial"),
Bowl: Item("common.items.crafting_ing.bowl"),
PotionMinor: Item("common.items.consumable.potion_minor"),
Amethyst: Item("common.items.crafting_ing.amethyst"),
Ruby: Item("common.items.crafting_ing.ruby"),
Diamond: Item("common.items.crafting_ing.diamond"),
Sapphire: Item("common.items.crafting_ing.sapphire"),
Topaz: Item("common.items.crafting_ing.topaz"),
Emerald: Item("common.items.crafting_ing.emerald"),
AmethystSmall: Item("common.items.crafting_ing.amethyst"),
TopazSmall: Item("common.items.crafting_ing.topaz"),
DiamondSmall: Item("common.items.crafting_ing.diamond"),
RubySmall: Item("common.items.crafting_ing.ruby"),
EmeraldSmall: Item("common.items.crafting_ing.emerald"),
SapphireSmall: Item("common.items.crafting_ing.sapphire"),
Seashells: Item("common.items.crafting_ing.seashells"),
Chest: LootTable("common.loot_tables.sprite.chest"),
ChestBuried: LootTable("common.loot_tables.sprite.chest-buried"),
Mud: LootTable("common.loot_tables.sprite.mud"),
Crate: LootTable("common.loot_tables.sprite.crate"),
},
)

BIN
assets/voxygen/element/items/coconutmilk.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1856,6 +1856,42 @@
"voxel.sprite.cabbage.cabbage",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
Consumable("Corn"): VoxTrans(
"voxel.sprite.corn.corn-1",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.0,
),
Consumable("Garlic"): VoxTrans(
"voxel.sprite.food.garlic",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
Consumable("Onion"): VoxTrans(
"voxel.sprite.food.onion",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.2,
),
Consumable("Turnip"): VoxTrans(
"voxel.sprite.turnip.turnip-3",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.2,
),
Ingredient("Wheat"): VoxTrans(
"voxel.sprite.wheat_yellow.wheat-0",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.2,
),
Ingredient("Flax"): VoxTrans(
"voxel.sprite.flax.flax-0",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.2,
),
Consumable("Radish"): VoxTrans(
"voxel.sprite.radish.3",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
Consumable("Blueberry"): VoxTrans(
"voxel.sprite.blueberry.1",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
Consumable("Pumpkin"): VoxTrans(
"voxel.sprite.pumpkin.2",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
Consumable("Fish"): VoxTrans(
"voxel.sprite.food.meat_fish",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,

BIN
assets/voxygen/voxel/sprite/food/applepie_threequarters.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/sprite/food/applepie_whole.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/sprite/food/garlic.vox (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/voxel/sprite/food/onion.vox (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/voxel/sprite/food/pumpkinpie_whole.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -2852,6 +2852,26 @@ Lantern: Some((
],
wind_sway: 0.0,
)),
Garlic: Some((
variations: [
(
model: "voxygen.voxel.sprite.food.garlic",
offset: (-2.5, -2.5, -6.0),
lod_axes: (0.0, 0.0, 0.0),
),
],
wind_sway: 0.0,
)),
Onion: Some((
variations: [
(
model: "voxygen.voxel.sprite.food.onion",
offset: (-2.5, -2.5, -5.0),
lod_axes: (0.0, 0.0, 0.0),
),
],
wind_sway: 0.2,
)),
// Anvil
Anvil: Some((
variations: [

View File

@ -13,9 +13,8 @@ use crate::{
CharacterAbility,
},
effect::Effect,
lottery::{LootSpec, Lottery},
recipe::RecipeInput,
terrain::{Block, SpriteKind},
terrain::{Block, SPRITE_BEHAVIOR_MANIFEST},
};
use core::{
convert::TryFrom,
@ -703,66 +702,13 @@ impl Item {
pub fn slot_mut(&mut self, slot: usize) -> Option<&mut InvSlot> { self.slots.get_mut(slot) }
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
let chosen;
Some(Item::new_from_asset_expect(match block.get_sprite()? {
SpriteKind::Apple => "common.items.food.apple",
SpriteKind::Mushroom => "common.items.food.mushroom",
SpriteKind::CaveMushroom => "common.items.food.mushroom",
SpriteKind::Velorite => "common.items.ore.velorite",
SpriteKind::VeloriteFrag => "common.items.ore.veloritefrag",
SpriteKind::BlueFlower => "common.items.flowers.blue",
SpriteKind::PinkFlower => "common.items.flowers.pink",
SpriteKind::PurpleFlower => "common.items.flowers.purple",
SpriteKind::RedFlower => "common.items.flowers.red",
SpriteKind::WhiteFlower => "common.items.flowers.white",
SpriteKind::YellowFlower => "common.items.flowers.yellow",
SpriteKind::Sunflower => "common.items.flowers.sunflower",
SpriteKind::LongGrass => "common.items.grasses.long",
SpriteKind::MediumGrass => "common.items.grasses.medium",
SpriteKind::ShortGrass => "common.items.grasses.short",
SpriteKind::Coconut => "common.items.food.coconut",
// Containers
// IMPORTANT: Add any new container to `SpriteKind::is_container`
SpriteKind::Chest => {
chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.sprite.chest").read();
return Some(chosen.choose().to_item());
},
SpriteKind::ChestBuried => {
chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.sprite.chest-buried")
.read();
return Some(chosen.choose().to_item());
},
SpriteKind::Mud => {
chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.sprite.mud").read();
return Some(chosen.choose().to_item());
},
SpriteKind::Crate => {
chosen = Lottery::<LootSpec>::load_expect("common.loot_tables.sprite.crate").read();
return Some(chosen.choose().to_item());
},
SpriteKind::Beehive => "common.items.crafting_ing.honey",
SpriteKind::Stones => "common.items.crafting_ing.stones",
SpriteKind::Twigs => "common.items.crafting_ing.twigs",
SpriteKind::VialEmpty => "common.items.crafting_ing.empty_vial",
SpriteKind::Bowl => "common.items.crafting_ing.bowl",
SpriteKind::PotionMinor => "common.items.consumable.potion_minor",
SpriteKind::Amethyst => "common.items.crafting_ing.amethyst",
SpriteKind::Ruby => "common.items.crafting_ing.ruby",
SpriteKind::Diamond => "common.items.crafting_ing.diamond",
SpriteKind::Sapphire => "common.items.crafting_ing.sapphire",
SpriteKind::Topaz => "common.items.crafting_ing.topaz",
SpriteKind::Emerald => "common.items.crafting_ing.emerald",
SpriteKind::AmethystSmall => "common.items.crafting_ing.amethyst",
SpriteKind::TopazSmall => "common.items.crafting_ing.topaz",
SpriteKind::DiamondSmall => "common.items.crafting_ing.diamond",
SpriteKind::RubySmall => "common.items.crafting_ing.ruby",
SpriteKind::EmeraldSmall => "common.items.crafting_ing.emerald",
SpriteKind::SapphireSmall => "common.items.crafting_ing.sapphire",
SpriteKind::Seashells => "common.items.crafting_ing.seashells",
_ => return None,
}))
Some(
SPRITE_BEHAVIOR_MANIFEST
.read()
.collectible_id
.get(&block.get_sprite()?)?
.to_item(),
)
}
pub fn ability_spec(&self) -> Option<&AbilitySpec> { self.item_def.ability_spec.as_ref() }

View File

@ -12,7 +12,7 @@ pub use self::{
block::{Block, BlockKind},
map::MapSizeLg,
site::SitesKind,
sprite::SpriteKind,
sprite::{SpriteKind, SPRITE_BEHAVIOR_MANIFEST},
structure::{Structure, StructuresGroup},
};
use roots::find_roots_cubic;

View File

@ -1,4 +1,9 @@
use crate::{comp::tool::ToolKind, make_case_elim};
use crate::{
assets::{Asset, AssetExt, AssetHandle, RonLoader},
comp::tool::ToolKind,
lottery::LootSpec,
make_case_elim,
};
use enum_iterator::IntoEnumIterator;
use hashbrown::HashMap;
use lazy_static::lazy_static;
@ -148,113 +153,51 @@ make_case_elim!(
Cauldron = 0x79,
Anvil = 0x7A,
CookingPot = 0x7B,
Garlic = 0x7C,
Onion = 0x7D,
}
);
#[derive(Debug, Deserialize)]
pub struct SpriteBehaviorManifest {
pub solid_height: HashMap<SpriteKind, f32>,
pub collectible_id: HashMap<SpriteKind, LootSpec>,
}
impl Asset for SpriteBehaviorManifest {
type Loader = RonLoader;
const EXTENSION: &'static str = "ron";
}
lazy_static! {
pub static ref SPRITE_BEHAVIOR_MANIFEST: AssetHandle<SpriteBehaviorManifest> =
AssetExt::load_expect("common.sprite_behavior_manifest");
}
impl SpriteKind {
pub fn solid_height(&self) -> Option<f32> {
// Beware: the height *must* be <= `MAX_HEIGHT` or the collision system will not
// properly detect it!
Some(match self {
SpriteKind::Tomato => 1.65,
SpriteKind::LargeCactus => 2.5,
SpriteKind::Scarecrow => 3.0,
SpriteKind::Turnip => 0.36,
SpriteKind::Pumpkin => 0.81,
SpriteKind::Cabbage => 0.45,
SpriteKind::Chest => 1.09,
SpriteKind::StreetLamp => 2.65,
SpriteKind::Carrot => 0.18,
SpriteKind::Radish => 0.18,
SpriteKind::FireBowlGround => 0.55,
// TODO: Uncomment this when we have a way to open doors
// SpriteKind::Door => 3.0,
SpriteKind::Bed => 1.54,
SpriteKind::Bench => 0.5,
SpriteKind::ChairSingle => 0.5,
SpriteKind::ChairDouble => 0.5,
SpriteKind::CoatRack => 2.36,
SpriteKind::Crate => 0.90,
SpriteKind::DrawerSmall => 1.0,
SpriteKind::DrawerMedium => 2.0,
SpriteKind::DrawerLarge => 2.0,
SpriteKind::DungeonWallDecor => 1.0,
SpriteKind::Planter => 1.09,
SpriteKind::TableSide => 1.27,
SpriteKind::TableDining => 1.45,
SpriteKind::TableDouble => 1.45,
SpriteKind::WardrobeSingle => 3.0,
SpriteKind::WardrobeDouble => 3.0,
SpriteKind::Pot => 0.90,
SpriteKind::Mud => 0.36,
SpriteKind::ChestBuried => 0.91,
SpriteKind::StonyCoral => 1.4,
SpriteKind::CraftingBench => 1.18,
SpriteKind::Forge => 2.7,
SpriteKind::Cauldron => 1.27,
SpriteKind::Anvil => 1.1,
SpriteKind::CookingPot => 1.36,
// TODO: Find suitable heights.
SpriteKind::BarrelCactus
| SpriteKind::RoundCactus
| SpriteKind::ShortCactus
| SpriteKind::MedFlatCactus
| SpriteKind::ShortFlatCactus
| SpriteKind::Apple
| SpriteKind::Velorite
| SpriteKind::VeloriteFrag
| SpriteKind::Coconut
| SpriteKind::StreetLampTall
| SpriteKind::Window1
| SpriteKind::Window2
| SpriteKind::Window3
| SpriteKind::Window4
| SpriteKind::DropGate => 1.0,
// TODO: Figure out if this should be solid or not.
SpriteKind::Shelf => 1.0,
SpriteKind::Lantern => 0.9,
_ => return None,
})
SPRITE_BEHAVIOR_MANIFEST
.read()
.solid_height
.get(self)
.copied()
}
pub fn is_collectible(&self) -> bool {
match self {
SpriteKind::BlueFlower => false,
SpriteKind::PinkFlower => false,
SpriteKind::PurpleFlower => false,
SpriteKind::RedFlower => true,
SpriteKind::WhiteFlower => false,
SpriteKind::YellowFlower => false,
SpriteKind::Sunflower => true,
SpriteKind::LongGrass => false,
SpriteKind::MediumGrass => false,
SpriteKind::ShortGrass => false,
SpriteKind::Apple => true,
SpriteKind::Mushroom => true,
SpriteKind::CaveMushroom => true,
// SpriteKind::Velorite => true,
// SpriteKind::VeloriteFrag => true,
SpriteKind::Chest => true,
SpriteKind::Coconut => true,
SpriteKind::Stones => true,
SpriteKind::Twigs => true,
SpriteKind::Crate => true,
SpriteKind::Beehive => true,
SpriteKind::VialEmpty => true,
SpriteKind::PotionMinor => true,
SpriteKind::Bowl => true,
SpriteKind::ChestBuried => true,
SpriteKind::Mud => true,
SpriteKind::Seashells => true,
_ => false,
}
SPRITE_BEHAVIOR_MANIFEST
.read()
.collectible_id
.get(self)
.is_some()
&& !self.mine_tool().is_some()
}
/// Is the sprite a container that will emit a mystery item?
pub fn is_container(&self) -> bool {
matches!(
self,
SpriteKind::Chest | SpriteKind::ChestBuried | SpriteKind::Mud | SpriteKind::Crate,
SPRITE_BEHAVIOR_MANIFEST.read().collectible_id.get(self),
Some(LootSpec::LootTable(_)),
)
}

View File

@ -509,7 +509,7 @@ impl Settlement {
let field = self.land.new_plot(Plot::Field {
farm,
seed: rng.gen(),
crop: match rng.gen_range(0..8) {
crop: match rng.gen_range(0..=11) {
0 => Crop::Corn,
1 => Crop::Wheat,
2 => Crop::Cabbage,
@ -518,7 +518,10 @@ impl Settlement {
5 => Crop::Carrot,
6 => Crop::Tomato,
7 => Crop::Radish,
_ => Crop::Sunflower,
8 => Crop::Turnip,
9 => Crop::Sunflower,
10 => Crop::Garlic,
_ => Crop::Onion,
},
});
let tiles =
@ -698,7 +701,13 @@ impl Settlement {
Crop::Tomato if roll(6, 2) == 0 => Some(SpriteKind::Tomato),
Crop::Radish if roll(7, 2) == 0 => Some(SpriteKind::Radish),
Crop::Turnip if roll(8, 2) == 0 => Some(SpriteKind::Turnip),
Crop::Sunflower => Some(SpriteKind::Sunflower),
Crop::Sunflower if roll(9, 2) == 0 => {
Some(SpriteKind::Sunflower)
},
Crop::Garlic if roll(10, 2) == 0 => {
Some(SpriteKind::Garlic)
},
Crop::Onion if roll(11, 2) == 0 => Some(SpriteKind::Onion),
_ => surface_sprite,
}
.or_else(|| {
@ -1055,6 +1064,8 @@ pub enum Crop {
Radish,
Turnip,
Sunflower,
Garlic,
Onion,
}
// NOTE: No support for struct variants in make_case_elim yet, unfortunately, so