Hardened loot table handling

- Rename LootSpec::None to LootSpec::Nothing to not confuse with Option
- Warn on invalid item paths in loot tables
This commit is contained in:
juliancoffee 2021-09-22 20:16:10 +03:00
parent 09dd9b4813
commit b056cccb0c
9 changed files with 31 additions and 21 deletions

View File

@ -4,5 +4,5 @@
// Food // Food
(1.0, LootTable("common.loot_tables.food.wild_ingredients")), (1.0, LootTable("common.loot_tables.food.wild_ingredients")),
// Nothing // Nothing
(2.0, None), (2.0, Nothing),
] ]

View File

@ -4,7 +4,7 @@
// Food // Food
(1.0, LootTable("common.loot_tables.food.wild_ingredients")), (1.0, LootTable("common.loot_tables.food.wild_ingredients")),
// Nothing // Nothing
(2.0, None), (2.0, Nothing),
// Placeholder Drop Location // Placeholder Drop Location
(1.0, Item("common.items.crafting_ing.sticky_thread")), (1.0, Item("common.items.crafting_ing.sticky_thread")),
] ]

View File

@ -4,5 +4,5 @@
// Food // Food
(1.0, LootTable("common.loot_tables.food.wild_ingredients")), (1.0, LootTable("common.loot_tables.food.wild_ingredients")),
// Nothing // Nothing
(2.0, None), (2.0, Nothing),
] ]

View File

@ -4,5 +4,5 @@
// Food // Food
(1.0, LootTable("common.loot_tables.food.prepared")), (1.0, LootTable("common.loot_tables.food.prepared")),
// Nothing // Nothing
(2.0, None), (2.0, Nothing),
] ]

View File

@ -4,5 +4,5 @@
// Food // Food
(1.0, LootTable("common.loot_tables.food.prepared")), (1.0, LootTable("common.loot_tables.food.prepared")),
// Nothing // Nothing
(2.0, None), (2.0, Nothing),
] ]

View File

@ -2,7 +2,7 @@
// Currency // Currency
(50.0, ItemQuantity("common.items.utility.coins", 50, 100)), (50.0, ItemQuantity("common.items.utility.coins", 50, 100)),
// Nothing // Nothing
(50.0, None), (50.0, Nothing),
// Special // Special
(1.0, Item("common.items.food.spore_corruption")), (1.0, Item("common.items.food.spore_corruption")),
] ]

View File

@ -1,4 +1,4 @@
[ [
// No loot is dropped // No loot is dropped
(1.0, None), (1.0, Nothing),
] ]

View File

@ -113,7 +113,7 @@ impl From<Vec<(f32, LootSpec<String>)>> for ProbabilityFile {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into_iter() .into_iter()
}, },
LootSpec::None => Vec::new().into_iter(), LootSpec::Nothing => Vec::new().into_iter(),
}) })
.collect(), .collect(),
} }

View File

@ -85,37 +85,47 @@ pub enum LootSpec<T: AsRef<str>> {
/// Loot table /// Loot table
LootTable(T), LootTable(T),
/// No loot given /// No loot given
None, Nothing,
} }
impl<T: AsRef<str>> LootSpec<T> { impl<T: AsRef<str>> LootSpec<T> {
pub fn to_item(&self) -> Option<Item> { pub fn to_item(&self) -> Option<Item> {
match self { match self {
Self::Item(item) => Item::new_from_asset(item.as_ref()).ok(), Self::Item(item) => Item::new_from_asset(item.as_ref()).map_or_else(
|e| {
warn!(?e, "Invalid item path");
None
},
|i| Some(i),
),
Self::ItemQuantity(item, lower, upper) => { Self::ItemQuantity(item, lower, upper) => {
let range = *lower..=*upper; let range = *lower..=*upper;
let quantity = thread_rng().gen_range(range); let quantity = thread_rng().gen_range(range);
if let Ok(mut item) = Item::new_from_asset(item.as_ref()) { match Item::new_from_asset(item.as_ref()) {
// TODO: Handle multiple of an item that is unstackable Ok(mut item) => {
if item.set_amount(quantity).is_err() { // TODO: Handle multiple of an item that is unstackable
warn!("Tried to set quantity on non stackable item"); if item.set_amount(quantity).is_err() {
} warn!("Tried to set quantity on non stackable item");
Some(item) }
} else { Some(item)
None },
Err(e) => {
warn!(?e, "Invalid item path");
None
},
} }
}, },
Self::LootTable(table) => Lottery::<LootSpec<String>>::load_expect(table.as_ref()) Self::LootTable(table) => Lottery::<LootSpec<String>>::load_expect(table.as_ref())
.read() .read()
.choose() .choose()
.to_item(), .to_item(),
Self::None => None, Self::Nothing => None,
} }
} }
} }
impl Default for LootSpec<String> { impl Default for LootSpec<String> {
fn default() -> Self { Self::None } fn default() -> Self { Self::Nothing }
} }
#[cfg(test)] #[cfg(test)]
@ -148,7 +158,7 @@ pub mod tests {
let loot_table = Lottery::<LootSpec<String>>::load_expect_cloned(loot_table); let loot_table = Lottery::<LootSpec<String>>::load_expect_cloned(loot_table);
validate_table_contents(loot_table); validate_table_contents(loot_table);
}, },
LootSpec::None => {}, LootSpec::Nothing => {},
} }
} }