Support for creature specific materails and materials having a quantity.

This commit is contained in:
Sam 2021-03-28 19:17:23 -04:00
parent 247004d180
commit cbca2a66b6
5 changed files with 350 additions and 284 deletions

View File

@ -16,6 +16,7 @@ pub mod theropod;
use crate::{ use crate::{
assets::{self, Asset}, assets::{self, Asset},
comp::Item,
make_case_elim, make_case_elim,
npc::NpcKind, npc::NpcKind,
}; };
@ -582,6 +583,12 @@ impl Body {
_ => Vec3::unit_z(), _ => Vec3::unit_z(),
} }
} }
pub fn get_loot(&self) -> Item {
Item::new_from_asset_expect(match self {
_ => "common.items.food.cheese"
})
}
} }
impl Component for Body { impl Component for Body {

View File

@ -610,7 +610,7 @@ impl Item {
_ => "common.loot_tables.armor_misc", _ => "common.loot_tables.armor_misc",
}) })
.read(); .read();
return Some(chosen.choose().to_item()) return Some(chosen.choose().to_item(None))
}, },
SpriteKind::ChestBurried => { SpriteKind::ChestBurried => {
chosen = Lottery::<LootSpec>::load_expect(match rng.gen_range(0..7) { chosen = Lottery::<LootSpec>::load_expect(match rng.gen_range(0..7) {
@ -620,7 +620,7 @@ impl Item {
_ => "common.loot_tables.armor_misc", _ => "common.loot_tables.armor_misc",
}) })
.read(); .read();
return Some(chosen.choose().to_item()) return Some(chosen.choose().to_item(None))
}, },
SpriteKind::Mud => { SpriteKind::Mud => {
chosen = Lottery::<LootSpec>::load_expect(match rng.gen_range(0..5) { chosen = Lottery::<LootSpec>::load_expect(match rng.gen_range(0..5) {
@ -630,7 +630,7 @@ impl Item {
_ => "common.loot_tables.rocks", _ => "common.loot_tables.rocks",
}) })
.read(); .read();
return Some(chosen.choose().to_item()) return Some(chosen.choose().to_item(None))
}, },
SpriteKind::Crate => { SpriteKind::Crate => {
chosen = Lottery::<LootSpec>::load_expect(match rng.gen_range(0..4) { chosen = Lottery::<LootSpec>::load_expect(match rng.gen_range(0..4) {
@ -638,7 +638,7 @@ impl Item {
_ => "common.loot_tables.food", _ => "common.loot_tables.food",
}) })
.read(); .read();
return Some(chosen.choose().to_item()) return Some(chosen.choose().to_item(None))
}, },
SpriteKind::Beehive => "common.items.crafting_ing.honey", SpriteKind::Beehive => "common.items.crafting_ing.honey",

View File

@ -26,7 +26,7 @@
// Cheese drop rate = 3/X = 29.6% // Cheese drop rate = 3/X = 29.6%
// Coconut drop rate = 1/X = 9.85% // Coconut drop rate = 1/X = 9.85%
use crate::{assets::{self, AssetExt}, comp::Item}; use crate::{assets::{self, AssetExt}, comp::{Body, Item}};
use rand::prelude::*; use rand::prelude::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
@ -74,17 +74,31 @@ impl<T> Lottery<T> {
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum LootSpec { pub enum LootSpec {
/// Asset specifier
Item(String), Item(String),
/// Asset specifier, lower range, upper range
ItemQuantity(String, u32, u32),
/// Loot table
LootTable(String), LootTable(String),
/// Matches on species to provide a crafting material
CreatureMaterial,
} }
impl LootSpec { impl LootSpec {
pub fn to_item(&self) -> Item { pub fn to_item(&self, body: Option<Body>) -> Item {
match self { match self {
Self::Item(item) => Item::new_from_asset_expect(&item), Self::Item(item) => Item::new_from_asset_expect(&item),
Self::LootTable(table) => { Self::ItemQuantity(item, lower, upper) => {
Lottery::<LootSpec>::load_expect(&table).read().choose().to_item() let range = *lower..=*upper;
let quantity = thread_rng().gen_range(range);
let mut item = Item::new_from_asset_expect(&item);
item.set_amount(quantity);
item
}, },
Self::LootTable(table) => {
Lottery::<LootSpec>::load_expect(&table).read().choose().to_item(body)
},
Self::CreatureMaterial => body.map_or(Item::new_from_asset_expect("common.items.food.cheese"), |b| b.get_loot()),
} }
} }
} }

View File

@ -444,7 +444,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
let item = { let item = {
let mut item_drops = state.ecs().write_storage::<comp::ItemDrop>(); let mut item_drops = state.ecs().write_storage::<comp::ItemDrop>();
item_drops.remove(entity).map_or_else( item_drops.remove(entity).map_or_else(
|| lottery().read().choose().to_item(), || lottery().read().choose().to_item(old_body),
|item_drop| item_drop.0, |item_drop| item_drop.0,
) )
}; };

View File

@ -617,160 +617,178 @@ impl Floor {
.with_alignment(comp::Alignment::Enemy) .with_alignment(comp::Alignment::Enemy)
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte) .with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
.with_skillset_config(common::skillset_builder::SkillSetConfig::CultistAcolyte) .with_skillset_config(common::skillset_builder::SkillSetConfig::CultistAcolyte)
.with_loot_drop(chosen.to_item()) .with_loot_drop(chosen.to_item(None))
.with_level(dynamic_rng.gen_range((room.difficulty as f32).powf(1.25) + 3.0..(room.difficulty as f32).powf(1.5) + 4.0).round() as u16); .with_level(dynamic_rng.gen_range((room.difficulty as f32).powf(1.25) + 3.0..(room.difficulty as f32).powf(1.5) + 4.0).round() as u16);
let entity = match room.difficulty { let entity = match room.difficulty {
0 => entity 0 => {
.with_body(comp::Body::BipedSmall( let body = comp::Body::BipedSmall(
comp::biped_small::Body::random_with( comp::biped_small::Body::random_with(
dynamic_rng, dynamic_rng,
&comp::biped_small::Species::Gnarling, &comp::biped_small::Species::Gnarling,
), ),
)) );
.with_name("Gnarling") entity
.with_loadout_config(loadout_builder::LoadoutConfig::Gnarling) .with_body(body)
.with_skillset_config( .with_name("Gnarling")
common::skillset_builder::SkillSetConfig::Gnarling, .with_loadout_config(loadout_builder::LoadoutConfig::Gnarling)
) .with_skillset_config(
.with_loot_drop(chosen.to_item()) common::skillset_builder::SkillSetConfig::Gnarling,
.with_main_tool(comp::Item::new_from_asset_expect( )
match dynamic_rng.gen_range(0..5) { .with_loot_drop(chosen.to_item(Some(body)))
0 => { .with_main_tool(comp::Item::new_from_asset_expect(
"common.items.npc_weapons.biped_small.gnarling.\ match dynamic_rng.gen_range(0..5) {
adlet_bow" 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"
},
}, },
1 => { ))
"common.items.npc_weapons.biped_small.gnarling.\ },
gnoll_staff" 1 => {
}, let body = comp::Body::BipedSmall(
_ => {
"common.items.npc_weapons.biped_small.gnarling.\
wooden_spear"
},
},
)),
1 => entity
.with_body(comp::Body::BipedSmall(
comp::biped_small::Body::random_with( comp::biped_small::Body::random_with(
dynamic_rng, dynamic_rng,
&comp::biped_small::Species::Adlet, &comp::biped_small::Species::Adlet,
), ),
)) );
.with_name("Adlet") entity
.with_loadout_config(loadout_builder::LoadoutConfig::Adlet) .with_body(body)
.with_skillset_config( .with_name("Adlet")
common::skillset_builder::SkillSetConfig::Adlet, .with_loadout_config(loadout_builder::LoadoutConfig::Adlet)
) .with_skillset_config(
.with_loot_drop(chosen.to_item()) common::skillset_builder::SkillSetConfig::Adlet,
.with_main_tool(comp::Item::new_from_asset_expect( )
match dynamic_rng.gen_range(0..5) { .with_loot_drop(chosen.to_item(Some(body)))
0 => "common.items.npc_weapons.biped_small.adlet.adlet_bow", .with_main_tool(comp::Item::new_from_asset_expect(
1 => { match dynamic_rng.gen_range(0..5) {
"common.items.npc_weapons.biped_small.adlet.gnoll_staff" 0 => "common.items.npc_weapons.biped_small.adlet.adlet_bow",
1 => {
"common.items.npc_weapons.biped_small.adlet.gnoll_staff"
},
_ => {
"common.items.npc_weapons.biped_small.adlet.\
wooden_spear"
},
}, },
_ => { ))
"common.items.npc_weapons.biped_small.adlet.\ },
wooden_spear" 2 => {
}, let body = comp::Body::BipedSmall(
},
)),
2 => entity
.with_body(comp::Body::BipedSmall(
comp::biped_small::Body::random_with( comp::biped_small::Body::random_with(
dynamic_rng, dynamic_rng,
&comp::biped_small::Species::Sahagin, &comp::biped_small::Species::Sahagin,
), ),
)) );
.with_name("Sahagin") entity
.with_loadout_config(loadout_builder::LoadoutConfig::Sahagin) .with_body(body)
.with_skillset_config( .with_name("Sahagin")
common::skillset_builder::SkillSetConfig::Sahagin, .with_loadout_config(loadout_builder::LoadoutConfig::Sahagin)
) .with_skillset_config(
.with_loot_drop(chosen.to_item()) common::skillset_builder::SkillSetConfig::Sahagin,
.with_main_tool(comp::Item::new_from_asset_expect( )
match dynamic_rng.gen_range(0..5) { .with_loot_drop(chosen.to_item(Some(body)))
0 => { .with_main_tool(comp::Item::new_from_asset_expect(
"common.items.npc_weapons.biped_small.sahagin.adlet_bow" 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"
},
}, },
1 => { ))
"common.items.npc_weapons.biped_small.sahagin.\ },
gnoll_staff" 3 => {
}, let body = comp::Body::BipedSmall(
_ => {
"common.items.npc_weapons.biped_small.sahagin.\
wooden_spear"
},
},
)),
3 => entity
.with_body(comp::Body::BipedSmall(
comp::biped_small::Body::random_with( comp::biped_small::Body::random_with(
dynamic_rng, dynamic_rng,
&comp::biped_small::Species::Haniwa, &comp::biped_small::Species::Haniwa,
), ),
)) );
.with_name("Haniwa") entity
.with_loadout_config(loadout_builder::LoadoutConfig::Haniwa) .with_body(body)
.with_skillset_config( .with_name("Haniwa")
common::skillset_builder::SkillSetConfig::Haniwa, .with_loadout_config(loadout_builder::LoadoutConfig::Haniwa)
) .with_skillset_config(
.with_loot_drop(chosen.to_item()) common::skillset_builder::SkillSetConfig::Haniwa,
.with_main_tool(comp::Item::new_from_asset_expect( )
match dynamic_rng.gen_range(0..5) { .with_loot_drop(chosen.to_item(Some(body)))
0 => { .with_main_tool(comp::Item::new_from_asset_expect(
"common.items.npc_weapons.biped_small.haniwa.adlet_bow" 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"
},
}, },
1 => { ))
"common.items.npc_weapons.biped_small.haniwa.\ },
gnoll_staff" 4 => {
}, let body = comp::Body::BipedSmall(
_ => {
"common.items.npc_weapons.biped_small.haniwa.\
wooden_spear"
},
},
)),
4 => entity
.with_body(comp::Body::BipedSmall(
comp::biped_small::Body::random_with( comp::biped_small::Body::random_with(
dynamic_rng, dynamic_rng,
&comp::biped_small::Species::Myrmidon, &comp::biped_small::Species::Myrmidon,
), ),
)) );
.with_name("Myrmidon") entity
.with_loadout_config(loadout_builder::LoadoutConfig::Myrmidon) .with_body(body)
.with_skillset_config( .with_name("Myrmidon")
common::skillset_builder::SkillSetConfig::Myrmidon, .with_loadout_config(loadout_builder::LoadoutConfig::Myrmidon)
)
.with_loot_drop(chosen.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"
},
},
)),
5 => match dynamic_rng.gen_range(0..6) {
0 => entity
.with_body(comp::Body::Humanoid(comp::humanoid::Body::random()))
.with_name("Cultist Warlock")
.with_loadout_config(loadout_builder::LoadoutConfig::Warlock)
.with_skillset_config( .with_skillset_config(
common::skillset_builder::SkillSetConfig::Warlock, common::skillset_builder::SkillSetConfig::Myrmidon,
) )
.with_loot_drop(chosen.to_item()) .with_loot_drop(chosen.to_item(Some(body)))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
"common.items.weapons.staff.cultist_staff", 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"
},
},
))
},
5 => match dynamic_rng.gen_range(0..6) {
0 => {
let body = comp::Body::Humanoid(comp::humanoid::Body::random());
entity
.with_body(body)
.with_name("Cultist Warlock")
.with_loadout_config(loadout_builder::LoadoutConfig::Warlock)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Warlock,
)
.with_loot_drop(chosen.to_item(Some(body)))
.with_main_tool(comp::Item::new_from_asset_expect(
"common.items.weapons.staff.cultist_staff",
))
},
1 => entity 1 => entity
.with_body(comp::Body::Object(comp::object::Body::Crossbow)) .with_body(comp::Body::Object(comp::object::Body::Crossbow))
.with_name("Possessed Turret".to_string()) .with_name("Possessed Turret".to_string())
@ -783,7 +801,7 @@ impl Floor {
.with_skillset_config( .with_skillset_config(
common::skillset_builder::SkillSetConfig::Warlord, common::skillset_builder::SkillSetConfig::Warlord,
) )
.with_loot_drop(chosen.to_item()) .with_loot_drop(chosen.to_item(None))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0..5) { match dynamic_rng.gen_range(0..5) {
0 => "common.items.weapons.axe.malachite_axe-0", 0 => "common.items.weapons.axe.malachite_axe-0",
@ -846,75 +864,93 @@ impl Floor {
let chosen = chosen.read(); let chosen = chosen.read();
let chosen = chosen.choose(); let chosen = chosen.choose();
let entity = match room.difficulty { let entity = match room.difficulty {
0 => vec![ 0 => {
EntityInfo::at(tile_wcenter.map(|e| e as f32)) let body = comp::Body::BipedLarge(
.with_body(comp::Body::BipedLarge( comp::biped_large::Body::random_with(
comp::biped_large::Body::random_with( dynamic_rng,
dynamic_rng, &comp::biped_large::Species::Harvester,
&comp::biped_large::Species::Harvester,
),
))
.with_name("Harvester".to_string())
.with_loot_drop(chosen.to_item()),
],
1 => vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Yeti,
),
))
.with_name("Yeti".to_string())
.with_loot_drop(chosen.to_item()),
],
2 => vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Tidalwarrior,
),
))
.with_name("Tidal Warrior".to_string())
.with_loot_drop(chosen.to_item()),
],
3 => vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::Golem(
comp::golem::Body::random_with(
dynamic_rng,
&comp::golem::Species::ClayGolem,
),
))
.with_name("Clay Golem".to_string())
.with_loot_drop(chosen.to_item()),
],
4 => vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Minotaur,
),
))
.with_name("Minotaur".to_string())
.with_loot_drop(chosen.to_item()),
],
5 => vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Mindflayer,
),
))
.with_name("Mindflayer".to_string())
.with_loot_drop(chosen.to_item())
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Mindflayer,
), ),
], );
vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Harvester".to_string())
.with_loot_drop(chosen.to_item(Some(body))),
]
},
1 => {
let body = comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Yeti,
),
);
vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Yeti".to_string())
.with_loot_drop(chosen.to_item(Some(body))),
]
},
2 => {
let body = comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Tidalwarrior,
),
);
vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Tidal Warrior".to_string())
.with_loot_drop(chosen.to_item(Some(body))),
]
},
3 => {
let body = comp::Body::Golem(
comp::golem::Body::random_with(
dynamic_rng,
&comp::golem::Species::ClayGolem,
),
);
vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Clay Golem".to_string())
.with_loot_drop(chosen.to_item(Some(body))),
]
},
4 => {
let body = comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Minotaur,
),
);
vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Minotaur".to_string())
.with_loot_drop(chosen.to_item(Some(body))),
]
},
5 => {
let body = comp::Body::BipedLarge(
comp::biped_large::Body::random_with(
dynamic_rng,
&comp::biped_large::Species::Mindflayer,
),
);
vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Mindflayer".to_string())
.with_loot_drop(chosen.to_item(Some(body)))
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Mindflayer,
),
]
},
_ => { _ => {
vec![EntityInfo::at(tile_wcenter.map(|e| e as f32)).with_body( vec![EntityInfo::at(tile_wcenter.map(|e| e as f32)).with_body(
comp::Body::QuadrupedSmall( comp::Body::QuadrupedSmall(
@ -986,96 +1022,105 @@ impl Floor {
let chosen = chosen.read(); let chosen = chosen.read();
let chosen = chosen.choose(); let chosen = chosen.choose();
let entity = match room.difficulty { let entity = match room.difficulty {
0 => vec![ 0 => {
EntityInfo::at(tile_wcenter.map(|e| e as f32)) let body = comp::Body::QuadrupedMedium(
.with_body(comp::Body::QuadrupedMedium( comp::quadruped_medium::Body::random_with(
comp::quadruped_medium::Body::random_with( dynamic_rng,
dynamic_rng, &comp::quadruped_medium::Species::Bonerattler,
&comp::quadruped_medium::Species::Bonerattler, ),
), );
)) vec![
.with_name("Bonerattler".to_string()) EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_loot_drop(chosen.to_item()), .with_body(body)
], .with_name("Bonerattler".to_string())
1 => vec![ .with_loot_drop(chosen.to_item(Some(body))),
EntityInfo::at(tile_wcenter.map(|e| e as f32)) ]
.with_body(comp::Body::QuadrupedMedium( },
comp::quadruped_medium::Body::random_with( 1 => {
dynamic_rng, let body = comp::Body::QuadrupedMedium(
&comp::quadruped_medium::Species::Bonerattler, comp::quadruped_medium::Body::random_with(
) dynamic_rng,
)) &comp::quadruped_medium::Species::Bonerattler,
.with_name("Bonerattler".to_string()) )
.with_loot_drop(chosen.to_item()); );
3 vec![
], EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(body)
.with_name("Bonerattler".to_string())
.with_loot_drop(chosen.to_item(Some(body)));
3
]
},
2 => { 2 => {
let mut entities = Vec::new(); let mut entities = Vec::new();
let body = comp::Body::QuadrupedLow(
comp::quadruped_low::Body::random_with(
dynamic_rng,
&comp::quadruped_low::Species::Hakulaq,
),
);
entities.resize_with(6, || { entities.resize_with(6, || {
EntityInfo::at(tile_wcenter.map(|e| e as f32)) EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::QuadrupedLow( .with_body(body)
comp::quadruped_low::Body::random_with(
dynamic_rng,
&comp::quadruped_low::Species::Hakulaq,
),
))
.with_name("Hakulaq".to_string()) .with_name("Hakulaq".to_string())
.with_loot_drop(chosen.to_item()) .with_loot_drop(chosen.to_item(Some(body)))
}); });
entities entities
}, },
3 => vec![ 3 => {
EntityInfo::at(tile_wcenter.map(|e| e as f32)) let mut entities = Vec::new();
.with_body(comp::Body::Humanoid( let body = comp::Body::Humanoid(
comp::humanoid::Body::random(), comp::humanoid::Body::random(),
)) );
.with_name("Animal Trainer".to_string()) entities.push(
.with_loot_drop(chosen.to_item()) EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte) .with_body(body)
.with_skillset_config( .with_name("Animal Trainer".to_string())
common::skillset_builder::SkillSetConfig::CultistAcolyte .with_loot_drop(chosen.to_item(Some(body)))
) .with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
.with_main_tool(comp::Item::new_from_asset_expect( .with_skillset_config(
match dynamic_rng.gen_range(0..6) { common::skillset_builder::SkillSetConfig::CultistAcolyte
0 => "common.items.weapons.axe.malachite_axe-0", )
1..=2 => "common.items.weapons.sword.cultist", .with_main_tool(comp::Item::new_from_asset_expect(
3 => { match dynamic_rng.gen_range(0..6) {
"common.items.weapons.hammer.cultist_purp_2h-0" 0 => "common.items.weapons.axe.malachite_axe-0",
1..=2 => "common.items.weapons.sword.cultist",
3 => {
"common.items.weapons.hammer.cultist_purp_2h-0"
},
4 => "common.items.weapons.staff.cultist_staff",
_ => "common.items.weapons.bow.bone-1",
}, },
4 => "common.items.weapons.staff.cultist_staff", )),
_ => "common.items.weapons.bow.bone-1", );
}, let body = comp::Body::QuadrupedMedium(
)), comp::quadruped_medium::Body::random_with(
EntityInfo::at(tile_wcenter.map(|e| e as f32)) dynamic_rng,
.with_body(comp::Body::QuadrupedMedium( &comp::quadruped_medium::Species::Darkhound,
comp::quadruped_medium::Body::random_with( ),
dynamic_rng, );
&comp::quadruped_medium::Species::Darkhound, entities.resize_with(entities.len() + 2, || {
), EntityInfo::at(tile_wcenter.map(|e| e as f32))
)) .with_body(body)
.with_name("Tamed Darkhound".to_string()) .with_name("Tamed Darkhound".to_string())
.with_loot_drop(chosen.to_item()), .with_loot_drop(chosen.to_item(Some(body)))
EntityInfo::at(tile_wcenter.map(|e| e as f32)) });
.with_body(comp::Body::QuadrupedMedium( entities
comp::quadruped_medium::Body::random_with( },
dynamic_rng, 4 => {
&comp::quadruped_medium::Species::Darkhound, let body = comp::Body::BipedLarge(
), comp::biped_large::Body::random_with(
)) dynamic_rng,
.with_name("Tamed Darkhound".to_string()) &comp::biped_large::Species::Dullahan,
.with_loot_drop(chosen.to_item()), ),
], );
4 => vec![ vec![
EntityInfo::at(tile_wcenter.map(|e| e as f32)) EntityInfo::at(tile_wcenter.map(|e| e as f32))
.with_body(comp::Body::BipedLarge( .with_body(body)
comp::biped_large::Body::random_with( .with_name("Dullahan Guard".to_string())
dynamic_rng, .with_loot_drop(chosen.to_item(Some(body))),
&comp::biped_large::Species::Dullahan, ]
), },
))
.with_name("Dullahan Guard".to_string())
.with_loot_drop(chosen.to_item()),
],
5 => { 5 => {
let mut entities = Vec::new(); let mut entities = Vec::new();
entities.resize_with(10, || { entities.resize_with(10, || {