diff --git a/assets/common/entity/dungeon/fallback/boss.ron b/assets/common/entity/dungeon/fallback/boss.ron index caf7fc2256..75c4df67af 100644 --- a/assets/common/entity/dungeon/fallback/boss.ron +++ b/assets/common/entity/dungeon/fallback/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Crazy Sheep"), - body: Some(RandomWith("sheep")), + name: Name("Crazy Sheep"), + body: RandomWith("sheep"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.fallback")), + loot: LootTable("common.loot_tables.fallback"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/fallback/enemy.ron b/assets/common/entity/dungeon/fallback/enemy.ron index 63e9172578..47f2e8acdf 100644 --- a/assets/common/entity/dungeon/fallback/enemy.ron +++ b/assets/common/entity/dungeon/fallback/enemy.ron @@ -1,10 +1,11 @@ EntityConfig ( - name: Some("Yan Hus"), - body: Some(RandomWith("humanoid")), + name: Name("Yan Hus"), + body: RandomWith("humanoid"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.fallback")), + loot: LootTable("common.loot_tables.fallback"), - main_tool: Some(Choice([ + hands: TwoHanded(Choice([ (1.0, Some(Item("common.items.weapons.tool.broom"))), (1.0, Some(Item("common.items.weapons.tool.hoe"))), (1.0, Some(Item("common.items.weapons.tool.pickaxe"))), @@ -13,8 +14,6 @@ EntityConfig ( (1.0, Some(Item("common.items.weapons.tool.shovel-1"))), (1.0, Some(Item("common.items.weapons.bow.bone-1"))), ])), - second_tool: None, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/fallback/miniboss.ron b/assets/common/entity/dungeon/fallback/miniboss.ron index 6f7ba8171e..94112f89f0 100644 --- a/assets/common/entity/dungeon/fallback/miniboss.ron +++ b/assets/common/entity/dungeon/fallback/miniboss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Big Goose"), - body: Some(RandomWith("goose")), + name: Name("Big Goose"), + body: RandomWith("goose"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.fallback")), + loot: LootTable("common.loot_tables.fallback"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-0/boss.ron b/assets/common/entity/dungeon/tier-0/boss.ron index 98483efc4d..b681c19cb5 100644 --- a/assets/common/entity/dungeon/tier-0/boss.ron +++ b/assets/common/entity/dungeon/tier-0/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Harvester"), - body: Some(RandomWith("harvester")), + name: Name("Harvester"), + body: RandomWith("harvester"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-0.boss")), + loot: LootTable("common.loot_tables.dungeon.tier-0.boss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-0/bow.ron b/assets/common/entity/dungeon/tier-0/bow.ron index be2948eb55..7ff0555517 100644 --- a/assets/common/entity/dungeon/tier-0/bow.ron +++ b/assets/common/entity/dungeon/tier-0/bow.ron @@ -1,12 +1,14 @@ EntityConfig ( - name: Some("Gnarling Stalker"), - body: Some(RandomWith("gnarling")), + name: Name("Gnarling Stalker"), + body: RandomWith("gnarling"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-0.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-0.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.adlet_bow")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.gnarling.adlet_bow")), - loadout_asset: Some("common.loadout.dungeon.tier-0.gnarling"), - skillset_asset: Some("common.skillset.dungeon.tier-0.bow"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-0.gnarling"), + SkillSetAsset("common.skillset.dungeon.tier-0.bow"), + ], ) diff --git a/assets/common/entity/dungeon/tier-0/miniboss.ron b/assets/common/entity/dungeon/tier-0/miniboss.ron index 411ef1a7b1..c02abcefee 100644 --- a/assets/common/entity/dungeon/tier-0/miniboss.ron +++ b/assets/common/entity/dungeon/tier-0/miniboss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Deadwood"), - body: Some(RandomWith("deadwood")), + name: Name("Deadwood"), + body: RandomWith("deadwood"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-0.miniboss")), + loot: LootTable("common.loot_tables.dungeon.tier-0.miniboss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-0/spear.ron b/assets/common/entity/dungeon/tier-0/spear.ron index e5a4d9e2ad..e30541c047 100644 --- a/assets/common/entity/dungeon/tier-0/spear.ron +++ b/assets/common/entity/dungeon/tier-0/spear.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Gnarling Mugger"), - body: Some(RandomWith("gnarling")), + name: Name("Gnarling Mugger"), + body: RandomWith("gnarling"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-0.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-0.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.wooden_spear")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.gnarling.wooden_spear")), - loadout_asset: Some("common.loadout.dungeon.tier-0.gnarling"), - skillset_asset: None, + meta: [ + LoadoutAsset("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 index 7202904324..cbcd59a973 100644 --- a/assets/common/entity/dungeon/tier-0/staff.ron +++ b/assets/common/entity/dungeon/tier-0/staff.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Gnarling Shaman"), - body: Some(RandomWith("gnarling")), + name: Name("Gnarling Shaman"), + body: RandomWith("gnarling"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-0.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-0.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.gnarling.gnoll_staff")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.gnarling.gnoll_staff")), - loadout_asset: Some("common.loadout.dungeon.tier-0.gnarling"), - skillset_asset: None, + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-0.gnarling"), + ], ) diff --git a/assets/common/entity/dungeon/tier-1/boss.ron b/assets/common/entity/dungeon/tier-1/boss.ron index 30035d7c3f..28b829d9bc 100644 --- a/assets/common/entity/dungeon/tier-1/boss.ron +++ b/assets/common/entity/dungeon/tier-1/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Yeti"), - body: Some(RandomWith("yeti")), + name: Name("Yeti"), + body: RandomWith("yeti"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-1.boss")), + loot: LootTable("common.loot_tables.dungeon.tier-1.boss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-1/bow.ron b/assets/common/entity/dungeon/tier-1/bow.ron index 013fd7c04c..df8961b483 100644 --- a/assets/common/entity/dungeon/tier-1/bow.ron +++ b/assets/common/entity/dungeon/tier-1/bow.ron @@ -1,12 +1,14 @@ EntityConfig ( - name: Some("Adlet Tracker"), - body: Some(RandomWith("adlet")), + name: Name("Adlet Tracker"), + body: RandomWith("adlet"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-1.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-1.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.adlet_bow")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.adlet.adlet_bow")), - loadout_asset: Some("common.loadout.dungeon.tier-1.adlet_bow"), - skillset_asset: Some("common.skillset.dungeon.tier-1.bow"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-1.adlet_bow"), + SkillSetAsset("common.skillset.dungeon.tier-1.bow"), + ], ) diff --git a/assets/common/entity/dungeon/tier-1/rat.ron b/assets/common/entity/dungeon/tier-1/rat.ron index 565057282d..f5d548b923 100644 --- a/assets/common/entity/dungeon/tier-1/rat.ron +++ b/assets/common/entity/dungeon/tier-1/rat.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Rat"), - body: Some(RandomWith("rat")), + name: Name("Rat"), + body: RandomWith("rat"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.creature.quad_small.generic")), + loot: LootTable("common.loot_tables.creature.quad_small.generic"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-1/spear.ron b/assets/common/entity/dungeon/tier-1/spear.ron index 0ce2a1b28c..882e6ea05d 100644 --- a/assets/common/entity/dungeon/tier-1/spear.ron +++ b/assets/common/entity/dungeon/tier-1/spear.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Adlet Hunter"), - body: Some(RandomWith("adlet")), + name: Name("Adlet Hunter"), + body: RandomWith("adlet"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-1.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-1.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.wooden_spear")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.adlet.wooden_spear")), - loadout_asset: Some("common.loadout.dungeon.tier-1.adlet_spear"), - skillset_asset: None, + meta: [ + LoadoutAsset("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 index d9dc6d2a3e..314e450021 100644 --- a/assets/common/entity/dungeon/tier-1/staff.ron +++ b/assets/common/entity/dungeon/tier-1/staff.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Adlet Shaman"), - body: Some(RandomWith("adlet")), + name: Name("Adlet Shaman"), + body: RandomWith("adlet"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-1.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-1.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.adlet.gnoll_staff")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.adlet.gnoll_staff")), - loadout_asset: Some("common.loadout.dungeon.tier-1.adlet_spear"), - skillset_asset: None, + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-1.adlet_spear"), + ], ) diff --git a/assets/common/entity/dungeon/tier-2/boss.ron b/assets/common/entity/dungeon/tier-2/boss.ron index 4db8d8d5d2..a9b4c2b26b 100644 --- a/assets/common/entity/dungeon/tier-2/boss.ron +++ b/assets/common/entity/dungeon/tier-2/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Tidal Warrior"), - body: Some(RandomWith("tidalwarrior")), + name: Name("Tidal Warrior"), + body: RandomWith("tidalwarrior"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-2.boss")), + loot: LootTable("common.loot_tables.dungeon.tier-2.boss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-2/bow.ron b/assets/common/entity/dungeon/tier-2/bow.ron index abd5927b14..f780d5c7d0 100644 --- a/assets/common/entity/dungeon/tier-2/bow.ron +++ b/assets/common/entity/dungeon/tier-2/bow.ron @@ -1,12 +1,14 @@ EntityConfig ( - name: Some("Sahagin Sniper"), - body: Some(RandomWith("sahagin")), + name: Name("Sahagin Sniper"), + body: RandomWith("sahagin"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-2.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-2.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.adlet_bow")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.sahagin.adlet_bow")), - loadout_asset: Some("common.loadout.dungeon.tier-2.sahagin"), - skillset_asset: Some("common.skillset.dungeon.tier-2.bow"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-2.sahagin"), + SkillSetAsset("common.skillset.dungeon.tier-2.bow"), + ], ) diff --git a/assets/common/entity/dungeon/tier-2/hakulaq.ron b/assets/common/entity/dungeon/tier-2/hakulaq.ron index 8f279e3943..46bc76a674 100644 --- a/assets/common/entity/dungeon/tier-2/hakulaq.ron +++ b/assets/common/entity/dungeon/tier-2/hakulaq.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Hakulaq"), - body: Some(RandomWith("hakulaq")), + name: Name("Hakulaq"), + body: RandomWith("hakulaq"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.creature.quad_low.fanged")), + loot: LootTable("common.loot_tables.creature.quad_low.fanged"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-2/spear.ron b/assets/common/entity/dungeon/tier-2/spear.ron index bce3699599..2d867f83fa 100644 --- a/assets/common/entity/dungeon/tier-2/spear.ron +++ b/assets/common/entity/dungeon/tier-2/spear.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Sahagin Spearman"), - body: Some(RandomWith("sahagin")), + name: Name("Sahagin Spearman"), + body: RandomWith("sahagin"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-2.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-2.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.wooden_spear")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.sahagin.wooden_spear")), - loadout_asset: Some("common.loadout.dungeon.tier-2.sahagin"), - skillset_asset: None, + meta: [ + LoadoutAsset("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 index e41cddb070..e1a883baa7 100644 --- a/assets/common/entity/dungeon/tier-2/staff.ron +++ b/assets/common/entity/dungeon/tier-2/staff.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Sahagin Sorcerer"), - body: Some(RandomWith("sahagin")), + name: Name("Sahagin Sorcerer"), + body: RandomWith("sahagin"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-2.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-2.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.sahagin.gnoll_staff")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.sahagin.gnoll_staff")), - loadout_asset: Some("common.loadout.dungeon.tier-2.sahagin"), - skillset_asset: None, + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-2.sahagin"), + ], ) diff --git a/assets/common/entity/dungeon/tier-3/bonerattler.ron b/assets/common/entity/dungeon/tier-3/bonerattler.ron index 1fbf9329eb..0af1afa98f 100644 --- a/assets/common/entity/dungeon/tier-3/bonerattler.ron +++ b/assets/common/entity/dungeon/tier-3/bonerattler.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Bonerattler"), - body: Some(RandomWith("bonerattler")), + name: Name("Bonerattler"), + body: RandomWith("bonerattler"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.creature.quad_medium.carapace")), + loot: LootTable("common.loot_tables.creature.quad_medium.carapace"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-3/boss.ron b/assets/common/entity/dungeon/tier-3/boss.ron index cf6ddc11ed..ecc9b398d5 100644 --- a/assets/common/entity/dungeon/tier-3/boss.ron +++ b/assets/common/entity/dungeon/tier-3/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Clay Golem"), - body: Some(RandomWith("claygolem")), + name: Name("Clay Golem"), + body: RandomWith("claygolem"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-3.boss")), + loot: LootTable("common.loot_tables.dungeon.tier-3.boss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-3/bow.ron b/assets/common/entity/dungeon/tier-3/bow.ron index f693a38d03..386a4dc500 100644 --- a/assets/common/entity/dungeon/tier-3/bow.ron +++ b/assets/common/entity/dungeon/tier-3/bow.ron @@ -1,12 +1,14 @@ EntityConfig ( - name: Some("Haniwa Archer"), - body: Some(RandomWith("haniwa")), + name: Name("Haniwa Archer"), + body: RandomWith("haniwa"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-3.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-3.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.adlet_bow")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.haniwa.adlet_bow")), - loadout_asset: Some("common.loadout.dungeon.tier-3.haniwa"), - skillset_asset: Some("common.skillset.dungeon.tier-3.bow"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-3.haniwa"), + SkillSetAsset("common.skillset.dungeon.tier-3.bow"), + ], ) diff --git a/assets/common/entity/dungeon/tier-3/sentry.ron b/assets/common/entity/dungeon/tier-3/sentry.ron index 724f259ee4..253e6b6070 100644 --- a/assets/common/entity/dungeon/tier-3/sentry.ron +++ b/assets/common/entity/dungeon/tier-3/sentry.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Haniwa Sentry"), - body: None, + name: Name("Haniwa Sentry"), + body: Exact(Object(HaniwaSentry)), + alignment: Alignment(Enemy), - loot: Some(Item("common.items.crafting_ing.stones")), + loot: Item("common.items.crafting_ing.stones"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-3/spear.ron b/assets/common/entity/dungeon/tier-3/spear.ron index 376d2d67e6..1999cd45af 100644 --- a/assets/common/entity/dungeon/tier-3/spear.ron +++ b/assets/common/entity/dungeon/tier-3/spear.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Haniwa Guard"), - body: Some(RandomWith("haniwa")), + name: Name("Haniwa Guard"), + body: RandomWith("haniwa"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-3.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-3.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.wooden_spear")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.haniwa.wooden_spear")), - loadout_asset: Some("common.loadout.dungeon.tier-3.haniwa"), - skillset_asset: None, + meta: [ + LoadoutAsset("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 index f8d051f2b7..d71561c3c5 100644 --- a/assets/common/entity/dungeon/tier-3/staff.ron +++ b/assets/common/entity/dungeon/tier-3/staff.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Haniwa Sorcerer"), - body: Some(RandomWith("haniwa")), + name: Name("Haniwa Sorcerer"), + body: RandomWith("haniwa"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-3.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-3.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.haniwa.gnoll_staff")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.haniwa.gnoll_staff")), - loadout_asset: Some("common.loadout.dungeon.tier-3.haniwa"), - skillset_asset: None, + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-3.haniwa"), + ], ) diff --git a/assets/common/entity/dungeon/tier-4/boss.ron b/assets/common/entity/dungeon/tier-4/boss.ron index 5f8883c1dd..23fdfabe82 100644 --- a/assets/common/entity/dungeon/tier-4/boss.ron +++ b/assets/common/entity/dungeon/tier-4/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Minotaur"), - body: Some(RandomWith("minotaur")), + name: Name("Minotaur"), + body: RandomWith("minotaur"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-4.boss")), + loot: LootTable("common.loot_tables.dungeon.tier-4.boss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-4/bow.ron b/assets/common/entity/dungeon/tier-4/bow.ron index 04ec56dc59..f56692f884 100644 --- a/assets/common/entity/dungeon/tier-4/bow.ron +++ b/assets/common/entity/dungeon/tier-4/bow.ron @@ -1,12 +1,14 @@ EntityConfig ( - name: Some("Myrmidon Marksman"), - body: Some(RandomWith("myrmidon")), + name: Name("Myrmidon Marksman"), + body: RandomWith("myrmidon"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-4.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-4.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.adlet_bow")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.myrmidon.adlet_bow")), - loadout_asset: Some("common.loadout.dungeon.tier-4.myrmidon"), - skillset_asset: Some("common.skillset.dungeon.tier-4.bow"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-4.myrmidon"), + SkillSetAsset("common.skillset.dungeon.tier-4.bow"), + ], ) diff --git a/assets/common/entity/dungeon/tier-4/miniboss.ron b/assets/common/entity/dungeon/tier-4/miniboss.ron index 46ba728ead..352fc3a70e 100644 --- a/assets/common/entity/dungeon/tier-4/miniboss.ron +++ b/assets/common/entity/dungeon/tier-4/miniboss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Dullahan"), - body: Some(RandomWith("dullahan")), + name: Name("Dullahan"), + body: RandomWith("dullahan"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-4.miniboss")), + loot: LootTable("common.loot_tables.dungeon.tier-4.miniboss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-4/spear.ron b/assets/common/entity/dungeon/tier-4/spear.ron index dffc6440dd..579f971a70 100644 --- a/assets/common/entity/dungeon/tier-4/spear.ron +++ b/assets/common/entity/dungeon/tier-4/spear.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Myrmidon Hoplite"), - body: Some(RandomWith("myrmidon")), + name: Name("Myrmidon Hoplite"), + body: RandomWith("myrmidon"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-4.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-4.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.wooden_spear")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.myrmidon.wooden_spear")), - loadout_asset: Some("common.loadout.dungeon.tier-4.myrmidon"), - skillset_asset: None, + meta: [ + LoadoutAsset("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 index 8d432875d2..e5a800e39a 100644 --- a/assets/common/entity/dungeon/tier-4/staff.ron +++ b/assets/common/entity/dungeon/tier-4/staff.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Myrmidon Wizard"), - body: Some(RandomWith("myrmidon")), + name: Name("Myrmidon Wizard"), + body: RandomWith("myrmidon"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-4.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-4.enemy"), - main_tool: Some(Item("common.items.npc_weapons.biped_small.myrmidon.gnoll_staff")), - second_tool: None, + hands: TwoHanded(Item("common.items.npc_weapons.biped_small.myrmidon.gnoll_staff")), - loadout_asset: Some("common.loadout.dungeon.tier-4.myrmidon"), - skillset_asset: None, + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-4.myrmidon"), + ], ) diff --git a/assets/common/entity/dungeon/tier-5/beastmaster.ron b/assets/common/entity/dungeon/tier-5/beastmaster.ron index 29987a13e2..fc58c78a73 100644 --- a/assets/common/entity/dungeon/tier-5/beastmaster.ron +++ b/assets/common/entity/dungeon/tier-5/beastmaster.ron @@ -1,17 +1,19 @@ EntityConfig ( - name: Some("Beastmaster"), - body: Some(RandomWith("humanoid")), + name: Name("Beastmaster"), + body: RandomWith("humanoid"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.miniboss")), + loot: LootTable("common.loot_tables.dungeon.tier-5.miniboss"), - main_tool: Some(Choice([ + hands: TwoHanded(Choice([ (1.0, Some(Item("common.items.weapons.axe.malachite_axe-0"))), (1.0, Some(Item("common.items.weapons.sword.bloodsteel-1"))), (1.0, Some(Item("common.items.weapons.bow.velorite"))), ])), - second_tool: None, - loadout_asset: Some("common.loadout.dungeon.tier-5.beastmaster"), - // TODO: make own skillset for him? - skillset_asset: Some("common.skillset.dungeon.tier-5.enemy"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-5.beastmaster"), + // TODO: make own skillset for him? + SkillSetAsset("common.skillset.dungeon.tier-5.enemy"), + ], ) diff --git a/assets/common/entity/dungeon/tier-5/boss.ron b/assets/common/entity/dungeon/tier-5/boss.ron index 9957ec5482..4de7ebd0da 100644 --- a/assets/common/entity/dungeon/tier-5/boss.ron +++ b/assets/common/entity/dungeon/tier-5/boss.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Mindflayer"), - body: Some(RandomWith("mindflayer")), + name: Name("Mindflayer"), + body: RandomWith("mindflayer"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.boss")), + loot: LootTable("common.loot_tables.dungeon.tier-5.boss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-5/cultist.ron b/assets/common/entity/dungeon/tier-5/cultist.ron index b8e7996861..88e29509b0 100644 --- a/assets/common/entity/dungeon/tier-5/cultist.ron +++ b/assets/common/entity/dungeon/tier-5/cultist.ron @@ -1,10 +1,11 @@ EntityConfig ( - name: Some("Cultist"), - body: Some(RandomWith("humanoid")), + name: Name("Cultist"), + body: RandomWith("humanoid"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-5.enemy"), - main_tool: Some(Choice([ + hands: TwoHanded(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"))), @@ -12,8 +13,9 @@ EntityConfig ( (1.0, Some(Item("common.items.weapons.bow.velorite"))), (1.0, Some(Item("common.items.weapons.sceptre.sceptre_velorite_0"))), ])), - second_tool: None, - loadout_asset: Some("common.loadout.dungeon.tier-5.cultist"), - skillset_asset: Some("common.skillset.dungeon.tier-5.enemy"), + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-5.cultist"), + SkillSetAsset("common.skillset.dungeon.tier-5.enemy"), + ], ) diff --git a/assets/common/entity/dungeon/tier-5/hound.ron b/assets/common/entity/dungeon/tier-5/hound.ron index 0b78c67746..85c3702bde 100644 --- a/assets/common/entity/dungeon/tier-5/hound.ron +++ b/assets/common/entity/dungeon/tier-5/hound.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Tamed Darkhound"), - body: Some(RandomWith("darkhound")), + name: Name("Tamed Darkhound"), + body: RandomWith("darkhound"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.minion")), + loot: LootTable("common.loot_tables.dungeon.tier-5.minion"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-5/husk.ron b/assets/common/entity/dungeon/tier-5/husk.ron index a28e46db0e..936a938867 100644 --- a/assets/common/entity/dungeon/tier-5/husk.ron +++ b/assets/common/entity/dungeon/tier-5/husk.ron @@ -1,12 +1,13 @@ EntityConfig ( - name: Some("Cultist Husk"), - body: Some(RandomWith("husk")), + name: Name("Cultist Husk"), + body: RandomWith("husk"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.minion")), + loot: LootTable("common.loot_tables.dungeon.tier-5.minion"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: Some("common.loadout.dungeon.tier-5.husk"), - skillset_asset: None, + meta: [ + LoadoutAsset("common.loadout.dungeon.tier-5.husk"), + ], ) diff --git a/assets/common/entity/dungeon/tier-5/husk_brute.ron b/assets/common/entity/dungeon/tier-5/husk_brute.ron index 40f26815b6..9c16fa0721 100644 --- a/assets/common/entity/dungeon/tier-5/husk_brute.ron +++ b/assets/common/entity/dungeon/tier-5/husk_brute.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Husk Brute"), - body: Some(RandomWith("husk_brute")), + name: Name("Husk Brute"), + body: RandomWith("husk_brute"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.miniboss")), + loot: LootTable("common.loot_tables.dungeon.tier-5.miniboss"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-5/turret.ron b/assets/common/entity/dungeon/tier-5/turret.ron index bb84413d6a..c31a081875 100644 --- a/assets/common/entity/dungeon/tier-5/turret.ron +++ b/assets/common/entity/dungeon/tier-5/turret.ron @@ -1,12 +1,11 @@ EntityConfig ( - name: Some("Possessed Turret"), - body: None, + name: Name("Possessed Turret"), + body: Exact(Object(Crossbow)), + alignment: Alignment(Enemy), - loot: Some(Item("common.items.crafting_ing.twigs")), + loot: Item("common.items.crafting_ing.twigs"), - main_tool: None, - second_tool: None, + hands: Uninit, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-5/warlock.ron b/assets/common/entity/dungeon/tier-5/warlock.ron index 369bd091cb..0ee439d4df 100644 --- a/assets/common/entity/dungeon/tier-5/warlock.ron +++ b/assets/common/entity/dungeon/tier-5/warlock.ron @@ -1,15 +1,14 @@ EntityConfig ( - name: Some("Cultist Warlock"), - body: Some(RandomWith("cultist_warlock")), + name: Name("Cultist Warlock"), + body: RandomWith("cultist_warlock"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-5.enemy"), - main_tool: Some(Choice([ + hands: TwoHanded(Choice([ (1.5, Some(Item("common.items.npc_weapons.staff.bipedlarge-cultist"))), (1.0, Some(Item("common.items.npc_weapons.bow.bipedlarge-velorite"))), ])), - second_tool: None, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/dungeon/tier-5/warlord.ron b/assets/common/entity/dungeon/tier-5/warlord.ron index fe2152e6e4..22bbe5741f 100644 --- a/assets/common/entity/dungeon/tier-5/warlord.ron +++ b/assets/common/entity/dungeon/tier-5/warlord.ron @@ -1,15 +1,14 @@ EntityConfig ( - name: Some("Cultist Warlord"), - body: Some(RandomWith("cultist_warlord")), + name: Name("Cultist Warlord"), + body: RandomWith("cultist_warlord"), + alignment: Alignment(Enemy), - loot: Some(LootTable("common.loot_tables.dungeon.tier-5.enemy")), + loot: LootTable("common.loot_tables.dungeon.tier-5.enemy"), - main_tool: Some(Choice([ + hands: TwoHanded(Choice([ (1.5, Some(Item("common.items.npc_weapons.sword.bipedlarge-cultist"))), (1.0, Some(Item("common.items.npc_weapons.hammer.bipedlarge-cultist"))), ])), - second_tool: None, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/template.ron b/assets/common/entity/template.ron new file mode 100644 index 0000000000..5743f305a3 --- /dev/null +++ b/assets/common/entity/template.ron @@ -0,0 +1,42 @@ +EntityConfig ( + /// Name of Entity + /// Can be Name(String) with given name + /// or Automatic which will call automatic name depend on Body + /// or Uninit (means it should be specified somewhere in code) + name: Name("Paddy"), + + /// Body + /// Can be Exact (Body with all fields e.g BodyType, Species, Hair color and such) + /// or RandomWith (will generate random body or species) + /// or Uninit (means it should be specified somewhere in code) + body: RandomWith("humanoid"), + + /// Alignment, can be Uninit + alignment: Alignment(Enemy), + + /// Loot + /// Can be Item (with asset_specifier for item) + /// or LootTable (with asset_specifier for loot table) + /// or Uninit (means it should be specified something in the code) + loot: LootTable("common.loot_tables.humanoids"), + + /// Hands: + /// - TwoHanded(ItemSpec) for one 2h or 1h weapon, + /// - Paired(ItemSpec) for two 1h weapons aka berserker mode, + /// - Mix { + /// mainhand: ItemSpec, + /// offhand: ItemSpec, + /// } for two different 1h weapons, + /// - Uninit which means that tool should be specified somewhere in code, + /// Where ItemSpec is taken from loadout_builder module + hands: TwoHanded(Item("common.items.weapons.sword.cultist")), + + /// Meta Info + /// Possible fields: + /// LoadoutAsset(String) with asset_specifier for loadout + /// SkillSetAsset(String) with asset_specifier for skillset + meta: [ + LoadoutAsset("common.loadout.village.merchant"), + SkillSetAsset("common.skillset.village.merchant"), + ], +) diff --git a/assets/common/entity/test.ron b/assets/common/entity/test.ron deleted file mode 100644 index 20c8ff8fb6..0000000000 --- a/assets/common/entity/test.ron +++ /dev/null @@ -1,30 +0,0 @@ -EntityConfig ( - /// Name of Entity - name: Some("Paddy"), - - /// 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")), - - /// Main and second tools - /// Can be Option (with asset_specifier for item) - /// or Choice - /// (array of pairs with weight of choosing some item and Option) - main_tool: Some(Item("common.items.weapons.axe_1h.orichalcum-0")), - second_tool: None, - - /// Loadout Config (with asset_specifier for loadout) - loadout_asset: Some("common.loadout.village.merchant"), - - /// Skillset Config (with asset_specifier for skillset) - skillset_asset: Some("common.skillset.village.merchant"), - - /// Loot - /// Can be Item (with asset_specifier for item) - /// or LootTable (with asset_specifier for loot table) - loot: Some(LootTable("common.loot_tables.humanoids")), - - /// Meta Info (level, alignment, agency, etc) - // meta: {}, -) diff --git a/assets/common/entity/village/dummy.ron b/assets/common/entity/village/dummy.ron new file mode 100644 index 0000000000..96e7b9d467 --- /dev/null +++ b/assets/common/entity/village/dummy.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("Training Dummy"), + body: Exact(Object(TrainingDummy)), + alignment: Alignment(Passive), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/village/guard.ron b/assets/common/entity/village/guard.ron index a80314380c..fc31245bca 100644 --- a/assets/common/entity/village/guard.ron +++ b/assets/common/entity/village/guard.ron @@ -1,13 +1,13 @@ EntityConfig ( - name: Some("Guard"), - // body is specified outsite - body: None, + name: Name("Guard"), + body: RandomWith("humanoid"), + alignment: Alignment(Npc), - loot: None, + loot: Uninit, - main_tool: Some(Item("common.items.weapons.sword.iron-4")), - second_tool: None, + hands: TwoHanded(Item("common.items.weapons.sword.iron-4")), - loadout_asset: None, - skillset_asset: Some("common.skillset.village.guard"), + meta: [ + SkillSetAsset("common.skillset.village.guard"), + ], ) diff --git a/assets/common/entity/village/merchant.ron b/assets/common/entity/village/merchant.ron index 7fb1de003d..d0632f737b 100644 --- a/assets/common/entity/village/merchant.ron +++ b/assets/common/entity/village/merchant.ron @@ -1,14 +1,14 @@ EntityConfig ( - name: Some("Merchant"), - // body is specified outsite - body: None, + name: Name("Merchant"), + body: RandomWith("humanoid"), + alignment: Alignment(Npc), // considering giving some gold/gems/materials? - loot: None, + loot: Uninit, - main_tool: Some(Item("common.items.weapons.bow.eldwood-0")), - second_tool: None, + hands: TwoHanded(Item("common.items.weapons.bow.eldwood-0")), - loadout_asset: None, - skillset_asset: Some("common.skillset.village.merchant"), + meta: [ + SkillSetAsset("common.skillset.village.merchant"), + ], ) diff --git a/assets/common/entity/village/villager.ron b/assets/common/entity/village/villager.ron index 37d6528807..4335b0df45 100644 --- a/assets/common/entity/village/villager.ron +++ b/assets/common/entity/village/villager.ron @@ -1,11 +1,11 @@ EntityConfig ( - name: None, - // body is specified outsite - body: None, + name: Automatic, + body: RandomWith("humanoid"), + alignment: Alignment(Npc), - loot: None, + loot: Uninit, - main_tool: Some(Choice([ + hands: TwoHanded(Choice([ (1.0, Some(Item("common.items.weapons.tool.broom"))), (1.0, Some(Item("common.items.weapons.tool.hoe"))), (1.0, Some(Item("common.items.weapons.tool.pickaxe"))), @@ -13,8 +13,6 @@ EntityConfig ( (1.0, Some(Item("common.items.weapons.tool.shovel-0"))), (1.0, Some(Item("common.items.weapons.tool.shovel-1"))), ])), - second_tool: None, - loadout_asset: None, - skillset_asset: None, + meta: [], ) diff --git a/assets/common/entity/wild/aggressive/alligator.ron b/assets/common/entity/wild/aggressive/alligator.ron new file mode 100644 index 0000000000..9e63eb22a2 --- /dev/null +++ b/assets/common/entity/wild/aggressive/alligator.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("alligator"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/archaeos.ron b/assets/common/entity/wild/aggressive/archaeos.ron new file mode 100644 index 0000000000..ef9fd560d9 --- /dev/null +++ b/assets/common/entity/wild/aggressive/archaeos.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("archaeos"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/asp.ron b/assets/common/entity/wild/aggressive/asp.ron new file mode 100644 index 0000000000..f40cbcb3ee --- /dev/null +++ b/assets/common/entity/wild/aggressive/asp.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("asp"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/batfox.ron b/assets/common/entity/wild/aggressive/batfox.ron new file mode 100644 index 0000000000..dd0c68e9a3 --- /dev/null +++ b/assets/common/entity/wild/aggressive/batfox.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("batfox"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/bear.ron b/assets/common/entity/wild/aggressive/bear.ron new file mode 100644 index 0000000000..66d3bd0042 --- /dev/null +++ b/assets/common/entity/wild/aggressive/bear.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("bear"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/bonerattler.ron b/assets/common/entity/wild/aggressive/bonerattler.ron new file mode 100644 index 0000000000..e5fa5910b1 --- /dev/null +++ b/assets/common/entity/wild/aggressive/bonerattler.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("bonerattler"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/cockatrice.ron b/assets/common/entity/wild/aggressive/cockatrice.ron new file mode 100644 index 0000000000..a367c30fcc --- /dev/null +++ b/assets/common/entity/wild/aggressive/cockatrice.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("cockatrice"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/crocodile.ron b/assets/common/entity/wild/aggressive/crocodile.ron new file mode 100644 index 0000000000..b839d4b4e5 --- /dev/null +++ b/assets/common/entity/wild/aggressive/crocodile.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("crocodile"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/cyclope.ron b/assets/common/entity/wild/aggressive/cyclope.ron new file mode 100644 index 0000000000..2e679b9458 --- /dev/null +++ b/assets/common/entity/wild/aggressive/cyclope.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("cyclops"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/deadwood.ron b/assets/common/entity/wild/aggressive/deadwood.ron new file mode 100644 index 0000000000..ebbcadf2e6 --- /dev/null +++ b/assets/common/entity/wild/aggressive/deadwood.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("deadwood"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/dodarock.ron b/assets/common/entity/wild/aggressive/dodarock.ron new file mode 100644 index 0000000000..444d4ae085 --- /dev/null +++ b/assets/common/entity/wild/aggressive/dodarock.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("dodarock"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/dreadhorn.ron b/assets/common/entity/wild/aggressive/dreadhorn.ron new file mode 100644 index 0000000000..e42bc14392 --- /dev/null +++ b/assets/common/entity/wild/aggressive/dreadhorn.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("dreadhorn"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/frostfang.ron b/assets/common/entity/wild/aggressive/frostfang.ron new file mode 100644 index 0000000000..c315373e4c --- /dev/null +++ b/assets/common/entity/wild/aggressive/frostfang.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("frostfang"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/grolgar.ron b/assets/common/entity/wild/aggressive/grolgar.ron new file mode 100644 index 0000000000..2b868ac934 --- /dev/null +++ b/assets/common/entity/wild/aggressive/grolgar.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("grolgar"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/hakulaq.ron b/assets/common/entity/wild/aggressive/hakulaq.ron new file mode 100644 index 0000000000..68e4b77697 --- /dev/null +++ b/assets/common/entity/wild/aggressive/hakulaq.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("hakulaq"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/hyena.ron b/assets/common/entity/wild/aggressive/hyena.ron new file mode 100644 index 0000000000..dea8ade1f6 --- /dev/null +++ b/assets/common/entity/wild/aggressive/hyena.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("hyena"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/icepike.ron b/assets/common/entity/wild/aggressive/icepike.ron new file mode 100644 index 0000000000..2cb568b75d --- /dev/null +++ b/assets/common/entity/wild/aggressive/icepike.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("icepike"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/lavadrake.ron b/assets/common/entity/wild/aggressive/lavadrake.ron new file mode 100644 index 0000000000..43f9dfd981 --- /dev/null +++ b/assets/common/entity/wild/aggressive/lavadrake.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("lavadrake"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/lion.ron b/assets/common/entity/wild/aggressive/lion.ron new file mode 100644 index 0000000000..703577cfa1 --- /dev/null +++ b/assets/common/entity/wild/aggressive/lion.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("lion"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/mammoth.ron b/assets/common/entity/wild/aggressive/mammoth.ron new file mode 100644 index 0000000000..6bf88c0e38 --- /dev/null +++ b/assets/common/entity/wild/aggressive/mammoth.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("mammoth"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/maneater.ron b/assets/common/entity/wild/aggressive/maneater.ron new file mode 100644 index 0000000000..92ff16fa66 --- /dev/null +++ b/assets/common/entity/wild/aggressive/maneater.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("maneater"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/mighty_saurok.ron b/assets/common/entity/wild/aggressive/mighty_saurok.ron new file mode 100644 index 0000000000..4fd00cc454 --- /dev/null +++ b/assets/common/entity/wild/aggressive/mighty_saurok.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("saurok_mighty"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/monitor.ron b/assets/common/entity/wild/aggressive/monitor.ron new file mode 100644 index 0000000000..2195fd63de --- /dev/null +++ b/assets/common/entity/wild/aggressive/monitor.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("monitor"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/mountain_troll.ron b/assets/common/entity/wild/aggressive/mountain_troll.ron new file mode 100644 index 0000000000..ef24ea5561 --- /dev/null +++ b/assets/common/entity/wild/aggressive/mountain_troll.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("troll_mountain"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/ngoubou.ron b/assets/common/entity/wild/aggressive/ngoubou.ron new file mode 100644 index 0000000000..191d6642ac --- /dev/null +++ b/assets/common/entity/wild/aggressive/ngoubou.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("ngoubou"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/ntouka.ron b/assets/common/entity/wild/aggressive/ntouka.ron new file mode 100644 index 0000000000..de2e848273 --- /dev/null +++ b/assets/common/entity/wild/aggressive/ntouka.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("ntouka"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/occult_saurok.ron b/assets/common/entity/wild/aggressive/occult_saurok.ron new file mode 100644 index 0000000000..332ce79602 --- /dev/null +++ b/assets/common/entity/wild/aggressive/occult_saurok.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("saurok_occult"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/odonto.ron b/assets/common/entity/wild/aggressive/odonto.ron new file mode 100644 index 0000000000..a8cba7c234 --- /dev/null +++ b/assets/common/entity/wild/aggressive/odonto.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("odonto"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/ogre.ron b/assets/common/entity/wild/aggressive/ogre.ron new file mode 100644 index 0000000000..7e3e655cfa --- /dev/null +++ b/assets/common/entity/wild/aggressive/ogre.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("ogre"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/rocksnapper.ron b/assets/common/entity/wild/aggressive/rocksnapper.ron new file mode 100644 index 0000000000..b003b4f4d7 --- /dev/null +++ b/assets/common/entity/wild/aggressive/rocksnapper.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("rocksnapper"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/roshwalr.ron b/assets/common/entity/wild/aggressive/roshwalr.ron new file mode 100644 index 0000000000..cee362c67b --- /dev/null +++ b/assets/common/entity/wild/aggressive/roshwalr.ron @@ -0,0 +1,14 @@ +EntityConfig ( + name: Automatic, + body: Exact(QuadrupedMedium(Body( + species: Roshwalr, + body_type: Male, + ))), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/roshwalr_boss.ron b/assets/common/entity/wild/aggressive/roshwalr_boss.ron new file mode 100644 index 0000000000..2f105614a1 --- /dev/null +++ b/assets/common/entity/wild/aggressive/roshwalr_boss.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: Exact(QuadrupedMedium(Body(species: Roshwalr, body_type: Female))), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/saber.ron b/assets/common/entity/wild/aggressive/saber.ron new file mode 100644 index 0000000000..08e39d6245 --- /dev/null +++ b/assets/common/entity/wild/aggressive/saber.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("sabertooth"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/sand_raptor.ron b/assets/common/entity/wild/aggressive/sand_raptor.ron new file mode 100644 index 0000000000..82f5a1abf3 --- /dev/null +++ b/assets/common/entity/wild/aggressive/sand_raptor.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("raptor_sand"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/sandshark.ron b/assets/common/entity/wild/aggressive/sandshark.ron new file mode 100644 index 0000000000..23df7e3f49 --- /dev/null +++ b/assets/common/entity/wild/aggressive/sandshark.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("sandshark"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/sly_saurok.ron b/assets/common/entity/wild/aggressive/sly_saurok.ron new file mode 100644 index 0000000000..d52795bda5 --- /dev/null +++ b/assets/common/entity/wild/aggressive/sly_saurok.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("saurok_sly"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/snow_leopard.ron b/assets/common/entity/wild/aggressive/snow_leopard.ron new file mode 100644 index 0000000000..fbdeb737a3 --- /dev/null +++ b/assets/common/entity/wild/aggressive/snow_leopard.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("snowleopard"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/snow_raptor.ron b/assets/common/entity/wild/aggressive/snow_raptor.ron new file mode 100644 index 0000000000..f892f197a3 --- /dev/null +++ b/assets/common/entity/wild/aggressive/snow_raptor.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("raptor_snow"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/sunlizard.ron b/assets/common/entity/wild/aggressive/sunlizard.ron new file mode 100644 index 0000000000..0d5d11803b --- /dev/null +++ b/assets/common/entity/wild/aggressive/sunlizard.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("sunlizard"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/swamp_troll.ron b/assets/common/entity/wild/aggressive/swamp_troll.ron new file mode 100644 index 0000000000..d8410db0e0 --- /dev/null +++ b/assets/common/entity/wild/aggressive/swamp_troll.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("troll_swamp"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/tarasque.ron b/assets/common/entity/wild/aggressive/tarasque.ron new file mode 100644 index 0000000000..9240f05109 --- /dev/null +++ b/assets/common/entity/wild/aggressive/tarasque.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("tarasque"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/tiger.ron b/assets/common/entity/wild/aggressive/tiger.ron new file mode 100644 index 0000000000..309c9e7df7 --- /dev/null +++ b/assets/common/entity/wild/aggressive/tiger.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("tiger"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/wendigo.ron b/assets/common/entity/wild/aggressive/wendigo.ron new file mode 100644 index 0000000000..8fef962284 --- /dev/null +++ b/assets/common/entity/wild/aggressive/wendigo.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("wendigo"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/wolf.ron b/assets/common/entity/wild/aggressive/wolf.ron new file mode 100644 index 0000000000..57509f6382 --- /dev/null +++ b/assets/common/entity/wild/aggressive/wolf.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("wolf"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/wood_raptor.ron b/assets/common/entity/wild/aggressive/wood_raptor.ron new file mode 100644 index 0000000000..fbc093e14a --- /dev/null +++ b/assets/common/entity/wild/aggressive/wood_raptor.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("raptor_wood"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/aggressive/yale.ron b/assets/common/entity/wild/aggressive/yale.ron new file mode 100644 index 0000000000..0ea8d6dc09 --- /dev/null +++ b/assets/common/entity/wild/aggressive/yale.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("yale"), + alignment: Alignment(Enemy), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/alpaca.ron b/assets/common/entity/wild/peaceful/alpaca.ron new file mode 100644 index 0000000000..b1b06b53a9 --- /dev/null +++ b/assets/common/entity/wild/peaceful/alpaca.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("alpaca"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/antelope.ron b/assets/common/entity/wild/peaceful/antelope.ron new file mode 100644 index 0000000000..573e457850 --- /dev/null +++ b/assets/common/entity/wild/peaceful/antelope.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("antelope"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/arctic_fox.ron b/assets/common/entity/wild/peaceful/arctic_fox.ron new file mode 100644 index 0000000000..4a289c0644 --- /dev/null +++ b/assets/common/entity/wild/peaceful/arctic_fox.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("Arctic Fox"), + body: Exact(QuadrupedSmall(Body(species: Fox, body_type: Female))), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/arctic_hare.ron b/assets/common/entity/wild/peaceful/arctic_hare.ron new file mode 100644 index 0000000000..566b5c15e2 --- /dev/null +++ b/assets/common/entity/wild/peaceful/arctic_hare.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("Arctic Hare"), + body: Exact(QuadrupedSmall(Body(species: Hare, body_type: Female))), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/axolotl.ron b/assets/common/entity/wild/peaceful/axolotl.ron new file mode 100644 index 0000000000..f7b04e723e --- /dev/null +++ b/assets/common/entity/wild/peaceful/axolotl.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("axolotl"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/beaver.ron b/assets/common/entity/wild/peaceful/beaver.ron new file mode 100644 index 0000000000..fb7ed84625 --- /dev/null +++ b/assets/common/entity/wild/peaceful/beaver.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("beaver"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/boar.ron b/assets/common/entity/wild/peaceful/boar.ron new file mode 100644 index 0000000000..bba9eac893 --- /dev/null +++ b/assets/common/entity/wild/peaceful/boar.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("boar"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/camel.ron b/assets/common/entity/wild/peaceful/camel.ron new file mode 100644 index 0000000000..fd574f17e1 --- /dev/null +++ b/assets/common/entity/wild/peaceful/camel.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("camel"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/catoblepas.ron b/assets/common/entity/wild/peaceful/catoblepas.ron new file mode 100644 index 0000000000..d15457d45c --- /dev/null +++ b/assets/common/entity/wild/peaceful/catoblepas.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("catoblepas"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/cattle.ron b/assets/common/entity/wild/peaceful/cattle.ron new file mode 100644 index 0000000000..72cc745057 --- /dev/null +++ b/assets/common/entity/wild/peaceful/cattle.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("cattle"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/chicken.ron b/assets/common/entity/wild/peaceful/chicken.ron new file mode 100644 index 0000000000..7d65a663ee --- /dev/null +++ b/assets/common/entity/wild/peaceful/chicken.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("chicken"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/clownfish.ron b/assets/common/entity/wild/peaceful/clownfish.ron new file mode 100644 index 0000000000..76c8698071 --- /dev/null +++ b/assets/common/entity/wild/peaceful/clownfish.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("clownfish"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/deer.ron b/assets/common/entity/wild/peaceful/deer.ron new file mode 100644 index 0000000000..0b12f635ca --- /dev/null +++ b/assets/common/entity/wild/peaceful/deer.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("deer"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/donkey.ron b/assets/common/entity/wild/peaceful/donkey.ron new file mode 100644 index 0000000000..5838cf2710 --- /dev/null +++ b/assets/common/entity/wild/peaceful/donkey.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("donkey"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/duck.ron b/assets/common/entity/wild/peaceful/duck.ron new file mode 100644 index 0000000000..c0f9283508 --- /dev/null +++ b/assets/common/entity/wild/peaceful/duck.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("duck"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/eagle.ron b/assets/common/entity/wild/peaceful/eagle.ron new file mode 100644 index 0000000000..093606f786 --- /dev/null +++ b/assets/common/entity/wild/peaceful/eagle.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("eagle"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/forest_fox.ron b/assets/common/entity/wild/peaceful/forest_fox.ron new file mode 100644 index 0000000000..f2a7e88651 --- /dev/null +++ b/assets/common/entity/wild/peaceful/forest_fox.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("Forest Fox"), + body: Exact(QuadrupedSmall(Body(species: Fox, body_type: Male))), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/frog.ron b/assets/common/entity/wild/peaceful/frog.ron new file mode 100644 index 0000000000..6bc65393f6 --- /dev/null +++ b/assets/common/entity/wild/peaceful/frog.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("frog"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/fungome.ron b/assets/common/entity/wild/peaceful/fungome.ron new file mode 100644 index 0000000000..96540f5d61 --- /dev/null +++ b/assets/common/entity/wild/peaceful/fungome.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("fungome"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/gecko.ron b/assets/common/entity/wild/peaceful/gecko.ron new file mode 100644 index 0000000000..830c51cb0d --- /dev/null +++ b/assets/common/entity/wild/peaceful/gecko.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("gecko"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/goat.ron b/assets/common/entity/wild/peaceful/goat.ron new file mode 100644 index 0000000000..9f33ed002e --- /dev/null +++ b/assets/common/entity/wild/peaceful/goat.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("goat"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/goose.ron b/assets/common/entity/wild/peaceful/goose.ron new file mode 100644 index 0000000000..294f05754a --- /dev/null +++ b/assets/common/entity/wild/peaceful/goose.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("goose"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/highland.ron b/assets/common/entity/wild/peaceful/highland.ron new file mode 100644 index 0000000000..ef992cd8fb --- /dev/null +++ b/assets/common/entity/wild/peaceful/highland.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("highland"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/hirdrasil.ron b/assets/common/entity/wild/peaceful/hirdrasil.ron new file mode 100644 index 0000000000..c97924afd9 --- /dev/null +++ b/assets/common/entity/wild/peaceful/hirdrasil.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("hirdrasil"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/holladon.ron b/assets/common/entity/wild/peaceful/holladon.ron new file mode 100644 index 0000000000..a57248dce9 --- /dev/null +++ b/assets/common/entity/wild/peaceful/holladon.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("holladon"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/horse.ron b/assets/common/entity/wild/peaceful/horse.ron new file mode 100644 index 0000000000..b42067c4c8 --- /dev/null +++ b/assets/common/entity/wild/peaceful/horse.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("horse"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/jackalope.ron b/assets/common/entity/wild/peaceful/jackalope.ron new file mode 100644 index 0000000000..130aad374a --- /dev/null +++ b/assets/common/entity/wild/peaceful/jackalope.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("jackalope"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/kelpie.ron b/assets/common/entity/wild/peaceful/kelpie.ron new file mode 100644 index 0000000000..1062c5bedb --- /dev/null +++ b/assets/common/entity/wild/peaceful/kelpie.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("kelpie"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/llama.ron b/assets/common/entity/wild/peaceful/llama.ron new file mode 100644 index 0000000000..3b40a2149e --- /dev/null +++ b/assets/common/entity/wild/peaceful/llama.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("llama"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/marlin.ron b/assets/common/entity/wild/peaceful/marlin.ron new file mode 100644 index 0000000000..e127c8aeba --- /dev/null +++ b/assets/common/entity/wild/peaceful/marlin.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("marlin"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/moose.ron b/assets/common/entity/wild/peaceful/moose.ron new file mode 100644 index 0000000000..47953674fc --- /dev/null +++ b/assets/common/entity/wild/peaceful/moose.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("moose"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/mouflon.ron b/assets/common/entity/wild/peaceful/mouflon.ron new file mode 100644 index 0000000000..c324dcbba5 --- /dev/null +++ b/assets/common/entity/wild/peaceful/mouflon.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("mouflon"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/owl.ron b/assets/common/entity/wild/peaceful/owl.ron new file mode 100644 index 0000000000..dd23ad327a --- /dev/null +++ b/assets/common/entity/wild/peaceful/owl.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("owl"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/pangolin.ron b/assets/common/entity/wild/peaceful/pangolin.ron new file mode 100644 index 0000000000..ba207dd831 --- /dev/null +++ b/assets/common/entity/wild/peaceful/pangolin.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("pangolin"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/parrot.ron b/assets/common/entity/wild/peaceful/parrot.ron new file mode 100644 index 0000000000..d680c71647 --- /dev/null +++ b/assets/common/entity/wild/peaceful/parrot.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("parrot"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/peacock.ron b/assets/common/entity/wild/peaceful/peacock.ron new file mode 100644 index 0000000000..b34c2e830d --- /dev/null +++ b/assets/common/entity/wild/peaceful/peacock.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("peacock"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/pig.ron b/assets/common/entity/wild/peaceful/pig.ron new file mode 100644 index 0000000000..3c20ae39cd --- /dev/null +++ b/assets/common/entity/wild/peaceful/pig.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("pig"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/piranha.ron b/assets/common/entity/wild/peaceful/piranha.ron new file mode 100644 index 0000000000..dc1f92651b --- /dev/null +++ b/assets/common/entity/wild/peaceful/piranha.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("piranha"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/porcupine.ron b/assets/common/entity/wild/peaceful/porcupine.ron new file mode 100644 index 0000000000..79fdade2b9 --- /dev/null +++ b/assets/common/entity/wild/peaceful/porcupine.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("porcupine"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/quokka.ron b/assets/common/entity/wild/peaceful/quokka.ron new file mode 100644 index 0000000000..e25c15cb3c --- /dev/null +++ b/assets/common/entity/wild/peaceful/quokka.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("quokka"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/rabbit.ron b/assets/common/entity/wild/peaceful/rabbit.ron new file mode 100644 index 0000000000..23ff937e6e --- /dev/null +++ b/assets/common/entity/wild/peaceful/rabbit.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("rabbit"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/raccoon.ron b/assets/common/entity/wild/peaceful/raccoon.ron new file mode 100644 index 0000000000..b941c98a24 --- /dev/null +++ b/assets/common/entity/wild/peaceful/raccoon.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("raccoon"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/rat.ron b/assets/common/entity/wild/peaceful/rat.ron new file mode 100644 index 0000000000..d911990b8b --- /dev/null +++ b/assets/common/entity/wild/peaceful/rat.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("rat"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/river_salamander.ron b/assets/common/entity/wild/peaceful/river_salamander.ron new file mode 100644 index 0000000000..3f2914df60 --- /dev/null +++ b/assets/common/entity/wild/peaceful/river_salamander.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("River Salamander"), + body: Exact(QuadrupedLow(Body(species: Salamander, body_type: Female))), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/sand_hare.ron b/assets/common/entity/wild/peaceful/sand_hare.ron new file mode 100644 index 0000000000..84a417974c --- /dev/null +++ b/assets/common/entity/wild/peaceful/sand_hare.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("Sand Hare"), + body: Exact(QuadrupedSmall(Body(species: Hare, body_type: Male))), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/sand_salamander.ron b/assets/common/entity/wild/peaceful/sand_salamander.ron new file mode 100644 index 0000000000..2740438c2b --- /dev/null +++ b/assets/common/entity/wild/peaceful/sand_salamander.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Name("Desert Salamander"), + body: Exact(QuadrupedLow(Body(species: Salamander, body_type: Male))), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/sheep.ron b/assets/common/entity/wild/peaceful/sheep.ron new file mode 100644 index 0000000000..fff177dfd3 --- /dev/null +++ b/assets/common/entity/wild/peaceful/sheep.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("sheep"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/skunk.ron b/assets/common/entity/wild/peaceful/skunk.ron new file mode 100644 index 0000000000..6e782adcfb --- /dev/null +++ b/assets/common/entity/wild/peaceful/skunk.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("skunk"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/squirrel.ron b/assets/common/entity/wild/peaceful/squirrel.ron new file mode 100644 index 0000000000..9daac3cd8e --- /dev/null +++ b/assets/common/entity/wild/peaceful/squirrel.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("squirrel"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/tortoise.ron b/assets/common/entity/wild/peaceful/tortoise.ron new file mode 100644 index 0000000000..4104f1c43a --- /dev/null +++ b/assets/common/entity/wild/peaceful/tortoise.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("tortoise"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/truffler.ron b/assets/common/entity/wild/peaceful/truffler.ron new file mode 100644 index 0000000000..c0c9adfc1f --- /dev/null +++ b/assets/common/entity/wild/peaceful/truffler.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("truffler"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/turtle.ron b/assets/common/entity/wild/peaceful/turtle.ron new file mode 100644 index 0000000000..4b55182fa6 --- /dev/null +++ b/assets/common/entity/wild/peaceful/turtle.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("turtle"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/tuskram.ron b/assets/common/entity/wild/peaceful/tuskram.ron new file mode 100644 index 0000000000..32c091db3a --- /dev/null +++ b/assets/common/entity/wild/peaceful/tuskram.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("tuskram"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/yak.ron b/assets/common/entity/wild/peaceful/yak.ron new file mode 100644 index 0000000000..95323b48d2 --- /dev/null +++ b/assets/common/entity/wild/peaceful/yak.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("yak"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/common/entity/wild/peaceful/zebra.ron b/assets/common/entity/wild/peaceful/zebra.ron new file mode 100644 index 0000000000..fd7667965b --- /dev/null +++ b/assets/common/entity/wild/peaceful/zebra.ron @@ -0,0 +1,11 @@ +EntityConfig ( + name: Automatic, + body: RandomWith("zebra"), + alignment: Alignment(Wild), + + loot: Uninit, + + hands: Uninit, + + meta: [], +) diff --git a/assets/world/wildlife/spawn/desert/area.ron b/assets/world/wildlife/spawn/desert/area.ron new file mode 100644 index 0000000000..2c3aca95e5 --- /dev/null +++ b/assets/world/wildlife/spawn/desert/area.ron @@ -0,0 +1,14 @@ +SpawnEntry ( + name: "Desert area wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (3, 6, "common.entity.wild.peaceful.zebra")), + (1, (3, 6, "common.entity.wild.peaceful.antelope")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/desert/hot.ron b/assets/world/wildlife/spawn/desert/hot.ron new file mode 100644 index 0000000000..1f56298d9e --- /dev/null +++ b/assets/world/wildlife/spawn/desert/hot.ron @@ -0,0 +1,25 @@ +SpawnEntry ( + name: "Desert hot area wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.peaceful.camel")), + (1, (1, 1, "common.entity.wild.peaceful.sand_hare")), + (1, (1, 1, "common.entity.wild.peaceful.sand_salamander")), + (1, (1, 1, "common.entity.wild.peaceful.gecko")), + ], + is_underwater: false, + day_period: [Morning, Noon, Evening], + ), + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.peaceful.holladon")), + (1, (1, 1, "common.entity.wild.peaceful.porcupine")), + (1, (1, 1, "common.entity.wild.peaceful.pangolin")), + ], + is_underwater: false, + day_period: [Night], + ), + ], +) diff --git a/assets/world/wildlife/spawn/desert/river.ron b/assets/world/wildlife/spawn/desert/river.ron new file mode 100644 index 0000000000..a032786de7 --- /dev/null +++ b/assets/world/wildlife/spawn/desert/river.ron @@ -0,0 +1,13 @@ +SpawnEntry ( + name: "Desert river wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.crocodile")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/desert/wasteland.ron b/assets/world/wildlife/spawn/desert/wasteland.ron new file mode 100644 index 0000000000..2752064ade --- /dev/null +++ b/assets/world/wildlife/spawn/desert/wasteland.ron @@ -0,0 +1,23 @@ +SpawnEntry ( + name: "Desert wasteland wildlife.", + note: "", + rules: [ + Pack( + groups: [ + // Casual + (100, (1, 1, "common.entity.wild.aggressive.bonerattler")), + (100, (1, 1, "common.entity.wild.aggressive.sand_raptor")), + (100, (1, 1, "common.entity.wild.aggressive.ngoubou")), + (100, (1, 1, "common.entity.wild.aggressive.sandshark")), + // Rare + (20, (1, 1, "common.entity.wild.aggressive.lavadrake")), + (20, (1, 1, "common.entity.wild.aggressive.ntouka")), + (20, (1, 1, "common.entity.wild.aggressive.archaeos")), + // Ultra_rare + (1, (1, 1, "common.entity.wild.aggressive.roshwalr_boss")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/jungle/rainforest.ron b/assets/world/wildlife/spawn/jungle/rainforest.ron new file mode 100644 index 0000000000..14b85d0145 --- /dev/null +++ b/assets/world/wildlife/spawn/jungle/rainforest.ron @@ -0,0 +1,30 @@ +SpawnEntry ( + name: "Jungle rainforest core wildlife.", + note: "Concentrated in the core of biome.", + rules: [ + Pack( + groups: [ + // Casual + (5, (1, 1, "common.entity.wild.aggressive.asp")), + (5, (1, 1, "common.entity.wild.aggressive.tiger")), + // Rare + (1, (1, 1, "common.entity.wild.aggressive.sunlizard")), + (1, (1, 1, "common.entity.wild.aggressive.odonto")), + (1, (1, 1, "common.entity.wild.aggressive.mighty_saurok")), + (1, (1, 1, "common.entity.wild.aggressive.occult_saurok")), + (1, (1, 1, "common.entity.wild.aggressive.sly_saurok")), + ], + is_underwater: false, + day_period: [Morning, Noon, Evening], + ), + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.tiger")), + (1, (1, 1, "common.entity.wild.aggressive.maneater")), + (1, (1, 1, "common.entity.wild.aggressive.cockatrice")), + ], + is_underwater: false, + day_period: [Night], + ), + ], +) diff --git a/assets/world/wildlife/spawn/jungle/rainforest_area.ron b/assets/world/wildlife/spawn/jungle/rainforest_area.ron new file mode 100644 index 0000000000..d25f2a6109 --- /dev/null +++ b/assets/world/wildlife/spawn/jungle/rainforest_area.ron @@ -0,0 +1,26 @@ +SpawnEntry ( + name: "Jungle rainforest rare wildlife.", + note: "Spread through the area.", + rules: [ + Pack( + groups: [ + // Casual + (5, (1, 1, "common.entity.wild.peaceful.parrot")), + (5, (1, 1, "common.entity.wild.peaceful.quokka")), + // Rare + (1, (1, 1, "common.entity.wild.peaceful.tortoise")), + (1, (1, 1, "common.entity.wild.aggressive.monitor")), + ], + is_underwater: false, + day_period: [Morning, Noon, Evening], + ), + Pack( + groups: [ + (5, (1, 1, "common.entity.wild.peaceful.quokka")), + (1, (1, 1, "common.entity.wild.peaceful.tortoise")), + ], + is_underwater: false, + day_period: [Night], + ), + ], +) diff --git a/assets/world/wildlife/spawn/taiga/area.ron b/assets/world/wildlife/spawn/taiga/area.ron new file mode 100644 index 0000000000..e9400a0988 --- /dev/null +++ b/assets/world/wildlife/spawn/taiga/area.ron @@ -0,0 +1,18 @@ +SpawnEntry ( + name: "Taiga animals.", + note: "Spread through the area", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.peaceful.eagle")), + (1, (1, 1, "common.entity.wild.peaceful.owl")), + (1, (1, 1, "common.entity.wild.peaceful.arctic_fox")), + (1, (1, 1, "common.entity.wild.peaceful.moose")), + (1, (1, 1, "common.entity.wild.peaceful.arctic_hare")), + (1, (1, 1, "common.entity.wild.peaceful.tuskram")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/taiga/core.ron b/assets/world/wildlife/spawn/taiga/core.ron new file mode 100644 index 0000000000..1604fa4171 --- /dev/null +++ b/assets/world/wildlife/spawn/taiga/core.ron @@ -0,0 +1,17 @@ +SpawnEntry ( + name: "Taiga pack animals.", + note: "Search for them in the heart of taiga.", + rules: [ + Pack( + groups: [ + (1, (1, 3, "common.entity.wild.peaceful.mouflon")), + (1, (1, 3, "common.entity.wild.peaceful.yak")), + (1, (1, 3, "common.entity.wild.peaceful.llama")), + (1, (1, 3, "common.entity.wild.peaceful.alpaca")), + (1, (1, 3, "common.entity.wild.peaceful.highland")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/taiga/core_forest.ron b/assets/world/wildlife/spawn/taiga/core_forest.ron new file mode 100644 index 0000000000..673d1579dc --- /dev/null +++ b/assets/world/wildlife/spawn/taiga/core_forest.ron @@ -0,0 +1,14 @@ +SpawnEntry ( + name: "Taiga rare forest wildlife.", + note: "Search for them in the heart of the taiga, if you are feeling lucky.", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.wendigo")), + (1, (1, 1, "common.entity.wild.aggressive.dreadhorn")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/taiga/forest.ron b/assets/world/wildlife/spawn/taiga/forest.ron new file mode 100644 index 0000000000..a6731694e2 --- /dev/null +++ b/assets/world/wildlife/spawn/taiga/forest.ron @@ -0,0 +1,13 @@ +SpawnEntry ( + name: "Taiga forest wildlife.", + note: "Search for them in taiga forests.", + rules: [ + Pack( + groups: [ + (1, (3, 7, "common.entity.wild.aggressive.wolf")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/taiga/water.ron b/assets/world/wildlife/spawn/taiga/water.ron new file mode 100644 index 0000000000..8ad83b0baa --- /dev/null +++ b/assets/world/wildlife/spawn/taiga/water.ron @@ -0,0 +1,13 @@ +SpawnEntry ( + name: "Taiga water wildlife.", + note: "River inhabitants", + rules: [ + Pack( + groups: [ + (1, (1, 2, "common.entity.wild.aggressive.icepike")), + ], + is_underwater: true, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/temperate/rainforest.ron b/assets/world/wildlife/spawn/temperate/rainforest.ron new file mode 100644 index 0000000000..c60b19cf5e --- /dev/null +++ b/assets/world/wildlife/spawn/temperate/rainforest.ron @@ -0,0 +1,51 @@ +SpawnEntry ( + name: "Temperate rainforest wildlife.", + note: "", + rules: [ + Pack( + groups: [ + // Pack animals + (1, (1, 7, "common.entity.wild.peaceful.deer")), + (1, (1, 3, "common.entity.wild.peaceful.rat")), + (1, (1, 7, "common.entity.wild.peaceful.rabbit")), + (1, (1, 7, "common.entity.wild.peaceful.jackalope")), + (1, (1, 7, "common.entity.wild.peaceful.boar")), + (1, (1, 7, "common.entity.wild.peaceful.sheep")), + (1, (1, 7, "common.entity.wild.peaceful.pig")), + (1, (1, 7, "common.entity.wild.peaceful.squirrel")), + (1, (1, 7, "common.entity.wild.peaceful.horse")), + (1, (1, 7, "common.entity.wild.peaceful.cattle")), + (1, (1, 7, "common.entity.wild.peaceful.goat")), + (1, (1, 7, "common.entity.wild.peaceful.llama")), + (1, (1, 7, "common.entity.wild.peaceful.alpaca")), + (1, (1, 7, "common.entity.wild.peaceful.chicken")), + // Solitary + (2, (1, 1, "common.entity.wild.peaceful.forest_fox")), + (2, (1, 1, "common.entity.wild.peaceful.donkey")), + (2, (1, 1, "common.entity.wild.peaceful.goose")), + (2, (1, 1, "common.entity.wild.peaceful.peacock")), + (2, (1, 1, "common.entity.wild.peaceful.skunk")), + (2, (1, 1, "common.entity.wild.peaceful.raccoon")), + (2, (1, 1, "common.entity.wild.peaceful.catoblepas")), + (2, (1, 1, "common.entity.wild.peaceful.turtle")), + (2, (1, 1, "common.entity.wild.peaceful.hirdrasil")), + (2, (1, 1, "common.entity.wild.peaceful.truffler")), + ], + is_underwater: false, + day_period: [Morning, Noon, Evening], + ), + Pack( + groups: [ + // Solitary + (1, (1, 1, "common.entity.wild.aggressive.batfox")), + (5, (1, 1, "common.entity.wild.peaceful.forest_fox")), + (5, (1, 1, "common.entity.wild.peaceful.raccoon")), + // Pack + (5, (1, 3, "common.entity.wild.peaceful.rat")), + (5, (1, 3, "common.entity.wild.peaceful.squirrel")), + ], + is_underwater: false, + day_period: [Night], + ), + ], +) diff --git a/assets/world/wildlife/spawn/temperate/rare.ron b/assets/world/wildlife/spawn/temperate/rare.ron new file mode 100644 index 0000000000..790ff2b2db --- /dev/null +++ b/assets/world/wildlife/spawn/temperate/rare.ron @@ -0,0 +1,15 @@ +SpawnEntry ( + name: "Temperate rare wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.ogre")), + (1, (1, 1, "common.entity.wild.aggressive.swamp_troll")), + (1, (1, 1, "common.entity.wild.aggressive.cyclope")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/temperate/river.ron b/assets/world/wildlife/spawn/temperate/river.ron new file mode 100644 index 0000000000..e8a7a4a146 --- /dev/null +++ b/assets/world/wildlife/spawn/temperate/river.ron @@ -0,0 +1,17 @@ +SpawnEntry ( + name: "Temperate river wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (5, (1, 1, "common.entity.wild.peaceful.beaver")), + (5, (1, 1, "common.entity.wild.peaceful.river_salamander")), + (5, (1, 1, "common.entity.wild.peaceful.duck")), + (1, (1, 1, "common.entity.wild.peaceful.kelpie")), + (1, (1, 1, "common.entity.wild.aggressive.hakulaq")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/temperate/water.ron b/assets/world/wildlife/spawn/temperate/water.ron new file mode 100644 index 0000000000..9906d3fa64 --- /dev/null +++ b/assets/world/wildlife/spawn/temperate/water.ron @@ -0,0 +1,15 @@ +SpawnEntry ( + name: "Temperate water wildlife.", + note: "River inhabitants", + rules: [ + Pack( + groups: [ + (1, (3, 4, "common.entity.wild.peaceful.marlin")), + (1, (3, 4, "common.entity.wild.peaceful.piranha")), + (1, (3, 4, "common.entity.wild.peaceful.clownfish")), + ], + is_underwater: true, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/temperate/wood.ron b/assets/world/wildlife/spawn/temperate/wood.ron new file mode 100644 index 0000000000..510ab327a3 --- /dev/null +++ b/assets/world/wildlife/spawn/temperate/wood.ron @@ -0,0 +1,17 @@ +SpawnEntry ( + name: "Temperate wood wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.bear")), + (1, (1, 1, "common.entity.wild.aggressive.tarasque")), + (1, (1, 1, "common.entity.wild.aggressive.wood_raptor")), + (1, (1, 1, "common.entity.wild.aggressive.deadwood")), + (1, (1, 1, "common.entity.wild.aggressive.saber")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tropical/rainforest.ron b/assets/world/wildlife/spawn/tropical/rainforest.ron new file mode 100644 index 0000000000..ed7375c42a --- /dev/null +++ b/assets/world/wildlife/spawn/tropical/rainforest.ron @@ -0,0 +1,14 @@ +SpawnEntry ( + name: "Tropical rainforest wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 2, "common.entity.wild.aggressive.lion")), + (1, (1, 3, "common.entity.wild.aggressive.hyena")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tropical/river.ron b/assets/world/wildlife/spawn/tropical/river.ron new file mode 100644 index 0000000000..c26932d6ac --- /dev/null +++ b/assets/world/wildlife/spawn/tropical/river.ron @@ -0,0 +1,15 @@ +SpawnEntry ( + name: "Tropical river wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 2, "common.entity.wild.peaceful.frog")), + (1, (1, 2, "common.entity.wild.peaceful.axolotl")), + (1, (1, 2, "common.entity.wild.peaceful.fungome")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tropical/river_rare.ron b/assets/world/wildlife/spawn/tropical/river_rare.ron new file mode 100644 index 0000000000..efdc77a4f7 --- /dev/null +++ b/assets/world/wildlife/spawn/tropical/river_rare.ron @@ -0,0 +1,13 @@ +SpawnEntry ( + name: "Tropical rare river wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 2, "common.entity.wild.aggressive.alligator")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tropical/rock.ron b/assets/world/wildlife/spawn/tropical/rock.ron new file mode 100644 index 0000000000..6a54b8b5a3 --- /dev/null +++ b/assets/world/wildlife/spawn/tropical/rock.ron @@ -0,0 +1,13 @@ +SpawnEntry ( + name: "Tropical rocks wildlife.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.dodarock")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tundra/core.ron b/assets/world/wildlife/spawn/tundra/core.ron new file mode 100644 index 0000000000..12315b9318 --- /dev/null +++ b/assets/world/wildlife/spawn/tundra/core.ron @@ -0,0 +1,16 @@ +SpawnEntry ( + name: "Tundra rare animals.", + note: "Search for them in the heart of tundra.", + rules: [ + Pack( + groups: [ + (15, (1, 1, "common.entity.wild.aggressive.snow_raptor")), + (1, (1, 1, "common.entity.wild.aggressive.wendigo")), + (1, (1, 1, "common.entity.wild.aggressive.mammoth")), + (1, (1, 1, "common.entity.wild.aggressive.mountain_troll")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tundra/forest.ron b/assets/world/wildlife/spawn/tundra/forest.ron new file mode 100644 index 0000000000..eb652f8e42 --- /dev/null +++ b/assets/world/wildlife/spawn/tundra/forest.ron @@ -0,0 +1,16 @@ +SpawnEntry ( + name: "Tundra forest animals.", + note: "", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.frostfang")), + (1, (1, 1, "common.entity.wild.aggressive.snow_leopard")), + (1, (1, 1, "common.entity.wild.aggressive.yale")), + (1, (1, 1, "common.entity.wild.aggressive.grolgar")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tundra/rock.ron b/assets/world/wildlife/spawn/tundra/rock.ron new file mode 100644 index 0000000000..79353d8f0d --- /dev/null +++ b/assets/world/wildlife/spawn/tundra/rock.ron @@ -0,0 +1,13 @@ +SpawnEntry ( + name: "Tundra rocky animals.", + note: "Search for the rocks in tundra and you will find them.", + rules: [ + Pack( + groups: [ + (1, (1, 1, "common.entity.wild.aggressive.rocksnapper")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/tundra/snow.ron b/assets/world/wildlife/spawn/tundra/snow.ron new file mode 100644 index 0000000000..41fd8a1f3e --- /dev/null +++ b/assets/world/wildlife/spawn/tundra/snow.ron @@ -0,0 +1,15 @@ +SpawnEntry ( + name: "Tundra animals.", + note: "Usually you can find them in snowy areas.", + rules: [ + Pack( + groups: [ + (1, (1, 3, "common.entity.wild.aggressive.frostfang")), + (1, (1, 3, "common.entity.wild.aggressive.snow_raptor")), + (1, (1, 3, "common.entity.wild.aggressive.roshwalr")), + ], + is_underwater: false, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 0cb2bb22cb..ba42292175 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -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, diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 9e1a5da439..7051349812 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -92,17 +92,26 @@ impl ItemSpec { /// /// # Panics /// 1) If weights are invalid - pub fn validate(&self, key: EquipSlot) { + /// 2) If item doesn't correspond to `EquipSlot` + pub fn validate(&self, equip_slot: EquipSlot) { match self { - ItemSpec::Item(specifier) => std::mem::drop(Item::new_from_asset_expect(specifier)), + ItemSpec::Item(specifier) => { + let item = Item::new_from_asset_expect(specifier); + if !equip_slot.can_hold(&item.kind) { + panic!("Tried to place {} into {:?}", specifier, equip_slot); + } + std::mem::drop(item); + }, ItemSpec::Choice(items) => { for (p, entry) in items { if p <= &0.0 { - let err = - format!("Weight is less or equal to 0.0.\n ({:?}: {:?})", key, self,); + let err = format!( + "Weight is less or equal to 0.0.\n ({:?}: {:?})", + equip_slot, self + ); panic!("\n\n{}\n\n", err); } else { - entry.as_ref().map(|e| e.validate(key)); + entry.as_ref().map(|e| e.validate(equip_slot)); } } }, @@ -389,13 +398,13 @@ impl LoadoutBuilder { .with_default_equipment(body) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] /// Set default active mainhand weapon based on `body` pub fn with_default_maintool(self, body: &Body) -> Self { self.active_mainhand(Some(default_main_tool(body))) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] /// Set default equipement based on `body` pub fn with_default_equipment(self, body: &Body) -> Self { let chest = match body { @@ -466,7 +475,7 @@ impl LoadoutBuilder { } } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn with_preset(mut self, preset: Preset) -> Self { let rng = &mut rand::thread_rng(); match preset { @@ -478,7 +487,7 @@ impl LoadoutBuilder { self } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn with_creator( mut self, creator: fn(LoadoutBuilder, Option<&SiteInformation>) -> LoadoutBuilder, @@ -497,7 +506,7 @@ impl LoadoutBuilder { /// 1) Will panic if there is no asset with such `asset_specifier` /// 2) Will panic if path to item specified in loadout file doesn't exist /// 3) Will panic while runs in tests and asset doesn't have "correct" form - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn with_asset_expect(mut self, asset_specifier: &str, rng: &mut impl Rng) -> Self { let spec = LoadoutSpec::load_expect(asset_specifier).read().0.clone(); for (key, entry) in spec { @@ -573,88 +582,96 @@ impl LoadoutBuilder { /// Set default armor items for the loadout. This may vary with game /// updates, but should be safe defaults for a new character. - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn defaults(self) -> Self { let rng = &mut rand::thread_rng(); self.with_asset_expect("common.loadout.default", rng) } + #[must_use = "Method consumes builder and returns updated builder."] fn with_equipment(mut self, equip_slot: EquipSlot, item: Option) -> Self { + // Panic if item doesn't correspond to slot + assert!( + item.as_ref() + .map_or(true, |item| equip_slot.can_hold(&item.kind)) + ); + self.0.swap(equip_slot, item); self } - #[must_use] - pub fn active_mainhand(self, item: Option) -> Self { - self.with_equipment(EquipSlot::ActiveMainhand, item) - } - - #[must_use] - pub fn active_offhand(self, item: Option) -> Self { - self.with_equipment(EquipSlot::ActiveOffhand, item) - } - - #[must_use] - pub fn inactive_mainhand(self, item: Option) -> Self { - self.with_equipment(EquipSlot::InactiveMainhand, item) - } - - #[must_use] - pub fn inactive_offhand(self, item: Option) -> Self { - self.with_equipment(EquipSlot::InactiveOffhand, item) - } - + #[must_use = "Method consumes builder and returns updated builder."] fn with_armor(self, armor_slot: ArmorSlot, item: Option) -> Self { self.with_equipment(EquipSlot::Armor(armor_slot), item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] + pub fn active_mainhand(self, item: Option) -> Self { + self.with_equipment(EquipSlot::ActiveMainhand, item) + } + + #[must_use = "Method consumes builder and returns updated builder."] + pub fn active_offhand(self, item: Option) -> Self { + self.with_equipment(EquipSlot::ActiveOffhand, item) + } + + #[must_use = "Method consumes builder and returns updated builder."] + pub fn inactive_mainhand(self, item: Option) -> Self { + self.with_equipment(EquipSlot::InactiveMainhand, item) + } + + #[must_use = "Method consumes builder and returns updated builder."] + pub fn inactive_offhand(self, item: Option) -> Self { + self.with_equipment(EquipSlot::InactiveOffhand, item) + } + + #[must_use = "Method consumes builder and returns updated builder."] pub fn shoulder(self, item: Option) -> Self { self.with_armor(ArmorSlot::Shoulders, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn chest(self, item: Option) -> Self { self.with_armor(ArmorSlot::Chest, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn belt(self, item: Option) -> Self { self.with_armor(ArmorSlot::Belt, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn hands(self, item: Option) -> Self { self.with_armor(ArmorSlot::Hands, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn pants(self, item: Option) -> Self { self.with_armor(ArmorSlot::Legs, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn feet(self, item: Option) -> Self { self.with_armor(ArmorSlot::Feet, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn back(self, item: Option) -> Self { self.with_armor(ArmorSlot::Back, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn ring1(self, item: Option) -> Self { self.with_armor(ArmorSlot::Ring1, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn ring2(self, item: Option) -> Self { self.with_armor(ArmorSlot::Ring2, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn neck(self, item: Option) -> Self { self.with_armor(ArmorSlot::Neck, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn lantern(self, item: Option) -> Self { self.with_equipment(EquipSlot::Lantern, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn glider(self, item: Option) -> Self { self.with_equipment(EquipSlot::Glider, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn head(self, item: Option) -> Self { self.with_armor(ArmorSlot::Head, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn tabard(self, item: Option) -> Self { self.with_armor(ArmorSlot::Tabard, item) } - #[must_use] + #[must_use = "Method consumes builder and returns updated builder."] pub fn bag(self, which: ArmorSlot, item: Option) -> Self { self.with_armor(which, item) } #[must_use] diff --git a/common/src/generation.rs b/common/src/generation.rs index e5a46562c0..bfc819cc1b 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -14,25 +14,58 @@ use serde::Deserialize; use vek::*; #[derive(Debug, Deserialize, Clone)] -enum BodyKind { +enum NameKind { + Name(String), + Automatic, + Uninit, +} + +#[derive(Debug, Deserialize, Clone)] +enum BodyBuilder { RandomWith(String), + Exact(Body), + Uninit, +} + +#[derive(Debug, Deserialize, Clone)] +enum AlignmentMark { + Alignment(Alignment), + Uninit, } #[derive(Debug, Deserialize, Clone)] enum LootKind { Item(String), LootTable(String), + Uninit, } #[derive(Debug, Deserialize, Clone)] -struct EntityConfig { - name: Option, - body: Option, - loot: Option, - main_tool: Option, - second_tool: Option, - loadout_asset: Option, - skillset_asset: Option, +enum Hands { + TwoHanded(ItemSpec), + Paired(ItemSpec), + Mix { + mainhand: ItemSpec, + offhand: ItemSpec, + }, + Uninit, +} + +#[derive(Debug, Deserialize, Clone)] +enum Meta { + LoadoutAsset(String), + SkillSetAsset(String), +} + +#[derive(Debug, Deserialize, Clone)] +pub struct EntityConfig { + name: NameKind, + body: BodyBuilder, + alignment: AlignmentMark, + loot: LootKind, + hands: Hands, + // Meta fields + meta: Vec, } impl assets::Asset for EntityConfig { @@ -41,6 +74,13 @@ impl assets::Asset for EntityConfig { const EXTENSION: &'static str = "ron"; } +impl EntityConfig { + pub fn from_asset_expect(asset_specifier: &str) -> EntityConfig { + Self::load_owned(asset_specifier) + .unwrap_or_else(|e| panic!("Failed to load {}. Error: {}", asset_specifier, e)) + } +} + #[derive(Clone)] pub struct EntityInfo { pub pos: Vec3, @@ -97,65 +137,100 @@ impl EntityInfo { } // helper function to apply config - fn with_entity_config(mut self, config: EntityConfig, asset_specifier: Option<&str>) -> Self { + fn with_entity_config(mut self, config: EntityConfig, config_asset: Option<&str>) -> Self { let EntityConfig { name, body, + alignment, loot, - main_tool, - second_tool, - loadout_asset, - skillset_asset, + hands, + meta, } = config; - if let Some(name) = name { - self = self.with_name(name); + match body { + BodyBuilder::RandomWith(string) => { + let npc::NpcBody(_body_kind, mut body_creator) = + string.parse::().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 Some(body) = body { - match body { - BodyKind::RandomWith(string) => { - let npc::NpcBody(_body_kind, mut body_creator) = - string.parse::().unwrap_or_else(|err| { - panic!("failed to parse body {:?}. Err: {:?}", &string, err) - }); - let body = body_creator(); - self = self.with_body(body); - }, - } + // NOTE: set name after body, as it's used with automatic name + match name { + NameKind::Name(name) => { + self = self.with_name(name); + }, + NameKind::Automatic => { + self = self.with_automatic_name(); + }, + NameKind::Uninit => {}, } - if let Some(loot) = loot { - match loot { - LootKind::Item(asset) => { - self = self.with_loot_drop(Item::new_from_asset_expect(&asset)); - }, - LootKind::LootTable(asset) => { - let table = Lottery::>::load_expect(&asset); - let drop = table.read().choose().to_item(); - self = self.with_loot_drop(drop); - }, - } + if let AlignmentMark::Alignment(alignment) = alignment { + self = self.with_alignment(alignment); + } + + match loot { + LootKind::Item(asset) => { + self = self.with_loot_drop(Item::new_from_asset_expect(&asset)); + }, + LootKind::LootTable(asset) => { + let table = Lottery::>::load_expect(&asset); + let drop = table.read().choose().to_item(); + self = self.with_loot_drop(drop); + }, + LootKind::Uninit => {}, } 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); + match hands { + Hands::TwoHanded(main_tool) => { + let tool = main_tool.try_to_item(config_asset.unwrap_or("??"), rng); + if let Some(tool) = tool { + self = self.with_main_tool(tool); + } + }, + Hands::Paired(tool) => { + //FIXME: very stupid code, which just tries same item two times + //figure out reasonable way to clone item + let main_tool = tool.try_to_item(config_asset.unwrap_or("??"), rng); + let second_tool = tool.try_to_item(config_asset.unwrap_or("??"), rng); + if let Some(main_tool) = main_tool { + self = self.with_main_tool(main_tool); + } + if let Some(second_tool) = second_tool { + self = self.with_second_tool(second_tool); + } + }, + Hands::Mix { mainhand, offhand } => { + let main_tool = mainhand.try_to_item(config_asset.unwrap_or("??"), rng); + let second_tool = offhand.try_to_item(config_asset.unwrap_or("??"), rng); + if let Some(main_tool) = main_tool { + self = self.with_main_tool(main_tool); + } + if let Some(second_tool) = second_tool { + self = self.with_second_tool(second_tool); + } + }, + Hands::Uninit => {}, } - if let Some(loadout_asset) = loadout_asset { - self = self.with_loadout_asset(loadout_asset); - } - - if let Some(skillset_asset) = skillset_asset { - self = self.with_skillset_asset(skillset_asset); + for field in meta { + match field { + Meta::LoadoutAsset(asset) => { + self = self.with_loadout_asset(asset); + }, + Meta::SkillSetAsset(asset) => { + self = self.with_skillset_asset(asset); + }, + } } self @@ -308,66 +383,147 @@ pub fn get_npc_name< mod tests { use super::*; use crate::{comp::inventory::slot::EquipSlot, SkillSetBuilder}; + use hashbrown::HashMap; + + #[derive(Debug, Eq, Hash, PartialEq)] + enum MetaId { + LoadoutAsset, + SkillSetAsset, + } + + impl Meta { + fn id(&self) -> MetaId { + match self { + Meta::LoadoutAsset(_) => MetaId::LoadoutAsset, + Meta::SkillSetAsset(_) => MetaId::SkillSetAsset, + } + } + } + + fn validate_hands(hands: Hands, _config_asset: &str) { + match hands { + Hands::TwoHanded(main_tool) => { + main_tool.validate(EquipSlot::ActiveMainhand); + }, + Hands::Paired(tool) => { + tool.validate(EquipSlot::ActiveMainhand); + tool.validate(EquipSlot::ActiveOffhand); + }, + Hands::Mix { mainhand, offhand } => { + mainhand.validate(EquipSlot::ActiveMainhand); + offhand.validate(EquipSlot::ActiveOffhand); + }, + Hands::Uninit => {}, + } + } + + fn validate_body_and_name(body: BodyBuilder, name: NameKind, config_asset: &str) { + match body { + BodyBuilder::RandomWith(string) => { + let npc::NpcBody(_body_kind, mut body_creator) = + string.parse::().unwrap_or_else(|err| { + panic!( + "failed to parse body {:?} in {}. Err: {:?}", + &string, config_asset, err + ) + }); + let _ = body_creator(); + }, + BodyBuilder::Uninit => { + if let NameKind::Automatic = name { + // there is a big chance to call automatic name + // when body is yet undefined + // + // use .with_automatic_name() in code explicitly + panic!("Used Automatic name with Uninit body in {}", config_asset); + } + }, + BodyBuilder::Exact { .. } => {}, + } + } + + fn validate_loot(loot: LootKind, config_asset: &str) { + match loot { + LootKind::Item(asset) => { + if let Err(e) = Item::new_from_asset(&asset) { + panic!( + "Unable to parse loot item ({}) in {}. Err: {:?}", + asset, config_asset, e + ); + } + }, + LootKind::LootTable(asset) => { + // we need to just load it check if it exists, + // because all loot tables are tested in Lottery module + if let Err(e) = Lottery::>::load(&asset) { + panic!( + "Unable to parse loot table ({}) in {}. Err: {:?}", + asset, config_asset, e + ); + } + }, + LootKind::Uninit => {}, + } + } + + fn validate_meta(meta: Vec, config_asset: &str) { + let mut meta_counter = HashMap::new(); + for field in meta { + meta_counter + .entry(field.id()) + .and_modify(|c| *c += 1) + .or_insert(1); + match field { + Meta::LoadoutAsset(asset) => { + let rng = &mut rand::thread_rng(); + let builder = LoadoutBuilder::default(); + // we need to just load it check if it exists, + // because all loadouts are tested in LoadoutBuilder module + std::mem::drop(builder.with_asset_expect(&asset, rng)); + }, + Meta::SkillSetAsset(asset) => { + std::mem::drop(SkillSetBuilder::from_asset_expect(&asset)); + }, + } + } + for (meta_id, counter) in meta_counter { + if counter > 1 { + panic!("Duplicate {:?} in {}", meta_id, config_asset); + } + } + } #[test] fn test_all_entity_assets() { // It just load everything that could - let entity_configs = assets::read_expect_dir::("common.entity", true); - for config in entity_configs { + let entity_configs = assets::load_dir::("common.entity", true) + .expect("Failed to access entity directory"); + for config_asset in entity_configs.ids() { + // print asset name so we don't need to find errors everywhere + // it'll be ignored by default so you'll see it only in case of errors + // + // TODO: + // 1) Add try_validate() for loadout_builder::ItemSpec which will return + // Result and we will happily panic in validate_hands() with name of + // config_asset. + // 2) Add try_from_asset() for LoadoutBuilder and + // SkillSet builder which will return Result and we will happily + // panic in validate_meta() with the name of config_asset + println!("{}:", config_asset); + let EntityConfig { - main_tool, - second_tool, - loadout_asset, - skillset_asset, - name: _name, + hands, body, + name, loot, - } = config.clone(); + meta, + alignment: _alignment, // can't fail if serialized, it's a boring enum + } = EntityConfig::from_asset_expect(config_asset); - if let Some(main_tool) = main_tool { - main_tool.validate(EquipSlot::ActiveMainhand); - } - - if let Some(second_tool) = second_tool { - 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::().unwrap_or_else(|err| { - panic!("failed to parse body {:?}. Err: {:?}", &string, err) - }); - let _ = body_creator(); - }, - } - } - - if let Some(loot) = loot { - match loot { - LootKind::Item(asset) => { - std::mem::drop(Item::new_from_asset_expect(&asset)); - }, - LootKind::LootTable(asset) => { - // we need to just load it check if it exists, - // because all loot tables are tested in Lottery module - let _ = Lottery::>::load_expect(&asset); - }, - } - } - - if let Some(loadout_asset) = loadout_asset { - let rng = &mut rand::thread_rng(); - let builder = LoadoutBuilder::default(); - // we need to just load it check if it exists, - // because all loadouts are tested in LoadoutBuilder module - std::mem::drop(builder.with_asset_expect(&loadout_asset, rng)); - } - - if let Some(skillset_asset) = skillset_asset { - std::mem::drop(SkillSetBuilder::from_asset_expect(&skillset_asset)); - } + validate_hands(hands, config_asset); + validate_body_and_name(body, name, config_asset); + validate_loot(loot, config_asset); + validate_meta(meta, config_asset); } } } diff --git a/common/src/time.rs b/common/src/time.rs index a13ba253f4..33a888cb85 100644 --- a/common/src/time.rs +++ b/common/src/time.rs @@ -1,4 +1,6 @@ -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +use serde::Deserialize; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize, Hash)] pub enum DayPeriod { Night, Morning, diff --git a/server/src/sys/terrain.rs b/server/src/sys/terrain.rs index 8514cfbb31..25ce94cd7f 100644 --- a/server/src/sys/terrain.rs +++ b/server/src/sys/terrain.rs @@ -208,6 +208,7 @@ impl<'a> System<'a> for Sys { let EntityInfo { skillset_asset, main_tool, + second_tool, loadout_asset, make_loadout, trading_information: economy, @@ -234,6 +235,11 @@ impl<'a> System<'a> for Sys { loadout_builder = loadout_builder.with_default_maintool(&body); } + // If second tool is passed, use it as well + if let Some(second_tool) = second_tool { + loadout_builder = loadout_builder.active_offhand(Some(second_tool)); + } + // If there is config, apply it. // If not, use default equipement for this body. if let Some(asset) = loadout_asset { diff --git a/world/src/config.rs b/world/src/config.rs index b3e841fce7..e6db31e6f2 100644 --- a/world/src/config.rs +++ b/world/src/config.rs @@ -53,13 +53,16 @@ pub struct Config { pub const CONFIG: Config = Config { sea_level: 140.0, mountain_scale: 2048.0, + // temperature snow_temp: -0.8, temperate_temp: -0.4, tropical_temp: 0.4, desert_temp: 0.8, + // humidity desert_hum: 0.15, forest_hum: 0.5, jungle_hum: 0.75, + // water rainfall_chunk_rate: 1.0 / (512.0 * 32.0 * 32.0), river_roughness: 0.06125, river_max_width: 2.0, diff --git a/world/src/index.rs b/world/src/index.rs index ab01a20452..7d5d6e4685 100644 --- a/world/src/index.rs +++ b/world/src/index.rs @@ -1,4 +1,5 @@ use crate::{ + layer::wildlife::{self, DensityFn, SpawnEntry}, site::{economy::TradeInformation, Site}, Colors, }; @@ -19,6 +20,7 @@ pub struct Index { pub noise: Noise, pub sites: Store, pub trade: TradeInformation, + pub wildlife_spawns: Vec<(AssetHandle, DensityFn)>, colors: AssetHandle>, } @@ -58,6 +60,10 @@ impl Index { /// NOTE: Panics if the color manifest cannot be loaded. pub fn new(seed: u32) -> Self { let colors = Arc::::load_expect(WORLD_COLORS_MANIFEST); + let wildlife_spawns = wildlife::spawn_manifest() + .into_iter() + .map(|(e, f)| (SpawnEntry::load_expect(e), f)) + .collect(); Self { seed, @@ -65,6 +71,7 @@ impl Index { noise: Noise::new(seed), sites: Store::default(), trade: Default::default(), + wildlife_spawns, colors, } } diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index df7c579196..e82b1afbc7 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -1,25 +1,267 @@ use crate::{column::ColumnSample, sim::SimChunk, IndexRef, CONFIG}; use common::{ - comp::{ - biped_large, bird_large, bird_medium, fish_medium, fish_small, quadruped_low, - quadruped_medium, quadruped_small, theropod, Alignment, - }, + assets::{self, AssetExt}, generation::{ChunkSupplement, EntityInfo}, resources::TimeOfDay, terrain::Block, - time::DayPeriod::{self, Evening, Morning, Night, Noon}, + time::DayPeriod, vol::{BaseVol, ReadVol, RectSizedVol, WriteVol}, }; use rand::prelude::*; -use std::{f32, ops::Range}; +use serde::Deserialize; +use std::f32; use vek::*; +type Weight = u32; +type Min = u8; +type Max = u8; + fn close(x: f32, tgt: f32, falloff: f32) -> f32 { (1.0 - (x - tgt).abs() / falloff).max(0.0).powf(0.125) } const BASE_DENSITY: f32 = 1.0e-5; // Base wildlife density +#[derive(Clone, Debug, Deserialize)] +pub struct SpawnEntry { + /// User-facing info for wiki, statistical tools, etc. + pub name: String, + pub note: String, + /// Rules describing what and when to spawn + pub rules: Vec, +} + +impl assets::Asset for SpawnEntry { + type Loader = assets::RonLoader; + + const EXTENSION: &'static str = "ron"; +} + +impl SpawnEntry { + pub fn from(asset_specifier: &str) -> Self { Self::load_expect(asset_specifier).read().clone() } + + pub fn request(&self, requested_period: DayPeriod, underwater: bool) -> Option { + self.rules + .iter() + .find(|pack| { + let time_match = pack + .day_period + .iter() + .any(|period| *period == requested_period); + let water_match = pack.is_underwater == underwater; + time_match && water_match + }) + .cloned() + } +} + +/// Dataset of animals to spawn +/// +/// Example: +/// ```text +/// Pack( +/// groups: [ +/// (3, (1, 2, "common.entity.wild.aggressive.frostfang")), +/// (1, (1, 1, "common.entity.wild.aggressive.snow_leopard")), +/// (1, (1, 1, "common.entity.wild.aggressive.yale")), +/// (1, (1, 1, "common.entity.wild.aggressive.grolgar")), +/// ], +/// is_underwater: false, +/// day_period: [Night, Morning, Noon, Evening], +/// ), +/// ``` +/// Groups: +/// ```text +/// (3, (1, 2, "common.entity.wild.aggressive.frostfang")), +/// ``` +/// (3, ...) means that it has x3 chance to spawn (3/6 when every other has +/// 1/6). +/// +/// (.., (1, 2, ...)) is `1..=2` group size which means that it has +/// chance to spawn as single mob or in pair +/// +/// (..., (..., "common.entity.wild.aggressive.frostfang")) corresponds +/// to `assets/common/entity/wild/aggressive/frostfang.ron` file with +/// EntityConfig +/// +/// Underwater: +/// `is_underwater: false` means mobs from this pack can't be spawned underwater +/// in rivers, lakes or ocean +/// +/// Day period: +/// `day_period: [Night, Morning, Noon, Evening]` +/// means that mobs from this pack may be spawned in any day period without +/// exception +#[derive(Clone, Debug, Deserialize)] +pub struct Pack { + pub groups: Vec<(Weight, (Min, Max, String))>, + pub is_underwater: bool, + pub day_period: Vec, +} + +impl Pack { + pub fn generate(&self, pos: Vec3, dynamic_rng: &mut impl Rng) -> (EntityInfo, u8) { + let (_, (from, to, entity_asset)) = self + .groups + .choose_weighted(dynamic_rng, |(p, _group)| *p) + .expect("Failed to choose group"); + let entity = EntityInfo::at(pos).with_asset_expect(entity_asset); + let group_size = dynamic_rng.gen_range(*from..=*to); + + (entity, group_size) + } +} + +pub type DensityFn = fn(&SimChunk, &ColumnSample) -> f32; + +pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> { + // NOTE: Order matters. + // Entries with more specific requirements + // and overall scarcity should come first, where possible. + vec![ + // **Tundra** + // Rock animals + ("world.wildlife.spawn.tundra.rock", |c, col| { + close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * col.rock * 1.0 + }), + // Core animals + ("world.wildlife.spawn.tundra.core", |c, _col| { + close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5 + }), + // Snowy animals + ("world.wildlife.spawn.tundra.snow", |c, col| { + close(c.temp, CONFIG.snow_temp, 0.3) * BASE_DENSITY * col.snow_cover as i32 as f32 * 1.0 + }), + // Forest animals + ("world.wildlife.spawn.tundra.forest", |c, col| { + close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4 + }), + // **Taiga** + // Forest core animals + ("world.wildlife.spawn.taiga.core_forest", |c, col| { + close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * col.tree_density * BASE_DENSITY * 0.4 + }), + // Core animals + ("world.wildlife.spawn.taiga.core", |c, _col| { + close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0 + }), + // Forest area animals + ("world.wildlife.spawn.taiga.forest", |c, col| { + close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * col.tree_density * BASE_DENSITY * 0.9 + }), + // Area animals + ("world.wildlife.spawn.taiga.area", |c, _col| { + close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0 + }), + // Water animals + ("world.wildlife.spawn.taiga.water", |c, col| { + close(c.temp, CONFIG.snow_temp, 0.15) * col.tree_density * BASE_DENSITY * 5.0 + }), + // **Temperate** + // Area rare + ("world.wildlife.spawn.temperate.rare", |c, _col| { + close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.08 + }), + // River wildlife + ("world.wildlife.spawn.temperate.river", |_c, col| { + close(col.temp, CONFIG.temperate_temp, 0.6) + * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { + 0.001 + } else { + 0.0 + } + }), + // Forest animals + ("world.wildlife.spawn.temperate.wood", |c, col| { + close(c.temp, CONFIG.temperate_temp + 0.1, 0.5) * col.tree_density * BASE_DENSITY * 1.0 + }), + // Rainforest animals + ("world.wildlife.spawn.temperate.rainforest", |c, _col| { + close(c.temp, CONFIG.temperate_temp + 0.1, 0.6) + * close(c.humidity, CONFIG.forest_hum, 0.6) + * BASE_DENSITY + * 4.0 + }), + // Water animals + ("world.wildlife.spawn.temperate.water", |c, col| { + close(c.temp, CONFIG.temperate_temp, 1.0) * col.tree_density * BASE_DENSITY * 5.0 + }), + // **Jungle** + // Rainforest animals + ("world.wildlife.spawn.jungle.rainforest", |c, _col| { + close(c.temp, CONFIG.tropical_temp + 0.2, 0.2) + * close(c.humidity, CONFIG.jungle_hum, 0.2) + * BASE_DENSITY + * 2.8 + }), + // Rainforest area animals + ("world.wildlife.spawn.jungle.rainforest_area", |c, _col| { + close(c.temp, CONFIG.tropical_temp + 0.2, 0.3) + * close(c.humidity, CONFIG.jungle_hum, 0.2) + * BASE_DENSITY + * 8.0 + }), + // **Tropical** + // Rare river animals + ("world.wildlife.spawn.tropical.river_rare", |_c, col| { + close(col.temp, CONFIG.tropical_temp + 0.2, 0.5) + * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { + 0.0001 + } else { + 0.0 + } + }), + // River animals + ("world.wildlife.spawn.tropical.river", |_c, col| { + close(col.temp, CONFIG.tropical_temp, 0.5) + * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { + 0.001 + } else { + 0.0 + } + }), + // Rainforest area animals + ("world.wildlife.spawn.tropical.rainforest", |c, _col| { + close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) + * close(c.humidity, CONFIG.desert_hum, 0.4) + * BASE_DENSITY + * 2.0 + }), + // Rock animals + ("world.wildlife.spawn.tropical.rock", |c, col| { + close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock * BASE_DENSITY * 5.0 + }), + // **Desert** + // Area animals + ("world.wildlife.spawn.desert.area", |c, _col| { + close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) + * close(c.humidity, CONFIG.desert_hum, 0.4) + * BASE_DENSITY + * 0.8 + }), + // Wasteland animals + ("world.wildlife.spawn.desert.wasteland", |c, _col| { + close(c.temp, CONFIG.desert_temp + 0.2, 0.3) + * close(c.humidity, CONFIG.desert_hum, 0.5) + * BASE_DENSITY + * 1.3 + }), + // River animals + ("world.wildlife.spawn.desert.river", |_c, col| { + close(col.temp, CONFIG.desert_temp + 0.2, 0.3) + * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { + 0.0001 + } else { + 0.0 + } + }), + // Hot area desert + ("world.wildlife.spawn.desert.hot", |c, _col| { + close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 3.8 + }), + ] +} + #[allow(clippy::eval_order_dependence)] pub fn apply_wildlife_supplement<'a, R: Rng>( // NOTE: Used only for dynamic elements like chests and entities! @@ -27,1031 +269,12 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( wpos2d: Vec2, mut get_column: impl FnMut(Vec2) -> Option<&'a ColumnSample<'a>>, vol: &(impl BaseVol + RectSizedVol + ReadVol + WriteVol), - _index: IndexRef, + index: IndexRef, chunk: &SimChunk, supplement: &mut ChunkSupplement, time: Option, ) { - struct Entry { - make_entity: fn(Vec3, &mut R) -> EntityInfo, // Entity - group_size: Range, // Group size range - is_underwater: bool, // Underwater? - day_period: Vec, // Period of the day - get_density: fn(&SimChunk, &ColumnSample) -> f32, // Density - } - - let scatter: &[Entry] = &[ - // Tundra snow pack ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Frostfang, - ) - .into(), - 1 => { - theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into() - }, - _ => quadruped_medium::Body { - species: quadruped_medium::Species::Roshwalr, - body_type: quadruped_medium::BodyType::Male, - } - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..4, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.snow_temp, 0.3) - * BASE_DENSITY - * col.snow_cover as i32 as f32 - * 1.0 - }, - }, - // Tundra solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..4) { - 0 => { - theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into() - }, - 1 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Snowleopard, - ) - .into(), - 2 => theropod::Body::random_with(rng, &theropod::Species::Yale).into(), - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Grolgar, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4 - }, - }, - // Tundra rare solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5, - }, - // Tundra rarer solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => biped_large::Body::random_with(rng, &biped_large::Species::Wendigo) - .into(), - 1 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Mammoth, - ) - .into(), - _ => biped_large::Body::random_with( - rng, - &biped_large::Species::Mountaintroll, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.15, - }, - // Tundra rock solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Rocksnapper) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * col.rock * 1.0 - }, - }, - // Taiga rare solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..2) { - 0 => biped_large::Body::random_with(rng, &biped_large::Species::Wendigo) - .into(), - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Dreadhorn, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * col.tree_density * BASE_DENSITY * 0.4 - }, - }, - // Taiga pack ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_medium::Body::random_with(rng, &quadruped_medium::Species::Wolf) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 3..8, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * col.tree_density * BASE_DENSITY * 0.9 - }, - }, - // Taiga pack wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..5) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Mouflon, - ) - .into(), - 1 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Yak, - ) - .into(), - 2 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Llama, - ) - .into(), - 3 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Alpaca, - ) - .into(), - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Highland, - ) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..4, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0, - }, - // Taiga solitary wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..6) { - 0 => { - bird_medium::Body::random_with(rng, &bird_medium::Species::Eagle).into() - }, - 1 => bird_medium::Body::random_with(rng, &bird_medium::Species::Owl).into(), - 2 => quadruped_small::Body { - species: quadruped_small::Species::Fox, - body_type: quadruped_small::BodyType::Female, - } - .into(), - 3 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Moose, - ) - .into(), - 4 => { - quadruped_small::Body { - species: quadruped_small::Species::Hare, - body_type: quadruped_small::BodyType::Female, - } - } - .into(), - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Tuskram, - ) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0, - }, - // Temperate solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..5) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Tarasque, - ) - .into(), - 1 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Bear, - ) - .into(), - 2 => { - theropod::Body::random_with(rng, &theropod::Species::Woodraptor).into() - }, - 3 => { - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Deadwood) - .into() - }, - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Saber, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.temperate_temp + 0.1, 0.5) - * col.tree_density - * BASE_DENSITY - * 1.0 - }, - }, - // Temperate pack wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..14) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Deer, - ) - .into(), - 1 => { - quadruped_small::Body::random_with(rng, &quadruped_small::Species::Rat) - .into() - }, - 2 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Rabbit, - ) - .into(), - 3 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Jackalope, - ) - .into(), - 4 => { - quadruped_small::Body::random_with(rng, &quadruped_small::Species::Boar) - .into() - }, - 5 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Sheep, - ) - .into(), - 6 => { - quadruped_small::Body::random_with(rng, &quadruped_small::Species::Pig) - .into() - }, - 7 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Squirrel, - ) - .into(), - 8 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Horse, - ) - .into(), - 9 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Cattle, - ) - .into(), - 10 => { - quadruped_small::Body::random_with(rng, &quadruped_small::Species::Goat) - .into() - }, - 11 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Llama, - ) - .into(), - 12 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Alpaca, - ) - .into(), - _ => bird_medium::Body::random_with(rng, &bird_medium::Species::Chicken) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..8, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.temperate_temp + 0.1, 0.6) - * close(c.humidity, CONFIG.forest_hum, 0.6) - * BASE_DENSITY - * 4.0 - }, - }, - // Temperate solitary wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..10) { - 0 => quadruped_small::Body { - species: quadruped_small::Species::Fox, - body_type: quadruped_small::BodyType::Male, - } - .into(), - 1 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Donkey, - ) - .into(), - 2 => { - bird_medium::Body::random_with(rng, &bird_medium::Species::Goose).into() - }, - 3 => bird_medium::Body::random_with(rng, &bird_medium::Species::Peacock) - .into(), - 4 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Skunk, - ) - .into(), - 5 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Raccoon, - ) - .into(), - 6 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Catoblepas, - ) - .into(), - 7 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Turtle, - ) - .into(), - 8 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Hirdrasil, - ) - .into(), - _ => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Truffler, - ) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.temperate_temp + 0.1, 0.6) - * BASE_DENSITY - * close(c.humidity, CONFIG.forest_hum, 0.6) - * 8.0 - }, - }, - // Temperate solitary wild night - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_small::Body::random_with(rng, &quadruped_small::Species::Batfox) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night], - get_density: |c, _col| { - close(c.temp, CONFIG.temperate_temp + 0.1, 0.6) - * BASE_DENSITY - * close(c.humidity, CONFIG.forest_hum, 0.6) - * 0.8 - }, - }, - // Rare temperate solitary enemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => { - biped_large::Body::random_with(rng, &biped_large::Species::Ogre).into() - }, - 1 => biped_large::Body::random_with(rng, &biped_large::Species::Swamptroll) - .into(), - _ => biped_large::Body::random_with(rng, &biped_large::Species::Cyclops) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.08, - }, - // Temperate river wildlife - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..4) { - 0 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Beaver, - ) - .into(), - 1 => quadruped_low::Body { - species: quadruped_low::Species::Salamander, - body_type: quadruped_low::BodyType::Female, - } - .into(), - 2 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Kelpie, - ) - .into(), - _ => { - bird_medium::Body::random_with(rng, &bird_medium::Species::Duck).into() - }, - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |_c, col| { - close(col.temp, CONFIG.temperate_temp, 0.6) - * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.001 - } else { - 0.0 - } - }, - }, - // Temperate rare river ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Kelpie, - ) - .into(), - ) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |_c, col| { - close(col.temp, CONFIG.temperate_temp, 0.6) - * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.00005 - } else { - 0.0 - } - }, - }, - // Temperate river ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Hakulaq) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |_c, col| { - close(col.temp, CONFIG.temperate_temp, 0.6) - * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.0001 - } else { - 0.0 - } - }, - }, - // Tropical rock solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Dodarock, - ) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock * BASE_DENSITY * 5.0 - }, - }, - // Jungle solitary ennemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => { - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Maneater) - .into() - }, - 1 => quadruped_low::Body::random_with(rng, &quadruped_low::Species::Asp) - .into(), - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Tiger, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.2, 0.2) - * close(c.humidity, CONFIG.jungle_hum, 0.2) - * BASE_DENSITY - * 2.8 - }, - }, - // Jungle solitary ennemies day - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - theropod::Body::random_with(rng, &theropod::Species::Sunlizard).into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.2, 0.2) - * close(c.humidity, CONFIG.jungle_hum, 0.2) - * BASE_DENSITY - * 0.5 - }, - }, - // Jungle rare solitary wild day - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..5) { - 0 => theropod::Body::random_with(rng, &theropod::Species::Odonto).into(), - 1 => { - biped_large::Body::random_with(rng, &biped_large::Species::Mightysaurok) - .into() - }, - 2 => { - biped_large::Body::random_with(rng, &biped_large::Species::Occultsaurok) - .into() - }, - 3 => bird_large::Body::random_with(rng, &bird_large::Species::Cockatrice) - .into(), - _ => biped_large::Body::random_with(rng, &biped_large::Species::Slysaurok) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.2, 0.2) - * close(c.humidity, CONFIG.jungle_hum, 0.2) - * BASE_DENSITY - * 0.8 - }, - }, - // Jungle solitary wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot) - .into(), - - 1 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Quokka, - ) - .into(), - _ => { - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Tortoise) - .into() - }, - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.2, 0.3) - * close(c.humidity, CONFIG.jungle_hum, 0.2) - * BASE_DENSITY - * 8.0 - }, - }, - // Jungle solitary wild day - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Monitor) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.2, 0.3) - * close(c.humidity, CONFIG.jungle_hum, 0.2) - * BASE_DENSITY - * 2.0 - }, - }, - // Tropical rare river enemy - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Alligator) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..3, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |_c, col| { - close(col.temp, CONFIG.tropical_temp + 0.2, 0.5) - * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.0001 - } else { - 0.0 - } - }, - }, - // Tropical rare river wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => { - quadruped_small::Body::random_with(rng, &quadruped_small::Species::Frog) - .into() - }, - 1 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Axolotl, - ) - .into(), - _ => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Fungome, - ) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..3, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |_c, col| { - close(col.temp, CONFIG.tropical_temp, 0.5) - * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.001 - } else { - 0.0 - } - }, - }, - // Tropical pack enemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..2) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Lion, - ) - .into(), - _ => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Hyena, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..3, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) - * close(c.humidity, CONFIG.desert_hum, 0.4) - * BASE_DENSITY - * 2.0 - }, - }, - // Desert pack wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..2) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Zebra, - ) - .into(), - _ => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Antelope, - ) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 3..7, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) - * close(c.humidity, CONFIG.desert_hum, 0.4) - * BASE_DENSITY - * 0.8 - }, - }, - // Desert solitary enemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..4) { - 0 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Bonerattler, - ) - .into(), - 1 => { - theropod::Body::random_with(rng, &theropod::Species::Sandraptor).into() - }, - 2 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Ngoubou, - ) - .into(), - _ => quadruped_low::Body::random_with( - rng, - &quadruped_low::Species::Sandshark, - ) - .into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.desert_temp + 0.2, 0.3) - * close(c.humidity, CONFIG.desert_hum, 0.5) - * BASE_DENSITY - * 1.3 - }, - }, - // Desert rare solitary enemies - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => quadruped_low::Body::random_with( - rng, - &quadruped_low::Species::Lavadrake, - ) - .into(), - 1 => theropod::Body::random_with(rng, &theropod::Species::Ntouka).into(), - _ => theropod::Body::random_with(rng, &theropod::Species::Archaeos).into(), - }) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.desert_temp + 0.2, 0.3) - * close(c.humidity, CONFIG.desert_hum, 0.5) - * BASE_DENSITY - * 0.15 - }, - }, - // Desert river solitary enemy - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Crocodile) - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..3, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |_c, col| { - close(col.temp, CONFIG.desert_temp + 0.2, 0.3) - * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.0001 - } else { - 0.0 - } - }, - }, - // Desert secret solitary enemy - Entry { - make_entity: |pos, _rng| { - EntityInfo::at(pos) - .with_body( - quadruped_medium::Body { - species: quadruped_medium::Species::Roshwalr, - body_type: quadruped_medium::BodyType::Female, - } - .into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..3, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.desert_temp + 0.2, 0.3) - * close(c.humidity, CONFIG.desert_hum, 0.5) - * BASE_DENSITY - * 0.005 - }, - }, - // Desert solitary wild - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..4) { - 0 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Holladon, - ) - .into(), - 1 => { - quadruped_low::Body::random_with(rng, &quadruped_low::Species::Pangolin) - .into() - }, - 2 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Camel, - ) - .into(), - 3 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Porcupine, - ) - .into(), - _ => quadruped_small::Body { - species: quadruped_small::Species::Hare, - body_type: quadruped_small::BodyType::Male, - } - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 3.8 - }, - }, - // Desert solitary wild day - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 1 => quadruped_low::Body { - species: quadruped_low::Species::Salamander, - body_type: quadruped_low::BodyType::Male, - } - .into(), - _ => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Gecko, - ) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 1..2, - is_underwater: false, - day_period: vec![Morning, Noon, Evening], - get_density: |c, _col| { - close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 1.0 - }, - }, - // Underwater temperate - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body(match rng.gen_range(0..3) { - 0 => fish_medium::Body::random_with(rng, &fish_medium::Species::Marlin) - .into(), - 1 => { - fish_small::Body::random_with(rng, &fish_small::Species::Piranha).into() - }, - _ => fish_small::Body::random_with(rng, &fish_small::Species::Clownfish) - .into(), - }) - .with_alignment(Alignment::Wild) - }, - group_size: 3..5, - is_underwater: true, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.temperate_temp, 1.0) * col.tree_density * BASE_DENSITY * 5.0 - }, - }, - // Underwater taiga - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - fish_medium::Body::random_with(rng, &fish_medium::Species::Icepike).into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 1..3, - is_underwater: true, - day_period: vec![Night, Morning, Noon, Evening], - get_density: |c, col| { - close(c.temp, CONFIG.snow_temp, 0.15) * col.tree_density * BASE_DENSITY * 5.0 - }, - }, - ]; + let scatter = &index.wildlife_spawns; for y in 0..vol.size_xy().y as i32 { for x in 0..vol.size_xy().x as i32 { @@ -1071,39 +294,32 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( if let Some(time) = time { current_day_period = DayPeriod::from(time.0) } else { - current_day_period = Noon + current_day_period = DayPeriod::Noon } - let entity_group = scatter.iter().enumerate().find_map( - |( - _i, - Entry { - make_entity, - group_size, - is_underwater, - day_period, - get_density, - }, - )| { + let entity_group = scatter + .iter() + .enumerate() + .find_map(|(_i, (entry, get_density))| { let density = get_density(chunk, col_sample); - if density > 0.0 - && dynamic_rng.gen::() < density * col_sample.spawn_rate - && underwater == *is_underwater - && day_period.contains(¤t_day_period) - && col_sample.gradient < Some(1.3) - { - Some((make_entity, group_size.clone())) - } else { - None - } - }, - ); + (density > 0.0) + .then(|| { + entry + .read() + .request(current_day_period, underwater) + .and_then(|pack| { + (dynamic_rng.gen::() < density * col_sample.spawn_rate + && col_sample.gradient < Some(1.3)) + .then(|| pack) + }) + }) + .flatten() + }); let alt = col_sample.alt as i32; - if let Some((make_entity, group_size)) = entity_group { - let group_size = dynamic_rng.gen_range(group_size.start..group_size.end); - let entity = make_entity( + if let Some(pack) = entity_group { + let (entity, group_size) = pack.generate( (wpos2d.map(|e| e as f32) + 0.5).with_z(alt as f32), dynamic_rng, ); @@ -1130,10 +346,110 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) { let mut entity = entity.clone(); entity.pos += offs_wpos2d.with_z(solid_end).map(|e| e as f32); - supplement.add_entity(entity.with_automatic_name()); + supplement.add_entity(entity); } } } } } } + +#[cfg(test)] +mod tests { + use super::*; + use hashbrown::{HashMap, HashSet}; + + // Checks that each entry in spawn manifest is loadable + #[test] + fn test_load_entries() { + let scatter = spawn_manifest(); + for (entry, _) in scatter.into_iter() { + std::mem::drop(SpawnEntry::from(entry)); + } + } + + // Check that each spawn entry has unique name + #[test] + fn test_name_uniqueness() { + let scatter = spawn_manifest(); + let mut names = HashMap::new(); + for (entry, _) in scatter.into_iter() { + let SpawnEntry { name, .. } = SpawnEntry::from(entry); + if let Some(old_entry) = names.insert(name, entry) { + panic!("{}: Found name duplicate with {}", entry, old_entry); + } + } + } + + // Checks that day_period aren't overlapping + // Quite strict rule, but otherwise may produce unexpected behaviour + #[test] + fn test_check_day_periods() { + let scatter = spawn_manifest(); + for (entry, _) in scatter.into_iter() { + let mut day_periods = HashSet::with_capacity(4); + let SpawnEntry { rules, .. } = SpawnEntry::from(entry); + for pack in rules { + let Pack { + day_period, + is_underwater, + .. + } = pack; + for period in day_period { + if !day_periods.insert((period, is_underwater)) { + panic!( + r#" + == {}: == + Found rules with duplicated `day_period` and `is_underwater` + If you have two of such entries, + there are big chances that second rule will be unreachable. + + If you want some animals spawned in different Packs + with same day_period, add those animals to both Packs + and choose day_period to not overlap. +"#, + entry + ) + } + } + } + } + } + + // Checks that each entity is loadable + #[test] + fn test_load_entities() { + let scatter = spawn_manifest(); + for (entry, _) in scatter.into_iter() { + let SpawnEntry { rules, .. } = SpawnEntry::from(entry); + for pack in rules { + let Pack { groups, .. } = pack; + for group in &groups { + println!("{}:", entry); + let (_, (_, _, asset)) = group; + let dummy_pos = Vec3::new(0.0, 0.0, 0.0); + let entity = EntityInfo::at(dummy_pos).with_asset_expect(asset); + std::mem::drop(entity); + } + } + } + } + + // Checks that group distribution has valid form + #[test] + fn test_group_choose() { + let scatter = spawn_manifest(); + for (entry, _) in scatter.into_iter() { + let SpawnEntry { rules, .. } = SpawnEntry::from(entry); + for pack in rules { + let Pack { groups, .. } = pack; + let dynamic_rng = &mut rand::thread_rng(); + let _ = groups + .choose_weighted(dynamic_rng, |(p, _group)| *p) + .unwrap_or_else(|err| { + panic!("{}: Failed to choose random group. Err: {}", entry, err) + }); + } + } + } +} diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 21fcb1baa8..b37cc4dcb2 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -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, @@ -859,7 +859,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! @@ -903,75 +902,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), + _ => humanoid(entity_wpos, &economy, dynamic_rng), + } + }; supplement.add_entity(entity); } @@ -1030,6 +973,60 @@ impl Settlement { } } +fn barnyard(pos: Vec3, dynamic_rng: &mut impl Rng) -> EntityInfo { + //TODO: use Lottery instead of ad-hoc RNG system + 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, dynamic_rng: &mut impl Rng) -> EntityInfo { + //TODO: use Lottery instead of ad-hoc RNG system + 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 humanoid(pos: Vec3, 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"), + } +} + fn merchant_loadout( loadout_builder: LoadoutBuilder, economy: Option<&trade::SiteInformation>, diff --git a/world/src/site2/plot/dungeon.rs b/world/src/site2/plot/dungeon.rs index 06664180cd..c8a96a1935 100644 --- a/world/src/site2/plot/dungeon.rs +++ b/world/src/site2/plot/dungeon.rs @@ -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) -> Vec) -> EntityInfo { + EntityInfo::at(pos).with_asset_expect("common.entity.dungeon.tier-3.sentry") +} + +fn turret_5(pos: Vec3) -> EntityInfo { + EntityInfo::at(pos).with_asset_expect("common.entity.dungeon.tier-5.turret") +} + fn boss_0(tile_wcenter: Vec3) -> Vec { vec![ EntityInfo::at(tile_wcenter.map(|e| e as f32)) @@ -1444,4 +1439,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); + } }