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
(1.0, LootTable("common.loot_tables.food.wild_ingredients")),
// Nothing
(2.0, None),
(2.0, Nothing),
]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
[
// 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<_>>()
.into_iter()
},
LootSpec::None => Vec::new().into_iter(),
LootSpec::Nothing => Vec::new().into_iter(),
})
.collect(),
}

View File

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