add InlineLootTable to LootSpec

This commit is contained in:
crabman 2024-03-05 13:01:02 +00:00
parent 69ade26498
commit 82052f4517
No known key found for this signature in database
13 changed files with 95 additions and 62 deletions

View File

@ -3,12 +3,7 @@
name: Automatic,
body: RandomWith("cyclops"),
alignment: Alignment(Enemy),
loot: All([
// Hat, wood and lantern, has a lower chance of dropping
LootTable("common.loot_tables.dungeon.myrmidon.miniboss"),
// Materials, always dropped
LootTable("common.loot_tables.dungeon.myrmidon.miniboss_extra"),
]),
loot: LootTable("common.loot_tables.dungeon.myrmidon.miniboss"),
inventory: (
loadout: FromBody,
),

View File

@ -3,14 +3,9 @@
name: Automatic,
body: RandomWith("phoenix"),
alignment: Alignment(Wild),
loot: All([
// Bow and glider, has a lower chance of dropping
LootTable("common.loot_tables.creature.bird_large.phoenix"),
// Phoenix feathers and food, always dropped
LootTable("common.loot_tables.creature.bird_large.phoenix_extra")
]),
loot: LootTable("common.loot_tables.creature.bird_large.phoenix"),
inventory: (
loadout: FromBody,
),
meta: [],
)
)

View File

@ -1,4 +1,12 @@
[
(1.6, Nothing),
(0.4, Item("common.items.weapons.bow.sagitta")),
]
(1, All([
MultiDrop(Item("common.items.food.meat.bird_large_raw"), 3, 4),
MultiDrop(Item("common.items.crafting_ing.animal_misc.phoenix_feather"), 1, 3),
// Special Drop
Lottery([
(0.4, Item("common.items.weapons.bow.sagitta")),
(1.6, Nothing),
]),
])),
]

View File

@ -1,7 +0,0 @@
[
// Extra materials dropped by phoenix
(1.0, All([
MultiDrop(Item("common.items.food.meat.bird_large_raw"), 3, 4),
MultiDrop(Item("common.items.crafting_ing.animal_misc.phoenix_feather"), 1, 3),
])),
]

View File

@ -3,7 +3,16 @@
Item("common.items.keys.bone_key"),
MultiDrop(Item("common.items.crafting_ing.animal_misc.fur"), 1, 2),
MultiDrop(Item("common.items.crafting_ing.leather.thick_leather"), 1, 2),
LootTable("common.loot_tables.dungeon.adlet.elder_extra"),
Lottery([
// Weapons
(4.0, LootTable("common.loot_tables.weapons.tier-2")),
// Armor
(4.0, LootTable("common.loot_tables.armor.tier-2")),
// Misc
(2.0, Item("common.items.armor.misc.neck.pendant_of_protection")),
(0.5, Item("common.items.tool.instruments.wildskin_drum")),
]),
],
)),
]
]

View File

@ -1,9 +0,0 @@
[
// Weapons
(4.0, LootTable("common.loot_tables.weapons.tier-2")),
// Armor
(4.0, LootTable("common.loot_tables.armor.tier-2")),
// Misc
(2.0, Item("common.items.armor.misc.neck.pendant_of_protection")),
(0.5, Item("common.items.tool.instruments.wildskin_drum")),
]

View File

@ -1,9 +1,18 @@
[
(1.05, Nothing),
// Lantern drop
(0.15, Item("common.items.lantern.blue_0")),
// Hat drop
(0.3, Item("common.items.armor.misc.head.mitre")),
// Allow for Eldwood to drop until entity droppers are implemented
(0.5, Item("common.items.log.eldwood")),
(1.0, All([
MultiDrop(Item("common.items.utility.coins"), 200, 500),
MultiDrop(Item("common.items.mineral.ingot.iron"), 5, 10),
MultiDrop(Item("common.items.consumable.potion_minor"), 4, 8),
// Special drop
Lottery([
// Lantern drop
(0.15, Item("common.items.lantern.blue_0")),
// Hat drop
(0.3, Item("common.items.armor.misc.head.mitre")),
// Allow for Eldwood to drop until entity droppers are implemented
(0.5, Item("common.items.log.eldwood")),
(1.05, Nothing),
]),
]))
]

View File

