mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add Exact body field for EntityConfig
Add Alignment field to EntityConfig + Migrate to specifying alignment and body in entity assets + Make Body required field (with Uninit if you want to specify it later)
This commit is contained in:
parent
54eb2a3ff7
commit
d920f911a2
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Crazy Sheep"),
|
||||
body: Some(RandomWith("sheep")),
|
||||
body: RandomWith("sheep"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.fallback")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Yan Hus"),
|
||||
body: Some(RandomWith("humanoid")),
|
||||
body: RandomWith("humanoid"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.fallback")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Big Goose"),
|
||||
body: Some(RandomWith("goose")),
|
||||
body: RandomWith("goose"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.fallback")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Harvester"),
|
||||
body: Some(RandomWith("harvester")),
|
||||
body: RandomWith("harvester"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-0.boss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Gnarling Stalker"),
|
||||
body: Some(RandomWith("gnarling")),
|
||||
body: RandomWith("gnarling"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-0.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Deadwood"),
|
||||
body: Some(RandomWith("deadwood")),
|
||||
body: RandomWith("deadwood"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-0.miniboss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Gnarling Mugger"),
|
||||
body: Some(RandomWith("gnarling")),
|
||||
body: RandomWith("gnarling"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-0.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Gnarling Shaman"),
|
||||
body: Some(RandomWith("gnarling")),
|
||||
body: RandomWith("gnarling"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-0.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Yeti"),
|
||||
body: Some(RandomWith("yeti")),
|
||||
body: RandomWith("yeti"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-1.boss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Adlet Tracker"),
|
||||
body: Some(RandomWith("adlet")),
|
||||
body: RandomWith("adlet"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-1.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Rat"),
|
||||
body: Some(RandomWith("rat")),
|
||||
body: RandomWith("rat"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.creature.quad_small.generic")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Adlet Hunter"),
|
||||
body: Some(RandomWith("adlet")),
|
||||
body: RandomWith("adlet"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-1.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Adlet Shaman"),
|
||||
body: Some(RandomWith("adlet")),
|
||||
body: RandomWith("adlet"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-1.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Tidal Warrior"),
|
||||
body: Some(RandomWith("tidalwarrior")),
|
||||
body: RandomWith("tidalwarrior"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-2.boss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Sahagin Sniper"),
|
||||
body: Some(RandomWith("sahagin")),
|
||||
body: RandomWith("sahagin"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-2.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Hakulaq"),
|
||||
body: Some(RandomWith("hakulaq")),
|
||||
body: RandomWith("hakulaq"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.creature.quad_low.fanged")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Sahagin Spearman"),
|
||||
body: Some(RandomWith("sahagin")),
|
||||
body: RandomWith("sahagin"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-2.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Sahagin Sorcerer"),
|
||||
body: Some(RandomWith("sahagin")),
|
||||
body: RandomWith("sahagin"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-2.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Bonerattler"),
|
||||
body: Some(RandomWith("bonerattler")),
|
||||
body: RandomWith("bonerattler"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.creature.quad_medium.carapace")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Clay Golem"),
|
||||
body: Some(RandomWith("claygolem")),
|
||||
body: RandomWith("claygolem"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-3.boss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Haniwa Archer"),
|
||||
body: Some(RandomWith("haniwa")),
|
||||
body: RandomWith("haniwa"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-3.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Haniwa Sentry"),
|
||||
body: None,
|
||||
body: Exact(Object(HaniwaSentry)),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(Item("common.items.crafting_ing.stones")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Haniwa Guard"),
|
||||
body: Some(RandomWith("haniwa")),
|
||||
body: RandomWith("haniwa"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-3.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Haniwa Sorcerer"),
|
||||
body: Some(RandomWith("haniwa")),
|
||||
body: RandomWith("haniwa"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-3.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Minotaur"),
|
||||
body: Some(RandomWith("minotaur")),
|
||||
body: RandomWith("minotaur"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-4.boss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Myrmidon Marksman"),
|
||||
body: Some(RandomWith("myrmidon")),
|
||||
body: RandomWith("myrmidon"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-4.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Dullahan"),
|
||||
body: Some(RandomWith("dullahan")),
|
||||
body: RandomWith("dullahan"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-4.miniboss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Myrmidon Hoplite"),
|
||||
body: Some(RandomWith("myrmidon")),
|
||||
body: RandomWith("myrmidon"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-4.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Myrmidon Wizard"),
|
||||
body: Some(RandomWith("myrmidon")),
|
||||
body: RandomWith("myrmidon"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-4.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Beastmaster"),
|
||||
body: Some(RandomWith("humanoid")),
|
||||
body: RandomWith("humanoid"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.miniboss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Mindflayer"),
|
||||
body: Some(RandomWith("mindflayer")),
|
||||
body: RandomWith("mindflayer"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.boss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Cultist"),
|
||||
body: Some(RandomWith("humanoid")),
|
||||
body: RandomWith("humanoid"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Tamed Darkhound"),
|
||||
body: Some(RandomWith("darkhound")),
|
||||
body: RandomWith("darkhound"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.minion")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Cultist Husk"),
|
||||
body: Some(RandomWith("husk")),
|
||||
body: RandomWith("husk"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.minion")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Husk Brute"),
|
||||
body: Some(RandomWith("husk_brute")),
|
||||
body: RandomWith("husk_brute"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.miniboss")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Possessed Turret"),
|
||||
body: None,
|
||||
body: Exact(Object(Crossbow)),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(Item("common.items.crafting_ing.twigs")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Cultist Warlock"),
|
||||
body: Some(RandomWith("cultist_warlock")),
|
||||
body: RandomWith("cultist_warlock"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.enemy")),
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Cultist Warlord"),
|
||||
body: Some(RandomWith("cultist_warlord")),
|
||||
body: RandomWith("cultist_warlord"),
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
loot: Some(LootTable("common.loot_tables.dungeon.tier-5.enemy")),
|
||||
|
||||
|
@ -5,7 +5,11 @@ EntityConfig (
|
||||
/// Body
|
||||
/// Can be Exact (Body with all fields e.g BodyType, Species, Hair color and such)
|
||||
/// or RandomWith (will generate random body or species)
|
||||
body: Some(RandomWith("humanoid")),
|
||||
/// or Uninit (means it should be specified somewhere in code)
|
||||
body: RandomWith("humanoid"),
|
||||
|
||||
/// Alignment, can be Uninit
|
||||
alignment: Alignment(Enemy),
|
||||
|
||||
/// Main and second tools
|
||||
/// Can be Option<Item> (with asset_specifier for item)
|
||||
|
13
assets/common/entity/village/dummy.ron
Normal file
13
assets/common/entity/village/dummy.ron
Normal file
@ -0,0 +1,13 @@
|
||||
EntityConfig (
|
||||
name: Some("Training Dummy"),
|
||||
body: Exact(Object(TrainingDummy)),
|
||||
alignment: Alignment(Passive),
|
||||
|
||||
loot: None,
|
||||
|
||||
main_tool: None,
|
||||
second_tool: None,
|
||||
|
||||
loadout_asset: None,
|
||||
skillset_asset: None,
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Guard"),
|
||||
// body is specified outsite
|
||||
body: None,
|
||||
body: RandomWith("humanoid"),
|
||||
alignment: Alignment(Npc),
|
||||
|
||||
loot: None,
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
EntityConfig (
|
||||
name: Some("Merchant"),
|
||||
// body is specified outsite
|
||||
body: None,
|
||||
body: RandomWith("humanoid"),
|
||||
alignment: Alignment(Npc),
|
||||
|
||||
// considering giving some gold/gems/materials?
|
||||
loot: None,
|
||||
|
@ -1,7 +1,8 @@
|
||||
EntityConfig (
|
||||
// name is specified outsite
|
||||
name: None,
|
||||
// body is specified outsite
|
||||
body: None,
|
||||
body: RandomWith("humanoid"),
|
||||
alignment: Alignment(Npc),
|
||||
|
||||
loot: None,
|
||||
|
||||
|
@ -5,6 +5,7 @@ use crate::{
|
||||
trade::{PendingTrade, ReducedInventory, SiteId, SitePrices, TradeId, TradeResult},
|
||||
uid::Uid,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use specs::{Component, Entity as EcsEntity};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::{collections::VecDeque, fmt};
|
||||
@ -16,7 +17,7 @@ pub const DEFAULT_INTERACTION_TIME: f32 = 1.0;
|
||||
pub const TRADE_INTERACTION_TIME: f32 = 300.0;
|
||||
pub const MAX_LISTEN_DIST: f32 = 100.0;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Deserialize)]
|
||||
pub enum Alignment {
|
||||
/// Wild animals and gentle giants
|
||||
Wild,
|
||||
|
@ -14,8 +14,10 @@ use serde::Deserialize;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
enum BodyKind {
|
||||
enum BodyBuilder {
|
||||
RandomWith(String),
|
||||
Exact(Body),
|
||||
Uninit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
@ -24,10 +26,17 @@ enum LootKind {
|
||||
LootTable(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
enum AlignmentMark {
|
||||
Alignment(Alignment),
|
||||
Uninit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
struct EntityConfig {
|
||||
name: Option<String>,
|
||||
body: Option<BodyKind>,
|
||||
body: BodyBuilder,
|
||||
alignment: AlignmentMark,
|
||||
loot: Option<LootKind>,
|
||||
main_tool: Option<ItemSpec>,
|
||||
second_tool: Option<ItemSpec>,
|
||||
@ -101,6 +110,7 @@ impl EntityInfo {
|
||||
let EntityConfig {
|
||||
name,
|
||||
body,
|
||||
alignment,
|
||||
loot,
|
||||
main_tool,
|
||||
second_tool,
|
||||
@ -112,17 +122,23 @@ impl EntityInfo {
|
||||
self = self.with_name(name);
|
||||
}
|
||||
|
||||
if let Some(body) = body {
|
||||
match body {
|
||||
BodyKind::RandomWith(string) => {
|
||||
let npc::NpcBody(_body_kind, mut body_creator) =
|
||||
string.parse::<npc::NpcBody>().unwrap_or_else(|err| {
|
||||
panic!("failed to parse body {:?}. Err: {:?}", &string, err)
|
||||
});
|
||||
let body = body_creator();
|
||||
self = self.with_body(body);
|
||||
},
|
||||
}
|
||||
match body {
|
||||
BodyBuilder::RandomWith(string) => {
|
||||
let npc::NpcBody(_body_kind, mut body_creator) =
|
||||
string.parse::<npc::NpcBody>().unwrap_or_else(|err| {
|
||||
panic!("failed to parse body {:?}. Err: {:?}", &string, err)
|
||||
});
|
||||
let body = body_creator();
|
||||
self = self.with_body(body);
|
||||
},
|
||||
BodyBuilder::Exact(body) => {
|
||||
self = self.with_body(body);
|
||||
},
|
||||
BodyBuilder::Uninit => {},
|
||||
}
|
||||
|
||||
if let AlignmentMark::Alignment(alignment) = alignment {
|
||||
self = self.with_alignment(alignment);
|
||||
}
|
||||
|
||||
if let Some(loot) = loot {
|
||||
@ -319,9 +335,10 @@ mod tests {
|
||||
second_tool,
|
||||
loadout_asset,
|
||||
skillset_asset,
|
||||
name: _name,
|
||||
body,
|
||||
loot,
|
||||
name: _name, // can't fail if serialized, it's a boring String
|
||||
alignment: _alignment, // can't fail if serialized, it's a boring enum
|
||||
} = config.clone();
|
||||
|
||||
if let Some(main_tool) = main_tool {
|
||||
@ -332,16 +349,15 @@ mod tests {
|
||||
second_tool.validate(EquipSlot::ActiveOffhand);
|
||||
}
|
||||
|
||||
if let Some(body) = body {
|
||||
match body {
|
||||
BodyKind::RandomWith(string) => {
|
||||
let npc::NpcBody(_body_kind, mut body_creator) =
|
||||
string.parse::<npc::NpcBody>().unwrap_or_else(|err| {
|
||||
panic!("failed to parse body {:?}. Err: {:?}", &string, err)
|
||||
});
|
||||
let _ = body_creator();
|
||||
},
|
||||
}
|
||||
match body {
|
||||
BodyBuilder::RandomWith(string) => {
|
||||
let npc::NpcBody(_body_kind, mut body_creator) =
|
||||
string.parse::<npc::NpcBody>().unwrap_or_else(|err| {
|
||||
panic!("failed to parse body {:?}. Err: {:?}", &string, err)
|
||||
});
|
||||
let _ = body_creator();
|
||||
},
|
||||
BodyBuilder::Exact { .. } | BodyBuilder::Uninit => {},
|
||||
}
|
||||
|
||||
if let Some(loot) = loot {
|
||||
|
@ -16,13 +16,13 @@ use crate::{
|
||||
use common::{
|
||||
astar::Astar,
|
||||
comp::{
|
||||
self, agent, bird_medium, humanoid,
|
||||
self, agent, bird_medium,
|
||||
inventory::{
|
||||
loadout_builder::{make_potion_bag, LoadoutBuilder},
|
||||
slot::ArmorSlot,
|
||||
trade_pricing::TradePricing,
|
||||
},
|
||||
object, quadruped_small, Item,
|
||||
quadruped_small, Item,
|
||||
},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
path::Path,
|
||||
@ -860,7 +860,6 @@ impl Settlement {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::eval_order_dependence)] // TODO: Pending review in #587
|
||||
pub fn apply_supplement<'a>(
|
||||
&'a self,
|
||||
// NOTE: Used only for dynamic elements like chests and entities!
|
||||
@ -904,75 +903,19 @@ impl Settlement {
|
||||
if matches!(sample.plot, Some(Plot::Town { .. }))
|
||||
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 40.0))
|
||||
{
|
||||
let is_human: bool;
|
||||
let is_dummy =
|
||||
RandomField::new(self.seed + 1).chance(Vec3::from(wpos2d), 1.0 / 15.0);
|
||||
let entity = EntityInfo::at(entity_wpos)
|
||||
.with_body(match dynamic_rng.gen_range(0..5) {
|
||||
_ if is_dummy => {
|
||||
is_human = false;
|
||||
object::Body::TrainingDummy.into()
|
||||
},
|
||||
0 => {
|
||||
let species = match dynamic_rng.gen_range(0..5) {
|
||||
0 => quadruped_small::Species::Pig,
|
||||
1 => quadruped_small::Species::Sheep,
|
||||
2 => quadruped_small::Species::Goat,
|
||||
3 => quadruped_small::Species::Dog,
|
||||
_ => quadruped_small::Species::Cat,
|
||||
};
|
||||
is_human = false;
|
||||
comp::Body::QuadrupedSmall(quadruped_small::Body::random_with(
|
||||
dynamic_rng,
|
||||
&species,
|
||||
))
|
||||
},
|
||||
1 => {
|
||||
let species = match dynamic_rng.gen_range(0..4) {
|
||||
0 => bird_medium::Species::Duck,
|
||||
1 => bird_medium::Species::Chicken,
|
||||
2 => bird_medium::Species::Goose,
|
||||
_ => bird_medium::Species::Peacock,
|
||||
};
|
||||
is_human = false;
|
||||
comp::Body::BirdMedium(bird_medium::Body::random_with(
|
||||
dynamic_rng,
|
||||
&species,
|
||||
))
|
||||
},
|
||||
_ => {
|
||||
is_human = true;
|
||||
comp::Body::Humanoid(humanoid::Body::random())
|
||||
},
|
||||
})
|
||||
.with_agency(!is_dummy)
|
||||
.with_alignment(if is_dummy {
|
||||
comp::Alignment::Passive
|
||||
} else if is_human {
|
||||
comp::Alignment::Npc
|
||||
} else {
|
||||
comp::Alignment::Tame
|
||||
})
|
||||
.do_if(!is_dummy, |e| e.with_automatic_name())
|
||||
.do_if(is_dummy, |e| e.with_name("Training Dummy"))
|
||||
.do_if(is_human && dynamic_rng.gen(), |entity| {
|
||||
match dynamic_rng.gen_range(0..6) {
|
||||
0 => entity
|
||||
.with_agent_mark(agent::Mark::Guard)
|
||||
.with_lazy_loadout(guard_loadout)
|
||||
.with_level(dynamic_rng.gen_range(10..15))
|
||||
.with_asset_expect("common.entity.village.guard"),
|
||||
1 | 2 => entity
|
||||
.with_agent_mark(agent::Mark::Merchant)
|
||||
.with_economy(&economy)
|
||||
.with_lazy_loadout(merchant_loadout)
|
||||
.with_level(dynamic_rng.gen_range(10..15))
|
||||
.with_asset_expect("common.entity.village.merchant"),
|
||||
_ => entity
|
||||
.with_lazy_loadout(villager_loadout)
|
||||
.with_asset_expect("common.entity.village.villager"),
|
||||
}
|
||||
});
|
||||
let entity = if is_dummy {
|
||||
EntityInfo::at(entity_wpos)
|
||||
.with_agency(false)
|
||||
.with_asset_expect("common.entity.village.dummy")
|
||||
} else {
|
||||
match dynamic_rng.gen_range(0..=4) {
|
||||
0 => barnyard(entity_wpos, dynamic_rng),
|
||||
1 => bird(entity_wpos, dynamic_rng),
|
||||
_ => human(entity_wpos, &economy, dynamic_rng),
|
||||
}
|
||||
};
|
||||
|
||||
supplement.add_entity(entity);
|
||||
}
|
||||
@ -1031,6 +974,59 @@ impl Settlement {
|
||||
}
|
||||
}
|
||||
|
||||
fn barnyard(pos: Vec3<f32>, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
let species = match dynamic_rng.gen_range(0..5) {
|
||||
0 => quadruped_small::Species::Pig,
|
||||
1 => quadruped_small::Species::Sheep,
|
||||
2 => quadruped_small::Species::Goat,
|
||||
3 => quadruped_small::Species::Dog,
|
||||
_ => quadruped_small::Species::Cat,
|
||||
};
|
||||
EntityInfo::at(pos)
|
||||
.with_body(comp::Body::QuadrupedSmall(
|
||||
quadruped_small::Body::random_with(dynamic_rng, &species),
|
||||
))
|
||||
.with_alignment(comp::Alignment::Tame)
|
||||
.with_automatic_name()
|
||||
}
|
||||
|
||||
fn bird(pos: Vec3<f32>, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
let species = match dynamic_rng.gen_range(0..4) {
|
||||
0 => bird_medium::Species::Duck,
|
||||
1 => bird_medium::Species::Chicken,
|
||||
2 => bird_medium::Species::Goose,
|
||||
_ => bird_medium::Species::Peacock,
|
||||
};
|
||||
EntityInfo::at(pos)
|
||||
.with_body(comp::Body::BirdMedium(bird_medium::Body::random_with(
|
||||
dynamic_rng,
|
||||
&species,
|
||||
)))
|
||||
.with_alignment(comp::Alignment::Tame)
|
||||
.with_automatic_name()
|
||||
}
|
||||
|
||||
fn human(pos: Vec3<f32>, economy: &SiteInformation, dynamic_rng: &mut impl Rng) -> EntityInfo {
|
||||
let entity = EntityInfo::at(pos);
|
||||
match dynamic_rng.gen_range(0..12) {
|
||||
0 => entity
|
||||
.with_agent_mark(agent::Mark::Guard)
|
||||
.with_lazy_loadout(guard_loadout)
|
||||
.with_level(dynamic_rng.gen_range(10..15))
|
||||
.with_asset_expect("common.entity.village.guard"),
|
||||
1 | 2 => entity
|
||||
.with_agent_mark(agent::Mark::Merchant)
|
||||
.with_economy(&economy)
|
||||
.with_lazy_loadout(merchant_loadout)
|
||||
.with_level(dynamic_rng.gen_range(10..15))
|
||||
.with_asset_expect("common.entity.village.merchant"),
|
||||
_ => entity
|
||||
.with_lazy_loadout(villager_loadout)
|
||||
.with_asset_expect("common.entity.village.villager")
|
||||
.with_automatic_name(),
|
||||
}
|
||||
}
|
||||
|
||||
fn merchant_loadout(
|
||||
loadout_builder: LoadoutBuilder,
|
||||
economy: Option<&trade::SiteInformation>,
|
||||
|
@ -9,7 +9,6 @@ use crate::{
|
||||
use common::{
|
||||
assets::{self, AssetExt, AssetHandle},
|
||||
astar::Astar,
|
||||
comp::{self},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
store::{Id, Store},
|
||||
terrain::{
|
||||
@ -235,16 +234,14 @@ impl Room {
|
||||
|
||||
for entity in entities {
|
||||
supplement.add_entity(
|
||||
entity
|
||||
.with_level(
|
||||
dynamic_rng
|
||||
.gen_range(
|
||||
(self.difficulty as f32).powf(1.25) + 3.0
|
||||
..(self.difficulty as f32).powf(1.5) + 4.0,
|
||||
)
|
||||
.round() as u16,
|
||||
)
|
||||
.with_alignment(comp::Alignment::Enemy),
|
||||
entity.with_level(
|
||||
dynamic_rng
|
||||
.gen_range(
|
||||
(self.difficulty as f32).powf(1.25) + 3.0
|
||||
..(self.difficulty as f32).powf(1.5) + 4.0,
|
||||
)
|
||||
.round() as u16,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -260,19 +257,13 @@ impl Room {
|
||||
- 16
|
||||
})
|
||||
.map(|e| e as f32 / 16.0);
|
||||
let turret =
|
||||
EntityInfo::at(pos.map(|e| e as f32)).with_alignment(comp::Alignment::Enemy);
|
||||
match self.difficulty {
|
||||
3 => {
|
||||
let turret = turret
|
||||
.with_body(comp::Body::Object(comp::object::Body::HaniwaSentry))
|
||||
.with_asset_expect("common.entity.dungeon.tier-3.sentry");
|
||||
let turret = turret_3(pos);
|
||||
supplement.add_entity(turret);
|
||||
},
|
||||
5 => {
|
||||
let turret = turret
|
||||
.with_body(comp::Body::Object(comp::object::Body::Crossbow))
|
||||
.with_asset_expect("common.entity.dungeon.tier-5.turret");
|
||||
let turret = turret_5(pos);
|
||||
supplement.add_entity(turret);
|
||||
},
|
||||
_ => {},
|
||||
@ -311,17 +302,15 @@ impl Room {
|
||||
|
||||
for entity in entities {
|
||||
supplement.add_entity(
|
||||
entity
|
||||
.with_level(
|
||||
dynamic_rng
|
||||
.gen_range(
|
||||
(self.difficulty as f32).powf(1.25) + 3.0
|
||||
..(self.difficulty as f32).powf(1.5) + 4.0,
|
||||
)
|
||||
.round() as u16
|
||||
* 5,
|
||||
)
|
||||
.with_alignment(comp::Alignment::Enemy),
|
||||
entity.with_level(
|
||||
dynamic_rng
|
||||
.gen_range(
|
||||
(self.difficulty as f32).powf(1.25) + 3.0
|
||||
..(self.difficulty as f32).powf(1.5) + 4.0,
|
||||
)
|
||||
.round() as u16
|
||||
* 5,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -357,17 +346,15 @@ impl Room {
|
||||
|
||||
for entity in entities {
|
||||
supplement.add_entity(
|
||||
entity
|
||||
.with_level(
|
||||
dynamic_rng
|
||||
.gen_range(
|
||||
(self.difficulty as f32).powf(1.25) + 3.0
|
||||
..(self.difficulty as f32).powf(1.5) + 4.0,
|
||||
)
|
||||
.round() as u16
|
||||
* 5,
|
||||
)
|
||||
.with_alignment(comp::Alignment::Enemy),
|
||||
entity.with_level(
|
||||
dynamic_rng
|
||||
.gen_range(
|
||||
(self.difficulty as f32).powf(1.25) + 3.0
|
||||
..(self.difficulty as f32).powf(1.5) + 4.0,
|
||||
)
|
||||
.round() as u16
|
||||
* 5,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -789,6 +776,14 @@ fn enemy_fallback(dynamic_rng: &mut impl Rng, tile_wcenter: Vec3<i32>) -> Vec<En
|
||||
entities
|
||||
}
|
||||
|
||||
fn turret_3(pos: Vec3<f32>) -> EntityInfo {
|
||||
EntityInfo::at(pos).with_asset_expect("common.entity.dungeon.tier-3.sentry")
|
||||
}
|
||||
|
||||
fn turret_5(pos: Vec3<f32>) -> EntityInfo {
|
||||
EntityInfo::at(pos).with_asset_expect("common.entity.dungeon.tier-5.turret")
|
||||
}
|
||||
|
||||
fn boss_0(tile_wcenter: Vec3<i32>) -> Vec<EntityInfo> {
|
||||
vec![
|
||||
EntityInfo::at(tile_wcenter.map(|e| e as f32))
|
||||
@ -1441,4 +1436,11 @@ mod tests {
|
||||
mini_boss_5(&mut dynamic_rng, tile_wcenter);
|
||||
mini_boss_fallback(tile_wcenter);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_creating_turrets() {
|
||||
let pos = Vec3::new(0.0, 0.0, 0.0);
|
||||
turret_3(pos);
|
||||
turret_5(pos);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user