From f5bf991eb0ddb0a97689f8dbf2e12bb6dbb008d2 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Sun, 6 Jun 2021 18:55:04 +0300 Subject: [PATCH] Start to load EntityInfo from assets in dungeons * All enemies in dungeons are now specify loadout_config, name and main_tool in assets * Add more variance to the enemies names --- assets/common/entity/dungeon/tier-0/bow.ron | 8 ++ assets/common/entity/dungeon/tier-0/spear.ron | 8 ++ assets/common/entity/dungeon/tier-0/staff.ron | 8 ++ assets/common/entity/dungeon/tier-1/bow.ron | 8 ++ assets/common/entity/dungeon/tier-1/spear.ron | 8 ++ assets/common/entity/dungeon/tier-1/staff.ron | 8 ++ assets/common/entity/dungeon/tier-2/bow.ron | 8 ++ assets/common/entity/dungeon/tier-2/spear.ron | 8 ++ assets/common/entity/dungeon/tier-2/staff.ron | 8 ++ assets/common/entity/dungeon/tier-3/bow.ron | 8 ++ assets/common/entity/dungeon/tier-3/spear.ron | 8 ++ assets/common/entity/dungeon/tier-3/staff.ron | 8 ++ assets/common/entity/dungeon/tier-4/bow.ron | 8 ++ assets/common/entity/dungeon/tier-4/spear.ron | 8 ++ assets/common/entity/dungeon/tier-4/staff.ron | 8 ++ .../common/entity/dungeon/tier-5/warlock.ron | 8 ++ .../common/entity/dungeon/tier-5/warlord.ron | 14 ++ assets/common/entity/test.ron | 18 +-- common/src/comp/inventory/loadout_builder.rs | 6 +- common/src/generation.rs | 92 +++++++++++- world/src/site/dungeon/mod.rs | 132 +++++++----------- 21 files changed, 292 insertions(+), 98 deletions(-) create mode 100644 assets/common/entity/dungeon/tier-0/bow.ron create mode 100644 assets/common/entity/dungeon/tier-0/spear.ron create mode 100644 assets/common/entity/dungeon/tier-0/staff.ron create mode 100644 assets/common/entity/dungeon/tier-1/bow.ron create mode 100644 assets/common/entity/dungeon/tier-1/spear.ron create mode 100644 assets/common/entity/dungeon/tier-1/staff.ron create mode 100644 assets/common/entity/dungeon/tier-2/bow.ron create mode 100644 assets/common/entity/dungeon/tier-2/spear.ron create mode 100644 assets/common/entity/dungeon/tier-2/staff.ron create mode 100644 assets/common/entity/dungeon/tier-3/bow.ron create mode 100644 assets/common/entity/dungeon/tier-3/spear.ron create mode 100644 assets/common/entity/dungeon/tier-3/staff.ron create mode 100644 assets/common/entity/dungeon/tier-4/bow.ron create mode 100644 assets/common/entity/dungeon/tier-4/spear.ron create mode 100644 assets/common/entity/dungeon/tier-4/staff.ron create mode 100644 assets/common/entity/dungeon/tier-5/warlock.ron create mode 100644 assets/common/entity/dungeon/tier-5/warlord.ron diff --git a/assets/common/entity/dungeon/tier-0/bow.ron b/assets/common/entity/dungeon/tier-0/bow.ron new file mode 100644 index 0000000000..0ba5a289d6 --- /dev/null +++ b/assets/common/entity/dungeon/tier-0/bow.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Gnarling Stalker"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.adlet_bow")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-0.gnarling"), +) diff --git a/assets/common/entity/dungeon/tier-0/spear.ron b/assets/common/entity/dungeon/tier-0/spear.ron new file mode 100644 index 0000000000..ffc2e9cf4f --- /dev/null +++ b/assets/common/entity/dungeon/tier-0/spear.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Gnarling Mugger"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.wooden_spear")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-0.gnarling"), +) diff --git a/assets/common/entity/dungeon/tier-0/staff.ron b/assets/common/entity/dungeon/tier-0/staff.ron new file mode 100644 index 0000000000..b0b6a7a751 --- /dev/null +++ b/assets/common/entity/dungeon/tier-0/staff.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Gnarling Shaman"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.gnoll_staff")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-0.gnarling"), +) diff --git a/assets/common/entity/dungeon/tier-1/bow.ron b/assets/common/entity/dungeon/tier-1/bow.ron new file mode 100644 index 0000000000..fde472fdb5 --- /dev/null +++ b/assets/common/entity/dungeon/tier-1/bow.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Adlet Tracker"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.adlet_bow")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-1.adlet_bow"), +) diff --git a/assets/common/entity/dungeon/tier-1/spear.ron b/assets/common/entity/dungeon/tier-1/spear.ron new file mode 100644 index 0000000000..48a07585be --- /dev/null +++ b/assets/common/entity/dungeon/tier-1/spear.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Adlet Hunter"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.wooden_spear")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-1.adlet_spear"), +) diff --git a/assets/common/entity/dungeon/tier-1/staff.ron b/assets/common/entity/dungeon/tier-1/staff.ron new file mode 100644 index 0000000000..820c12436c --- /dev/null +++ b/assets/common/entity/dungeon/tier-1/staff.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Adlet Shaman"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.gnoll_staff")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-1.adlet_spear"), +) diff --git a/assets/common/entity/dungeon/tier-2/bow.ron b/assets/common/entity/dungeon/tier-2/bow.ron new file mode 100644 index 0000000000..8ea21fa08c --- /dev/null +++ b/assets/common/entity/dungeon/tier-2/bow.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Sahagin Sniper"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.adlet_bow")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-2.sahagin"), +) diff --git a/assets/common/entity/dungeon/tier-2/spear.ron b/assets/common/entity/dungeon/tier-2/spear.ron new file mode 100644 index 0000000000..bd8d7c9e4e --- /dev/null +++ b/assets/common/entity/dungeon/tier-2/spear.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Sahagin Spearman"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.wooden_spear")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-2.sahagin"), +) diff --git a/assets/common/entity/dungeon/tier-2/staff.ron b/assets/common/entity/dungeon/tier-2/staff.ron new file mode 100644 index 0000000000..73cb84ee55 --- /dev/null +++ b/assets/common/entity/dungeon/tier-2/staff.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Sahagin Sorcerer"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.gnoll_staff")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-2.sahagin"), +) diff --git a/assets/common/entity/dungeon/tier-3/bow.ron b/assets/common/entity/dungeon/tier-3/bow.ron new file mode 100644 index 0000000000..d1a9d98924 --- /dev/null +++ b/assets/common/entity/dungeon/tier-3/bow.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Haniwa Archer"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.adlet_bow")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-3.haniwa"), +) diff --git a/assets/common/entity/dungeon/tier-3/spear.ron b/assets/common/entity/dungeon/tier-3/spear.ron new file mode 100644 index 0000000000..5e303990af --- /dev/null +++ b/assets/common/entity/dungeon/tier-3/spear.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Haniwa Guard"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.wooden_spear")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-3.haniwa"), +) diff --git a/assets/common/entity/dungeon/tier-3/staff.ron b/assets/common/entity/dungeon/tier-3/staff.ron new file mode 100644 index 0000000000..ef130792c0 --- /dev/null +++ b/assets/common/entity/dungeon/tier-3/staff.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Haniwa Sorcerer"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.gnoll_staff")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-3.haniwa"), +) diff --git a/assets/common/entity/dungeon/tier-4/bow.ron b/assets/common/entity/dungeon/tier-4/bow.ron new file mode 100644 index 0000000000..7a9006fb5a --- /dev/null +++ b/assets/common/entity/dungeon/tier-4/bow.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Myrmidon Marksman"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.adlet_bow")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-4.myrmidon"), +) diff --git a/assets/common/entity/dungeon/tier-4/spear.ron b/assets/common/entity/dungeon/tier-4/spear.ron new file mode 100644 index 0000000000..3ae610eb7e --- /dev/null +++ b/assets/common/entity/dungeon/tier-4/spear.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Myrmidon Hoplite"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.wooden_spear")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-4.myrmidon"), +) diff --git a/assets/common/entity/dungeon/tier-4/staff.ron b/assets/common/entity/dungeon/tier-4/staff.ron new file mode 100644 index 0000000000..23d0521872 --- /dev/null +++ b/assets/common/entity/dungeon/tier-4/staff.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Myrmidon Wizard"), + + main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.gnoll_staff")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-4.myrmidon"), +) diff --git a/assets/common/entity/dungeon/tier-5/warlock.ron b/assets/common/entity/dungeon/tier-5/warlock.ron new file mode 100644 index 0000000000..f151381032 --- /dev/null +++ b/assets/common/entity/dungeon/tier-5/warlock.ron @@ -0,0 +1,8 @@ +EntityConfig ( + name: Some("Cultist Warlock"), + + main_tool: Some(Item("common.items.weapons.staff.cultist_staff")), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-5.warlock"), +) diff --git a/assets/common/entity/dungeon/tier-5/warlord.ron b/assets/common/entity/dungeon/tier-5/warlord.ron new file mode 100644 index 0000000000..8369c3f29c --- /dev/null +++ b/assets/common/entity/dungeon/tier-5/warlord.ron @@ -0,0 +1,14 @@ +EntityConfig ( + name: Some("Cultist Warlord"), + + main_tool: Some(Choice([ + (1.0, Some(Item("common.items.weapons.axe_1h.orichalcum-0"))), + (2.0, Some(Item("common.items.weapons.sword.cultist"))), + (1.0, Some(Item("common.items.weapons.hammer.cultist_purp_2h-0"))), + (1.0, Some(Item("common.items.weapons.hammer_1h.orichalcum-0"))), + (1.0, Some(Item("common.items.weapons.bow.velorite"))), + ])), + second_tool: None, + + loadout_config: Some("common.loadout.dungeon.tier-5.warlord"), +) diff --git a/assets/common/entity/test.ron b/assets/common/entity/test.ron index 2a70be337c..040cc162b2 100644 --- a/assets/common/entity/test.ron +++ b/assets/common/entity/test.ron @@ -1,4 +1,4 @@ -{ +EntityConfig ( /// Name of Entity name: Some("Paddy"), @@ -8,11 +8,6 @@ /// or RandomWith (will use random_with if available for this Body) // body: Humanoid(Random), - /// Loot - /// Can be Item (with asset_specifier for item) - /// or LootTable (with asset_specifier for loot table) - loot: LootTable("common.loot_tables.humanoids"), - /// Main and second tools /// Can be Option (with asset_specifier for item) /// or Choice @@ -20,12 +15,17 @@ main_tool: Some(Item("common.items.weapons.axe_1h.orichalcum-0")), second_tool: None, - /// Loadout Config as Option (with asset_specifier for loadout) - loadout_config: Some(Loadout("common.loadout.village.merchant")), + /// Loadout Config (with asset_specifier for loadout) + loadout_config: Some("common.loadout.village.merchant"), /// Skillset Config as Option (with asset_specifier for skillset) // skillset_config: None, + /// Loot + /// Can be Item (with asset_specifier for item) + /// or LootTable (with asset_specifier for loot table) + // loot: LootTable("common.loot_tables.humanoids"), + /// Meta Info (level, alignment, agency, etc) // meta: {}, -} +) diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 8e49b3c4ae..fff159b3fe 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -46,7 +46,7 @@ pub enum LoadoutPreset { } #[derive(Debug, Deserialize, Clone)] -enum ItemSpec { +pub enum ItemSpec { /// One specific item. /// Example: /// Item("common.items.armor.steel.foot") @@ -61,7 +61,7 @@ enum ItemSpec { } impl ItemSpec { - fn try_to_item(&self, asset_specifier: &str, rng: &mut impl Rng) -> Option { + pub fn try_to_item(&self, asset_specifier: &str, rng: &mut impl Rng) -> Option { match self { ItemSpec::Item(specifier) => Some(Item::new_from_asset_expect(&specifier)), @@ -80,7 +80,7 @@ impl ItemSpec { #[cfg(test)] // Read everything and checks if it's loading - fn validate(&self, key: EquipSlot) { + pub fn validate(&self, key: EquipSlot) { match self { ItemSpec::Item(specifier) => std::mem::drop(Item::new_from_asset_expect(&specifier)), ItemSpec::Choice(items) => { diff --git a/common/src/generation.rs b/common/src/generation.rs index 78e5726bbb..79959c5552 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -1,7 +1,8 @@ use crate::{ + assets::{self, AssetExt}, comp::{ self, agent, humanoid, - inventory::loadout_builder::{LoadoutBuilder, LoadoutPreset}, + inventory::loadout_builder::{ItemSpec, LoadoutBuilder, LoadoutPreset}, Alignment, Body, Item, }, npc::{self, NPC_NAMES}, @@ -9,10 +10,21 @@ use crate::{ trade, trade::SiteInformation, }; +use serde::Deserialize; use vek::*; -pub enum EntityTemplate { - Traveller, +#[derive(Debug, Deserialize, Clone)] +struct EntityConfig { + name: Option, + main_tool: Option, + second_tool: Option, + loadout_config: Option, +} + +impl assets::Asset for EntityConfig { + type Loader = assets::RonLoader; + + const EXTENSION: &'static str = "ron"; } #[derive(Clone)] @@ -70,6 +82,44 @@ impl EntityInfo { } } + pub fn with_asset_expect(self, asset_specifier: &str) -> Self { + let config = EntityConfig::load_expect(asset_specifier).read().clone(); + + self.with_entity_config(config, Some(asset_specifier)) + } + + // helper function to apply config + fn with_entity_config(mut self, config: EntityConfig, asset_specifier: Option<&str>) -> Self { + let EntityConfig { + name, + main_tool, + second_tool, + loadout_config, + } = config; + + if let Some(name) = name { + self = self.with_name(name); + } + + let rng = &mut rand::thread_rng(); + if let Some(main_tool) = + main_tool.and_then(|i| i.try_to_item(asset_specifier.unwrap_or("??"), rng)) + { + self = self.with_main_tool(main_tool); + } + if let Some(second_tool) = + second_tool.and_then(|i| i.try_to_item(asset_specifier.unwrap_or("??"), rng)) + { + self = self.with_main_tool(second_tool); + } + + if let Some(loadout_config) = loadout_config { + self = self.with_loadout_config(&loadout_config); + } + + self + } + pub fn do_if(mut self, cond: bool, f: impl FnOnce(Self) -> Self) -> Self { if cond { self = f(self); @@ -224,3 +274,39 @@ pub fn get_npc_name< ) -> &'a str { &body_data.species[&species].generic } + +#[cfg(test)] +mod tests { + use super::*; + use assets::Error; + + #[test] + fn test_all_entity_assets() { + #[derive(Clone)] + struct EntityList(Vec); + impl assets::Compound for EntityList { + fn load( + cache: &assets::AssetCache, + specifier: &str, + ) -> Result { + let list = cache + .load::(specifier)? + .read() + .iter() + .map(|spec| EntityConfig::load_cloned(spec)) + .collect::>()?; + + Ok(Self(list)) + } + } + + // It just load everything that could + // TODO: add some checks, e.g. that Armor(Head) key correspond + // to Item with ItemKind Head(_) + let entity_configs = EntityList::load_expect_cloned("common.entity.*").0; + for config in entity_configs { + let pos = Vec3::new(0.0, 0.0, 0.0); + std::mem::drop(EntityInfo::at(pos).with_entity_config(config, None)); + } + } +} diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index c52ce446eb..86b8401b06 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -925,24 +925,21 @@ impl Floor { fn enemy_0(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { let chosen = Lottery::::load_expect("common.loot_tables.dungeon.tier-0.enemy"); - entity + let gnarling = entity .with_body(comp::Body::BipedSmall( comp::biped_small::Body::random_with( dynamic_rng, &comp::biped_small::Species::Gnarling, ), )) - .with_name("Gnarling") - .with_loadout_config("common.loadout.dungeon.tier-0.gnarling") - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Gnarling) .with_loot_drop(chosen.read().choose().to_item()) - .with_main_tool(comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0..5) { - 0 => "common.items.npc_weapons.biped_small.gnarling.adlet_bow", - 1 => "common.items.npc_weapons.biped_small.gnarling.gnoll_staff", - _ => "common.items.npc_weapons.biped_small.gnarling.wooden_spear", - }, - )) + .with_skillset_preset(common::skillset_builder::SkillSetConfig::Gnarling); + + match dynamic_rng.gen_range(0..5) { + 0 => gnarling.with_asset_expect("common.entity.dungeon.tier-0.bow"), + 1 => gnarling.with_asset_expect("common.entity.dungeon.tier-0.staff"), + _ => gnarling.with_asset_expect("common.entity.dungeon.tier-0.spear"), + } } fn enemy_1(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { @@ -952,48 +949,33 @@ fn enemy_1(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { .with_body(comp::Body::BipedSmall( comp::biped_small::Body::random_with(dynamic_rng, &comp::biped_small::Species::Adlet), )) - .with_name("Adlet") .with_skillset_preset(common::skillset_builder::SkillSetConfig::Adlet) .with_loot_drop(chosen.read().choose().to_item()); match dynamic_rng.gen_range(0..5) { - 0 => adlet - .with_main_tool(comp::Item::new_from_asset_expect( - "common.items.npc_weapons.biped_small.adlet.adlet_bow", - )) - .with_loadout_config("common.loadout.dungeon.tier-1.adlet_bow"), - 1 => adlet - .with_main_tool(comp::Item::new_from_asset_expect( - "common.items.npc_weapons.biped_small.adlet.adlet_staff", - )) - .with_loadout_config("common.loadout.dungeon.tier-1.adlet_spear"), - _ => adlet - .with_main_tool(comp::Item::new_from_asset_expect( - "common.items.npc_weapons.biped_small.adlet.adlet_spear", - )) - .with_loadout_config("common.loadout.dungeon.tier-1.adlet_spear"), + 0 => adlet.with_asset_expect("common.entity.dungeon.tier-1.bow"), + 1 => adlet.with_asset_expect("common.entity.dungeon.tier-1.staff"), + _ => adlet.with_asset_expect("common.entity.dungeon.tier-1.spear"), } } fn enemy_2(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { let chosen = Lottery::::load_expect("common.loot_tables.dungeon.tier-2.enemy"); - entity + let sahagin = entity .with_body(comp::Body::BipedSmall( comp::biped_small::Body::random_with(dynamic_rng, &comp::biped_small::Species::Sahagin), )) - .with_name("Sahagin") - .with_loadout_config("common.loadout.dungeon.tier-2.sahagin") .with_skillset_preset(common::skillset_builder::SkillSetConfig::Sahagin) - .with_loot_drop(chosen.read().choose().to_item()) - .with_main_tool(comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0..5) { - 0 => "common.items.npc_weapons.biped_small.sahagin.adlet_bow", - 1 => "common.items.npc_weapons.biped_small.sahagin.gnoll_staff", - _ => "common.items.npc_weapons.biped_small.sahagin.wooden_spear", - }, - )) + .with_loot_drop(chosen.read().choose().to_item()); + + match dynamic_rng.gen_range(0..5) { + 0 => sahagin.with_asset_expect("common.entity.dungeon.tier-2.bow"), + 1 => sahagin.with_asset_expect("common.entity.dungeon.tier-2.staff"), + _ => sahagin.with_asset_expect("common.entity.dungeon.tier-2.spear"), + } } + fn enemy_3(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { let chosen = Lottery::::load_expect("common.loot_tables.dungeon.tier-3.enemy"); @@ -1004,48 +986,45 @@ fn enemy_3(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { .with_loot_drop(comp::Item::new_from_asset_expect( "common.items.crafting_ing.stones", )), - _ => entity - .with_body(comp::Body::BipedSmall( - comp::biped_small::Body::random_with( - dynamic_rng, - &comp::biped_small::Species::Haniwa, - ), - )) - .with_name("Haniwa") - .with_loadout_config("common.loadout.dungeon.tier-3.haniwa") - .with_skillset_preset(common::skillset_builder::SkillSetConfig::Haniwa) - .with_loot_drop(chosen.read().choose().to_item()) - .with_main_tool(comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0..5) { - 0 => "common.items.npc_weapons.biped_small.haniwa.adlet_bow", - 1 => "common.items.npc_weapons.biped_small.haniwa.gnoll_staff", - _ => "common.items.npc_weapons.biped_small.haniwa.wooden_spear", - }, - )), + _ => { + let haniwa = entity + .with_body(comp::Body::BipedSmall( + comp::biped_small::Body::random_with( + dynamic_rng, + &comp::biped_small::Species::Haniwa, + ), + )) + .with_skillset_preset(common::skillset_builder::SkillSetConfig::Haniwa) + .with_loot_drop(chosen.read().choose().to_item()); + + match dynamic_rng.gen_range(0..5) { + 0 => haniwa.with_asset_expect("common.entity.dungeon.tier-3.bow"), + 1 => haniwa.with_asset_expect("common.entity.dungeon.tier-3.staff"), + _ => haniwa.with_asset_expect("common.entity.dungeon.tier-3.spear"), + } + }, } } fn enemy_4(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { let chosen = Lottery::::load_expect("common.loot_tables.dungeon.tier-4.enemy"); - entity + let myrmidon = entity .with_body(comp::Body::BipedSmall( comp::biped_small::Body::random_with( dynamic_rng, &comp::biped_small::Species::Myrmidon, ), )) - .with_name("Myrmidon") - .with_loadout_config("common.loadout.dungeon.tier-4.myrmidon") .with_skillset_preset(common::skillset_builder::SkillSetConfig::Myrmidon) - .with_loot_drop(chosen.read().choose().to_item()) - .with_main_tool(comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0..5) { - 0 => "common.items.npc_weapons.biped_small.myrmidon.adlet_bow", - 1 => "common.items.npc_weapons.biped_small.myrmidon.gnoll_staff", - _ => "common.items.npc_weapons.biped_small.myrmidon.wooden_spear", - }, - )) + .with_loot_drop(chosen.read().choose().to_item()); + + match dynamic_rng.gen_range(0..5) { + 0 => myrmidon.with_asset_expect("common.entity.dungeon.tier-4.bow"), + 1 => myrmidon.with_asset_expect("common.entity.dungeon.tier-4.staff"), + _ => myrmidon.with_asset_expect("common.entity.dungeon.tier-4.spear"), + } } + fn enemy_5(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { let chosen = Lottery::::load_expect("common.loot_tables.dungeon.tier-5.enemy"); @@ -1058,27 +1037,14 @@ fn enemy_5(dynamic_rng: &mut impl Rng, entity: EntityInfo) -> EntityInfo { )), 1 => entity .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) - .with_name("Cultist Warlock") - .with_loadout_config("common.loadout.dungeon.tier-5.warlock") .with_skillset_preset(common::skillset_builder::SkillSetConfig::Warlock) .with_loot_drop(chosen.read().choose().to_item()) - .with_main_tool(comp::Item::new_from_asset_expect( - "common.items.weapons.staff.cultist_staff", - )), + .with_asset_expect("common.entity.dungeon.tier-5.warlock"), _ => entity - .with_name("Cultist Warlord") - .with_loadout_config("common.loadout.dungeon.tier-5.warlord") + .with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) .with_skillset_preset(common::skillset_builder::SkillSetConfig::Warlord) .with_loot_drop(chosen.read().choose().to_item()) - .with_main_tool(comp::Item::new_from_asset_expect( - match dynamic_rng.gen_range(0..6) { - 0 => "common.items.weapons.axe_1h.orichalcum-0", - 1..=2 => "common.items.weapons.sword.cultist", - 3 => "common.items.weapons.hammer.cultist_purp_2h-0", - 4 => "common.items.weapons.hammer_1h.orichalcum-0", - _ => "common.items.weapons.bow.bone-1", - }, - )), + .with_asset_expect("common.entity.dungeon.tier-5.warlord"), } }