@ -1,8 +0,0 @@
[
// Mats, always dropped
(1.0, All([
MultiDrop(Item("common.items.utility.coins"), 200, 500),
MultiDrop(Item("common.items.mineral.ingot.iron"), 5, 10),
MultiDrop(Item("common.items.consumable.potion_minor"), 4, 8),
])),
]

View File

@ -1,7 +1,15 @@
[
(1, All([
Item("common.items.keys.terracotta_key_door"),
LootTable("common.loot_tables.dungeon.terracotta.cursekeeper_extra"),
Lottery([
// Weapons
(3.0, LootTable("common.loot_tables.weapons.tier-5")),
// Armor
(3.0, LootTable("common.loot_tables.armor.tier-5")),
// Misc
(0.25, Item("common.items.tool.instruments.steeltonguedrum")),
]),
],
)),
]
]

View File

@ -1,8 +0,0 @@
[
// Weapons
(3.0, LootTable("common.loot_tables.weapons.tier-5")),
// Armor
(3.0, LootTable("common.loot_tables.armor.tier-5")),
// Misc
(0.25, Item("common.items.tool.instruments.steeltonguedrum")),
]

View File

@ -301,6 +301,11 @@ fn loot_table(loot_table: &str) -> Result<(), Box<dyn Error>> {
write_loot_spec(wtr, spec, chance)?;
}
},
LootSpec::Lottery(lottery) => {
for (_weight, spec) in lottery {
write_loot_spec(wtr, spec, "")?;
}
},
}
Ok(())
}
@ -480,6 +485,7 @@ fn entity_drops(entity_config: &str) -> Result<(), Box<dyn Error>> {
}
},
LootSpec::LootTable(_) => unreachable!(),
LootSpec::Lottery(_) => todo!(),
LootSpec::MultiDrop(_, _, _) => todo!(),
LootSpec::All(_) => todo!(),
}

View File

@ -379,6 +379,15 @@ impl From<Vec<(f32, LootSpec<String>)>> for ProbabilityFile {
.map(|(p1, asset, amount)| (*p1 * scale, asset.clone(), *amount))
.collect::<Vec<_>>()
},
LootSpec::Lottery(table) => {
let unscaled = ProbabilityFile::from(table);
let scale = p0 * rescale;
unscaled
.content
.into_iter()
.map(|(p1, asset, amount)| (p1 * scale, asset, amount))
.collect::<Vec<_>>()
},
LootSpec::ModularWeapon {
tool,
material,

View File

@ -207,7 +207,7 @@ pub fn distribute_many<T: Copy + Eq + Hash, I>(
}
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum LootSpec<T: AsRef<str>> {
/// Asset specifier
Item(T),
@ -232,6 +232,8 @@ pub enum LootSpec<T: AsRef<str>> {
/// Each category is evaluated, often used to have guaranteed quest Item +
/// random reward
All(Vec<LootSpec<T>>),
/// Like a `LootTable` but inline
Lottery(Vec<(f32, LootSpec<T>)>),
}
impl<T: AsRef<str>> LootSpec<T> {
@ -291,6 +293,18 @@ impl<T: AsRef<str>> LootSpec<T> {
loot_spec.choose().to_items_inner(rng, 1, items)
}
},
Self::Lottery(table) => {
let lottery = Lottery::from(
table
.iter()
.map(|(weight, spec)| (*weight, spec))
.collect::<Vec<_>>(),
);
for _ in 0..amount {
lottery.choose().to_items_inner(rng, 1, items)
}
},
Self::Nothing => {},
Self::ModularWeapon {
tool,
@ -368,6 +382,8 @@ impl Default for LootSpec<String> {
#[cfg(test)]
pub mod tests {
use std::borrow::Borrow;
use super::*;
use crate::{assets, comp::Item};
use assets::AssetExt;
@ -426,12 +442,22 @@ pub mod tests {
validate_loot_spec(loot_spec);
}
},
LootSpec::Lottery(table) => {
let lottery = Lottery::from(
table
.iter()
.map(|(weight, spec)| (*weight, spec))
.collect::<Vec<_>>(),
);
validate_table_contents(&lottery);
},
}
}
fn validate_table_contents(table: &Lottery<LootSpec<String>>) {
fn validate_table_contents<T: Borrow<LootSpec<String>>>(table: &Lottery<T>) {
for (_, item) in table.iter() {
validate_loot_spec(item);
validate_loot_spec(item.borrow());
}
}