Merge branch 'pfau_zest/crafting' into 'master'

Crafting

See merge request veloren/veloren!1183
This commit is contained in:
Monty Marz 2020-07-14 20:11:39 +00:00
commit c0d7ff6951
122 changed files with 1406 additions and 129 deletions

View File

@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added spin attack for axe
- Creature specific stats
- Minimap compass
- Initial crafting system implementation
### Changed

View File

@ -2,11 +2,10 @@ Item(
name: "Large Potion",
description: "Restores 100 Health\n\n<Right-Click to use>",
kind: Consumable(
kind: PotionMinor,
kind: PotionLarge,
effect: Health((
amount: 100,
cause: Item,
)),
,
),
)

View File

@ -2,7 +2,7 @@ Item(
name: "Medium Potion",
description: "Restores 70 Health\n\n<Right-Click to use>",
kind: Consumable(
kind: PotionMinor,
kind: PotionMed,
effect: Health((
amount: 70,
cause: Item,

View File

@ -0,0 +1,7 @@
Item(
name: "Empty Vial",
description: "Can be filled with fluids.",
kind: Ingredient(
kind: EmptyVial,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Leather Scraps",
description: "Used to craft various items.",
kind: Ingredient(
kind: LeatherScraps,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Shiny Gem",
description: "It's so shiny!",
kind: Ingredient(
kind: ShinyGem,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Stones",
description: "Pebbles from the ground.",
kind: Ingredient(
kind: Stones,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Twigs",
description: "Dry.",
kind: Ingredient(
kind: Twigs,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Craftsman Hammer",
description: "Used to craft various items.",
kind: Ingredient(
kind: CraftsmanHammer,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Mortar and Pestle",
description: "Crushes and grinds things into\na fine powder or paste.\nUsed to craft various items.",
kind: Ingredient(
kind: MortarPestle,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Empty Vial",
description: "Can be filled with fluids.",
kind: Ingredient(
kind: EmptyVial,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Leather Scraps",
description: "Used to craft various items.",
kind: Ingredient(
kind: LeatherScraps,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Shiny Gem",
description: "It's so shiny!",
kind: Ingredient(
kind: ShinyGem,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Stones",
description: "Pebbles from the ground.",
kind: Ingredient(
kind: Stones,
)
)

View File

@ -0,0 +1,7 @@
Item(
name: "Twigs",
description: "Dry.",
kind: Ingredient(
kind: Twigs,
)
)

View File

@ -0,0 +1,11 @@
Item(
name: "Mushroom Curry",
description: "Restores 120 Health\n\nWho could say no to that?\n\n<Right-Click to use>",
kind: Consumable(
kind: AppleShroomCurry,
effect: Health((
amount: 120,
cause: Item,
)),
),
)

View File

@ -0,0 +1,11 @@
Item(
name: "Apple Stick",
description: "Restores 60 Health\n\n<Right-Click to use>",
kind: Consumable(
kind: AppleStick,
effect: Health((
amount: 60,
cause: Item,
)),
),
)

View File

@ -0,0 +1,11 @@
Item(
name: "Mushroom Stick",
description: "Restores 50 Health\n\n<Right-Click to use>",
kind: Consumable(
kind: MushroomStick,
effect: Health((
amount: 50,
cause: Item,
)),
),
)

View File

@ -1,18 +1,23 @@
[
// All loot rates go here
// food
(3, "common.items.cheese"),
(3, "common.items.apple"),
(3, "common.items.mushroom"),
(3, "common.items.food.cheese"),
(3, "common.items.food.apple"),
(3, "common.items.food.mushroom"),
(1, "common.items.food.coconut"),
// miscellaneous
(0.4, "common.items.velorite"),
(0.6, "common.items.veloritefrag"),
(0.6, "common.items.cheese"),
(0.6, "common.items.apple"),
(1.5, "common.items.potion_minor"),
(0.5, "common.items.collar"),
(0.5, "common.items.bomb_pile"),
(1, "common.items.bomb"),
(0.4, "common.items.ore.velorite"),
(0.6, "common.items.ore.veloritefrag"),
(0.1, "common.items.consumable.potion_minor"),
(0.01, "common.items.utility.collar"),
(0.01, "common.items.utility.bomb_pile"),
(0.1, "common.items.utility.bomb"),
// crafting ingredients
(0.5, "common.items.crafting_ing.shiny_gem"),
(2, "common.items.crafting_ing.leather_scraps"),
(1, "common.items.crafting_ing.empty_vial"),
(2, "common.items.crafting_ing.stones"),
(3, "common.items.crafting_ing.twigs"),
// swords
(0.1, "common.items.weapons.sword.starter_sword"),
(0.1, "common.items.weapons.sword.wood_sword"),

View File

@ -0,0 +1,12 @@
{
"crafting_hammer": (("common.items.crafting_tools.craftsman_hammer", 1),[("common.items.crafting_ing.twigs", 10), ("common.items.crafting_ing.stones", 10)]),
"mortar_pestle": (("common.items.crafting_tools.mortar_pestle", 1), [("common.items.crafting_ing.stones", 6), ("common.items.food.coconut", 2), ("common.items.crafting_tools.craftsman_hammer", 0)]),
"velorite_frag": (("common.items.ore.veloritefrag", 2), [("common.items.ore.velorite", 1), ("common.items.crafting_tools.craftsman_hammer", 0)]),
"potion_s": (("common.items.consumable.potion_minor", 1), [("common.items.crafting_ing.empty_vial", 1), ("common.items.ore.veloritefrag", 2)]),
"potion_m": (("common.items.consumable.potion_med", 1), [("common.items.consumable.potion_minor", 2), ("common.items.ore.veloritefrag", 4)]),
"collar_basic": (("common.items.utility.collar", 1), [("common.items.crafting_ing.leather_scraps", 5), ("common.items.crafting_ing.shiny_gem", 1)]),
"bomb_coconut": (("common.items.utility.bomb", 1), [("common.items.crafting_ing.stones", 10), ("common.items.food.coconut", 2), ("common.items.ore.veloritefrag", 2), ("common.items.crafting_tools.mortar_pestle", 0)]),
"apple_shroom_curry": (("common.items.food.apple_mushroom_curry", 1), [("common.items.food.mushroom", 10), ("common.items.food.coconut", 1), ("common.items.food.apple", 5), ("common.items.crafting_tools.mortar_pestle", 0)]),
"apples_stick": (("common.items.food.apple_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.apple", 3)]),
"mushroom_stick": (("common.items.food.mushroom_stick", 1),[("common.items.crafting_ing.twigs", 1), ("common.items.food.mushroom", 5)]),
}

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 KiB

After

Width:  |  Height:  |  Size: 885 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 795 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -304,6 +304,8 @@ magischen Gegenstände ergattern?"#,
"hud.settings.audio_device": "Ausgabegerät",
"hud.settings.awaitingkey": "Drückt eine Taste...",
"hud.settings.unbound": "-",
"hud.settings.reset_keybinds": "Auf Standard zurücksetzen",
"hud.social": "Sozial",
"hud.social.online": "Online",
@ -314,6 +316,12 @@ magischen Gegenstände ergattern?"#,
"hud.spell": "Zauber",
"hud.crafting": "Herstellen",
"hud.crafting.recipes": "Rezepte",
"hud.crafting.ingredients": "Zutaten:",
"hud.crafting.craft": "Herstellen",
"hud.crafting.tool_cata": "Benötigt:",
"hud.free_look_indicator": "Freie Sicht aktiv",
"hud.auto_walk_indicator": "Automatisches Laufen aktiv",

View File

@ -118,8 +118,6 @@ Thanks for taking the time to read this notice, we hope you enjoy the game!
// Login process description
"main.login_process": r#"Information on the Login Process:
If you are having issues signing in:
Please note that you now need an account
to play on auth-enabled servers.
@ -313,7 +311,13 @@ magically infused items?"#,
"hud.social.faction": "Faction",
"hud.social.play_online_fmt": "{nb_player} player(s) online",
"hud.spell": "Spells",
"hud.crafting": "Crafting",
"hud.crafting.recipes": "Recipes",
"hud.crafting.ingredients": "Ingredients:",
"hud.crafting.craft": "Craft",
"hud.crafting.tool_cata": "Requires:",
"hud.spell": "Spells",
"hud.free_look_indicator": "Free look active",
"hud.auto_walk_indicator": "Auto walk active",

View File

@ -191,7 +191,7 @@
Tool(Hammer(BasicHammer)): VoxTrans(
"voxel.weapon.hammer.rusty_2h",
(2.0, -1.0, 0.0), (-135.0, 90.0, 0.0), 1.1,
),
),
// Staffs
Tool(Staff(BasicStaff)): VoxTrans(
"voxel.weapon.staff.wood-fire",
@ -743,24 +743,30 @@
),
// Consumables
Consumable(Apple):
VoxTrans(
Png(
"element.icons.item_apple",
(0.0, 0.0, 0.0), (-90.0, 90.0, 0.0), 1.0,
),
Consumable(Coconut): Png(
"element.icons.item_coconut",
),
Consumable(PotionMed): VoxTrans(
"voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.7,
),
Consumable(PotionMinor): VoxTrans(
"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.5,
),
Consumable(PotionLarge): VoxTrans(
"voxel.object.potion_red",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.9,
),
Consumable(PotionExp): VoxTrans(
"voxel.object.potion_turq",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
Consumable(Cheese): VoxTrans(
Consumable(Cheese): Png(
"element.icons.item_cheese",
(0.0, 0.0, 0.0), (-90.0, 90.0, 0.0), 0.9,
),
Consumable(Potion): VoxTrans(
"voxel.object.potion_red",
@ -776,18 +782,32 @@
),
Consumable(VeloriteFrag): VoxTrans(
"voxel.sprite.velorite.velorite_1",
(0.0, -1.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(
"element.icons.item_apple_curry",
),
Consumable(AppleStick): Png(
"element.icons.item_apple_stick",
),
Consumable(MushroomStick): Png(
"element.icons.item_shroom_stick",
),
// Throwables
Throwable(Bomb): VoxTrans(
"voxel.object.bomb",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
(0.0, 0.5, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Throwable(TrainingDummy): VoxTrans(
"voxel.object.training_dummy",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
// Ingredients
Ingredient(CraftsmanHammer): VoxTrans( //TODO This should be a 1h hammer!
"voxel.weapon.hammer.craftsman",
(1.0, 1.0, 0.0), (-135.0, 90.0, 0.0), 1.0,
),
Ingredient(Flower): VoxTrans(
"voxel.sprite.flowers.flower_red_2",
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
@ -796,6 +816,27 @@
"voxel.sprite.grass.grass_long_5",
(0.0, 0.0, 0.0), (-90.0, 50.0, 0.0), 1.0,
),
Ingredient(Stones): VoxTrans(
"voxel.sprite.rocks.rock-0",
(0.0, 0.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
),
Ingredient(Twigs): VoxTrans(
"voxel.sprite.twigs.twigs-0",
(0.0, 0.0, 0.0), (-20.0, 10.0, 20.0), 0.9,
),
Ingredient(LeatherScraps): Png(
"element.icons.item_leather0",
),
Ingredient(ShinyGem): Png(
"element.icons.gem",
),
Ingredient(MortarPestle): Png(
"element.icons.item_mortarpestlecoco",
),
Ingredient(EmptyVial): VoxTrans(
"voxel.object.potion_empty",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
// Debug Items
Tool(Debug(Boost)): VoxTrans(
"voxel.weapon.tool.broom_belzeshrub_purple",

View File

@ -176,6 +176,10 @@
vox_spec: ("weapon.hammer.rusty_2h", (-2.5, -5.5, -4.0)),
color: None
),
/*Dagger(Craftsman): ( //TODO This should be a 1h hammer!
vox_spec: ("weapon.hammer.craftsman", (-2.0, -5.0, -5.5)),
color: None
),*/
// Daggers
Dagger(BasicDagger): (
vox_spec: ("weapon.dagger.dagger_rusty", (-1.5, -3.0, -3.0)),

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
#![deny(unsafe_code)]
#![feature(label_break_value)]
#![feature(label_break_value, option_zip)]
pub mod cmd;
pub mod error;
@ -25,6 +25,7 @@ use common::{
PlayerInfo, PlayerListUpdate, RegisterError, RequestStateError, ServerInfo, ServerMsg,
MAX_BYTES_CHAT_MSG,
},
recipe::RecipeBook,
state::State,
sync::{Uid, UidAllocator, WorldSyncExt},
terrain::{block::Block, TerrainChunk, TerrainChunkSize},
@ -33,7 +34,7 @@ use common::{
use futures_executor::block_on;
use futures_timer::Delay;
use futures_util::{select, FutureExt};
use hashbrown::HashMap;
use hashbrown::{HashMap, HashSet};
use image::DynamicImage;
use network::{
Network, Participant, Pid, ProtocolAddr, Stream, PROMISES_CONSISTENCY, PROMISES_ORDERED,
@ -75,6 +76,8 @@ pub struct Client {
pub player_list: HashMap<Uid, PlayerInfo>,
pub character_list: CharacterList,
pub active_character_id: Option<i32>,
recipe_book: RecipeBook,
available_recipes: HashSet<String>,
_network: Network,
participant: Option<Participant>,
@ -123,7 +126,7 @@ impl Client {
let mut stream = block_on(participant.open(10, PROMISES_ORDERED | PROMISES_CONSISTENCY))?;
// Wait for initial sync
let (state, entity, server_info, world_map) = block_on(async {
let (state, entity, server_info, world_map, recipe_book) = block_on(async {
loop {
match stream.recv().await? {
ServerMsg::InitialSync {
@ -131,6 +134,7 @@ impl Client {
server_info,
time_of_day,
world_map: (map_size, world_map),
recipe_book,
} => {
// TODO: Display that versions don't match in Voxygen
if &server_info.git_hash != *common::util::GIT_HASH {
@ -174,7 +178,13 @@ impl Client {
);
debug!("Done preparing image...");
break Ok((state, entity, server_info, (world_map, map_size)));
break Ok((
state,
entity,
server_info,
(world_map, map_size),
recipe_book,
));
},
ServerMsg::TooManyPlayers => break Err(Error::TooManyPlayers),
err => {
@ -200,6 +210,8 @@ impl Client {
player_list: HashMap::new(),
character_list: CharacterList::default(),
active_character_id: None,
recipe_book,
available_recipes: HashSet::default(),
_network: network,
participant: Some(participant),
@ -372,6 +384,40 @@ impl Client {
}
}
pub fn recipe_book(&self) -> &RecipeBook { &self.recipe_book }
pub fn available_recipes(&self) -> &HashSet<String> { &self.available_recipes }
pub fn can_craft_recipe(&self, recipe: &str) -> bool {
self.recipe_book
.get(recipe)
.zip(self.inventories().get(self.entity))
.map(|(recipe, inv)| inv.contains_ingredients(&*recipe).is_ok())
.unwrap_or(false)
}
pub fn craft_recipe(&mut self, recipe: &str) -> bool {
if self.can_craft_recipe(recipe) {
self.singleton_stream
.send(ClientMsg::ControlEvent(ControlEvent::InventoryManip(
InventoryManip::CraftRecipe(recipe.to_string()),
)))
.unwrap();
true
} else {
false
}
}
fn update_available_recipes(&mut self) {
self.available_recipes = self
.recipe_book
.iter()
.map(|(name, _)| name.clone())
.filter(|name| self.can_craft_recipe(name))
.collect();
}
pub fn toggle_lantern(&mut self) {
self.singleton_stream
.send(ClientMsg::ControlEvent(ControlEvent::ToggleLantern))
@ -949,6 +995,8 @@ impl Client {
},
}
self.update_available_recipes();
frontend_events.push(Event::InventoryUpdated(event));
},
ServerMsg::TerrainChunkUpdate { key, chunk } => {

View File

@ -80,13 +80,14 @@ pub fn load_map<A: Asset + 'static, F: FnOnce(A) -> A>(
specifier: &str,
f: F,
) -> Result<Arc<A>, Error> {
let mut assets_write = ASSETS.write().unwrap();
let assets_write = ASSETS.read().unwrap();
match assets_write.get(specifier) {
Some(asset) => Ok(Arc::clone(asset).downcast()?),
None => {
drop(assets_write); // Drop the asset hashmap to permit recursive loading
let asset = Arc::new(f(A::parse(load_file(specifier, A::ENDINGS)?)?));
let clone = Arc::clone(&asset);
assets_write.insert(specifier.to_owned(), clone);
ASSETS.write().unwrap().insert(specifier.to_owned(), clone);
Ok(asset)
},
}

View File

@ -15,6 +15,7 @@ pub enum InventoryManip {
Use(Slot),
Swap(Slot, Slot),
Drop(Slot),
CraftRecipe(String),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -349,5 +349,14 @@ pub enum Armor {
Tabard(Tabard),
}
impl Armor {
/// Determines whether two pieces of armour are superficially equivalent to
/// one another (i.e: one may be substituted for the other in crafting
/// recipes or item possession checks).
pub fn superficially_eq(&self, other: &Self) -> bool {
std::mem::discriminant(self) == std::mem::discriminant(other)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Stats(pub u32);

View File

@ -26,7 +26,12 @@ pub enum Consumable {
Velorite,
VeloriteFrag,
PotionMinor,
PotionMed,
PotionLarge,
PotionExp,
AppleShroomCurry,
AppleStick,
MushroomStick,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
@ -44,6 +49,13 @@ pub enum Utility {
pub enum Ingredient {
Flower,
Grass,
EmptyVial,
LeatherScraps,
ShinyGem,
Stones,
Twigs,
MortarPestle,
CraftsmanHammer,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
@ -159,13 +171,25 @@ impl Item {
pub fn description(&self) -> &str { &self.description }
pub fn amount(&self) -> u32 {
match &self.kind {
ItemKind::Tool(_) => 1,
ItemKind::Lantern(_) => 1,
ItemKind::Armor { .. } => 1,
ItemKind::Consumable { amount, .. } => *amount,
ItemKind::Throwable { amount, .. } => *amount,
ItemKind::Utility { amount, .. } => *amount,
ItemKind::Ingredient { amount, .. } => *amount,
}
}
pub fn try_reclaim_from_block(block: Block) -> Option<Self> {
match block.kind() {
BlockKind::Apple => Some(assets::load_expect_cloned("common.items.apple")),
BlockKind::Mushroom => Some(assets::load_expect_cloned("common.items.mushroom")),
BlockKind::Velorite => Some(assets::load_expect_cloned("common.items.velorite")),
BlockKind::Apple => Some(assets::load_expect_cloned("common.items.food.apple")),
BlockKind::Mushroom => Some(assets::load_expect_cloned("common.items.food.mushroom")),
BlockKind::Velorite => Some(assets::load_expect_cloned("common.items.ore.velorite")),
BlockKind::VeloriteFrag => {
Some(assets::load_expect_cloned("common.items.veloritefrag"))
Some(assets::load_expect_cloned("common.items.ore.veloritefrag"))
},
BlockKind::BlueFlower => Some(assets::load_expect_cloned("common.items.flowers.blue")),
BlockKind::PinkFlower => Some(assets::load_expect_cloned("common.items.flowers.pink")),
@ -185,16 +209,44 @@ impl Item {
Some(assets::load_expect_cloned("common.items.grasses.medium"))
},
BlockKind::ShortGrass => Some(assets::load_expect_cloned("common.items.grasses.short")),
BlockKind::Coconut => Some(assets::load_expect_cloned("common.items.coconut")),
BlockKind::Coconut => Some(assets::load_expect_cloned("common.items.food.coconut")),
BlockKind::Chest => {
let chosen = assets::load_expect::<lottery::Lottery<_>>("common.loot_table");
let chosen = chosen.choose();
Some(assets::load_expect_cloned(chosen))
},
BlockKind::Stones => Some(assets::load_expect_cloned(
"common.items.crafting_ing.stones",
)),
BlockKind::Twigs => Some(assets::load_expect_cloned(
"common.items.crafting_ing.twigs",
)),
BlockKind::ShinyGem => Some(assets::load_expect_cloned(
"common.items.crafting_ing.shiny_gem",
)),
_ => None,
}
}
/// Determines whether two items are superficially equivalent to one another
/// (i.e: one may be substituted for the other in crafting recipes or
/// item possession checks).
pub fn superficially_eq(&self, other: &Self) -> bool {
match (&self.kind, &other.kind) {
(ItemKind::Tool(a), ItemKind::Tool(b)) => a.superficially_eq(b),
// TODO: Differentiate between lantern colors?
(ItemKind::Lantern(_), ItemKind::Lantern(_)) => true,
(ItemKind::Armor { kind: a, .. }, ItemKind::Armor { kind: b, .. }) => {
a.superficially_eq(b)
},
(ItemKind::Consumable { kind: a, .. }, ItemKind::Consumable { kind: b, .. }) => a == b,
(ItemKind::Throwable { kind: a, .. }, ItemKind::Throwable { kind: b, .. }) => a == b,
(ItemKind::Utility { kind: a, .. }, ItemKind::Utility { kind: b, .. }) => a == b,
(ItemKind::Ingredient { kind: a, .. }, ItemKind::Ingredient { kind: b, .. }) => a == b,
_ => false,
}
}
}
impl Component for Item {

Some files were not shown because too many files have changed in this diff Show More