diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron
index 98ab4eecb1..016ace5fba 100644
--- a/assets/common/abilities/ability_set_manifest.ron
+++ b/assets/common/abilities/ability_set_manifest.ron
@@ -321,6 +321,11 @@
secondary: "common.abilities.custom.turret.arrows",
abilities: [],
),
+ Custom("Organ"): (
+ primary: "common.abilities.custom.organ.organaura",
+ secondary: "common.abilities.custom.organ.organaura",
+ abilities: [],
+ ),
Custom("Haniwa Sentry"): (
primary: "common.abilities.custom.turret.flamethrower",
secondary: "common.abilities.custom.turret.flamethrower",
@@ -367,6 +372,20 @@
(None, "common.abilities.custom.harvester.explodingpumpkin"),
],
),
+ // TODO: Allow ability sets to expand other ability sets
+ Custom("Dagon"): (
+ primary: "common.abilities.custom.dagon.dagonbombs",
+ secondary: "common.abilities.custom.dagon.seaurchins",
+ abilities: [],
+ ),
+ Custom("Cardinal"): (
+ primary: "common.abilities.sceptre.lifestealbeam",
+ secondary: "common.abilities.sceptre.healingaura",
+ abilities: [
+ (Some(Sceptre(UnlockAura)), "common.abilities.sceptre.wardingaura"),
+ (None, "common.abilities.custom.cardinal.summonseacrocs"),
+ ],
+ ),
Custom("Oni"): (
primary: "common.abilities.custom.oni.dash",
secondary: "common.abilities.custom.oni.doublestrike",
diff --git a/assets/common/abilities/custom/cardinal/summonseacrocs.ron b/assets/common/abilities/custom/cardinal/summonseacrocs.ron
new file mode 100644
index 0000000000..216b7d097c
--- /dev/null
+++ b/assets/common/abilities/custom/cardinal/summonseacrocs.ron
@@ -0,0 +1,18 @@
+BasicSummon(
+ buildup_duration: 0.5,
+ cast_duration: 1.0,
+ recover_duration: 0.5,
+ summon_amount: 4,
+ summon_distance: (4, 4),
+ summon_info: (
+ body: QuadrupedLow((
+ species: SeaCrocodile,
+ body_type: Male,
+ )),
+ scale: None,
+ has_health: true,
+ loadout_config: None,
+ skillset_config: Some(Rank5),
+ ),
+ duration: None,
+)
diff --git a/assets/common/abilities/custom/dagon/dagonbombs.ron b/assets/common/abilities/custom/dagon/dagonbombs.ron
new file mode 100644
index 0000000000..6744061753
--- /dev/null
+++ b/assets/common/abilities/custom/dagon/dagonbombs.ron
@@ -0,0 +1,16 @@
+BasicRanged(
+ energy_cost: 0,
+ buildup_duration: 0.4,
+ recover_duration: 0.6,
+ projectile: DagonBomb(
+ damage: 32.0,
+ knockback: 25.0,
+ radius: 10.0,
+ min_falloff: 0.6,
+ ),
+ projectile_body: Object(DagonBomb),
+ projectile_light: None,
+ projectile_speed: 30.0,
+ num_projectiles: 1,
+ projectile_spread: 0.0,
+)
diff --git a/assets/common/abilities/custom/dagon/seaurchins.ron b/assets/common/abilities/custom/dagon/seaurchins.ron
new file mode 100644
index 0000000000..ad76f2755d
--- /dev/null
+++ b/assets/common/abilities/custom/dagon/seaurchins.ron
@@ -0,0 +1,8 @@
+SpriteSummon(
+ buildup_duration: 0.1,
+ cast_duration: 0.1,
+ recover_duration: 0.9,
+ sprite: SeaUrchin,
+ summon_distance: (3, 3.1),
+ sparseness: 0.2,
+)
\ No newline at end of file
diff --git a/assets/common/abilities/custom/organ/organaura.ron b/assets/common/abilities/custom/organ/organaura.ron
new file mode 100644
index 0000000000..00aa669fd7
--- /dev/null
+++ b/assets/common/abilities/custom/organ/organaura.ron
@@ -0,0 +1,19 @@
+BasicAura(
+ buildup_duration: 0.0,
+ cast_duration: 0.0,
+ recover_duration: 2.0,
+ targets: InGroup,
+ auras: [
+ (
+ kind: ProtectingWard,
+ strength: 0.20,
+ duration: Some(10.0),
+ category: Magical,
+ ),
+ ],
+ aura_duration: 34.75,
+ range: 18.0,
+ energy_cost: 0.0,
+ scales_with_combo: false,
+ specifier: Some(WardingAura),
+)
\ No newline at end of file
diff --git a/assets/common/entity/dungeon/sea_chapel/cardinal.ron b/assets/common/entity/dungeon/sea_chapel/cardinal.ron
new file mode 100644
index 0000000000..4f6b7b6825
--- /dev/null
+++ b/assets/common/entity/dungeon/sea_chapel/cardinal.ron
@@ -0,0 +1,16 @@
+#![enable(implicit_some)]
+(
+ name: Name("Cardinal"),
+ body: RandomWith("humanoid"),
+ alignment: Alignment(Enemy),
+ loot: LootTable("common.loot_tables.dungeon.sea_chapel.cardinal"),
+ inventory: (
+ loadout: Inline((
+ inherit: Asset("common.loadout.dungeon.sea_chapel.cardinal"),
+ active_hands: InHands((Item("common.items.npc_weapons.unique.cardinal"), None)),
+ )),
+ ),
+ meta: [
+ SkillSetAsset("common.skillset.preset.rank5.fullskill"),
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/entity/dungeon/sea_chapel/dagon.ron b/assets/common/entity/dungeon/sea_chapel/dagon.ron
new file mode 100644
index 0000000000..986d5d3e0e
--- /dev/null
+++ b/assets/common/entity/dungeon/sea_chapel/dagon.ron
@@ -0,0 +1,11 @@
+#![enable(implicit_some)]
+(
+ name: Name("Dagon"),
+ body: RandomWith("dagon"),
+ alignment: Alignment(Enemy),
+ loot: LootTable("common.loot_tables.dungeon.sea_chapel.dagon"),
+ inventory: (
+ loadout: FromBody,
+ ),
+ meta: [],
+)
\ No newline at end of file
diff --git a/assets/common/entity/dungeon/sea_chapel/organ.ron b/assets/common/entity/dungeon/sea_chapel/organ.ron
new file mode 100644
index 0000000000..c8acfdbe7c
--- /dev/null
+++ b/assets/common/entity/dungeon/sea_chapel/organ.ron
@@ -0,0 +1,11 @@
+#![enable(implicit_some)]
+(
+ name: Name("Organ"),
+ body: Exact(Object(BarrelOrgan)),
+ alignment: Alignment(Enemy),
+ loot: Item("common.items.crafting_ing.seashells"),
+ inventory: (
+ loadout: FromBody
+ ),
+ meta: [],
+)
\ No newline at end of file
diff --git a/assets/common/entity/dungeon/sea_chapel/sea_cleric.ron b/assets/common/entity/dungeon/sea_chapel/sea_cleric.ron
new file mode 100644
index 0000000000..15b0b6920b
--- /dev/null
+++ b/assets/common/entity/dungeon/sea_chapel/sea_cleric.ron
@@ -0,0 +1,21 @@
+#![enable(implicit_some)]
+(
+ name: Name("Sea Cleric"),
+ body: RandomWith("danari"),
+ alignment: Alignment(Enemy),
+ loot: LootTable("common.loot_tables.dungeon.sea_chapel.sea_cleric"),
+ inventory: (
+ loadout: Inline((
+ inherit: Asset("common.loadout.dungeon.sea_chapel.sea_cleric"),
+ active_hands: InHands((Choice([
+ (2, ModularWeapon(tool: Axe, material: Cobalt, hands: None)),
+ (2, ModularWeapon(tool: Sword, material: Cobalt, hands: None)),
+ (2, ModularWeapon(tool: Hammer, material: Cobalt, hands: None)),
+ (2, ModularWeapon(tool: Bow, material: Ironwood, hands: None)),
+ ]), None)),
+ )),
+ ),
+ meta: [
+ SkillSetAsset("common.skillset.preset.rank4.fullskill"),
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/entity/dungeon/sea_chapel/sea_cleric_sceptre.ron b/assets/common/entity/dungeon/sea_chapel/sea_cleric_sceptre.ron
new file mode 100644
index 0000000000..4ac20749ad
--- /dev/null
+++ b/assets/common/entity/dungeon/sea_chapel/sea_cleric_sceptre.ron
@@ -0,0 +1,18 @@
+#![enable(implicit_some)]
+(
+ name: Name("Sea Cleric"),
+ body: RandomWith("danari"),
+ alignment: Alignment(Enemy),
+ loot: LootTable("common.loot_tables.dungeon.sea_chapel.sea_cleric"),
+ inventory: (
+ loadout: Inline((
+ inherit: Asset("common.loadout.dungeon.sea_chapel.sea_cleric"),
+ active_hands: InHands((Choice([
+ (1, ModularWeapon(tool: Sceptre, material: Ironwood, hands: None)),
+ ]), None)),
+ )),
+ ),
+ meta: [
+ SkillSetAsset("common.skillset.preset.rank4.fullskill"),
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/cardinal/belt.ron b/assets/common/items/armor/cardinal/belt.ron
new file mode 100644
index 0000000000..c4b67693c7
--- /dev/null
+++ b/assets/common/items/armor/cardinal/belt.ron
@@ -0,0 +1,18 @@
+ItemDef(
+ name: "Cardinal's Belt",
+ description: "Seemlessly transitions...",
+ kind: Armor((
+ kind: Belt,
+ stats: Direct((
+ protection: Some(Normal(24.0)),
+ poise_resilience: Some(Normal(3.0)),
+ energy_max: Some(20),
+ energy_reward: Some(0.025),
+ crit_power: Some(0.06),
+ stealth: Some(0.0),
+ )),
+ )),
+ quality: Legendary,
+ tags: [
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/cardinal/chest.ron b/assets/common/items/armor/cardinal/chest.ron
new file mode 100644
index 0000000000..d20c5fc785
--- /dev/null
+++ b/assets/common/items/armor/cardinal/chest.ron
@@ -0,0 +1,18 @@
+ItemDef(
+ name: "Cardinal's Cloak",
+ description: "A part of the cardinal's exquisite cloak.",
+ kind: Armor((
+ kind: Chest,
+ stats: Direct((
+ protection: Some(Normal(60.0)),
+ poise_resilience: Some(Normal(18.0)),
+ energy_max: Some(120),
+ energy_reward: Some(0.060),
+ crit_power: Some(0.375),
+ stealth: Some(0.0),
+ )),
+ )),
+ quality: Legendary,
+ tags: [
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/cardinal/foot.ron b/assets/common/items/armor/cardinal/foot.ron
new file mode 100644
index 0000000000..0bfa1311dd
--- /dev/null
+++ b/assets/common/items/armor/cardinal/foot.ron
@@ -0,0 +1,18 @@
+ItemDef(
+ name: "Cardinal's Boots",
+ description: "The boots with millions of steps.",
+ kind: Armor((
+ kind: Foot,
+ stats: Direct((
+ protection: Some(Normal(24.0)),
+ poise_resilience: Some(Normal(6.0)),
+ energy_max: Some(85),
+ energy_reward: Some(0.105),
+ crit_power: Some(0.12),
+ stealth: Some(0.0),
+ )),
+ )),
+ quality: Legendary,
+ tags: [
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/cardinal/hand.ron b/assets/common/items/armor/cardinal/hand.ron
new file mode 100644
index 0000000000..73dcb6f0e4
--- /dev/null
+++ b/assets/common/items/armor/cardinal/hand.ron
@@ -0,0 +1,18 @@
+ItemDef(
+ name: "Cardinal's Gloves",
+ description: "Bloodstained and rugged.",
+ kind: Armor((
+ kind: Hand,
+ stats: Direct((
+ protection: Some(Normal(20.0)),
+ poise_resilience: Some(Normal(6.0)),
+ energy_max: Some(75),
+ energy_reward: Some(0.09),
+ crit_power: Some(0.12),
+ stealth: Some(0.0),
+ )),
+ )),
+ quality: Legendary,
+ tags: [
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/cardinal/pants.ron b/assets/common/items/armor/cardinal/pants.ron
new file mode 100644
index 0000000000..c4af2de612
--- /dev/null
+++ b/assets/common/items/armor/cardinal/pants.ron
@@ -0,0 +1,18 @@
+ItemDef(
+ name: "Cardinal's Jeans",
+ description: "Pants with many experiences.",
+ kind: Armor((
+ kind: Pants,
+ stats: Direct((
+ protection: Some(Normal(45.0)),
+ poise_resilience: Some(Normal(12.0)),
+ energy_max: Some(150.0),
+ energy_reward: Some(0.05),
+ crit_power: Some(0.24),
+ stealth: Some(0.00),
+ )),
+ )),
+ quality: Legendary,
+ tags: [
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/cardinal/shoulder.ron b/assets/common/items/armor/cardinal/shoulder.ron
new file mode 100644
index 0000000000..4960b46639
--- /dev/null
+++ b/assets/common/items/armor/cardinal/shoulder.ron
@@ -0,0 +1,18 @@
+ItemDef(
+ name: "Cardinal's Shoulderguard",
+ description: "The other was lost in a vicious fight.",
+ kind: Armor((
+ kind: Shoulder,
+ stats: Direct((
+ protection: Some(Normal(30.0)),
+ poise_resilience: Some(Normal(15.0)),
+ energy_max: Some(90),
+ energy_reward: Some(0.05),
+ crit_power: Some(0.24),
+ stealth: Some(0.0),
+ )),
+ )),
+ quality: Legendary,
+ tags: [
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/armor/misc/neck/abyssal_gorget.ron b/assets/common/items/armor/misc/neck/abyssal_gorget.ron
new file mode 100644
index 0000000000..994494cf4a
--- /dev/null
+++ b/assets/common/items/armor/misc/neck/abyssal_gorget.ron
@@ -0,0 +1,17 @@
+ItemDef(
+ name: "Abyssal Gorget",
+ description: "Harnessed vigour of the tides",
+ kind: Armor((
+ kind: Neck,
+ stats: Direct((
+ protection: Some(Normal(2.0)),
+ energy_reward: Some(0.2),
+ crit_power: Some(0.1),
+ poise_resilience: Some(Normal(1.0)),
+ )),
+ )),
+ quality: Moderate,
+ tags: [
+
+ ],
+)
\ No newline at end of file
diff --git a/assets/common/items/crafting_ing/abyssal_heart.ron b/assets/common/items/crafting_ing/abyssal_heart.ron
new file mode 100644
index 0000000000..e2f66769ad
--- /dev/null
+++ b/assets/common/items/crafting_ing/abyssal_heart.ron
@@ -0,0 +1,9 @@
+ItemDef(
+ name: "Abyssal Heart",
+ description: "Source of Dagons Power.",
+ kind: Ingredient(
+ // Descriptor not needed
+ descriptor: "", ),
+ quality: Epic,
+ tags: [],
+)
diff --git a/assets/common/items/crafting_ing/coral_branch.ron b/assets/common/items/crafting_ing/coral_branch.ron
new file mode 100644
index 0000000000..272867d267
--- /dev/null
+++ b/assets/common/items/crafting_ing/coral_branch.ron
@@ -0,0 +1,9 @@
+ItemDef(
+ name: "Coral Branch",
+ description: "Treasure from the bottom of the sea.",
+ kind: Ingredient(
+ // Descriptor not needed
+ descriptor: "", ),
+ quality: Common,
+ tags: [],
+)
diff --git a/assets/common/items/npc_weapons/unique/cardinal.ron b/assets/common/items/npc_weapons/unique/cardinal.ron
new file mode 100644
index 0000000000..25fb54df95
--- /dev/null
+++ b/assets/common/items/npc_weapons/unique/cardinal.ron
@@ -0,0 +1,21 @@
+ItemDef(
+ name: "Caduceus",
+ description: "The snakes seem to be alive",
+ kind: Tool((
+ kind: Sceptre,
+ hands: Two,
+ stats: (
+ equip_time_secs: 0.4,
+ power: 1.2,
+ effect_power: 0.8,
+ speed: 1.2,
+ crit_chance: 0.4,
+ range: 1.0,
+ energy_efficiency: 1.0,
+ buff_strength: 1.0,
+ ),
+ )),
+ quality: Legendary,
+ tags: [],
+ ability_spec: Some(Custom("Cardinal")),
+)
\ No newline at end of file
diff --git a/assets/common/items/npc_weapons/unique/dagon.ron b/assets/common/items/npc_weapons/unique/dagon.ron
new file mode 100644
index 0000000000..f7914ca412
--- /dev/null
+++ b/assets/common/items/npc_weapons/unique/dagon.ron
@@ -0,0 +1,21 @@
+ItemDef(
+ name: "Dagon Kit",
+ description: "Placeholder",
+ kind: Tool((
+ kind: Natural,
+ hands: Two,
+ stats: (
+ equip_time_secs: 0.001,
+ power: 1.0,
+ effect_power: 1.0,
+ speed: 1.0,
+ crit_chance: 0.05078125,
+ range: 1.0,
+ energy_efficiency: 1.0,
+ buff_strength: 1.0,
+ ),
+ )),
+ quality: Low,
+ tags: [],
+ ability_spec: Some(Custom("Dagon")),
+)
\ No newline at end of file
diff --git a/assets/common/items/npc_weapons/unique/organ.ron b/assets/common/items/npc_weapons/unique/organ.ron
new file mode 100644
index 0000000000..87149aa32f
--- /dev/null
+++ b/assets/common/items/npc_weapons/unique/organ.ron
@@ -0,0 +1,21 @@
+ItemDef(
+ name: "Organ Aura",
+ description: "Motivational Tune",
+ kind: Tool((
+ kind: Organ,
+ hands: Two,
+ stats: (
+ equip_time_secs: 0.0,
+ power: 2.5,
+ effect_power: 1.0,
+ speed: 0.8,
+ crit_chance: 0.2,
+ range: 1.0,
+ energy_efficiency: 1.0,
+ buff_strength: 1.0,
+ ),
+ )),
+ quality: Common,
+ tags: [],
+ ability_spec: Some(Custom("Organ")),
+)
\ No newline at end of file
diff --git a/assets/common/loadout/dungeon/sea_chapel/cardinal.ron b/assets/common/loadout/dungeon/sea_chapel/cardinal.ron
new file mode 100644
index 0000000000..7f77141b61
--- /dev/null
+++ b/assets/common/loadout/dungeon/sea_chapel/cardinal.ron
@@ -0,0 +1,14 @@
+#![enable(implicit_some)]
+(
+ shoulders: Item("common.items.armor.cardinal.shoulder"),
+ chest: Item("common.items.armor.cardinal.chest"),
+ gloves: Item("common.items.armor.cardinal.hand"),
+ ring1: Item("common.items.armor.misc.ring.gold"),
+ ring2: Item("common.items.armor.misc.ring.gold"),
+ belt: Item("common.items.armor.cardinal.belt"),
+ legs: Item("common.items.armor.cardinal.pants"),
+ feet: Item("common.items.armor.cardinal.foot"),
+ lantern: Item("common.items.lantern.blue_0"),
+ neck: Item("common.items.armor.misc.neck.abyssal_gorget"),
+
+)
\ No newline at end of file
diff --git a/assets/common/loadout/dungeon/sea_chapel/sea_cleric.ron b/assets/common/loadout/dungeon/sea_chapel/sea_cleric.ron
new file mode 100644
index 0000000000..53dccc043e
--- /dev/null
+++ b/assets/common/loadout/dungeon/sea_chapel/sea_cleric.ron
@@ -0,0 +1,13 @@
+#![enable(implicit_some)]
+(
+ head: Item("common.items.armor.misc.head.winged_coronet"),
+ shoulders: Item("common.items.armor.cloth.silken.shoulder"),
+ chest: Item("common.items.armor.cloth.silken.chest"),
+ gloves: Item("common.items.armor.cloth.silken.hand"),
+ ring1: Item("common.items.armor.misc.ring.gold"),
+ ring2: Item("common.items.armor.misc.ring.gold"),
+ belt: Item("common.items.armor.cloth.silken.belt"),
+ legs: Item("common.items.armor.cloth.silken.pants"),
+ feet: Item("common.items.armor.cloth.silken.foot"),
+ lantern: Item("common.items.lantern.blue_0"),
+)
\ No newline at end of file
diff --git a/assets/common/loot_tables/dungeon/sea_chapel/cardinal.ron b/assets/common/loot_tables/dungeon/sea_chapel/cardinal.ron
new file mode 100644
index 0000000000..d45657e9fb
--- /dev/null
+++ b/assets/common/loot_tables/dungeon/sea_chapel/cardinal.ron
@@ -0,0 +1,5 @@
+[
+ (0.5, Item("common.items.crafting_ing.abyssal_heart")),
+ (2.5, LootTable("common.loot_tables.food.prepared")),
+ (2.5, Item("common.items.crafting_ing.seashells")),
+]
\ No newline at end of file
diff --git a/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron b/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron
new file mode 100644
index 0000000000..e537aa6fbd
--- /dev/null
+++ b/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron
@@ -0,0 +1,5 @@
+[
+ // Ingredients
+ (0.5, Item("common.items.crafting_ing.coral_branch")),
+ (5.0, Item("common.items.crafting_ing.seashells")),
+]
\ No newline at end of file
diff --git a/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron b/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron
new file mode 100644
index 0000000000..e45ac3e322
--- /dev/null
+++ b/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron
@@ -0,0 +1,4 @@
+[
+ (0.5, Item("common.items.crafting_ing.abyssal_heart")),
+ (5.0, LootTable("common.loot_tables.creature.quad_low.fanged")),
+]
\ No newline at end of file
diff --git a/assets/common/loot_tables/dungeon/sea_chapel/sea_cleric.ron b/assets/common/loot_tables/dungeon/sea_chapel/sea_cleric.ron
new file mode 100644
index 0000000000..e18dccd5ec
--- /dev/null
+++ b/assets/common/loot_tables/dungeon/sea_chapel/sea_cleric.ron
@@ -0,0 +1,4 @@
+[
+ // Nothing
+ (1.0, Nothing),
+]
\ No newline at end of file
diff --git a/assets/common/npc_names.ron b/assets/common/npc_names.ron
index 5d3394342e..54c843d971 100644
--- a/assets/common/npc_names.ron
+++ b/assets/common/npc_names.ron
@@ -1201,6 +1201,10 @@
keyword: "hakulaq",
generic: "Hakulaq"
),
+ dagon: (
+ keyword: "dagon",
+ generic: "Dagon"
+ ),
lavadrake: (
keyword: "lavadrake",
generic: "Lava Drake"
diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron
index b56ea50853..f9c9ee09bc 100644
--- a/assets/common/recipe_book.ron
+++ b/assets/common/recipe_book.ron
@@ -1723,6 +1723,15 @@
],
craft_sprite: None,
),
+ "abyssal gorget": (
+ output: ("common.items.armor.misc.neck.abyssal_gorget", 1),
+ inputs: [
+ (Item("common.items.crafting_ing.coral_branch"), 10, false),
+ (Item("common.items.crafting_ing.abyssal_heart"), 2, false),
+ (Item("common.items.crafting_ing.cloth.linen"), 2, false),
+ ],
+ craft_sprite: Some(CraftingBench),
+ ),
"tin pickaxe": (
output: ("common.items.tool.pickaxe_stone", 1),
inputs: [
@@ -2049,4 +2058,4 @@
craft_sprite: Some(Cauldron),
is_recycling: false,
),
-}
+}
\ No newline at end of file
diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron
index ecd3f5bb22..d786aa3e08 100644
--- a/assets/voxygen/audio/sfx.ron
+++ b/assets/voxygen/audio/sfx.ron
@@ -450,6 +450,12 @@
],
threshold: 0.2,
),
+ Attack(BasicAura, Organ): (
+ files: [
+ "voxygen.audio.sfx.abilities.barrel_organ",
+ ],
+ threshold: 34.75,
+ ),
//Attack(BasicRanged, Staff): (
// files: [
// "voxygen.audio.sfx.abilities.staff_channeling",
@@ -588,7 +594,6 @@
],
threshold: 0.3,
),
-
//
// Inventory
//
@@ -952,6 +957,13 @@
],
threshold: 1.0,
),
+ Utterance(Angry, SeaCrocodile): (
+ files: [
+ "voxygen.audio.sfx.utterance.sea_crocodile_angry1",
+ "voxygen.audio.sfx.utterance.sea_crocodile_angry2",
+ ],
+ threshold: 1.0,
+ ),
Utterance(Angry, Antelope): (
files: [
"voxygen.audio.sfx.utterance.antelope_angry1",
diff --git a/assets/voxygen/audio/sfx/abilities/barrel_organ.ogg b/assets/voxygen/audio/sfx/abilities/barrel_organ.ogg
new file mode 100644
index 0000000000..4b9e3ae178
--- /dev/null
+++ b/assets/voxygen/audio/sfx/abilities/barrel_organ.ogg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4528a71f4c063e47db68fd047d40bbdc1f32ef11518eeba454f855cf774defad
+size 253317
diff --git a/assets/voxygen/element/ui/map/buttons/sea_chapel.png b/assets/voxygen/element/ui/map/buttons/sea_chapel.png
new file mode 100644
index 0000000000..7372ec0ca9
--- /dev/null
+++ b/assets/voxygen/element/ui/map/buttons/sea_chapel.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f8a3367f5a884f66e50eaaf9b248253a8b80a064da34ccef7aeb56140e0a4de6
+size 15856
diff --git a/assets/voxygen/element/ui/map/buttons/sea_chapel_bg.png b/assets/voxygen/element/ui/map/buttons/sea_chapel_bg.png
new file mode 100644
index 0000000000..2dcbdd1cd0
--- /dev/null
+++ b/assets/voxygen/element/ui/map/buttons/sea_chapel_bg.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:00b86a830cb88748ca4c0c778fb5035ae6200bcec9e13e6c479e8c7da6e6cd32
+size 8617
diff --git a/assets/voxygen/element/ui/map/buttons/sea_chapel_hover.png b/assets/voxygen/element/ui/map/buttons/sea_chapel_hover.png
new file mode 100644
index 0000000000..21ebcb25dc
--- /dev/null
+++ b/assets/voxygen/element/ui/map/buttons/sea_chapel_hover.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b9d34dcc9067ef480240b5ff8d378eae3639bb2a62b0aa7978f4003f635c4b24
+size 18257
diff --git a/assets/voxygen/i18n/en/common.ftl b/assets/voxygen/i18n/en/common.ftl
index 8314927865..e3151be8ae 100644
--- a/assets/voxygen/i18n/en/common.ftl
+++ b/assets/voxygen/i18n/en/common.ftl
@@ -70,6 +70,7 @@ common-weapons-staff_simple = Simple Staff
common-weapons-axe_simple = Simple Axe
common-weapons-bow_simple = Simple Bow
common-weapons-unique = Unique
+common-weapons-organ = Organ
common-tool-debug = Debug
common-tool-farming = Farming Tool
common-tool-pick = Pickaxe
diff --git a/assets/voxygen/i18n/en/common.ron b/assets/voxygen/i18n/en/common.ron
new file mode 100644
index 0000000000..5736ac36bf
--- /dev/null
+++ b/assets/voxygen/i18n/en/common.ron
@@ -0,0 +1,130 @@
+/// WARNING: Localization files shall be saved in UTF-8 format without BOM
+
+/// Localization for "global" English
+(
+ string_map: {
+ // Texts used in multiple locations with the same formatting
+ "common.username": "username",
+ "common.singleplayer": "Singleplayer",
+ "common.multiplayer": "Multiplayer",
+ "common.servers": "Servers",
+ "common.quit": "Quit",
+ "common.settings": "Settings",
+ "common.languages": "Languages",
+ "common.interface": "Interface",
+ "common.gameplay": "Gameplay",
+ "common.controls": "Controls",
+ "common.video": "Graphics",
+ "common.sound": "Sound",
+ "common.chat": "Chat",
+ "common.resume": "Resume",
+ "common.characters": "Characters",
+ "common.close": "Close",
+ "common.yes": "Yes",
+ "common.no": "No",
+ "common.back": "Back",
+ "common.create": "Create",
+ "common.okay": "Okay",
+ "common.add": "Add",
+ "common.accept": "Accept",
+ "common.decline": "Decline",
+ "common.disclaimer": "Disclaimer",
+ "common.cancel": "Cancel",
+ "common.none": "None",
+ "common.error": "Error",
+ "common.fatal_error": "Fatal Error",
+ "common.you": "You",
+ "common.automatic": "Auto",
+ "common.random": "Random",
+ "common.empty": "Empty",
+ "common.confirm": "Confirm",
+ "common.delete_server": "Delete Server",
+
+ // Settings Window title
+ "common.interface_settings": "Interface Settings",
+ "common.gameplay_settings": "Gameplay Settings",
+ "common.controls_settings": "Controls Settings",
+ "common.video_settings": "Graphics Settings",
+ "common.sound_settings": "Sound Settings",
+ "common.language_settings": "Language Settings",
+ "common.chat_settings": "Chat Settings",
+
+ // Message when connection to the server is lost
+ "common.connection_lost": r#"Connection lost!
+Did the server restart?
+Is the client up to date?"#,
+
+
+ "common.species.orc": "Orc",
+ "common.species.human": "Human",
+ "common.species.dwarf": "Dwarf",
+ "common.species.elf": "Elf",
+ "common.species.draugr": "Draugr",
+ "common.species.danari": "Danari",
+
+ "common.weapons.axe": "Axe",
+ "common.weapons.dagger": "Dagger",
+ "common.weapons.greatsword": "Greatsword",
+ "common.weapons.shortswords": "Shortswords",
+ "common.weapons.sword": "Sword",
+ "common.weapons.staff": "Firestaff",
+ "common.weapons.bow": "Bow",
+ "common.weapons.hammer": "Hammer",
+ "common.weapons.general": "General Combat",
+ "common.weapons.sceptre": "Healing Sceptre",
+ "common.weapons.shield": "Shield",
+ "common.weapons.spear": "Spear",
+ "common.weapons.hammer_simple": "Simple Hammer",
+ "common.weapons.sword_simple": "Simple Sword",
+ "common.weapons.staff_simple": "Simple Staff",
+ "common.weapons.axe_simple": "Simple Axe",
+ "common.weapons.bow_simple": "Simple Bow",
+ "common.weapons.unique": "Unique",
+ "common.tool.debug": "Debug",
+ "common.tool.farming": "Farming Tool",
+ "common.tool.pick": "Pickaxe",
+ "common.tool.mining": "Mining",
+ "common.kind.modular_component": "Modular Component",
+ "common.kind.modular_component_partial": "Component",
+ "common.kind.glider": "Glider",
+ "common.kind.consumable": "Consumable",
+ "common.kind.throwable": "Can be thrown",
+ "common.kind.utility": "Utility",
+ "common.kind.ingredient": "Ingredient",
+ "common.kind.lantern": "Lantern",
+ "common.hands.one": "One-Handed",
+ "common.hands.two": "Two-Handed",
+
+ "common.rand_appearance": "Random appearance",
+ "common.rand_name": "Random name",
+
+ "common.stats.combat_rating": "CR",
+ "common.stats.power": "Power",
+ "common.stats.speed": "Speed",
+ "common.stats.poise": "Poise",
+ "common.stats.range": "Range",
+ "common.stats.energy_efficiency": "Energy Efficiency",
+ "common.stats.buff_strength": "Buff/Debuff Strength",
+ "common.stats.crit_chance": "Crit Chance",
+ "common.stats.crit_mult": "Crit Mult",
+ "common.stats.armor": "Armor",
+ "common.stats.poise_res":"Stun Res",
+ "common.stats.energy_max": "Max Energy",
+ "common.stats.energy_reward": "Energy Reward",
+ "common.stats.crit_power": "Crit Power",
+ "common.stats.stealth": "Stealth",
+ "common.stats.slots": "Slots",
+
+ "common.material.metal": "Metal",
+ "common.material.wood": "Wood",
+ "common.material.stone": "Stone",
+ "common.material.cloth": "Cloth",
+ "common.material.hide": "Hide",
+
+ "common.sprite.chest": "Chest",
+ },
+
+
+ vector_map: {
+ }
+)
diff --git a/assets/voxygen/i18n/en/hud/map.ftl b/assets/voxygen/i18n/en/hud/map.ftl
index 94a01a061d..8f7635164e 100644
--- a/assets/voxygen/i18n/en/hud/map.ftl
+++ b/assets/voxygen/i18n/en/hud/map.ftl
@@ -31,4 +31,5 @@ hud-map-zoom_minimap_explanation =
Zoom in the Minimap to see
the area around you in higher detail
hud-map-gnarling = Gnarling Fortification
+hud-map-chapel_site = Sea Chapel
hud-map-placed_by = Placed by { $name }
\ No newline at end of file
diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron
index d28341f06b..19c8d54197 100644
--- a/assets/voxygen/item_image_manifest.ron
+++ b/assets/voxygen/item_image_manifest.ron
@@ -2018,6 +2018,31 @@
"voxel.armor.misc.foot.jackalope",
(0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9,
),
+ //Cardinal Set
+ Simple("common.items.armor.cardinal.chest"): VoxTrans(
+ "voxel.armor.cardinal.chest",
+ (0.0, 1.0, 0.0), (-120.0, 210.0,15.0), 1.1,
+ ),
+ Simple("common.items.armor.cardinal.pants"): VoxTrans(
+ "voxel.armor.cardinal.pants",
+ (0.0, 1.0, 0.0), (-120.0, 210.0,15.0), 0.9,
+ ),
+ Simple("common.items.armor.cardinal.belt"): VoxTrans(
+ "voxel.armor.cardinal.belt",
+ (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9,
+ ),
+ Simple("common.items.armor.cardinal.foot"): VoxTrans(
+ "voxel.armor.cardinal.foot",
+ (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9,
+ ),
+ Simple("common.items.armor.cardinal.hand"): VoxTrans(
+ "voxel.armor.cardinal.hand",
+ (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9,
+ ),
+ Simple("common.items.armor.cardinal.shoulder"): VoxTrans(
+ "voxel.armor.cardinal.shoulder",
+ (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 1.0,
+ ),
//Twig Set
Simple("common.items.armor.twigs.chest"): VoxTrans(
"voxel.armor.twigs.chest",
@@ -2915,6 +2940,10 @@
"voxel.armor.misc.neck.scratched",
(0.0, 0.2, 0.0), (-70.0, 20.0, 10.0), 0.9,
),
+ Simple("common.items.armor.misc.neck.abyssal_gorget"): VoxTrans(
+ "voxel.armor.misc.neck.abyssal_gorget",
+ (0.0, 0.2, 0.0), (-70.0, 20.0, 10.0), 0.9,
+ ),
// Tabards
Simple("common.items.armor.misc.tabard.admin"): VoxTrans(
@@ -3486,6 +3515,14 @@
"voxel.sprite.wood.item.wood",
(0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
),
+ Simple("common.items.crafting_ing.abyssal_heart"): VoxTrans(
+ "voxel.sprite.crafting_ing.abyssal_heart",
+ (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
+ ),
+ Simple("common.items.crafting_ing.coral_branch"): VoxTrans(
+ "voxel.sprite.crafting_ing.coral_branch",
+ (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8,
+ ),
// Gliders
Simple("common.items.glider.cloverleaf"): VoxTrans(
"voxel.glider.starter",
diff --git a/assets/voxygen/voxel/armor/cardinal/belt.vox b/assets/voxygen/voxel/armor/cardinal/belt.vox
new file mode 100644
index 0000000000..aa8ca54805
--- /dev/null
+++ b/assets/voxygen/voxel/armor/cardinal/belt.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:03b5851769e677fb79da2a4ff27ec6d23bffa0d410dacab24bafba1189a709a2
+size 1496
diff --git a/assets/voxygen/voxel/armor/cardinal/chest.vox b/assets/voxygen/voxel/armor/cardinal/chest.vox
new file mode 100644
index 0000000000..92bc90ab19
--- /dev/null
+++ b/assets/voxygen/voxel/armor/cardinal/chest.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3d1f424de34c80001ca69a097e78a837f6f1c5e2d794f185ced1e6c62396c452
+size 2880
diff --git a/assets/voxygen/voxel/armor/cardinal/foot.vox b/assets/voxygen/voxel/armor/cardinal/foot.vox
new file mode 100644
index 0000000000..9971125def
--- /dev/null
+++ b/assets/voxygen/voxel/armor/cardinal/foot.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:38d8eb73c514400d00ff1205a375525ce37c9df7e77b73572e1986c4dcdd64a2
+size 1580
diff --git a/assets/voxygen/voxel/armor/cardinal/hand.vox b/assets/voxygen/voxel/armor/cardinal/hand.vox
new file mode 100644
index 0000000000..2d756f0a07
--- /dev/null
+++ b/assets/voxygen/voxel/armor/cardinal/hand.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fe7989bb326d88e51aa8c4373d2cc90c09c8bb64e8e857bc6490121ad784e58c
+size 1396
diff --git a/assets/voxygen/voxel/armor/cardinal/pants.vox b/assets/voxygen/voxel/armor/cardinal/pants.vox
new file mode 100644
index 0000000000..f887986165
--- /dev/null
+++ b/assets/voxygen/voxel/armor/cardinal/pants.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6e6b0d6f1a282b653da07c84d3af556fd6624f2f02c49c2aec8e55fdb6f8589a
+size 2104
diff --git a/assets/voxygen/voxel/armor/cardinal/shoulder.vox b/assets/voxygen/voxel/armor/cardinal/shoulder.vox
new file mode 100644
index 0000000000..e8e919ea6b
--- /dev/null
+++ b/assets/voxygen/voxel/armor/cardinal/shoulder.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c1f73335cdb76c0bbddd9b1b7cac7eb4d3dfde74864a6e704503e6345c9871a0
+size 1360
diff --git a/assets/voxygen/voxel/armor/misc/neck/abyssal_gorget.vox b/assets/voxygen/voxel/armor/misc/neck/abyssal_gorget.vox
new file mode 100644
index 0000000000..8dcfac51ac
--- /dev/null
+++ b/assets/voxygen/voxel/armor/misc/neck/abyssal_gorget.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eea39e850a3aa2f66d0fe7fe85a014be55cf6afdaa8007f4fb5eeac8f2833908
+size 1380
diff --git a/assets/voxygen/voxel/biped_weapon_manifest.ron b/assets/voxygen/voxel/biped_weapon_manifest.ron
index 2f0fa64e57..a06dc48981 100644
--- a/assets/voxygen/voxel/biped_weapon_manifest.ron
+++ b/assets/voxygen/voxel/biped_weapon_manifest.ron
@@ -1529,6 +1529,10 @@
vox_spec: ("armor.empty", (-3.0, -3.5, 1.0)),
color: None
),
+ Tool("common.items.npc_weapons.unique.cardinal"): (
+ vox_spec: ("weapon.sceptre.caduceus", (-2.5, -4.5, -6.0)),
+ color: None
+ ),
//BIPEDLARGE
Tool("common.items.npc_weapons.hammer.ogre_hammer"): (
vox_spec: ("weapon.hammer.2hhammer_ogre", (-5.0, -5.5, -7.0)),
diff --git a/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron b/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron
index 69212f2ae1..768255cc0a 100644
--- a/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron
+++ b/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron
@@ -172,6 +172,10 @@
vox_spec: ("armor.mail.orichalcum.belt", (-4.0, -3.5, 1.0)),
color: None
),
+ "common.items.armor.cardinal.belt": (
+ vox_spec: ("armor.cardinal.belt", (-4.0, -3.8, 1.3)),
+ color: None
+ ),
"common.items.armor.merchant.belt": (
vox_spec: ("armor.merchant.belt", (-5.0, -4.0, 2.0)),
color: None
diff --git a/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron b/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron
index f9e9d49786..6f058cf5b6 100644
--- a/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron
+++ b/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron
@@ -242,6 +242,10 @@
vox_spec: ("armor.mail.orichalcum.chest", (-7.0, -4.0, 1.0)),
color: None
),
+ "common.items.armor.cardinal.chest": (
+ vox_spec: ("armor.cardinal.chest", (-7.0, -4.0, 1.0)),
+ color: None
+ ),
"common.items.armor.merchant.chest": (
vox_spec: ("armor.merchant.chest", (-7.0, -4.0, 1.0)),
color: None
diff --git a/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron b/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron
index d4b95c17d3..646bc47c2e 100644
--- a/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron
+++ b/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron
@@ -160,6 +160,10 @@
vox_spec: ("armor.mail.orichalcum.foot", (-2.5, -3.5, -2.0)),
color: None
),
+ "common.items.armor.cardinal.foot": (
+ vox_spec: ("armor.cardinal.foot",(-2.5, -3.5, -2.0)),
+ color: None
+ ),
"common.items.armor.merchant.foot": (
vox_spec: ("armor.merchant.foot", (-2.5, -3.5, -2.0)),
color: None
diff --git a/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron b/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron
index b4ca981c87..3a961a1f7d 100644
--- a/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron
+++ b/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron
@@ -380,6 +380,16 @@
color: None
)
),
+ "common.items.armor.cardinal.hand": (
+ left: (
+ vox_spec: ("armor.cardinal.hand", (-2.5, -2.5, -4.0)),
+ color: None
+ ),
+ right: (
+ vox_spec: ("armor.cardinal.hand", (-1.5, -2.5, -4.0)),
+ color: None
+ )
+ ),
"common.items.armor.merchant.hand": (
left: (
vox_spec: ("armor.merchant.hand", (-2.5, -2.0, -4.0)),
diff --git a/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron b/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron
index eedc856df7..09b36eb831 100644
--- a/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron
+++ b/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron
@@ -200,6 +200,10 @@
vox_spec: ("armor.mail.orichalcum.pants", (-6.0, -4.0, 0.5)),
color: None
),
+ "common.items.armor.cardinal.pants": (
+ vox_spec: ("armor.cardinal.pants", (-5.0, -4.0, -0.4)),
+ color: None
+ ),
"common.items.armor.merchant.pants": (
vox_spec: ("armor.merchant.pants", (-6.0, -4.0, 0.5)),
color: None
diff --git a/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron b/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron
index 25509a2cc3..c305c92f29 100644
--- a/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron
+++ b/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron
@@ -451,6 +451,16 @@
color: None
)
),
+ "common.items.armor.cardinal.shoulder": (
+ left: (
+ vox_spec: ("armor.cardinal.shoulder", (-5.0, -4.0, -2.0)),
+ color: None
+ ),
+ right: (
+ vox_spec: ("armor.empty", (-0.5, -4.0, -2.0)),
+ color: None
+ )
+ ),
"common.items.armor.merchant.shoulder": (
left: (
vox_spec: ("armor.merchant.shoulder_l", (-3.0, -4.0 , -8.0)),
diff --git a/assets/voxygen/voxel/item_drop_manifest.ron b/assets/voxygen/voxel/item_drop_manifest.ron
index 87947b2ed9..ff916912ba 100644
--- a/assets/voxygen/voxel/item_drop_manifest.ron
+++ b/assets/voxygen/voxel/item_drop_manifest.ron
@@ -734,6 +734,7 @@
Simple("common.items.armor.misc.neck.gem_of_resilience"): "voxel.armor.misc.neck.resilience_gem",
Simple("common.items.armor.misc.neck.shell"): "voxel.armor.misc.neck.shell",
Simple("common.items.armor.misc.neck.amethyst"): "voxel.armor.misc.neck.amethyst",
+ Simple("common.items.armor.misc.neck.abyssal_gorget"): "voxel.armor.misc.neck.abyssal_gorget",
Simple("common.items.armor.misc.neck.diamond"): "voxel.armor.misc.neck.diamond",
Simple("common.items.armor.cultist.necklace"): "voxel.armor.cultist.necklace",
Simple("common.items.armor.misc.neck.ruby"): "voxel.armor.misc.neck.ruby",
@@ -844,6 +845,8 @@
Simple("common.items.crafting_ing.animal_misc.grim_eyeball"): "voxel.sprite.crafting_ing.animal_misc.grim_eyeball",
Simple("common.items.flowers.plant_fiber"): "voxel.sprite.crafting_ing.plant_fiber",
Simple("common.items.flowers.moonbell"): "voxel.sprite.flowers.moonbell",
+ Simple("common.items.crafting_ing.abyssal_heart"): "voxel.sprite.crafting_ing.abyssal_heart",
+ Simple("common.items.crafting_ing.coral_branch"): "voxel.sprite.crafting_ing.coral_branch",
Simple("common.items.flowers.pyrebloom"): "voxel.sprite.flowers.pyrebloom",
Simple("common.items.flowers.wild_flax"): "voxel.sprite.flowers.flax",
Simple("common.items.crafting_ing.cotton_boll"): "voxel.sprite.crafting_ing.cotton_boll",
diff --git a/assets/voxygen/voxel/npc/dagon/male/chest.vox b/assets/voxygen/voxel/npc/dagon/male/chest.vox
new file mode 100644
index 0000000000..8604dc3082
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/chest.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d5f6fecc2fd3c10f80761123a1c29b7330c3142229ad27313721d3383d1a8871
+size 7656
diff --git a/assets/voxygen/voxel/npc/dagon/male/foot_br.vox b/assets/voxygen/voxel/npc/dagon/male/foot_br.vox
new file mode 100644
index 0000000000..7f6ff730ce
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/foot_br.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bf299b185164db1bc5fc274f9c4fe3a9a5c470b393a69859201593d91e7d3e9c
+size 1740
diff --git a/assets/voxygen/voxel/npc/dagon/male/foot_fr.vox b/assets/voxygen/voxel/npc/dagon/male/foot_fr.vox
new file mode 100644
index 0000000000..aa5ef293ed
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/foot_fr.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1f0ce90b8983a15b8a7ca37463933a7dff62f958ded16fc38c6a2bdd3b93886c
+size 2104
diff --git a/assets/voxygen/voxel/npc/dagon/male/head_lower.vox b/assets/voxygen/voxel/npc/dagon/male/head_lower.vox
new file mode 100644
index 0000000000..3cf7d672ca
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/head_lower.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:20d4958d6487dbd3f082474bf1ff26252ed80c3e1f24657781121c2a64e9e224
+size 4120
diff --git a/assets/voxygen/voxel/npc/dagon/male/head_upper.vox b/assets/voxygen/voxel/npc/dagon/male/head_upper.vox
new file mode 100644
index 0000000000..2d61bdd7bd
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/head_upper.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d7c7b2d74b235314b12e7f54e26764cef723f9cee4aac9badea6f61d3dbc5e8c
+size 3188
diff --git a/assets/voxygen/voxel/npc/dagon/male/jaw.vox b/assets/voxygen/voxel/npc/dagon/male/jaw.vox
new file mode 100644
index 0000000000..5f25f5ef93
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/jaw.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0e318aa86d561727dc3ea63144233de2edaa8ff0a009a81927e97326e6c5e90f
+size 2168
diff --git a/assets/voxygen/voxel/npc/dagon/male/tail_front.vox b/assets/voxygen/voxel/npc/dagon/male/tail_front.vox
new file mode 100644
index 0000000000..9202436281
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/tail_front.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1af8558fc0586a724f91a1a7501d2a5ccb4ee98fd2d7820e9c50c865c3419b6d
+size 2128
diff --git a/assets/voxygen/voxel/npc/dagon/male/tail_rear.vox b/assets/voxygen/voxel/npc/dagon/male/tail_rear.vox
new file mode 100644
index 0000000000..74a9af0469
--- /dev/null
+++ b/assets/voxygen/voxel/npc/dagon/male/tail_rear.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:619baee168e170990d2da0a7e7148fab0ce6fcb242caeb39fc87382f248dc0c4
+size 2228
diff --git a/assets/voxygen/voxel/object/dagon_bomb.vox b/assets/voxygen/voxel/object/dagon_bomb.vox
new file mode 100644
index 0000000000..680ad33039
--- /dev/null
+++ b/assets/voxygen/voxel/object/dagon_bomb.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aba33e8577174796ac831af8a5befa1eac3aab4b337cf5242e92ac74e4c8f0b6
+size 2284
diff --git a/assets/voxygen/voxel/object/sea_urchin.vox b/assets/voxygen/voxel/object/sea_urchin.vox
new file mode 100644
index 0000000000..8fb919a064
--- /dev/null
+++ b/assets/voxygen/voxel/object/sea_urchin.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1291b6ce35372547f55f34555213a4e7ae143555b06ec0bc52c044d77540ffd1
+size 1660
diff --git a/assets/voxygen/voxel/object/seashell_lantern.vox b/assets/voxygen/voxel/object/seashell_lantern.vox
new file mode 100644
index 0000000000..24e6f2d872
--- /dev/null
+++ b/assets/voxygen/voxel/object/seashell_lantern.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:073ae7d89a5118abc445638ccb266effa6344c6f4a48b853698b20563fd91b1d
+size 1884
diff --git a/assets/voxygen/voxel/object_manifest.ron b/assets/voxygen/voxel/object_manifest.ron
index bc56ce1b90..548d5a8bd9 100644
--- a/assets/voxygen/voxel/object_manifest.ron
+++ b/assets/voxygen/voxel/object_manifest.ron
@@ -19,6 +19,16 @@
central: ("armor.empty"),
)
),
+ DagonBomb: (
+ bone0: (
+ offset: (-5.5, -5.5, 0.0),
+ central: ("object.dagon_bomb"),
+ ),
+ bone1: (
+ offset: (0.0, 0.0, 0.0),
+ central: ("armor.empty"),
+ )
+ ),
FireworkBlue: (
bone0: (
offset: (0.0, 0.0, 0.0),
@@ -249,6 +259,16 @@
central: ("armor.empty"),
)
),
+ BarrelOrgan: (
+ bone0: (
+ offset: (-9.0, -10.0, 0.0),
+ central: ("sprite.misc.barrel_organ"),
+ ),
+ bone1: (
+ offset: (0.0, 0.0, 0.0),
+ central: ("armor.empty"),
+ )
+ ),
LanternGround: (
bone0: (
offset: (-3.5, -3.5, 0.0),
diff --git a/assets/voxygen/voxel/quadruped_low_central_manifest.ron b/assets/voxygen/voxel/quadruped_low_central_manifest.ron
index 6ff66eec07..c1d95b2214 100644
--- a/assets/voxygen/voxel/quadruped_low_central_manifest.ron
+++ b/assets/voxygen/voxel/quadruped_low_central_manifest.ron
@@ -572,6 +572,58 @@
central: ("npc.hakulaq.male.tail_front"),
),
),
+ (Dagon, Male): (
+ upper: (
+ offset: (-4.5, 2.5, -13.0),
+ central: ("npc.dagon.male.head_upper"),
+ ),
+ lower: (
+ offset: (-4.5, -10.0, -10.5),
+ central: ("npc.dagon.male.head_lower"),
+ ),
+ jaw: (
+ offset: (-3.5, 11.5, -13.0),
+ central: ("npc.dagon.male.jaw"),
+ ),
+ chest: (
+ offset: (-4.5, -8.0, -10.5),
+ central: ("npc.dagon.male.chest"),
+ ),
+ tail_rear: (
+ offset: (-0.5, -31.0, -8.0),
+ central: ("npc.dagon.male.tail_rear"),
+ ),
+ tail_front: (
+ offset: (-1.5, -12.0, -10.0),
+ central: ("npc.dagon.male.tail_front"),
+ ),
+ ),
+ (Dagon, Female): (
+ upper: (
+ offset: (-4.5, 2.5, -13.0),
+ central: ("npc.dagon.male.head_upper"),
+ ),
+ lower: (
+ offset: (-4.5, -10.0, -10.5),
+ central: ("npc.dagon.male.head_lower"),
+ ),
+ jaw: (
+ offset: (-3.5, 11.5, -13.0),
+ central: ("npc.dagon.male.jaw"),
+ ),
+ chest: (
+ offset: (-4.5, -8.0, -10.5),
+ central: ("npc.dagon.male.chest"),
+ ),
+ tail_rear: (
+ offset: (-0.5, -31.0, -8.0),
+ central: ("npc.dagon.male.tail_rear"),
+ ),
+ tail_front: (
+ offset: (-1.5, -12.0, -10.0),
+ central: ("npc.dagon.male.tail_front"),
+ ),
+ ),
(Sandshark, Male): (
upper: (
offset: (-5.5, -8.0, -5.0),
diff --git a/assets/voxygen/voxel/quadruped_low_lateral_manifest.ron b/assets/voxygen/voxel/quadruped_low_lateral_manifest.ron
index d39d73d77f..26e1b3a8b8 100644
--- a/assets/voxygen/voxel/quadruped_low_lateral_manifest.ron
+++ b/assets/voxygen/voxel/quadruped_low_lateral_manifest.ron
@@ -395,6 +395,42 @@
lateral: ("npc.hakulaq.male.foot_br", false),
),
),
+ (Dagon, Male): (
+ front_left: (
+ offset: (-9.0, 5.0, -9.0),
+ lateral: ("npc.dagon.male.foot_fr", false),
+ ),
+ front_right: (
+ offset: (-2.0, 5.0, -9.0),
+ lateral: ("npc.dagon.male.foot_fr", false),
+ ),
+ back_left: (
+ offset: (-11.0, 3.0, -9.0),
+ lateral: ("npc.dagon.male.foot_br", false),
+ ),
+ back_right: (
+ offset: (0.0, 3.0, -9.0),
+ lateral: ("npc.dagon.male.foot_br", false),
+ ),
+ ),
+ (Dagon, Female): (
+ front_left: (
+ offset: (-9.0, 5.0, -9.0),
+ lateral: ("npc.dagon.male.foot_fr", false),
+ ),
+ front_right: (
+ offset: (-2.0, 5.0, -9.0),
+ lateral: ("npc.dagon.male.foot_fr", false),
+ ),
+ back_left: (
+ offset: (-11.0, 3.0, -9.0),
+ lateral: ("npc.dagon.male.foot_br", false),
+ ),
+ back_right: (
+ offset: (0.0, 3.0, -9.0),
+ lateral: ("npc.dagon.male.foot_br", false),
+ ),
+ ),
(Sandshark, Male): (
front_left: (
offset: (-17.0, 0.0, -12.0),
diff --git a/assets/voxygen/voxel/sprite/chests/chest_coral.vox b/assets/voxygen/voxel/sprite/chests/chest_coral.vox
new file mode 100644
index 0000000000..920228e4ac
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/chests/chest_coral.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a5f5487e2271538e3f94ddec587f4477e7b459615b0259dce608ef645bc00ab
+size 5336
diff --git a/assets/voxygen/voxel/sprite/crafting_ing/abyssal_heart.vox b/assets/voxygen/voxel/sprite/crafting_ing/abyssal_heart.vox
new file mode 100644
index 0000000000..c3bfbc62fd
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/crafting_ing/abyssal_heart.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f7692822b93e1ea3c08479e4b7a105da17b0d4f9bd65c8135f6f489c7be4bb0d
+size 1960
diff --git a/assets/voxygen/voxel/sprite/crafting_ing/coral_branch.vox b/assets/voxygen/voxel/sprite/crafting_ing/coral_branch.vox
new file mode 100644
index 0000000000..3a19f953af
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/crafting_ing/coral_branch.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e5fb3144793a6d802316679bbac79a6e545be11b93115192ede3734491dced60
+size 1176
diff --git a/assets/voxygen/voxel/sprite/misc/barrel_organ.vox b/assets/voxygen/voxel/sprite/misc/barrel_organ.vox
new file mode 100644
index 0000000000..a8031e84a1
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/barrel_organ.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c541a8126216c0f50a26502e3e5d8523300a593f0d6edbda154f2d185f3b6040
+size 12984
diff --git a/assets/voxygen/voxel/sprite/misc/glass_barrier.vox b/assets/voxygen/voxel/sprite/misc/glass_barrier.vox
new file mode 100644
index 0000000000..db51993d70
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/glass_barrier.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4447a9680c0a2401e400203f10171e345e2ccfde4a96e5ef9e6384ae7efabe7e
+size 2268
diff --git a/assets/voxygen/voxel/sprite/misc/rope.vox b/assets/voxygen/voxel/sprite/misc/rope.vox
new file mode 100644
index 0000000000..41d9406d23
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/rope.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e1930c55aa200d5a3ca17c73f2bde240e6d2c498173b3514c33d33b554623364
+size 1888
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_block.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_block.vox
new file mode 100644
index 0000000000..07cbd29bec
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_block.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4709c5acc8fcc98d332749c5e4b327df63d5e88e625080edc4427ec193229c17
+size 6420
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_chain.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_chain.vox
new file mode 100644
index 0000000000..c3567de471
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_chain.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4a025c97a09ffd4d91b11fe27963fa0c9faf17da89445da5671d0493ce4eb999
+size 1232
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_emblem.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_emblem.vox
new file mode 100644
index 0000000000..7e851a1cd1
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_emblem.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cd98c7f9a687f04ff235ba58afd5987c9a08843db24b7293f9a4bf6e9672b253
+size 3368
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-0.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-0.vox
new file mode 100644
index 0000000000..68006dc889
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-0.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8331d89f4bbfd0e26fea06072a83f829756d44ffa06ca00bb8fe0ab9d8bdfcf0
+size 6920
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-1.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-1.vox
new file mode 100644
index 0000000000..4ceff39e72
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-1.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b3ff9529a4478ee747772696d9e8859757d2fb4af2a833c5471378a06f9f17ad
+size 6788
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-2.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-2.vox
new file mode 100644
index 0000000000..c268c9bc2a
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-2.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c60a387315db09de6f0ae888f12fc4b97598f79607acf4350fe59afa73fc450f
+size 7168
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-3.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-3.vox
new file mode 100644
index 0000000000..e6cad95023
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-3.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d2d53fdf83f15f6713391865eb34671a1e0f11e632353838815e6f3343c1175b
+size 7376
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-4.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-4.vox
new file mode 100644
index 0000000000..339b87602b
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-4.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b0fcb10b46981f074eb371212d619562a3c391efd93fefa33934d3491f6d2ae
+size 4360
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-5.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-5.vox
new file mode 100644
index 0000000000..2c32907b17
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-5.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3fd2e94e58760635299b5f68ffac6db78c79a87b372da9f8ba79400350b1861d
+size 4348
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-6.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-6.vox
new file mode 100644
index 0000000000..42cb5b07d3
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-6.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bfa516c88e0c07875ef2efb3142b37fd02b602d1a5482d1f5ea08f37951bfb10
+size 4364
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-7.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-7.vox
new file mode 100644
index 0000000000..07d62a9b10
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_pillar-7.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:258a9a317a58d5b4f2ed7146ea3768f36b717e0d3989a2947900066151652443
+size 4348
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_window_hor.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_window_hor.vox
new file mode 100644
index 0000000000..cd025c929f
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_window_hor.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:432c81b08d1e74dad147fec4104f6bbeb02566619fd710cb465a61faa5188bec
+size 1240
diff --git a/assets/voxygen/voxel/sprite/misc/sea_decor_window_ver.vox b/assets/voxygen/voxel/sprite/misc/sea_decor_window_ver.vox
new file mode 100644
index 0000000000..aed7ca6523
--- /dev/null
+++ b/assets/voxygen/voxel/sprite/misc/sea_decor_window_ver.vox
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a79b159c7560e94e4c6d7d0a425347b027a09604b50df3b42922287141305163
+size 1240
diff --git a/assets/voxygen/voxel/sprite_manifest.ron b/assets/voxygen/voxel/sprite_manifest.ron
index c4439fba25..50b3486c02 100644
--- a/assets/voxygen/voxel/sprite_manifest.ron
+++ b/assets/voxygen/voxel/sprite_manifest.ron
@@ -864,6 +864,151 @@ DungeonChest5: Some((
],
wind_sway: 0.0,
)),
+// Rope
+Rope: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.rope",
+ offset: (-5.5, -5.5, -0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Coral Chest
+CoralChest: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.chests.chest_coral",
+ offset: (-7.0, -5.0, -0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Sea DecorChain
+SeaDecorChain: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_chain",
+ offset: (-5.5, -5.5, -0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Sea DecorBlock
+SeaDecorBlock: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_block",
+ offset: (-5.5, -5.5, -0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Sea DecorWindow Horizontal
+SeaDecorWindowHor: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_window_hor",
+ offset: (-5.5, -5.5, -0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Sea DecorWindow Vertical
+SeaDecorWindowVer: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_window_ver",
+ offset: (-5.5, -5.5, -0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Sea Decor Emblem
+SeaDecorEmblem: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_emblem",
+ offset: (-5.5, -5.5, -4.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// Sea Decor Pillar
+SeaDecorPillar: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-0",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-1",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-2",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-3",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-4",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-5",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-6",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ (
+ model: "voxygen.voxel.sprite.misc.sea_decor_pillar-7",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (1.0, 1.0, 1.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// SeashellLantern
+SeashellLantern: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.object.seashell_lantern",
+ offset: (-4.5, -4.5, 0.0),
+ lod_axes: (0.0, 0.0, 0.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
+// GlassBarrier
+GlassBarrier: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.sprite.misc.glass_barrier",
+ offset: (-5.5, -5.5, 0.0),
+ lod_axes: (0.0, 0.0, 0.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
// Welwitch
Welwitch: Some((
variations: [
@@ -3617,6 +3762,17 @@ EnsnaringVines: Some((
],
wind_sway: 0.0,
)),
+// Sea Urchin
+SeaUrchin: Some((
+ variations: [
+ (
+ model: "voxygen.voxel.object.sea_urchin",
+ offset: (-5.0, -6.5, 0.0),
+ lod_axes: (0.0, 0.0, 0.0),
+ ),
+ ],
+ wind_sway: 0.0,
+)),
// WitchWindow
WitchWindow: Some((
variations: [
diff --git a/common/net/src/msg/world_msg.rs b/common/net/src/msg/world_msg.rs
index e92740b9fc..1ab33ee89c 100644
--- a/common/net/src/msg/world_msg.rs
+++ b/common/net/src/msg/world_msg.rs
@@ -145,6 +145,7 @@ pub enum SiteKind {
Cave,
Tree,
Gnarling,
+ ChapelSite,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/common/src/bin/csv_export/main.rs b/common/src/bin/csv_export/main.rs
index f802d2ed2c..b67d00b93b 100644
--- a/common/src/bin/csv_export/main.rs
+++ b/common/src/bin/csv_export/main.rs
@@ -175,6 +175,7 @@ fn get_tool_kind(kind: &ToolKind) -> String {
ToolKind::Farming => "Farming".to_string(),
ToolKind::Pick => "Pick".to_string(),
ToolKind::Natural => "Natural".to_string(),
+ ToolKind::Organ => "Organ".to_string(),
ToolKind::Empty => "Empty".to_string(),
}
}
diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs
index af15ed8991..1b84fa7122 100644
--- a/common/src/comp/body.rs
+++ b/common/src/comp/body.rs
@@ -735,6 +735,7 @@ impl Body {
Body::Object(object) => match object {
object::Body::TrainingDummy => 1000,
object::Body::Crossbow => 80,
+ object::Body::BarrelOrgan => 500,
object::Body::HaniwaSentry => 60,
object::Body::SeaLantern => 100,
object::Body::GnarlingTotemGreen => 25,
@@ -766,6 +767,7 @@ impl Body {
quadruped_low::Species::Maneater => 130,
quadruped_low::Species::Sandshark => 110,
quadruped_low::Species::Hakulaq => 120,
+ quadruped_low::Species::Dagon => 1200,
quadruped_low::Species::Lavadrake => 160,
quadruped_low::Species::Basilisk => 200,
quadruped_low::Species::Deadwood => 120,
@@ -831,6 +833,7 @@ impl Body {
)
)
},
+ BuffKind::ProtectingWard => matches!(self, Body::Object(object::Body::BarrelOrgan)),
_ => false,
}
}
diff --git a/common/src/comp/body/object.rs b/common/src/comp/body/object.rs
index a351c345e5..3865b4fbd4 100644
--- a/common/src/comp/body/object.rs
+++ b/common/src/comp/body/object.rs
@@ -98,6 +98,8 @@ make_case_elim!(
GnarlingTotemRed = 83,
GnarlingTotemGreen = 84,
GnarlingTotemWhite = 85,
+ DagonBomb = 86,
+ BarrelOrgan = 87,
}
);
@@ -108,7 +110,7 @@ impl Body {
}
}
-pub const ALL_OBJECTS: [Body; 86] = [
+pub const ALL_OBJECTS: [Body; 88] = [
Body::Arrow,
Body::Bomb,
Body::Scarecrow,
@@ -195,6 +197,8 @@ pub const ALL_OBJECTS: [Body; 86] = [
Body::GnarlingTotemRed,
Body::GnarlingTotemWhite,
Body::GnarlingTotemGreen,
+ Body::DagonBomb,
+ Body::BarrelOrgan,
];
impl From
for super::Body {
@@ -290,6 +294,8 @@ impl Body {
Body::GnarlingTotemRed => "gnarling_totem_red",
Body::GnarlingTotemGreen => "gnarling_totem_green",
Body::GnarlingTotemWhite => "gnarling_totem_white",
+ Body::DagonBomb => "dagon_bomb",
+ Body::BarrelOrgan => "barrel_organ",
}
}
@@ -307,9 +313,12 @@ impl Body {
pub fn density(&self) -> Density {
let density = match self {
Body::Anvil | Body::Cauldron => IRON_DENSITY,
- Body::Arrow | Body::ArrowSnake | Body::ArrowTurret | Body::MultiArrow | Body::Dart => {
- 500.0
- },
+ Body::Arrow
+ | Body::ArrowSnake
+ | Body::ArrowTurret
+ | Body::MultiArrow
+ | Body::Dart
+ | Body::DagonBomb => 500.0,
Body::Bomb => 2000.0, // I have no idea what it's supposed to be
Body::Crate => 300.0, // let's say it's a lot of wood and maybe some contents
Body::Scarecrow => 900.0,
@@ -337,10 +346,10 @@ impl Body {
| Body::BoltNature
| Body::BoltIcicle
| Body::SpitPoison => 1.0,
- Body::Bomb => {
+ Body::Bomb | Body::DagonBomb => {
0.5 * IRON_DENSITY * std::f32::consts::PI / 6.0 * self.dimensions().x.powi(3)
},
- Body::Campfire | Body::CampfireLit => 300.0,
+ Body::Campfire | Body::CampfireLit | Body::BarrelOrgan => 300.0,
Body::Carpet
| Body::CarpetHumanRound
| Body::CarpetHumanSquare
@@ -420,6 +429,7 @@ impl Body {
Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => {
Vec3::new(0.8, 0.8, 1.4)
},
+ Body::BarrelOrgan => Vec3::new(4.0, 2.0, 3.0),
// FIXME: this *must* be exhaustive match
_ => Vec3::broadcast(0.5),
}
diff --git a/common/src/comp/body/quadruped_low.rs b/common/src/comp/body/quadruped_low.rs
index 9a432e721b..e779d70c5d 100644
--- a/common/src/comp/body/quadruped_low.rs
+++ b/common/src/comp/body/quadruped_low.rs
@@ -55,6 +55,7 @@ make_case_elim!(
Deadwood = 13,
Icedrake = 14,
SeaCrocodile = 15,
+ Dagon = 16,
}
);
@@ -75,6 +76,7 @@ pub struct AllSpecies {
pub maneater: SpeciesMeta,
pub sandshark: SpeciesMeta,
pub hakulaq: SpeciesMeta,
+ pub dagon: SpeciesMeta,
pub lavadrake: SpeciesMeta,
pub basilisk: SpeciesMeta,
pub deadwood: SpeciesMeta,
@@ -99,6 +101,7 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies
Species::Maneater => &self.maneater,
Species::Sandshark => &self.sandshark,
Species::Hakulaq => &self.hakulaq,
+ Species::Dagon => &self.dagon,
Species::Lavadrake => &self.lavadrake,
Species::Basilisk => &self.basilisk,
Species::Deadwood => &self.deadwood,
@@ -107,7 +110,7 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies
}
}
-pub const ALL_SPECIES: [Species; 16] = [
+pub const ALL_SPECIES: [Species; 17] = [
Species::Crocodile,
Species::SeaCrocodile,
Species::Alligator,
@@ -120,6 +123,7 @@ pub const ALL_SPECIES: [Species; 16] = [
Species::Maneater,
Species::Sandshark,
Species::Hakulaq,
+ Species::Dagon,
Species::Lavadrake,
Species::Basilisk,
Species::Deadwood,
diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs
index ed61131771..43b7b54fbc 100644
--- a/common/src/comp/inventory/item/tool.rs
+++ b/common/src/comp/inventory/item/tool.rs
@@ -34,6 +34,7 @@ pub enum ToolKind {
/// Intended for invisible weapons (e.g. a creature using its claws or
/// biting)
Natural,
+ Organ,
/// This is an placeholder item, it is used by non-humanoid npcs to attack
Empty,
}
@@ -55,6 +56,7 @@ impl ToolKind {
ToolKind::Debug => "debug",
ToolKind::Farming => "farming",
ToolKind::Pick => "pickaxe",
+ ToolKind::Organ => "organ",
ToolKind::Empty => "empty",
}
}
diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs
index 1ccb2aef47..74ecb92091 100644
--- a/common/src/comp/inventory/loadout_builder.rs
+++ b/common/src/comp/inventory/loadout_builder.rs
@@ -579,6 +579,9 @@ fn default_main_tool(body: &Body) -> Item {
quadruped_low::Species::Asp => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.asp",
)),
+ quadruped_low::Species::Dagon => Some(Item::new_from_asset_expect(
+ "common.items.npc_weapons.unique.dagon",
+ )),
quadruped_low::Species::Crocodile
| quadruped_low::Species::SeaCrocodile
| quadruped_low::Species::Alligator
@@ -718,6 +721,9 @@ fn default_main_tool(body: &Body) -> Item {
object::Body::Crossbow => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.turret",
)),
+ object::Body::BarrelOrgan => Some(Item::new_from_asset_expect(
+ "common.items.npc_weapons.unique.organ",
+ )),
object::Body::HaniwaSentry => Some(Item::new_from_asset_expect(
"common.items.npc_weapons.unique.haniwa_sentry",
)),
diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs
index 532866b654..f7d5c1bc46 100644
--- a/common/src/comp/projectile.rs
+++ b/common/src/comp/projectile.rs
@@ -88,6 +88,12 @@ pub enum ProjectileConstructor {
knockback: f32,
min_falloff: f32,
},
+ DagonBomb {
+ damage: f32,
+ radius: f32,
+ knockback: f32,
+ min_falloff: f32,
+ },
}
impl ProjectileConstructor {
@@ -457,6 +463,63 @@ impl ProjectileConstructor {
is_point: true,
}
},
+ DagonBomb {
+ damage,
+ radius,
+ knockback,
+ min_falloff,
+ } => {
+ let knockback = AttackEffect::new(
+ Some(GroupTarget::OutOfGroup),
+ CombatEffect::Knockback(Knockback {
+ strength: knockback,
+ direction: KnockbackDir::Away,
+ }),
+ )
+ .with_requirement(CombatRequirement::AnyDamage);
+ let buff = AttackEffect::new(
+ Some(GroupTarget::OutOfGroup),
+ CombatEffect::Buff(CombatBuff {
+ kind: BuffKind::Burning,
+ dur_secs: 5.0,
+ strength: CombatBuffStrength::DamageFraction(0.2 * buff_strength),
+ chance: 1.0,
+ }),
+ )
+ .with_requirement(CombatRequirement::AnyDamage);
+ let damage = AttackDamage::new(
+ Damage {
+ source: DamageSource::Explosion,
+ kind: DamageKind::Energy,
+ value: damage,
+ },
+ Some(GroupTarget::OutOfGroup),
+ instance,
+ );
+ let attack = Attack::default()
+ .with_damage(damage)
+ .with_crit(crit_chance, crit_mult)
+ .with_effect(knockback)
+ .with_effect(buff);
+ let explosion = Explosion {
+ effects: vec![
+ RadiusEffect::Attack(attack),
+ RadiusEffect::TerrainDestruction(5.0),
+ ],
+ radius,
+ reagent: Some(Reagent::Blue),
+ min_falloff,
+ };
+ Projectile {
+ hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
+ hit_entity: vec![Effect::Explode(explosion), Effect::Vanish],
+ time_left: Duration::from_secs(10),
+ owner,
+ ignore_group: true,
+ is_sticky: true,
+ is_point: true,
+ }
+ },
}
}
@@ -532,6 +595,14 @@ impl ProjectileConstructor {
*damage *= power;
*radius *= range;
},
+ DagonBomb {
+ ref mut damage,
+ ref mut radius,
+ ..
+ } => {
+ *damage *= power;
+ *radius *= range;
+ },
}
self
}
diff --git a/common/src/states/sprite_summon.rs b/common/src/states/sprite_summon.rs
index 0483de1bce..13b2497dab 100644
--- a/common/src/states/sprite_summon.rs
+++ b/common/src/states/sprite_summon.rs
@@ -118,12 +118,18 @@ impl CharacterBehavior for Data {
// Location sprite will be created
let sprite_pos =
Vec3::new(sprite_pos.x as i32, sprite_pos.y as i32, z);
-
- // Send server event to create sprite
- output_events.emit_server(ServerEvent::CreateSprite {
- pos: sprite_pos,
- sprite: self.static_data.sprite,
- });
+ // Layers of sprites
+ let layers = match self.static_data.sprite {
+ SpriteKind::SeaUrchin => 2,
+ _ => 1,
+ };
+ for i in 0..layers {
+ // Send server event to create sprite
+ output_events.emit_server(ServerEvent::CreateSprite {
+ pos: Vec3::new(sprite_pos.x as i32, sprite_pos.y, z + i),
+ sprite: self.static_data.sprite,
+ });
+ }
}
}
}
diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs
index 5a95138f4d..0d18f761ed 100644
--- a/common/src/states/utils.rs
+++ b/common/src/states/utils.rs
@@ -126,6 +126,7 @@ impl Body {
quadruped_low::Species::Maneater => 80.0,
quadruped_low::Species::Sandshark => 160.0,
quadruped_low::Species::Hakulaq => 140.0,
+ quadruped_low::Species::Dagon => 140.0,
quadruped_low::Species::Lavadrake => 100.0,
quadruped_low::Species::Icedrake => 100.0,
quadruped_low::Species::Basilisk => 90.0,
diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs
index f1224324e1..74abc44363 100644
--- a/common/src/terrain/block.rs
+++ b/common/src/terrain/block.rs
@@ -235,6 +235,9 @@ impl Block {
| SpriteKind::EmeraldSmall
| SpriteKind::SapphireSmall => Some(3),
SpriteKind::Lantern => Some(24),
+ SpriteKind::SeashellLantern => Some(16),
+ SpriteKind::SeaDecorEmblem => Some(12),
+ SpriteKind::SeaDecorBlock => Some(10),
_ => None,
},
}
@@ -294,8 +297,16 @@ impl Block {
| SpriteKind::DungeonChest3
| SpriteKind::DungeonChest4
| SpriteKind::DungeonChest5
- | SpriteKind::ChestBuried => None,
- SpriteKind::EnsnaringVines | SpriteKind::EnsnaringWeb => Some(0.1),
+ | SpriteKind::ChestBuried
+ | SpriteKind::SeaDecorBlock
+ | SpriteKind::SeaDecorChain
+ | SpriteKind::SeaDecorWindowHor
+ | SpriteKind::SeaDecorWindowVer
+ | SpriteKind::Rope
+ | SpriteKind::GlassBarrier => None,
+ SpriteKind::EnsnaringVines | SpriteKind::EnsnaringWeb | SpriteKind::SeaUrchin => {
+ Some(0.1)
+ },
_ => Some(0.25),
}),
}
diff --git a/common/src/terrain/sprite.rs b/common/src/terrain/sprite.rs
index 8d7a5dcaff..14709accc8 100644
--- a/common/src/terrain/sprite.rs
+++ b/common/src/terrain/sprite.rs
@@ -215,6 +215,17 @@ make_case_elim!(
Ironwood = 0xBC,
Frostwood = 0xBD,
Eldwood = 0xBE,
+ SeaUrchin = 0xBF,
+ GlassBarrier = 0xC0,
+ CoralChest = 0xC1,
+ SeaDecorChain = 0xC2,
+ SeaDecorBlock = 0xC3,
+ SeaDecorWindowHor = 0xC4,
+ SeaDecorWindowVer = 0xC5,
+ SeaDecorEmblem = 0xC6,
+ SeaDecorPillar = 0xC7,
+ SeashellLantern = 0xC8,
+ Rope = 0xC9,
}
);
@@ -237,6 +248,14 @@ impl SpriteKind {
SpriteKind::DungeonChest3 => 1.09,
SpriteKind::DungeonChest4 => 1.09,
SpriteKind::DungeonChest5 => 1.09,
+ SpriteKind::CoralChest => 1.09,
+ SpriteKind::SeaDecorChain => 1.09,
+ SpriteKind::SeaDecorBlock => 1.00,
+ SpriteKind::SeaDecorWindowHor => 0.55,
+ SpriteKind::SeaDecorWindowVer => 1.09,
+ SpriteKind::SeaDecorPillar => 2.55,
+ SpriteKind::SeashellLantern => 2.09,
+ SpriteKind::Rope => 1.09,
SpriteKind::StreetLamp => 2.65,
SpriteKind::Carrot => 0.18,
SpriteKind::Radish => 0.18,
@@ -290,6 +309,8 @@ impl SpriteKind {
| SpriteKind::Window4
| SpriteKind::DropGate
| SpriteKind::WitchWindow
+ | SpriteKind::SeaUrchin
+ | SpriteKind::GlassBarrier
| SpriteKind::Bomb => 1.0,
// TODO: Figure out if this should be solid or not.
SpriteKind::Shelf => 1.0,
@@ -398,6 +419,7 @@ impl SpriteKind {
SpriteKind::DungeonChest5 => table("common.loot_tables.dungeon.tier-5.chest"),
SpriteKind::Chest => table("common.loot_tables.sprite.chest"),
SpriteKind::ChestBuried => table("common.loot_tables.sprite.chest-buried"),
+ SpriteKind::CoralChest => table("common.loot_tables.dungeon.sea_chapel.chest_coral"),
SpriteKind::Mud => table("common.loot_tables.sprite.mud"),
SpriteKind::Crate => table("common.loot_tables.sprite.crate"),
SpriteKind::Wood => item("common.items.log.wood"),
@@ -448,7 +470,8 @@ impl SpriteKind {
| SpriteKind::Tin
| SpriteKind::Silver
| SpriteKind::Gold
- | SpriteKind::SapphireSmall => Some(ToolKind::Pick),
+ | SpriteKind::SapphireSmall
+ | SpriteKind::GlassBarrier => Some(ToolKind::Pick),
_ => None,
}
}
@@ -491,6 +514,9 @@ impl SpriteKind {
| SpriteKind::DungeonChest3
| SpriteKind::DungeonChest4
| SpriteKind::DungeonChest5
+ | SpriteKind::CoralChest
+ | SpriteKind::SeaDecorWindowVer
+ | SpriteKind::SeaDecorEmblem
| SpriteKind::DropGate
| SpriteKind::DropGateBottom
| SpriteKind::Door
diff --git a/common/systems/src/buff.rs b/common/systems/src/buff.rs
index 4bfb9c6810..caf755edb0 100644
--- a/common/systems/src/buff.rs
+++ b/common/systems/src/buff.rs
@@ -152,6 +152,21 @@ impl<'a> System<'a> for Sys {
)),
});
}
+ if matches!(
+ physics_state.on_ground.and_then(|b| b.get_sprite()),
+ Some(SpriteKind::SeaUrchin)
+ ) {
+ // If touching Sea Urchin apply Bleeding buff
+ server_emitter.emit(ServerEvent::Buff {
+ entity,
+ buff_change: BuffChange::Add(Buff::new(
+ BuffKind::Bleeding,
+ BuffData::new(1.0, Some(Duration::from_secs_f32(6.0))),
+ Vec::new(),
+ BuffSource::World,
+ )),
+ });
+ }
if matches!(
physics_state.in_fluid,
Some(Fluid::Liquid {
diff --git a/server/src/persistence/json_models.rs b/server/src/persistence/json_models.rs
index 95bae90d0f..2e5dfecb9b 100644
--- a/server/src/persistence/json_models.rs
+++ b/server/src/persistence/json_models.rs
@@ -85,7 +85,8 @@ pub fn skill_group_to_db_string(skill_group: comp::skillset::SkillGroupKind) ->
| Weapon(ToolKind::Debug)
| Weapon(ToolKind::Farming)
| Weapon(ToolKind::Empty)
- | Weapon(ToolKind::Natural) => panic!(
+ | Weapon(ToolKind::Natural)
+ | Weapon(ToolKind::Organ) => panic!(
"Tried to add unsupported skill group to database: {:?}",
skill_group
),
@@ -104,6 +105,7 @@ pub fn db_string_to_skill_group(skill_group_string: &str) -> comp::skillset::Ski
"Weapon Staff" => Weapon(ToolKind::Staff),
"Weapon Sceptre" => Weapon(ToolKind::Sceptre),
"Weapon Pick" => Weapon(ToolKind::Pick),
+
_ => panic!(
"Tried to convert an unsupported string from the database: {}",
skill_group_string
@@ -203,6 +205,7 @@ fn tool_kind_to_string(tool: Option) -> String {
Some(Farming) => "Farming",
Some(Debug) => "Debug",
Some(Natural) => "Natural",
+ Some(Organ) => "Organ",
Some(Empty) => "Empty",
None => "None",
})
@@ -226,6 +229,7 @@ fn tool_kind_from_string(tool: String) -> Option {
"Farming" => Some(Farming),
"Debug" => Some(Debug),
"Natural" => Some(Natural),
+ "Organ" => Some(Organ),
"Empty" => Some(Empty),
"None" => None,
unknown => {
diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs
index b172d040b6..bcf2c83207 100644
--- a/server/src/sys/agent.rs
+++ b/server/src/sys/agent.rs
@@ -944,6 +944,7 @@ impl<'a> AgentData<'a> {
"Quad Low Breathe" | "Quad Low Beam" | "Basilisk" => {
Tactic::QuadLowBeam
},
+ "Organ" => Tactic::OrganAura,
"Quad Low Tail" | "Husk Brute" => Tactic::TailSlap,
"Quad Low Quick" => Tactic::QuadLowQuick,
"Quad Low Basic" => Tactic::QuadLowBasic,
@@ -972,6 +973,8 @@ impl<'a> AgentData<'a> {
| "Gnarling Totem White" => Tactic::RadialTurret,
"Yeti" => Tactic::Yeti,
"Harvester" => Tactic::Harvester,
+ "Cardinal" => Tactic::Cardinal,
+ "Dagon" => Tactic::Dagon,
"Gnarling Dagger" => Tactic::SimpleBackstab,
"Gnarling Blowgun" => Tactic::ElevatedRanged,
"Deadwood" => Tactic::Deadwood,
@@ -1242,6 +1245,9 @@ impl<'a> AgentData<'a> {
tgt_data,
read_data,
),
+ Tactic::OrganAura => {
+ self.handle_organ_aura_attack(agent, controller, &attack_data, tgt_data, read_data)
+ },
Tactic::Theropod => {
self.handle_theropod_attack(agent, controller, &attack_data, tgt_data, read_data)
},
@@ -1332,6 +1338,17 @@ impl<'a> AgentData<'a> {
Tactic::Harvester => {
self.handle_harvester_attack(agent, controller, &attack_data, tgt_data, read_data)
},
+ Tactic::Cardinal => self.handle_cardinal_attack(
+ agent,
+ controller,
+ &attack_data,
+ tgt_data,
+ read_data,
+ rng,
+ ),
+ Tactic::Dagon => {
+ self.handle_dagon_attack(agent, controller, &attack_data, tgt_data, read_data)
+ },
Tactic::SimpleBackstab => {
self.handle_simple_backstab(agent, controller, &attack_data, tgt_data, read_data)
},
diff --git a/server/src/sys/agent/attack.rs b/server/src/sys/agent/attack.rs
index e53f8b3cb4..cdc8bce929 100644
--- a/server/src/sys/agent/attack.rs
+++ b/server/src/sys/agent/attack.rs
@@ -1305,6 +1305,31 @@ impl<'a> AgentData<'a> {
}
}
+ pub fn handle_organ_aura_attack(
+ &self,
+ agent: &mut Agent,
+ controller: &mut Controller,
+ attack_data: &AttackData,
+ _tgt_data: &TargetData,
+ read_data: &ReadData,
+ ) {
+ const ORGAN_AURA_DURATION: f32 = 34.75;
+ if attack_data.dist_sqrd < (7.0 * attack_data.min_attack_dist).powi(2) {
+ if agent.action_state.timer > ORGAN_AURA_DURATION {
+ agent.action_state.timer = 0.0;
+ } else if agent.action_state.timer < 1.0 {
+ controller
+ .actions
+ .push(ControlAction::basic_input(InputKind::Primary));
+ agent.action_state.timer += read_data.dt.0;
+ } else {
+ agent.action_state.timer += read_data.dt.0;
+ }
+ } else {
+ agent.target = None;
+ }
+ }
+
pub fn handle_theropod_attack(
&self,
agent: &mut Agent,
@@ -2309,6 +2334,205 @@ impl<'a> AgentData<'a> {
);
}
+ pub fn handle_cardinal_attack(
+ &self,
+ agent: &mut Agent,
+ controller: &mut Controller,
+ attack_data: &AttackData,
+ tgt_data: &TargetData,
+ read_data: &ReadData,
+ rng: &mut impl Rng,
+ ) {
+ const DESIRED_ENERGY_LEVEL: f32 = 50.0;
+ const DESIRED_COMBO_LEVEL: u32 = 8;
+ const MINION_SUMMON_THRESHOLD: f32 = 0.10;
+ let health_fraction = self.health.map_or(0.5, |h| h.fraction());
+ // Sets counter at start of combat, using `condition` to keep track of whether
+ // it was already intitialized
+ if !agent.action_state.condition {
+ agent.action_state.counter = 1.0 - MINION_SUMMON_THRESHOLD;
+ agent.action_state.condition = true;
+ }
+
+ if agent.action_state.counter > health_fraction {
+ // Summon minions at particular thresholds of health
+ controller.push_basic_input(InputKind::Ability(1));
+
+ if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover))
+ {
+ agent.action_state.counter -= MINION_SUMMON_THRESHOLD;
+ }
+ }
+ // Logic to use abilities
+ else if attack_data.dist_sqrd > attack_data.min_attack_dist.powi(2)
+ && entities_have_line_of_sight(
+ self.pos,
+ self.body,
+ tgt_data.pos,
+ tgt_data.body,
+ read_data,
+ )
+ {
+ // If far enough away, and can see target, check which skill is appropriate to
+ // use
+ if self.energy.current() > DESIRED_ENERGY_LEVEL
+ && read_data
+ .combos
+ .get(*self.entity)
+ .map_or(false, |c| c.counter() >= DESIRED_COMBO_LEVEL)
+ && !read_data.buffs.get(*self.entity).iter().any(|buff| {
+ buff.iter_kind(BuffKind::Regeneration)
+ .peekable()
+ .peek()
+ .is_some()
+ })
+ {
+ // If have enough energy and combo to use healing aura, do so
+ controller.push_basic_input(InputKind::Secondary);
+ } else if self
+ .skill_set
+ .has_skill(Skill::Sceptre(SceptreSkill::UnlockAura))
+ && self.energy.current() > DESIRED_ENERGY_LEVEL
+ && !read_data.buffs.get(*self.entity).iter().any(|buff| {
+ buff.iter_kind(BuffKind::ProtectingWard)
+ .peekable()
+ .peek()
+ .is_some()
+ })
+ {
+ // Use ward if target is far enough away, self is not buffed, and have
+ // sufficient energy
+ controller.push_basic_input(InputKind::Ability(0));
+ } else {
+ // If low on energy, use primary to attempt to regen energy
+ // Or if at desired energy level but not able/willing to ward, just attack
+ controller.push_basic_input(InputKind::Primary);
+ }
+ } else if attack_data.dist_sqrd < (2.0 * attack_data.min_attack_dist).powi(2) {
+ if self.body.map_or(false, |b| b.is_humanoid())
+ && self.energy.current() > CharacterAbility::default_roll().get_energy_cost()
+ && !matches!(self.char_state, CharacterState::BasicAura(c) if !matches!(c.stage_section, StageSection::Recover))
+ {
+ // Else roll away if can roll and have enough energy, and not using aura or in
+ // recover
+ controller.push_basic_input(InputKind::Roll);
+ } else if attack_data.angle < 15.0 {
+ controller.push_basic_input(InputKind::Primary);
+ }
+ }
+ // Logic to move. Intentionally kept separate from ability logic where possible
+ // so duplicated work is less necessary.
+ if attack_data.dist_sqrd < (2.0 * attack_data.min_attack_dist).powi(2) {
+ // Attempt to move away from target if too close
+ if let Some((bearing, speed)) = agent.chaser.chase(
+ &*read_data.terrain,
+ self.pos.0,
+ self.vel.0,
+ tgt_data.pos.0,
+ TraversalConfig {
+ min_tgt_dist: 1.25,
+ ..self.traversal_config
+ },
+ ) {
+ controller.inputs.move_dir =
+ -bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
+ }
+ } else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
+ // Else attempt to circle target if neither too close nor too far
+ if let Some((bearing, speed)) = agent.chaser.chase(
+ &*read_data.terrain,
+ self.pos.0,
+ self.vel.0,
+ tgt_data.pos.0,
+ TraversalConfig {
+ min_tgt_dist: 1.25,
+ ..self.traversal_config
+ },
+ ) {
+ if entities_have_line_of_sight(
+ self.pos,
+ self.body,
+ tgt_data.pos,
+ tgt_data.body,
+ read_data,
+ ) && attack_data.angle < 45.0
+ {
+ controller.inputs.move_dir = bearing
+ .xy()
+ .rotated_z(rng.gen_range(0.5..1.57))
+ .try_normalized()
+ .unwrap_or_else(Vec2::zero)
+ * speed;
+ } else {
+ // Unless cannot see target, then move towards them
+ controller.inputs.move_dir =
+ bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
+ self.jump_if(bearing.z > 1.5, controller);
+ controller.inputs.move_z = bearing.z;
+ }
+ }
+ // Sometimes try to roll
+ if self.body.map(|b| b.is_humanoid()).unwrap_or(false)
+ && !matches!(self.char_state, CharacterState::BasicAura(_))
+ && attack_data.dist_sqrd < 16.0f32.powi(2)
+ && rng.gen::() < 0.01
+ {
+ controller.push_basic_input(InputKind::Roll);
+ }
+ } else {
+ // If too far, move towards target
+ self.path_toward_target(
+ agent,
+ controller,
+ tgt_data.pos.0,
+ read_data,
+ Path::Partial,
+ None,
+ );
+ }
+ }
+
+ pub fn handle_dagon_attack(
+ &self,
+ agent: &mut Agent,
+ controller: &mut Controller,
+ attack_data: &AttackData,
+ tgt_data: &TargetData,
+ read_data: &ReadData,
+ ) {
+ // if close to target, shoot dagon bombs and lay out sea urchins
+ if attack_data.angle < 70.0
+ && attack_data.dist_sqrd < (1.3 * attack_data.min_attack_dist).powi(2)
+ {
+ controller.inputs.move_dir = Vec2::zero();
+ if agent.action_state.timer > 1.0 {
+ controller.push_basic_input(InputKind::Primary);
+ agent.action_state.timer += read_data.dt.0;
+ } else {
+ controller.push_basic_input(InputKind::Secondary);
+ agent.action_state.timer += read_data.dt.0;
+ }
+ } else if attack_data.angle < 30.0
+ && entities_have_line_of_sight(
+ self.pos,
+ self.body,
+ tgt_data.pos,
+ tgt_data.body,
+ read_data,
+ )
+ {
+ // if in range, angle and sight, shoot dagon bombs at target
+ controller.push_basic_input(InputKind::Primary);
+ }
+ // chase
+ let path = if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
+ Path::Separate
+ } else {
+ Path::Partial
+ };
+ self.path_toward_target(agent, controller, tgt_data.pos.0, read_data, path, None);
+ }
+
pub fn handle_deadwood(
&self,
agent: &mut Agent,
diff --git a/server/src/sys/agent/data.rs b/server/src/sys/agent/data.rs
index 6b2516d99d..c6fbb0f67d 100644
--- a/server/src/sys/agent/data.rs
+++ b/server/src/sys/agent/data.rs
@@ -119,6 +119,9 @@ pub enum Tactic {
Mandragora,
WoodGolem,
GnarlingChieftain,
+ OrganAura,
+ Dagon,
+ Cardinal,
}
#[derive(SystemData)]
diff --git a/voxygen/anim/src/quadruped_low/mod.rs b/voxygen/anim/src/quadruped_low/mod.rs
index 23655e3ee6..2b0a2df6db 100644
--- a/voxygen/anim/src/quadruped_low/mod.rs
+++ b/voxygen/anim/src/quadruped_low/mod.rs
@@ -164,6 +164,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (7.0, 11.5),
(Sandshark, _) => (8.5, 0.5),
(Hakulaq, _) => (8.0, 10.0),
+ (Dagon, _) => (8.0, 10.0),
(Lavadrake, _) => (7.0, 8.0),
(Icedrake, _) => (7.0, 8.0),
(Basilisk, _) => (5.0, 2.5),
@@ -183,6 +184,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (1.0, 4.5),
(Sandshark, _) => (13.5, -10.5),
(Hakulaq, _) => (10.5, 1.0),
+ (Dagon, _) => (10.5, 1.0),
(Lavadrake, _) => (9.0, -6.0),
(Icedrake, _) => (11.5, -6.0),
(Basilisk, _) => (12.5, -5.5),
@@ -202,6 +204,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (-1.0, 4.0),
(Sandshark, _) => (-8.0, -5.5),
(Hakulaq, _) => (-6.5, -4.0),
+ (Dagon, _) => (-6.5, -4.0),
(Lavadrake, _) => (3.0, -5.0),
(Icedrake, _) => (-0.5, -8.0),
(Basilisk, _) => (0.5, -3.0),
@@ -221,6 +224,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (0.0, 12.0),
(Sandshark, _) => (0.0, 20.0),
(Hakulaq, _) => (0.0, 13.5),
+ (Dagon, _) => (0.0, 13.5),
(Lavadrake, _) => (0.0, 16.5),
(Icedrake, _) => (0.0, 16.5),
(Basilisk, _) => (0.0, 15.0),
@@ -240,6 +244,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (-15.0, 4.0),
(Sandshark, _) => (-10.0, 0.5),
(Hakulaq, _) => (-9.0, -2.0),
+ (Dagon, _) => (-9.0, -2.0),
(Lavadrake, _) => (-12.0, -2.0),
(Icedrake, _) => (-12.0, 1.0),
(Basilisk, _) => (-10.0, -4.0),
@@ -259,6 +264,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (-1.0, 4.0),
(Sandshark, _) => (-13.0, -8.0),
(Hakulaq, _) => (-6.0, -5.5),
+ (Dagon, _) => (-9.0, -2.0),
(Lavadrake, _) => (-7.0, -4.5),
(Icedrake, _) => (-7.0, -4.5),
(Basilisk, _) => (-6.5, -5.5),
@@ -278,6 +284,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (4.5, 4.0, -5.5),
(Sandshark, _) => (5.5, 2.0, -8.0),
(Hakulaq, _) => (4.5, 2.0, -4.5),
+ (Dagon, _) => (4.5, 2.0, -4.5),
(Lavadrake, _) => (4.5, 4.0, -6.5),
(Icedrake, _) => (4.5, 4.0, -6.5),
(Basilisk, _) => (6.5, 4.0, -2.0),
@@ -297,6 +304,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Maneater, _) => (4.5, -2.5, -3.0),
(Sandshark, _) => (3.5, -15.0, -14.0),
(Hakulaq, _) => (3.5, -8.0, -4.5),
+ (Dagon, _) => (3.5, -8.0, -4.5),
(Lavadrake, _) => (3.5, -8.0, -6.5),
(Icedrake, _) => (3.5, -8.0, -6.5),
(Basilisk, _) => (5.5, -6.5, -2.0),
@@ -315,6 +323,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Asp, _) => (1.12),
(Rocksnapper, _) => (1.12),
(Hakulaq, _) => (1.05),
+ (Dagon, _) => (1.05),
(Pangolin, _) => (1.05),
(Maneater, _) => (1.12),
(Lavadrake, _) => (1.12),
@@ -331,6 +340,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
(Tortoise, _) => (0.7),
(Rocksnapper, _) => (0.7),
(Hakulaq, _) => (1.2),
+ (Dagon, _) => (1.2),
(Pangolin, _) => (1.15),
(Maneater, _) => (0.9),
(Lavadrake, _) => (1.1),
@@ -357,6 +367,7 @@ fn mount_point(body: &Body) -> Vec3 {
(Maneater, _) => (0.0, 4.0, -11.5),
(Sandshark, _) => (0.0, -4.0, -2.0),
(Hakulaq, _) => (0.0, 4.0, -4.5),
+ (Dagon, _) => (0.0, 4.0, -4.5),
(Lavadrake, _) => (0.0, 2.0, -2.5),
(Icedrake, _) => (0.0, -8.0, 2.5),
(Basilisk, _) => (0.0, -2.0, 2.0),
diff --git a/voxygen/src/hud/diary.rs b/voxygen/src/hud/diary.rs
index f761bcb2e6..f2a932f53c 100644
--- a/voxygen/src/hud/diary.rs
+++ b/voxygen/src/hud/diary.rs
@@ -2835,6 +2835,7 @@ fn unlock_skill_strings(group: SkillGroupKind) -> SkillStrings<'static> {
| ToolKind::Farming
| ToolKind::Pick
| ToolKind::Natural
+ | ToolKind::Organ
| ToolKind::Empty,
) => {
tracing::warn!("Requesting title for unlocking unexpected skill group");
diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs
index 6f2a65f835..56f6f042dd 100644
--- a/voxygen/src/hud/img_ids.rs
+++ b/voxygen/src/hud/img_ids.rs
@@ -410,6 +410,9 @@ image_ids! {
mmap_site_town: "voxygen.element.ui.map.buttons.town",
mmap_site_town_hover: "voxygen.element.ui.map.buttons.town_hover",
mmap_site_town_bg: "voxygen.element.ui.map.buttons.town_bg",
+ mmap_site_sea_chapel_hover: "voxygen.element.ui.map.buttons.sea_chapel_hover",
+ mmap_site_sea_chapel_bg: "voxygen.element.ui.map.buttons.sea_chapel_bg",
+ mmap_site_sea_chapel: "voxygen.element.ui.map.buttons.sea_chapel",
mmap_site_dungeon: "voxygen.element.ui.map.buttons.dungeon",
mmap_site_dungeon_hover: "voxygen.element.ui.map.buttons.dungeon_hover",
mmap_site_dungeon_bg: "voxygen.element.ui.map.buttons.dungeon_bg",
diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs
index 85f7c6cff2..8002f1f201 100644
--- a/voxygen/src/hud/map.rs
+++ b/voxygen/src/hud/map.rs
@@ -57,6 +57,9 @@ widget_ids! {
show_towns_img,
show_towns_box,
show_towns_text,
+ show_sea_chapels_img,
+ show_sea_chapels_box,
+ show_sea_chapels_text,
show_castles_img,
show_castles_box,
show_castles_text,
@@ -878,6 +881,7 @@ impl<'a> Widget for Map<'a> {
SiteKind::Cave => i18n.get_msg("hud-map-cave"),
SiteKind::Tree => i18n.get_msg("hud-map-tree"),
SiteKind::Gnarling => i18n.get_msg("hud-map-gnarling"),
+ SiteKind::ChapelSite => i18n.get_msg("hud-map-chapel_Site"),
});
let (difficulty, desc) = match &site.kind {
SiteKind::Town => (None, i18n.get_msg("hud-map-town")),
@@ -902,10 +906,12 @@ impl<'a> Widget for Map<'a> {
SiteKind::Cave => (None, i18n.get_msg("hud-map-cave")),
SiteKind::Tree => (None, i18n.get_msg("hud-map-tree")),
SiteKind::Gnarling => (Some(0), i18n.get_msg("hud-map-gnarling")),
+ SiteKind::ChapelSite => (Some(0), i18n.get_msg("hud-map-chapel_site")),
};
let desc = desc.into_owned() + &get_site_economy(site_rich);
let site_btn = Button::image(match &site.kind {
SiteKind::Town => self.imgs.mmap_site_town,
+ SiteKind::ChapelSite => self.imgs.mmap_site_sea_chapel,
SiteKind::Castle => self.imgs.mmap_site_castle,
SiteKind::Cave => self.imgs.mmap_site_cave,
SiteKind::Tree => self.imgs.mmap_site_tree,
@@ -924,6 +930,7 @@ impl<'a> Widget for Map<'a> {
.w_h(rside as f64, rside as f64)
.hover_image(match &site.kind {
SiteKind::Town => self.imgs.mmap_site_town_hover,
+ SiteKind::ChapelSite => self.imgs.mmap_site_sea_chapel_hover,
SiteKind::Castle => self.imgs.mmap_site_castle_hover,
SiteKind::Cave => self.imgs.mmap_site_cave_hover,
SiteKind::Tree => self.imgs.mmap_site_tree_hover,
@@ -943,13 +950,15 @@ impl<'a> Widget for Map<'a> {
match &site.kind {
SiteKind::Town => TEXT_COLOR,
SiteKind::Castle => TEXT_COLOR,
- SiteKind::Dungeon { .. } | SiteKind::Gnarling => match difficulty {
- Some(0) => QUALITY_LOW,
- Some(1) => QUALITY_COMMON,
- Some(2) => QUALITY_MODERATE,
- Some(3) => QUALITY_HIGH,
- Some(4 | 5) => QUALITY_EPIC,
- _ => TEXT_COLOR,
+ SiteKind::Dungeon { .. } | SiteKind::Gnarling | SiteKind::ChapelSite => {
+ match difficulty {
+ Some(0) => QUALITY_LOW,
+ Some(1) => QUALITY_COMMON,
+ Some(2) => QUALITY_MODERATE,
+ Some(3) => QUALITY_HIGH,
+ Some(4 | 5) => QUALITY_EPIC,
+ _ => TEXT_COLOR,
+ }
},
SiteKind::Cave => TEXT_COLOR,
SiteKind::Tree => TEXT_COLOR,
@@ -967,7 +976,9 @@ impl<'a> Widget for Map<'a> {
// Only display sites that are toggled on
let show_site = match &site.kind {
SiteKind::Town => show_towns,
- SiteKind::Dungeon { .. } | SiteKind::Gnarling => show_dungeons,
+ SiteKind::Dungeon { .. } | SiteKind::Gnarling | SiteKind::ChapelSite => {
+ show_dungeons
+ },
SiteKind::Castle => show_castles,
SiteKind::Cave => show_caves,
SiteKind::Tree => show_trees,
@@ -1023,7 +1034,7 @@ impl<'a> Widget for Map<'a> {
dif_img.set(state.ids.site_difs[i], ui)
}
},
- SiteKind::Dungeon { .. } | SiteKind::Gnarling => {
+ SiteKind::Dungeon { .. } | SiteKind::Gnarling | SiteKind::ChapelSite => {
if show_dungeons {
dif_img.set(state.ids.site_difs[i], ui)
}
diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs
index ce12a72cd1..9e15d1b1dd 100644
--- a/voxygen/src/hud/minimap.rs
+++ b/voxygen/src/hud/minimap.rs
@@ -692,6 +692,7 @@ impl<'a> Widget for MiniMap<'a> {
};
let difficulty = match &site.kind {
SiteKind::Town => None,
+ SiteKind::ChapelSite => Some(0),
SiteKind::Dungeon { difficulty } => Some(*difficulty),
SiteKind::Castle => None,
SiteKind::Cave => None,
@@ -701,6 +702,7 @@ impl<'a> Widget for MiniMap<'a> {
Image::new(match &site.kind {
SiteKind::Town => self.imgs.mmap_site_town_bg,
+ SiteKind::ChapelSite => self.imgs.mmap_site_sea_chapel_bg,
SiteKind::Dungeon { .. } => self.imgs.mmap_site_dungeon_bg,
SiteKind::Castle => self.imgs.mmap_site_castle_bg,
SiteKind::Cave => self.imgs.mmap_site_cave_bg,
@@ -725,6 +727,7 @@ impl<'a> Widget for MiniMap<'a> {
.set(state.ids.mmap_site_icons_bgs[i], ui);
Image::new(match &site.kind {
SiteKind::Town => self.imgs.mmap_site_town,
+ SiteKind::ChapelSite => self.imgs.mmap_site_sea_chapel,
SiteKind::Dungeon { .. } => self.imgs.mmap_site_dungeon,
SiteKind::Castle => self.imgs.mmap_site_castle,
SiteKind::Cave => self.imgs.mmap_site_cave,
diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index 322a8fc95e..8acb48ce9c 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -4644,6 +4644,7 @@ pub fn get_buff_desc(buff: BuffKind, data: BuffData, localized_strings: &Localiz
pub fn get_sprite_desc(sprite: SpriteKind, localized_strings: &Localization) -> Option> {
let i18n_key = match sprite {
SpriteKind::Empty => return None,
+ SpriteKind::GlassBarrier => return None,
SpriteKind::Anvil => "hud-crafting-anvil",
SpriteKind::Cauldron => "hud-crafting-cauldron",
SpriteKind::CookingPot => "hud-crafting-cooking_pot",
@@ -4655,6 +4656,7 @@ pub fn get_sprite_desc(sprite: SpriteKind, localized_strings: &Localization) ->
SpriteKind::DismantlingBench => "hud-crafting-salvaging_station",
SpriteKind::ChestBuried
| SpriteKind::Chest
+ | SpriteKind::CoralChest
| SpriteKind::DungeonChest0
| SpriteKind::DungeonChest1
| SpriteKind::DungeonChest2
diff --git a/voxygen/src/hud/util.rs b/voxygen/src/hud/util.rs
index 199859ed0b..c1dd3ebd99 100644
--- a/voxygen/src/hud/util.rs
+++ b/voxygen/src/hud/util.rs
@@ -252,6 +252,7 @@ fn tool_kind<'a>(tool: &Tool, i18n: &'a Localization) -> Cow<'a, str> {
ToolKind::Shield => i18n.get_msg("common-weapons-shield"),
ToolKind::Spear => i18n.get_msg("common-weapons-spear"),
ToolKind::Blowgun => i18n.get_msg("common-weapons-blowgun"),
+ ToolKind::Organ => i18n.get_msg("common-weapons-organ"),
ToolKind::Natural => i18n.get_msg("common-weapons-natural"),
ToolKind::Debug => i18n.get_msg("common-tool-debug"),
ToolKind::Farming => i18n.get_msg("common-tool-farming"),
@@ -350,7 +351,6 @@ pub fn ability_image(imgs: &img_ids::Imgs, ability_id: &str) -> image::Id {
"common.abilities.dagger.tempbasic" => imgs.onehdagger_m1,
// Pickaxe
"common.abilities.pick.swing" => imgs.mining,
-
_ => imgs.not_found,
}
}
diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs
index 384feb5b45..7c701fa3f6 100644
--- a/voxygen/src/render/pipelines/particle.rs
+++ b/voxygen/src/render/pipelines/particle.rs
@@ -89,6 +89,7 @@ pub enum ParticleMode {
WebStrand = 36,
BlackSmoke = 37,
Lightning = 38,
+ BarrelOrgan = 39,
}
impl ParticleMode {
diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs
index 3f7d4814b7..4eeccdefd4 100644
--- a/voxygen/src/scene/particle.rs
+++ b/voxygen/src/scene/particle.rs
@@ -359,6 +359,9 @@ impl ParticleMgr {
Body::Object(object::Body::CampfireLit) => {
self.maintain_campfirelit_particles(scene_data, interpolated.pos, vel)
},
+ Body::Object(object::Body::BarrelOrgan) => {
+ self.maintain_barrel_organ_particles(scene_data, interpolated.pos, vel)
+ },
Body::Object(object::Body::BoltFire) => {
self.maintain_boltfire_particles(scene_data, interpolated.pos, vel)
},
@@ -418,6 +421,39 @@ impl ParticleMgr {
}
}
+ fn maintain_barrel_organ_particles(
+ &mut self,
+ scene_data: &SceneData,
+ pos: Vec3,
+ vel: Option<&Vel>,
+ ) {
+ span!(
+ _guard,
+ "barrel_organ_particles",
+ "ParticleMgr::maintain_barrel_organ_particles"
+ );
+ let time = scene_data.state.get_time();
+ let dt = scene_data.state.get_delta_time();
+ let mut rng = thread_rng();
+
+ for _ in 0..self.scheduler.heartbeats(Duration::from_millis(20)) {
+ self.particles.push(Particle::new(
+ Duration::from_millis(250),
+ time,
+ ParticleMode::BarrelOrgan,
+ pos,
+ ));
+
+ self.particles.push(Particle::new(
+ Duration::from_secs(10),
+ time,
+ ParticleMode::BarrelOrgan,
+ pos.map(|e| e + thread_rng().gen_range(-0.25..0.25))
+ + vel.map_or(Vec3::zero(), |v| -v.0 * dt * rng.gen::()),
+ ));
+ }
+ }
+
fn maintain_boltfire_particles(
&mut self,
scene_data: &SceneData,
diff --git a/world/src/civ/mod.rs b/world/src/civ/mod.rs
index 1aeb62eb53..07a6fbcef6 100644
--- a/world/src/civ/mod.rs
+++ b/world/src/civ/mod.rs
@@ -15,7 +15,9 @@ use common::{
path::Path,
spiral::Spiral2d,
store::{Id, Store},
- terrain::{uniform_idx_as_vec2, MapSizeLg, TerrainChunkSize, TERRAIN_CHUNK_BLOCKS_LG},
+ terrain::{
+ uniform_idx_as_vec2, BiomeKind, MapSizeLg, TerrainChunkSize, TERRAIN_CHUNK_BLOCKS_LG,
+ },
vol::RectVolSize,
};
use core::{fmt, hash::BuildHasherDefault, ops::Range};
@@ -111,6 +113,7 @@ impl Civs {
info!(?initial_civ_count, "all civilisations created");
let mut gnarling_enemies: Vec> = start_locations.clone();
+ let mut chapel_site_enemies: Vec> = start_locations.clone();
let mut dungeon_enemies: Vec> = start_locations.clone();
let mut tree_enemies: Vec> = start_locations.clone();
let mut castle_enemies: Vec> = Vec::new();
@@ -126,12 +129,14 @@ impl Civs {
}
},
32..=37 => (SiteKind::Gnarling, (&gnarling_enemies, 40)),
+ 38..=43 => (SiteKind::ChapelSite, (&chapel_site_enemies, 40)),
_ => (SiteKind::Dungeon, (&dungeon_enemies, 40)),
};
let loc = find_site_loc(&mut ctx, avoid, kind)?;
match kind {
SiteKind::Castle => {
gnarling_enemies.push(loc);
+ chapel_site_enemies.push(loc);
dungeon_enemies.push(loc);
tree_enemies.push(loc);
castle_enemies.push(loc);
@@ -140,9 +145,17 @@ impl Civs {
castle_enemies.push(loc);
dungeon_enemies.push(loc);
gnarling_enemies.push(loc);
+ chapel_site_enemies.push(loc);
+ },
+ SiteKind::ChapelSite => {
+ castle_enemies.push(loc);
+ dungeon_enemies.push(loc);
+ gnarling_enemies.push(loc);
+ chapel_site_enemies.push(loc);
},
SiteKind::Dungeon => {
gnarling_enemies.push(loc);
+ chapel_site_enemies.push(loc);
dungeon_enemies.push(loc);
castle_enemies.push(loc);
},
@@ -171,6 +184,7 @@ impl Civs {
SiteKind::Refactor => (32i32, 10.0),
SiteKind::CliffTown => (32i32, 10.0),
SiteKind::DesertCity => (64i32, 25.0),
+ SiteKind::ChapelSite => (36i32, 10.0),
SiteKind::Tree => (12i32, 8.0),
SiteKind::GiantTree => (12i32, 8.0),
SiteKind::Gnarling => (16i32, 10.0),
@@ -271,6 +285,9 @@ impl Civs {
&mut rng,
wpos,
)),
+ SiteKind::ChapelSite => WorldSite::chapel_site(
+ site2::Site::generate_chapel_site(&Land::from_sim(ctx.sim), &mut rng, wpos),
+ ),
});
sim_site.site_tmp = Some(site);
let site_ref = &index.sites[site];
@@ -1130,24 +1147,8 @@ fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2, site_kind: SiteKind) ->
}
true
}
- let possible_terrain = if let Some(chunk) = sim.get(loc) {
- !chunk.river.is_ocean()
- && !chunk.river.is_lake()
- && !chunk.river.is_river()
- && !chunk.is_underwater()
- && !matches!(
- chunk.get_biome(),
- common::terrain::BiomeKind::Lake | common::terrain::BiomeKind::Ocean
- )
- && sim
- .get_gradient_approx(loc)
- .map(|grad| grad < 1.0)
- .unwrap_or(false)
- } else {
- false
- };
let not_occupied = check_chunk_occupation(sim, loc, site_kind.exclusion_radius());
- possible_terrain && site_kind.is_suitable_loc(loc, sim) && not_occupied
+ site_kind.is_suitable_loc(loc, sim) && not_occupied
}
/// Attempt to search for a location that's suitable for site construction
@@ -1240,6 +1241,7 @@ pub enum SiteKind {
Refactor,
CliffTown,
DesertCity,
+ ChapelSite,
Tree,
GiantTree,
Gnarling,
@@ -1247,6 +1249,26 @@ pub enum SiteKind {
impl SiteKind {
pub fn is_suitable_loc(&self, loc: Vec2, sim: &WorldSim) -> bool {
+ let on_land = || -> bool {
+ if let Some(chunk) = sim.get(loc) {
+ !chunk.river.is_ocean()
+ && !chunk.river.is_lake()
+ && !chunk.river.is_river()
+ && !chunk.is_underwater()
+ && !matches!(
+ chunk.get_biome(),
+ common::terrain::BiomeKind::Lake | common::terrain::BiomeKind::Ocean
+ )
+ } else {
+ false
+ }
+ };
+ let on_flat_terrain = || -> bool {
+ sim.get_gradient_approx(loc)
+ .map(|grad| grad < 1.0)
+ .unwrap_or(false)
+ };
+
sim.get(loc).map_or(false, |chunk| {
let suitable_for_town = |score_threshold: f32| -> bool {
const RESOURCE_RADIUS: i32 = 1;
@@ -1345,10 +1367,16 @@ impl SiteKind {
};
match self {
SiteKind::Gnarling => {
- (-0.3..0.4).contains(&chunk.temp) && chunk.tree_density > 0.75
+ on_land()
+ && on_flat_terrain()
+ && (-0.3..0.4).contains(&chunk.temp)
+ && chunk.tree_density > 0.75
},
SiteKind::GiantTree | SiteKind::Tree => {
- chunk.tree_density > 0.4 && (-0.3..0.4).contains(&chunk.temp)
+ on_land()
+ && on_flat_terrain()
+ && chunk.tree_density > 0.4
+ && (-0.3..0.4).contains(&chunk.temp)
},
SiteKind::CliffTown => {
(-0.6..0.4).contains(&chunk.temp)
@@ -1360,6 +1388,10 @@ impl SiteKind {
&& !chunk.near_cliffs()
&& suitable_for_town(4.0)
},
+ SiteKind::ChapelSite => {
+ matches!(chunk.get_biome(), BiomeKind::Ocean)
+ && CONFIG.sea_level < chunk.alt + 1.0
+ },
SiteKind::Castle => {
if chunk.tree_density > 0.4 || chunk.river.near_water() || chunk.near_cliffs() {
return false;
@@ -1387,8 +1419,8 @@ impl SiteKind {
}
true
},
+ SiteKind::Dungeon => on_land(),
SiteKind::Refactor | SiteKind::Settlement => suitable_for_town(6.7),
- _ => true,
}
})
}
diff --git a/world/src/lib.rs b/world/src/lib.rs
index 7ce7e3defc..e77c4837e4 100644
--- a/world/src/lib.rs
+++ b/world/src/lib.rs
@@ -161,6 +161,7 @@ impl World {
civ::SiteKind::Tree | civ::SiteKind::GiantTree => world_msg::SiteKind::Tree,
// TODO: Maybe change?
civ::SiteKind::Gnarling => world_msg::SiteKind::Gnarling,
+ civ::SiteKind::ChapelSite => world_msg::SiteKind::ChapelSite,
},
wpos: site.center * TerrainChunkSize::RECT_SIZE.map(|e| e as i32),
}
diff --git a/world/src/site/economy/context.rs b/world/src/site/economy/context.rs
index 4d6f2250db..0614c0f932 100644
--- a/world/src/site/economy/context.rs
+++ b/world/src/site/economy/context.rs
@@ -128,6 +128,7 @@ impl Environment {
SiteKind::Tree(_) => (),
SiteKind::GiantTree(_) => (),
SiteKind::Gnarling(_) => {},
+ SiteKind::ChapelSite(_) => {},
}
}
if towns.valid() {
diff --git a/world/src/site/mod.rs b/world/src/site/mod.rs
index 3665f9f375..434d0e77bb 100644
--- a/world/src/site/mod.rs
+++ b/world/src/site/mod.rs
@@ -69,6 +69,7 @@ pub enum SiteKind {
CliffTown(site2::Site),
Tree(Tree),
DesertCity(site2::Site),
+ ChapelSite(site2::Site),
GiantTree(site2::Site),
Gnarling(site2::Site),
}
@@ -123,6 +124,13 @@ impl Site {
}
}
+ pub fn chapel_site(p: site2::Site) -> Self {
+ Self {
+ kind: SiteKind::ChapelSite(p),
+ economy: Economy::default(),
+ }
+ }
+
pub fn tree(t: Tree) -> Self {
Self {
kind: SiteKind::Tree(t),
@@ -145,6 +153,7 @@ impl Site {
SiteKind::Refactor(s) => s.radius(),
SiteKind::CliffTown(ct) => ct.radius(),
SiteKind::DesertCity(dc) => dc.radius(),
+ SiteKind::ChapelSite(p) => p.radius(),
SiteKind::Tree(t) => t.radius(),
SiteKind::GiantTree(gt) => gt.radius(),
SiteKind::Gnarling(g) => g.radius(),
@@ -159,6 +168,7 @@ impl Site {
SiteKind::Refactor(s) => s.origin,
SiteKind::CliffTown(ct) => ct.origin,
SiteKind::DesertCity(dc) => dc.origin,
+ SiteKind::ChapelSite(p) => p.origin,
SiteKind::Tree(t) => t.origin,
SiteKind::GiantTree(gt) => gt.origin,
SiteKind::Gnarling(g) => g.origin,
@@ -173,6 +183,7 @@ impl Site {
SiteKind::Refactor(s) => s.spawn_rules(wpos),
SiteKind::CliffTown(ct) => ct.spawn_rules(wpos),
SiteKind::DesertCity(dc) => dc.spawn_rules(wpos),
+ SiteKind::ChapelSite(p) => p.spawn_rules(wpos),
SiteKind::Tree(t) => t.spawn_rules(wpos),
SiteKind::GiantTree(gt) => gt.spawn_rules(wpos),
SiteKind::Gnarling(g) => g.spawn_rules(wpos),
@@ -187,6 +198,7 @@ impl Site {
SiteKind::Refactor(s) => s.name(),
SiteKind::CliffTown(ct) => ct.name(),
SiteKind::DesertCity(dc) => dc.name(),
+ SiteKind::ChapelSite(p) => p.name(),
SiteKind::Tree(_) => "Giant Tree",
SiteKind::GiantTree(gt) => gt.name(),
SiteKind::Gnarling(g) => g.name(),
@@ -219,6 +231,7 @@ impl Site {
SiteKind::Refactor(s) => s.render(canvas, dynamic_rng),
SiteKind::CliffTown(ct) => ct.render(canvas, dynamic_rng),
SiteKind::DesertCity(dc) => dc.render(canvas, dynamic_rng),
+ SiteKind::ChapelSite(p) => p.render(canvas, dynamic_rng),
SiteKind::Tree(t) => t.render(canvas, dynamic_rng),
SiteKind::GiantTree(gt) => gt.render(canvas, dynamic_rng),
SiteKind::Gnarling(g) => g.render(canvas, dynamic_rng),
@@ -246,6 +259,7 @@ impl Site {
SiteKind::Refactor(_) => {},
SiteKind::CliffTown(_) => {},
SiteKind::DesertCity(_) => {},
+ SiteKind::ChapelSite(p) => p.apply_supplement(dynamic_rng, wpos2d, supplement),
SiteKind::Tree(_) => {},
SiteKind::GiantTree(gt) => gt.apply_supplement(dynamic_rng, wpos2d, supplement),
SiteKind::Gnarling(g) => g.apply_supplement(dynamic_rng, wpos2d, supplement),
diff --git a/world/src/site/namegen.rs b/world/src/site/namegen.rs
index e043a390ce..a9d5453556 100644
--- a/world/src/site/namegen.rs
+++ b/world/src/site/namegen.rs
@@ -529,7 +529,6 @@ impl<'a, R: Rng> NameGen<'a, R> {
end: &[&str],
) -> String {
let mut name = String::new();
-
name += start.choose(self.rng).unwrap();
for _ in 0..self.approx_syllables.saturating_sub(2) {
name += vowel.choose(self.rng).unwrap();
@@ -586,8 +585,8 @@ impl<'a, R: Rng> NameGen<'a, R> {
"d", "ph", "r", "st", "t", "s", "p", "th", "br", "tr", "m", "k", "cr", "phr", "dr",
"pl", "ch", "l", "ap", "akr", "ak", "ar", "ath", "asp", "al", "aph", "aphr", "oph",
"or", "ok", "on", "od", "oth", "om", "ep", "er", "em", "eph", "eth", "yps", "yph",
- "ach", "amph", "yp", "ik", "is", "iph", "ith", "pr", "as", "asph", "ps", "b", "n", "z",
- "x", "kr", "kt", "cht", "chr", "thr", "dr", "pr", "pl", "h", "in", "g", "sph",
+ "ach", "amph", "yp", "ik", "is", "iph", "ith", "pr", "as", "ps", "b", "n", "z", "x",
+ "kr", "kt", "cht", "chr", "thr", "dr", "pr", "pl", "h", "in", "g", "sph",
];
let vowel = [
"o", "e", "a", "i", "y", "eo", "ae", "ea", "oi", "io", "ia", "aeo",
diff --git a/world/src/site2/mod.rs b/world/src/site2/mod.rs
index eb12c761c0..527e6077ad 100644
--- a/world/src/site2/mod.rs
+++ b/world/src/site2/mod.rs
@@ -887,6 +887,38 @@ impl Site {
site
}
+ pub fn generate_chapel_site(land: &Land, rng: &mut impl Rng, origin: Vec2) -> Self {
+ let mut rng = reseed(rng);
+ let mut site = Site {
+ origin,
+ name: NameGen::location(&mut rng).generate_danari(),
+ ..Site::default()
+ };
+ // SeaChapel
+ let size = 10.0 as i32;
+ let aabr = Aabr {
+ min: Vec2::broadcast(-size),
+ max: Vec2::broadcast(size),
+ };
+ {
+ let sea_chapel = plot::SeaChapel::generate(land, &mut reseed(&mut rng), &site, aabr);
+ let sea_chapel_alt = sea_chapel.alt;
+ let plot = site.create_plot(Plot {
+ kind: PlotKind::SeaChapel(sea_chapel),
+ root_tile: aabr.center(),
+ tiles: aabr_tiles(aabr).collect(),
+ seed: rng.gen(),
+ });
+
+ site.blit_aabr(aabr, Tile {
+ kind: TileKind::Building,
+ plot: Some(plot),
+ hard_alt: Some(sea_chapel_alt),
+ });
+ }
+ site
+ }
+
pub fn wpos_tile_pos(&self, wpos2d: Vec2) -> Vec2 {
(wpos2d - self.origin).map(|e| e.div_euclid(TILE_SIZE as i32))
}
@@ -1131,6 +1163,7 @@ impl Site {
PlotKind::House(house) => house.render_collect(self, canvas),
PlotKind::Workshop(workshop) => workshop.render_collect(self, canvas),
PlotKind::Castle(castle) => castle.render_collect(self, canvas),
+ PlotKind::SeaChapel(sea_chapel) => sea_chapel.render_collect(self, canvas),
PlotKind::Dungeon(dungeon) => dungeon.render_collect(self, canvas),
PlotKind::Gnarling(gnarling) => gnarling.render_collect(self, canvas),
PlotKind::GiantTree(giant_tree) => giant_tree.render_collect(self, canvas),
diff --git a/world/src/site2/plot.rs b/world/src/site2/plot.rs
index df70e74ac4..27f3543ac5 100644
--- a/world/src/site2/plot.rs
+++ b/world/src/site2/plot.rs
@@ -6,12 +6,13 @@ pub mod dungeon;
mod giant_tree;
mod gnarling;
mod house;
+mod sea_chapel;
mod workshop;
pub use self::{
castle::Castle, cliff_tower::CliffTower, desert_city_multiplot::DesertCityMultiPlot,
desert_city_temple::DesertCityTemple, dungeon::Dungeon, giant_tree::GiantTree,
- gnarling::GnarlingFortification, house::House, workshop::Workshop,
+ gnarling::GnarlingFortification, house::House, sea_chapel::SeaChapel, workshop::Workshop,
};
use super::*;
@@ -52,6 +53,7 @@ pub enum PlotKind {
Workshop(Workshop),
DesertCityMultiPlot(DesertCityMultiPlot),
DesertCityTemple(DesertCityTemple),
+ SeaChapel(SeaChapel),
Plaza,
Castle(Castle),
Road(Path>),
diff --git a/world/src/site2/plot/sea_chapel.rs b/world/src/site2/plot/sea_chapel.rs
new file mode 100644
index 0000000000..93a324328a
--- /dev/null
+++ b/world/src/site2/plot/sea_chapel.rs
@@ -0,0 +1,4995 @@
+use super::*;
+use crate::{
+ site2::{plot::dungeon::spiral_staircase, util::Dir},
+ util::{sampler::Sampler, RandomField, NEIGHBORS},
+ Land, CONFIG,
+};
+use common::{
+ generation::EntityInfo,
+ terrain::{Block, BlockKind, SpriteKind},
+};
+
+use rand::prelude::*;
+use std::sync::Arc;
+use vek::*;
+
+pub struct SeaChapel {
+ bounds: Aabr,
+ pub(crate) alt: i32,
+}
+impl SeaChapel {
+ pub fn generate(_land: &Land, _rng: &mut impl Rng, site: &Site, tile_aabr: Aabr) -> Self {
+ let bounds = Aabr {
+ min: site.tile_wpos(tile_aabr.min),
+ max: site.tile_wpos(tile_aabr.max),
+ };
+ Self {
+ bounds,
+ alt: CONFIG.sea_level as i32,
+ }
+ }
+}
+
+impl Structure for SeaChapel {
+ fn render(&self, _site: &Site, _land: &Land, painter: &Painter) {
+ let base = self.alt + 1;
+ let center = self.bounds.center();
+ let diameter = 54;
+ let mut rng = thread_rng();
+ // Fills
+ let (top, washed) = match (RandomField::new(0).get(center.with_z(base))) % 2 {
+ 0 => {
+ //color_scheme_1 blue
+ (
+ Fill::Brick(BlockKind::Rock, Rgb::new(0, 51, 209), 24),
+ Fill::Brick(BlockKind::Rock, Rgb::new(24, 115, 242), 12),
+ )
+ },
+ _ => {
+ //color_scheme_2 turquoise
+ (
+ Fill::Brick(BlockKind::Rock, Rgb::new(0, 55, 71), 24),
+ Fill::Brick(BlockKind::Rock, Rgb::new(2, 106, 129), 24),
+ )
+ },
+ };
+ let water = Fill::Block(Block::new(BlockKind::Water, Rgb::zero()));
+ let rope = Fill::Block(Block::air(SpriteKind::Rope));
+ let ropefix1 = Fill::Brick(BlockKind::Rock, Rgb::new(80, 75, 35), 24);
+ let ropefix2 = Fill::Brick(BlockKind::Rock, Rgb::new(172, 172, 172), 4);
+ let white_polished = Fill::Brick(BlockKind::Rock, Rgb::new(202, 202, 202), 24);
+ let white_coral = Fill::Sampling(Arc::new(|center| {
+ let c = (RandomField::new(0).get(center) % 13) as u8 * 10 + 120;
+ Some(Block::new(BlockKind::Rock, Rgb::new(c, c, c)))
+ }));
+ let white = match (RandomField::new(0).get(center.with_z(base - 1))) % 2 {
+ 0 => white_polished,
+ _ => white_coral.clone(),
+ };
+ let gold = Fill::Brick(BlockKind::GlowingRock, Rgb::new(245, 232, 0), 10);
+ let gold_chain = Fill::Block(Block::air(SpriteKind::SeaDecorChain));
+ let gold_decor = Fill::Block(Block::air(SpriteKind::SeaDecorBlock));
+ let window_hor = Fill::Block(Block::air(SpriteKind::SeaDecorWindowHor));
+ let window_ver = Fill::Block(Block::air(SpriteKind::SeaDecorWindowVer));
+ let window_ver2 = Fill::Block(
+ Block::air(SpriteKind::SeaDecorWindowVer)
+ .with_ori(2)
+ .unwrap(),
+ );
+ let glass_barrier = Fill::Block(Block::air(SpriteKind::GlassBarrier));
+ // random exit from water basin to side building
+ let mut connect_gate_types = vec![
+ SpriteKind::GlassBarrier,
+ SpriteKind::SeaDecorWindowHor,
+ SpriteKind::SeaDecorWindowHor,
+ SpriteKind::SeaDecorWindowHor,
+ ];
+ //Paint SeaChapel
+ // balcony1
+ let center_b1 = Vec2::new(center.x + (diameter / 2) - (diameter / 4), center.y);
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3) + 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 8),
+ max: (center_b1 + (diameter / 3) - 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 7),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 7),
+ max: (center_b1 + (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 6),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 6),
+ max: (center_b1 + (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ max: (center_b1 + (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ max: (center_b1 + (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ })
+ .clear();
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3) - 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ max: (center_b1 + (diameter / 3) + 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b1 - (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ max: (center_b1 + (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ })
+ .clear();
+ // balcony2
+ let center_b2 = Vec2::new(center.x, center.y + (diameter / 2) - (diameter / 4));
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3) + 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 8),
+ max: (center_b2 + (diameter / 3) - 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 7),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 7),
+ max: (center_b2 + (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 6),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 6),
+ max: (center_b2 + (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ max: (center_b2 + (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ max: (center_b2 + (diameter / 3))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ })
+ .clear();
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3) - 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ max: (center_b2 + (diameter / 3) + 2)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_b2 - (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ max: (center_b2 + (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ })
+ .clear();
+ // chapel bottom
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 2)).with_z(base - (2 * (diameter / 3))),
+ max: (center + (diameter / 2)).with_z(base - (2 * (diameter / 3)) + diameter),
+ })
+ .fill(white.clone());
+ // chapel clear bottom
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 2) + 1).with_z(base - (2 * (diameter / 3)) + 1),
+ max: (center + (diameter / 2) - 1)
+ .with_z(base - (2 * (diameter / 3)) + diameter - 1),
+ })
+ .clear();
+ // chapel main room
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 2)).with_z(base - (diameter / 8)),
+ max: (center + (diameter / 2)).with_z(base - (diameter / 8) + diameter),
+ })
+ .fill(white.clone());
+ // chapel main room entry1 stairs1
+ // entry1 white floor
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) + 3,
+ center.y - 5,
+ base + (diameter / 8) - 4,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + (diameter / 5),
+ center.y + 5,
+ base + (diameter / 8) - 1,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .ramp(
+ Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - 12,
+ center.y - 3,
+ base - (diameter / 8) - 7,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 2,
+ center.y + 3,
+ base - (diameter / 8) + 7,
+ ),
+ },
+ 14,
+ Dir::X,
+ )
+ .fill(white.clone());
+ // chapel main room entry2 stairs
+ // entry2 white floor
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - (diameter / 5),
+ center.y - 5,
+ base + (diameter / 8) - 4,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) - 3,
+ center.y + 5,
+ base + (diameter / 8) - 1,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .ramp(
+ Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 2,
+ center.y - 3,
+ base - (diameter / 8) - 7,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + 12,
+ center.y + 3,
+ base - (diameter / 8) + 7,
+ ),
+ },
+ 14,
+ Dir::NegX,
+ )
+ .fill(white.clone());
+ // chapel 1st washed out top
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 2)).with_z(base - (diameter / 8)),
+ max: (center + (diameter / 2)).with_z(base - (diameter / 8) + diameter),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (center - (diameter / 2)).with_z(base - (diameter / 8)),
+ max: (center + (diameter / 2)).with_z(base - (diameter / 8) + (diameter / 2)),
+ }))
+ .fill(washed.clone());
+ // chapel 1st top
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 2) + 1).with_z(base - (diameter / 8)),
+ max: (center + (diameter / 2)).with_z(base - (diameter / 8) + diameter),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (center - (diameter / 2)).with_z(base - (diameter / 8)),
+ max: (center + (diameter / 2)).with_z(base - (diameter / 8) + (diameter / 2)),
+ }))
+ .fill(top.clone());
+ // chapel small top room
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 3)),
+ max: (center + (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter + (diameter / 3)),
+ })
+ .fill(white.clone());
+ // chapel small washed out top
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 3)),
+ max: (center + (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter + (diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center - (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 3)),
+ max: (center + (diameter / 3)).with_z(base - (diameter / 8) + diameter),
+ }),
+ )
+ .fill(washed.clone());
+ // chapel small top
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 3)),
+ max: (center + (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter + (diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center - (diameter / 3))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 3)),
+ max: (center + (diameter / 3)).with_z(base - (diameter / 8) + diameter),
+ }),
+ )
+ .fill(top.clone());
+ // ground to top room stairway3
+ let center_s3 = Vec2::new(center.x, center.y - (diameter / 2));
+ // stairway3 top room
+ painter
+ .sphere(Aabb {
+ min: (center_s3 - (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 3) - 3),
+ })
+ .fill(white.clone());
+ // stairway3 top washed out
+ painter
+ .sphere(Aabb {
+ min: (center_s3 - (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 3) - 3),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s3 - (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 3),
+ }),
+ )
+ .fill(washed.clone());
+ // stairway3 top
+ painter
+ .sphere(Aabb {
+ min: (center_s3 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 3) - 3),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s3 - (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) - 3),
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 3),
+ }),
+ )
+ .fill(top.clone());
+ // stairway3 top gold ring
+ painter
+ .cylinder(Aabb {
+ min: (center_s3 - (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 2),
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 1),
+ })
+ .fill(gold.clone());
+ // stairway3 clear top halfway
+ painter
+ .sphere(Aabb {
+ min: (center_s3 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 2),
+ max: (center_s3 + (diameter / 6) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 3) - 4),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s3 - (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2))
+ - 2,
+ max: (center_s3 + (diameter / 6))
+ .with_z(base - (diameter / 8) + (diameter / 2) + (diameter / 10) - 3),
+ }),
+ )
+ .clear();
+ // stairway3 top window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s3.x + (diameter / 6) - 1,
+ center_s3.y - 1,
+ base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 5,
+ ),
+ max: Vec3::new(
+ center_s3.x + (diameter / 6),
+ center_s3.y + 1,
+ base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 4,
+ ),
+ })
+ .fill(window_ver2.clone());
+ // stairway3 top window2
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s3.x - (diameter / 6),
+ center_s3.y - 1,
+ base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 5,
+ ),
+ max: Vec3::new(
+ center_s3.x - (diameter / 6) + 1,
+ center_s3.y + 1,
+ base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 4,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // stairway3 top window3
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s3.x - 1,
+ center_s3.y - (diameter / 6),
+ base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 5,
+ ),
+ max: Vec3::new(
+ center_s3.x + 1,
+ center_s3.y - (diameter / 6) + 1,
+ base - (diameter / 8) + (diameter / 2) + (diameter / 6) - 4,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ // chapel clear room
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 2) + 1).with_z(base - (diameter / 8) + 1),
+ max: (center + (diameter / 2) - 1).with_z(base - (diameter / 8) + diameter - 1),
+ })
+ .clear();
+ // chapel main room entry1 gold door frame
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) + 2,
+ center.y - 2,
+ base + (diameter / 8) + 5,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 4,
+ center.y + 2,
+ base + (diameter / 8) + 6,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) + 2,
+ center.y - 3,
+ base + (diameter / 8) + 3,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 5,
+ center.y + 3,
+ base + (diameter / 8) + 5,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) + 3,
+ center.y - 3,
+ base + (diameter / 8) - 3,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 5,
+ center.y + 3,
+ base + (diameter / 8) + 3,
+ ),
+ })
+ .fill(gold_decor.clone());
+ // chapel main room entry2 gold door frame
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 4,
+ center.y - 2,
+ base + (diameter / 8) + 5,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) - 2,
+ center.y + 2,
+ base + (diameter / 8) + 6,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 5,
+ center.y - 3,
+ base + (diameter / 8) + 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) - 2,
+ center.y + 3,
+ base + (diameter / 8) + 5,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 5,
+ center.y - 3,
+ base + (diameter / 8) - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) - 3,
+ center.y + 3,
+ base + (diameter / 8) + 3,
+ ),
+ })
+ .fill(gold_decor.clone());
+ // chapel main room clear entries
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - 8,
+ center.y - 2,
+ base + (diameter / 8) - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + 8,
+ center.y + 2,
+ base + (diameter / 8) + 4,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - 8,
+ center.y - 1,
+ base + (diameter / 8) + 4,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + 8,
+ center.y + 1,
+ base + (diameter / 8) + 5,
+ ),
+ })
+ .clear();
+ // chapel main room mobilees
+ let mbl_corner = center - 5;
+ for dir in SQUARE_4 {
+ let mbl_center = mbl_corner + dir * 10;
+ let mbl_offset =
+ ((RandomField::new(0).get((mbl_corner - dir).with_z(base))) % 4) as i32 - 2;
+ painter
+ .cone(Aabb {
+ min: (mbl_center - 2)
+ .with_z(base - (diameter / 8) + (diameter / 3) + 2 + mbl_offset),
+ max: (mbl_center + 3)
+ .with_z(base - (diameter / 8) + (diameter / 3) + 2 + mbl_offset + 2),
+ })
+ .fill(top.clone());
+ painter
+ .cylinder(Aabb {
+ min: (mbl_center - 2)
+ .with_z(base - (diameter / 8) + (diameter / 3) + 1 + mbl_offset),
+ max: (mbl_center + 3)
+ .with_z(base - (diameter / 8) + (diameter / 3) + 2 + mbl_offset),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: (mbl_center - 1)
+ .with_z(base - (diameter / 8) + (diameter / 3) + 1 + mbl_offset),
+ max: (mbl_center + 2)
+ .with_z(base - (diameter / 8) + (diameter / 3) + 2 + mbl_offset),
+ })
+ .clear();
+ // chapel main room mobilee chains
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ mbl_center.x,
+ mbl_center.y,
+ base - (diameter / 8) + (diameter / 3) + 4 + mbl_offset,
+ ),
+ max: Vec3::new(
+ mbl_center.x + 1,
+ mbl_center.y + 1,
+ base - (diameter / 8) + (diameter / 2) + 1,
+ ),
+ })
+ .fill(gold_chain.clone());
+ }
+ // chapel main room window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2),
+ center.y - 4,
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 1,
+ center.y + 4,
+ base - (diameter / 8) + (diameter / 2) - 1,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2),
+ center.y - 3,
+ base - (diameter / 8) + (diameter / 2) - 3,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 1,
+ center.y + 3,
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ })
+ .fill(window_ver2.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2),
+ center.y - 2,
+ base - (diameter / 8) + (diameter / 2) - 4,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + 1,
+ center.y + 2,
+ base - (diameter / 8) + (diameter / 2) - 3,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // chapel main room window2 to balcony1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 1,
+ center.y - 4,
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2),
+ center.y + 4,
+ base - (diameter / 8) + (diameter / 2) - 1,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 1,
+ center.y - 3,
+ base - (diameter / 8) + (diameter / 2) - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2),
+ center.y + 3,
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - 1,
+ center.y - 2,
+ base - (diameter / 8) + (diameter / 2) - 4,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2),
+ center.y + 2,
+ base - (diameter / 8) + (diameter / 2) - 3,
+ ),
+ })
+ .clear();
+ // chapel main room window3 to balcony2
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 4,
+ center.y + (diameter / 2) - 1,
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ center.x + 4,
+ center.y + (diameter / 2),
+ base - (diameter / 8) + (diameter / 2) - 1,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 3,
+ center.y + (diameter / 2) - 1,
+ base - (diameter / 8) + (diameter / 2) - 3,
+ ),
+ max: Vec3::new(
+ center.x + 3,
+ center.y + (diameter / 2),
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 2,
+ center.y + (diameter / 2) - 1,
+ base - (diameter / 8) + (diameter / 2) - 4,
+ ),
+ max: Vec3::new(
+ center.x + 2,
+ center.y + (diameter / 2),
+ base - (diameter / 8) + (diameter / 2) - 3,
+ ),
+ })
+ .clear();
+ // chapel gold ring and white floor
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 2)).with_z(base - (diameter / 8) + (diameter / 2) + 1),
+ max: (center + (diameter / 2)).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ })
+ .fill(gold.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 2) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) + 1),
+ max: (center + (diameter / 2) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ })
+ .fill(white.clone());
+ // chapel main room organ podium
+ let center_o = Vec2::new(center.x - (diameter / 4), center.y + (diameter / 4));
+ painter
+ .cylinder(Aabb {
+ min: (center_o - 2).with_z(base),
+ max: (center_o + 2).with_z(base + (diameter / 8) - 2),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_o - 3).with_z(base + (diameter / 8) - 2),
+ max: (center_o + 3).with_z(base + (diameter / 8) - 1),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_o - 4).with_z(base + (diameter / 8) - 1),
+ max: (center_o + 4).with_z(base + (diameter / 8)),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_o - 3).with_z(base + (diameter / 8) - 1),
+ max: (center_o + 3).with_z(base + (diameter / 8)),
+ })
+ .fill(white.clone());
+ // organ on chapel main room organ podium
+ let main_room_organ_pos = center_o.with_z(base + (diameter / 8));
+ painter.spawn(
+ EntityInfo::at(main_room_organ_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.organ", &mut rng),
+ );
+ // sea clerics in chapel main room
+ let main_room_sea_clerics_pos = (center_o - 2).with_z(base + (diameter / 8));
+ for _ in 0..(4 + ((RandomField::new(0).get((main_room_sea_clerics_pos).with_z(base))) % 4))
+ {
+ painter.spawn(
+ EntityInfo::at(main_room_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ )
+ }
+ // chapel first floor organ podium
+ let center_o2 = Vec2::new(center.x - (diameter / 4), center.y - (diameter / 4));
+ painter
+ .cylinder(Aabb {
+ min: (center_o2 - 4).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ max: (center_o2 + 4).with_z(base - (diameter / 8) + (diameter / 2) + 3),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center_o2 - 3).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ max: (center_o2 + 3).with_z(base - (diameter / 8) + (diameter / 2) + 3),
+ })
+ .fill(white.clone());
+ // organ on chapel first floor organ podium
+ let first_floor_organ_pos = center_o2.with_z(base - (diameter / 8) + (diameter / 2) + 2);
+ painter.spawn(
+ EntityInfo::at(first_floor_organ_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.organ", &mut rng),
+ );
+ // sea clerics on first floor
+ let first_floor_sea_clerics_pos =
+ (center_o2 - 2).with_z(base - (diameter / 8) + (diameter / 2) + 2);
+ for _ in
+ 0..(3 + ((RandomField::new(0).get((first_floor_sea_clerics_pos).with_z(base))) % 3))
+ {
+ painter.spawn(
+ EntityInfo::at(first_floor_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ )
+ }
+ // ground to top room stairway1
+ let center_s1 = Vec2::new(
+ center.x - (diameter / 2) + (diameter / 8),
+ center.y - (diameter / 8) - (diameter / 16),
+ );
+ // stairway1 top room
+ painter
+ .sphere(Aabb {
+ min: (center_s1 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4)),
+ max: (center_s1 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 3)),
+ })
+ .fill(white.clone());
+ // stairway1 top washed out
+ painter
+ .sphere(Aabb {
+ min: (center_s1 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4)),
+ max: (center_s1 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s1 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4)),
+ max: (center_s1 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6)),
+ }),
+ )
+ .fill(washed.clone());
+ // stairway1 top
+ painter
+ .sphere(Aabb {
+ min: (center_s1 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4)),
+ max: (center_s1 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s1 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4)),
+ max: (center_s1 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6)),
+ }),
+ )
+ .fill(top.clone());
+ // stairway1 top gold ring
+ painter
+ .cylinder(Aabb {
+ min: (center_s1 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) + 1),
+ max: (center_s1 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) + 2),
+ })
+ .fill(gold.clone());
+ // stairway1 top window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s1.x - (diameter / 6),
+ center_s1.y - 1,
+ base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) - 2,
+ ),
+ max: Vec3::new(
+ center_s1.x - (diameter / 6) + 1,
+ center_s1.y + 1,
+ base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) - 1,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // stairway1 top window2
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s1.x - 1,
+ center_s1.y - (diameter / 6),
+ base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) - 2,
+ ),
+ max: Vec3::new(
+ center_s1.x + 1,
+ center_s1.y - (diameter / 6) + 1,
+ base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) - 1,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ // stairway1 top window3
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s1.x - 1,
+ center_s1.y + (diameter / 6) - 1,
+ base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) - 2,
+ ),
+ max: Vec3::new(
+ center_s1.x + 1,
+ center_s1.y + (diameter / 6),
+ base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 6) - 1,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ // ground to top room stairway2
+ let center_s2 = Vec2::new(
+ center.x + (diameter / 2) - (diameter / 6),
+ center.y + (diameter / 8) + (diameter / 16),
+ );
+ // stairway2 top room
+ painter
+ .sphere(Aabb {
+ min: (center_s2 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10)),
+ max: (center_s2 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 3)),
+ })
+ .fill(white.clone());
+ // stairway2 top washed out
+ painter
+ .sphere(Aabb {
+ min: (center_s2 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10)),
+ max: (center_s2 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s2 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10)),
+ max: (center_s2 + (diameter / 6)).with_z(
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6),
+ ),
+ }),
+ )
+ .fill(washed.clone());
+ // stairway2 top
+ painter
+ .sphere(Aabb {
+ min: (center_s2 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10)),
+ max: (center_s2 + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center_s2 - (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10)),
+ max: (center_s2 + (diameter / 6)).with_z(
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6),
+ ),
+ }),
+ )
+ .fill(top.clone());
+ // stairway2 top gold ring
+ painter
+ .cylinder(Aabb {
+ min: (center_s2 - (diameter / 6)).with_z(
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6) + 1,
+ ),
+ max: (center_s2 + (diameter / 6)).with_z(
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6) + 2,
+ ),
+ })
+ .fill(gold.clone());
+ // chapel clear top room
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 3) + 1),
+ max: (center + (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + diameter + (diameter / 3) - 1),
+ })
+ .clear();
+ // stairway1 clear top halfway
+ painter
+ .sphere(Aabb {
+ min: (center_s1 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + 1),
+ max: (center_s1 + (diameter / 6) - 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + (diameter / 3) - 1),
+ })
+ .without(
+ painter.sphere(Aabb {
+ min: (center_s1 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 4) + 1),
+ max: (center_s1 + (diameter / 6) - 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ }),
+ )
+ .clear();
+ // stairway2 clear top halfway
+ painter
+ .sphere(Aabb {
+ min: (center_s2 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10) + 1),
+ max: (center_s2 + (diameter / 6) - 1).with_z(
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 3) - 1,
+ ),
+ })
+ .without(
+ painter.sphere(Aabb {
+ min: (center_s2 - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 10) + 1),
+ max: (center_s2 + (diameter / 6) - 1)
+ .with_z(base - (diameter / 8) + diameter + 2),
+ }),
+ )
+ .clear();
+ // stairway2 top window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s2.x + (diameter / 6) - 1,
+ center_s2.y - 1,
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6) - 2,
+ ),
+ max: Vec3::new(
+ center_s2.x + (diameter / 6),
+ center_s2.y + 1,
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6) - 1,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // stairway2 top window2
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s2.x - 1,
+ center_s2.y + (diameter / 6) - 1,
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6) - 2,
+ ),
+ max: Vec3::new(
+ center_s2.x + 1,
+ center_s2.y + (diameter / 6),
+ base - (diameter / 8) + diameter - (diameter / 10) + (diameter / 6) - 1,
+ ),
+ })
+ .fill(window_ver.clone());
+ // chapel tube1 / NPC-fence
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6)).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ max: (center + (diameter / 6)).with_z(base - (diameter / 8) + diameter + 1),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6) + 1)
+ .with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ max: (center + (diameter / 6) - 1).with_z(base - (diameter / 8) + diameter + 1),
+ })
+ .clear();
+ // chapel tube1 glass barrier / gold door
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 1,
+ base + (diameter / 2) + 5,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 1,
+ base + (diameter / 2) + 6,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 2,
+ base + (diameter / 2) + 4,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 2,
+ base + (diameter / 2) + 5,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 1,
+ base + (diameter / 2) + 4,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6) + 1,
+ center.y + 1,
+ base + (diameter / 2) + 5,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 3,
+ base + (diameter / 2) + 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 3,
+ base + (diameter / 2) + 4,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 2,
+ base + (diameter / 2) + 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6) + 1,
+ center.y + 2,
+ base + (diameter / 2) + 4,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 2,
+ base + (diameter / 2) + 1,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 2,
+ base + (diameter / 2) + 2,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 1,
+ base + (diameter / 2) + 1,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6) + 1,
+ center.y + 1,
+ base + (diameter / 2) + 2,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 1,
+ base + (diameter / 2),
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 1,
+ base + (diameter / 2) + 1,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 2,
+ base + (diameter / 2) + 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 2,
+ base + (diameter / 2) + 4,
+ ),
+ })
+ .fill(window_ver2.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 1,
+ base + (diameter / 2) + 1,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 1,
+ base + (diameter / 2) + 5,
+ ),
+ })
+ .fill(window_ver2.clone());
+ // chapel floor1 mobilees and cages
+ let floor1_corner = center - (diameter / 5);
+ for dir in SQUARE_4 {
+ let floor1_pos = floor1_corner + dir * (2 * diameter / 5);
+ let floor1_variant = (RandomField::new(0).get((floor1_corner + dir).with_z(base))) % 10;
+ match floor1_variant {
+ // chapel first floor mobilee
+ 0..=4 => {
+ let floor1_mbl_top = Aabb {
+ min: (floor1_pos - 3)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 8),
+ max: (floor1_pos + 2)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 6),
+ };
+ let floor1_mbl_gold = painter.cylinder(Aabb {
+ min: (floor1_pos - 3)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 9),
+ max: (floor1_pos + 2)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 8),
+ });
+ let floor1_mbl_gold_clear = painter.aabb(Aabb {
+ min: (floor1_pos - 2)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 9),
+ max: (floor1_pos + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 8),
+ });
+ let floor1_mbl_chain = Aabb {
+ min: (floor1_pos - 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 6),
+ max: (floor1_pos)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 1),
+ };
+ painter.cone(floor1_mbl_top).fill(top.clone());
+ floor1_mbl_gold.fill(gold_decor.clone());
+ floor1_mbl_gold_clear.clear();
+ painter.aabb(floor1_mbl_chain).fill(gold_chain.clone());
+ },
+ _ => {
+ // chapel floor1 hanging cages
+ let cage_glass_barriers = Aabb {
+ min: (floor1_pos - 3).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 5,
+ ),
+ max: (floor1_pos + 3)
+ .with_z(base - (diameter / 4) + diameter - (diameter / 8)),
+ };
+ let cage_clear1 = Aabb {
+ min: (floor1_pos - 3 + 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 5,
+ ),
+ max: (floor1_pos + 3 - 1)
+ .with_z(base - (diameter / 4) + diameter - (diameter / 8)),
+ };
+ let cage_clear2 = Aabb {
+ min: (floor1_pos - 3)
+ .with_z(base - (diameter / 4) + diameter - (diameter / 8) - 2),
+ max: (floor1_pos + 3)
+ .with_z(base - (diameter / 4) + diameter - (diameter / 8) - 1),
+ };
+ let cage_windows = Aabb {
+ min: (floor1_pos - 3 + 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 4,
+ ),
+ max: (floor1_pos + 3 - 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 5,
+ ),
+ };
+ let cage_platform = Aabb {
+ min: (floor1_pos - 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 4,
+ ),
+ max: (floor1_pos + 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 5,
+ ),
+ };
+ let cage_chain = Aabb {
+ min: (floor1_pos - 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 5,
+ ),
+ max: (floor1_pos + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 2),
+ };
+ let cage_chain_fix = Aabb {
+ min: (floor1_pos - 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 2),
+ max: (floor1_pos + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 1),
+ };
+ let cage_coral_chest_podium = Aabb {
+ min: (floor1_pos + 1).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 4,
+ ),
+ max: (floor1_pos + 2).with_z(
+ base - (diameter / 4) + diameter
+ - (diameter / 8)
+ - (2 * (diameter / 11))
+ + 6,
+ ),
+ };
+ let cage_coral_chest_pos = (floor1_pos + 1).with_z(
+ base - (diameter / 4) + diameter - (diameter / 8) - (2 * (diameter / 11))
+ + 6,
+ );
+ // first floor cage Sea Cleric
+ let cage_sea_cleric_pos = (floor1_pos - 1).with_z(
+ base - (diameter / 4) + diameter - (diameter / 8) - (2 * (diameter / 11))
+ + 5,
+ );
+ painter
+ .cylinder(cage_glass_barriers)
+ .fill(glass_barrier.clone());
+ painter.aabb(cage_clear1).clear();
+ painter.cylinder(cage_clear2).clear();
+ painter.aabb(cage_windows).fill(window_hor.clone());
+ painter.aabb(cage_platform).fill(gold_decor.clone());
+ painter.aabb(cage_chain).fill(gold_chain.clone());
+ painter.aabb(cage_chain_fix).fill(gold_decor.clone());
+ painter
+ .aabb(cage_coral_chest_podium)
+ .fill(gold_decor.clone());
+ painter.rotated_sprite(cage_coral_chest_pos, SpriteKind::CoralChest, 2);
+ painter.spawn(EntityInfo::at(cage_sea_cleric_pos.as_()).with_asset_expect(
+ "common.entity.dungeon.sea_chapel.sea_cleric_sceptre",
+ &mut rng,
+ ));
+ },
+ }
+ }
+
+ // chapel floor1 window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 3),
+ center.y,
+ base - (diameter / 8) + diameter - 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 3) + 1,
+ center.y + 2,
+ base - (diameter / 8) + diameter - 1,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 3),
+ center.y,
+ base - (diameter / 8) + diameter - 3,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 3) + 1,
+ center.y + 1,
+ base - (diameter / 8) + diameter - 2,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // chapel floor1 window2
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 3) - 1,
+ center.y - 2,
+ base - (diameter / 8) + diameter - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 3),
+ center.y,
+ base - (diameter / 8) + diameter - 1,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 3) - 1,
+ center.y - 1,
+ base - (diameter / 8) + diameter - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 3),
+ center.y,
+ base - (diameter / 8) + diameter - 2,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // chapel floor1 window3
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 2,
+ center.y + (diameter / 3) - 1,
+ base - (diameter / 8) + diameter - 2,
+ ),
+ max: Vec3::new(
+ center.x + 2,
+ center.y + (diameter / 3),
+ base - (diameter / 8) + diameter - 1,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 1,
+ center.y + (diameter / 3) - 1,
+ base - (diameter / 8) + diameter - 3,
+ ),
+ max: Vec3::new(
+ center.x + 1,
+ center.y + (diameter / 3),
+ base - (diameter / 8) + diameter - 2,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ // chapel floor1 window4
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 2,
+ center.y - (diameter / 3),
+ base - (diameter / 8) + diameter - 2,
+ ),
+ max: Vec3::new(
+ center.x + 2,
+ center.y - (diameter / 3) + 1,
+ base - (diameter / 8) + diameter - 1,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 1,
+ center.y - (diameter / 3),
+ base - (diameter / 8) + diameter - 3,
+ ),
+ max: Vec3::new(
+ center.x + 1,
+ center.y - (diameter / 3) + 1,
+ base - (diameter / 8) + diameter - 2,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ // chapel floor1
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 3)).with_z(base - (diameter / 8) + diameter + 1),
+ max: (center + (diameter / 3)).with_z(base - (diameter / 8) + diameter + 2),
+ })
+ .fill(gold.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 3) + 1).with_z(base - (diameter / 8) + diameter + 1),
+ max: (center + (diameter / 3) - 1).with_z(base - (diameter / 8) + diameter + 2),
+ })
+ .fill(white.clone());
+ // chapel tube2 / NPC-fence
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6)).with_z(base - (diameter / 8) + diameter + 2),
+ max: (center + (diameter / 6))
+ .with_z(base - (diameter / 8) + diameter + (diameter / 3) - 3),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6) + 1).with_z(base - (diameter / 8) + diameter + 2),
+ max: (center + (diameter / 6) - 1)
+ .with_z(base - (diameter / 8) + diameter + (diameter / 3) - 3),
+ })
+ .clear();
+ // chapel tube2 gold door
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 3,
+ base - (diameter / 8) + diameter + 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 3,
+ base - (diameter / 8) + diameter + 6,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 2,
+ base - (diameter / 8) + diameter + 6,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6),
+ center.y + 2,
+ base - (diameter / 8) + diameter + 7,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 2,
+ base - (diameter / 8) + diameter + 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6) + 1,
+ center.y + 2,
+ base - (diameter / 8) + diameter + 5,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 6) - 1,
+ center.y - 1,
+ base - (diameter / 8) + diameter + 5,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 6) + 1,
+ center.y + 1,
+ base - (diameter / 8) + diameter + 6,
+ ),
+ })
+ .clear();
+ //chapel floor2
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 1),
+ max: (center + (diameter / 3) - 1)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ })
+ .fill(white.clone());
+ //chapel floor2 glass barriers in tube
+ painter
+ .cylinder(Aabb {
+ min: (center - 4).with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ max: (center + 4).with_z(base - (diameter / 8) + diameter - (diameter / 8) + 2),
+ })
+ .fill(glass_barrier.clone());
+ //chapel floor2 drawer and potion
+ painter.sprite(
+ (center - (diameter / 8)).with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ SpriteKind::DrawerSmall,
+ );
+ painter.sprite(
+ (center - (diameter / 8)).with_z(base - (diameter / 8) + diameter - (diameter / 8) + 1),
+ SpriteKind::PotionMinor,
+ );
+ //chapel main room pillars1
+ for dir in SQUARE_4 {
+ let sq_corner = Vec2::new(center.x - 3, center.y - (diameter / 4) - 2);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * 5),
+ sq_corner.y + (dir.y * ((diameter / 2) + 2)),
+ base - (diameter / 8) + (diameter / 6),
+ );
+ painter.sprite(pos, SpriteKind::SeaDecorPillar);
+ }
+ //chapel main room pillars2
+ for dir in SQUARE_4 {
+ let sq_corner = Vec2::new(center.x - (diameter / 2) + 6, center.y - 4);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * (diameter - 13)),
+ sq_corner.y + (dir.y * 7),
+ base - (diameter / 8) + (diameter / 6) + 2,
+ );
+ painter.sprite(pos, SpriteKind::SeaDecorPillar);
+ }
+ //chapel floor1 pillars inside tube
+ for dir in SQUARE_4 {
+ let sq_corner = Vec2::new(center.x - (diameter / 8) - 2, center.y - 3);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * ((diameter / 4) + 2)),
+ sq_corner.y + (dir.y * 5),
+ base - (diameter / 8) + (diameter / 2) + 2,
+ );
+ painter.sprite(pos, SpriteKind::SeaDecorPillar);
+ }
+ //chapel floor1 pillars outside tube
+ for dir in SQUARE_4 {
+ let sq_corner = Vec2::new(center.x - (diameter / 8) - 3, center.y - 4);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * ((diameter / 4) + 4)),
+ sq_corner.y + (dir.y * 7),
+ base - (diameter / 8) + (diameter / 2) + 2,
+ );
+ painter.sprite(pos, SpriteKind::SeaDecorPillar);
+ }
+ //chapel floor2/3 pillars inside tube
+ for dir in SQUARE_4 {
+ for f in 0..2 {
+ let sq_corner = Vec2::new(center.x - (diameter / 8) - 2, center.y - 3);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * ((diameter / 4) + 2)),
+ sq_corner.y + (dir.y * 5),
+ base - (diameter / 8) + diameter - (diameter / 8) + (f * ((diameter / 8) + 2)),
+ );
+ painter.sprite(pos, SpriteKind::SeaDecorPillar);
+ }
+ }
+ //chapel floor2/3 pillars outside tube
+ for dir in SQUARE_4 {
+ for f in 0..2 {
+ let sq_corner = Vec2::new(center.x - (diameter / 8) - 3, center.y - 4);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * ((diameter / 4) + 4)),
+ sq_corner.y + (dir.y * 7),
+ base - (diameter / 8) + diameter - (diameter / 8) + (f * ((diameter / 8) + 2)),
+ );
+ painter.sprite(pos, SpriteKind::SeaDecorPillar);
+ }
+ }
+ // floor2 tube Sea Clerics
+ let fl2_tb_sea_clerics_pos = (center + (diameter / 8) - 2)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) + 1);
+ for _ in 0..(1 + (RandomField::new(0).get((fl2_tb_sea_clerics_pos).with_z(base))) % 3) {
+ painter.spawn(
+ EntityInfo::at(fl2_tb_sea_clerics_pos.as_()).with_asset_expect(
+ "common.entity.dungeon.sea_chapel.sea_cleric_sceptre",
+ &mut rng,
+ ),
+ )
+ }
+ // chapel upper floor exits
+ let (exit_pos1, exit_pos2) = (
+ Vec2::new(center.x, center.y + (diameter / 4)),
+ Vec2::new(center.x, center.y - (diameter / 4)),
+ );
+ let floors_exit_distr = RandomField::new(0).get(center.with_z(base)) as usize % 2;
+ let (floor2_exit_center, floor3_exit_center) = match floors_exit_distr {
+ 0 => (exit_pos1, exit_pos2),
+ _ => (exit_pos2, exit_pos1),
+ };
+ // floor3 exit
+ painter
+ .cylinder(Aabb {
+ min: (floor3_exit_center - 2).with_z(base - (diameter / 8) + diameter + 1),
+ max: (floor3_exit_center + 2).with_z(base - (diameter / 8) + diameter + 2),
+ })
+ .fill(glass_barrier.clone());
+ // floor2 exit
+ painter
+ .cylinder(Aabb {
+ min: (floor2_exit_center - 2)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8) - 1),
+ max: (floor2_exit_center + 2)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ })
+ .fill(glass_barrier.clone());
+ // floor 2 Sea Clerics
+ let fl2_sea_clerics_pos = Vec3::new(
+ center.x - 3,
+ center.y - (diameter / 4),
+ base - (diameter / 8) + diameter - (diameter / 8) + 1,
+ );
+ for _ in 0..(2 + ((RandomField::new(0).get((fl2_sea_clerics_pos).with_z(base))) % 4)) {
+ painter.spawn(
+ EntityInfo::at(fl2_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ )
+ }
+ // floor 3 Sea Clerics
+ let fl3_sea_clerics_pos =
+ (center - (diameter / 6)).with_z(base - (diameter / 8) + diameter + 2);
+ for _ in 0..(2 + ((RandomField::new(0).get((fl3_sea_clerics_pos).with_z(base))) % 2)) {
+ painter.spawn(
+ EntityInfo::at(fl3_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ )
+ }
+ // chapel gold top emblem4
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 7,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 9,
+ ),
+ max: Vec3::new(
+ center.x + 7,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 11,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 3,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 9,
+ ),
+ max: Vec3::new(
+ center.x + 3,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 11,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem5
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 9,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 11,
+ ),
+ max: Vec3::new(
+ center.x + 9,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 13,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 11,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 13,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem6
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 11,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 13,
+ ),
+ max: Vec3::new(
+ center.x + 11,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 17,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 7,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 13,
+ ),
+ max: Vec3::new(
+ center.x + 7,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 17,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem7
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 9,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 17,
+ ),
+ max: Vec3::new(
+ center.x + 9,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 19,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 17,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 19,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem8
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 9,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 19,
+ ),
+ max: Vec3::new(
+ center.x + 9,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 21,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 3,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 19,
+ ),
+ max: Vec3::new(
+ center.x + 3,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 21,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem9
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 11,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 21,
+ ),
+ max: Vec3::new(
+ center.x + 11,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 23,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 7,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 21,
+ ),
+ max: Vec3::new(
+ center.x + 7,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 23,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem10
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 11,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 23,
+ ),
+ max: Vec3::new(
+ center.x + 11,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 25,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 23,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 25,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem11
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 9,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 25,
+ ),
+ max: Vec3::new(
+ center.x + 9,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 27,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 3,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 25,
+ ),
+ max: Vec3::new(
+ center.x + 3,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 27,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem12
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 27,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 29,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 3,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 27,
+ ),
+ max: Vec3::new(
+ center.x + 3,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 29,
+ ),
+ })
+ .clear();
+ // chapel gold top emblem13
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 7,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 29,
+ ),
+ max: Vec3::new(
+ center.x + 7,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 31,
+ ),
+ })
+ .fill(gold.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 29,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 31,
+ ),
+ })
+ .clear();
+ // chapel gold top sphere
+ painter
+ .sphere(Aabb {
+ min: (center - 4).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 3),
+ max: (center + 4).with_z(base - (diameter / 8) + diameter + (diameter / 3) + 5),
+ })
+ .fill(gold.clone());
+ // chapel gold top pole
+ painter
+ .aabb(Aabb {
+ min: (center - 1).with_z(base - (diameter / 8) + diameter + (diameter / 3) + 5),
+ max: (center + 1).with_z(base - (diameter / 8) + diameter + (diameter / 3) + 21),
+ })
+ .fill(gold.clone());
+ // chapel gold top emblem1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 3,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 11,
+ ),
+ max: Vec3::new(
+ center.x + 3,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 19,
+ ),
+ })
+ .fill(gold.clone());
+ // chapel gold top emblem2
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 21,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 23,
+ ),
+ })
+ .fill(gold.clone());
+ // chapel gold top emblem3
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - 5,
+ center.y - 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 7,
+ ),
+ max: Vec3::new(
+ center.x + 5,
+ center.y + 1,
+ base - (diameter / 8) + diameter + (diameter / 3) + 9,
+ ),
+ })
+ .fill(gold.clone());
+ // chapel main room pulpit
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 6)).with_z(base - (diameter / 8)),
+ max: (center + (diameter / 6)).with_z(base - (diameter / 8) + (diameter / 3)),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6)).with_z(base - (diameter / 8) + (diameter / 6)),
+ max: (center + (diameter / 6)).with_z(base - (diameter / 8) + (diameter / 3)),
+ })
+ .clear();
+ // chapel main room pulpit gold ring
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 6)).with_z(base - (diameter / 8) + (diameter / 6)),
+ max: (center + (diameter / 6)).with_z(base - (diameter / 8) + (diameter / 6) + 1),
+ })
+ .fill(gold_decor.clone());
+
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6) + 1).with_z(base - (diameter / 8) + (diameter / 6)),
+ max: (center + (diameter / 6) - 1)
+ .with_z(base - (diameter / 8) + (diameter / 6) + 1),
+ })
+ .clear();
+ // chapel clear rope & platform entries
+ painter
+ .cylinder(Aabb {
+ min: (center - 3).with_z(base - (2 * (diameter / 3)) + 3),
+ max: (center + 3).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 2),
+ })
+ .clear();
+ //chapel main room gold window downwards
+ painter
+ .cylinder(Aabb {
+ min: (center - 3).with_z(base - (diameter / 8)),
+ max: (center + 3).with_z(base - (diameter / 8) + 1),
+ })
+ .fill(window_hor.clone());
+ // chapel Ropefix1
+ painter
+ .cylinder(Aabb {
+ min: (center - 2).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 3),
+ max: (center + 2).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 2),
+ })
+ .fill(ropefix1.clone());
+ // chapel Ropefix2
+ painter
+ .cylinder(Aabb {
+ min: (center).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 4),
+ max: (center + 1).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 3),
+ })
+ .fill(ropefix2.clone());
+ // chapel rope
+ painter
+ .cylinder(Aabb {
+ min: (center).with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ max: (center + 1).with_z(base - (diameter / 8) + diameter + (diameter / 3) - 4),
+ })
+ .fill(rope.clone());
+ // chapel floor1 to cellar1 tube (access to dagons room)
+ let t_center = Vec2::new(center.x + (diameter / 4) + 2, center.y + (diameter / 4) + 4);
+ painter
+ .cylinder(Aabb {
+ min: (t_center - 2).with_z(base - (diameter / 8)),
+ max: (t_center + 2).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: (t_center - 1).with_z(base - (diameter / 8)),
+ max: (t_center + 1).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ })
+ .clear();
+ painter
+ .cylinder(Aabb {
+ min: (t_center - 1).with_z(base - (diameter / 8) + (diameter / 2) + 1),
+ max: (t_center + 1).with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ })
+ .fill(glass_barrier.clone());
+ // chapel cellar2 water
+ painter
+ .cylinder(Aabb {
+ min: (center - 5).with_z(base - (2 * (diameter / 3)) + 1),
+ max: (center + 5).with_z(base - (2 * (diameter / 3)) + 2),
+ })
+ .fill(water.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - 11).with_z(base - (2 * (diameter / 3)) + 2),
+ max: (center + 11).with_z(base - (2 * (diameter / 3)) + 3),
+ })
+ .fill(water.clone());
+ // chapel cellar to basin glass barrier barricade downwards & miniboss
+ // cellar floor
+ painter
+ .cylinder(Aabb {
+ min: (center - (2 * (diameter / 3))).with_z(base - (2 * (diameter / 3)) + 10),
+ max: (center + (2 * (diameter / 3))).with_z(base - (2 * (diameter / 3)) + 16),
+ })
+ .fill(white_coral.clone());
+ // exit to water basin
+ let exit = Fill::Sampling(Arc::new(|center| {
+ let c = RandomField::new(0).get(center - 6) % 11;
+ Some(if c < 8 {
+ let c = c as u8 * 10 + 120;
+ Block::new(BlockKind::Rock, Rgb::new(c, c, c))
+ } else {
+ Block::air(SpriteKind::GlassBarrier)
+ })
+ }));
+ // glass barriers with center clearance for dagon
+ painter
+ .cylinder(Aabb {
+ min: (center - 9).with_z(base - (2 * (diameter / 3)) + 10),
+ max: (center + 9).with_z(base - (2 * (diameter / 3)) + 16),
+ })
+ .fill(glass_barrier.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - 9).with_z(base - (2 * (diameter / 3)) + 13),
+ max: (center + 9).with_z(base - (2 * (diameter / 3)) + 14),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (center - 8).with_z(base - (2 * (diameter / 3)) + 13),
+ max: (center + 8).with_z(base - (2 * (diameter / 3)) + 14),
+ }))
+ .fill(exit);
+ painter
+ .cylinder(Aabb {
+ min: (center - 8).with_z(base - (2 * (diameter / 3)) + 14),
+ max: (center + 8).with_z(base - (2 * (diameter / 3)) + 16),
+ })
+ .clear();
+ painter
+ .cylinder(Aabb {
+ min: (center - 8).with_z(base - (2 * (diameter / 3)) + 10),
+ max: (center + 8).with_z(base - (2 * (diameter / 3)) + 14),
+ })
+ .fill(white_coral);
+ let cellar_miniboss_pos = center.with_z(base - (2 * (diameter / 3)) + 17);
+ painter.spawn(
+ EntityInfo::at(cellar_miniboss_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.dagon", &mut rng),
+ );
+ // cellar 2 sea crocodiles
+ let cellar_sea_croc_pos = (center - 12).with_z(base - (2 * (diameter / 3)) + 8);
+ for _ in 0..(3 + ((RandomField::new(0).get((cellar_sea_croc_pos).with_z(base))) % 5)) {
+ painter.spawn(
+ EntityInfo::at(cellar_sea_croc_pos.as_())
+ .with_asset_expect("common.entity.wild.aggressive.sea_crocodile", &mut rng),
+ )
+ }
+ // water basin
+ painter
+ .sphere(Aabb {
+ min: (center - diameter + (diameter / 5) + 1).with_z(base - (4 * diameter / 3)),
+ max: (center + diameter - (diameter / 5) - 1).with_z(base + 1),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (center - diameter + (diameter / 5) + 1).with_z(base - (2 * diameter / 3) + 1),
+ max: (center + diameter - (diameter / 5) - 1).with_z(base + 1),
+ }))
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: (center - diameter + (diameter / 5) + 2).with_z(base - (4 * diameter / 3) + 1),
+ max: (center + diameter - (diameter / 5) - 2).with_z(base + 1),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (center - diameter + (diameter / 5) + 2).with_z(base - (2 * diameter / 3) + 1),
+ max: (center + diameter - (diameter / 5) - 2).with_z(base + 1),
+ }))
+ .fill(water.clone());
+ // stairway1 bottom
+ painter
+ .sphere(Aabb {
+ min: (center_s1 - (diameter / 4))
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 2)),
+ max: (center_s1 + (diameter / 4)).with_z(base - (2 * (diameter / 3)) + 3),
+ })
+ .fill(white.clone());
+ // stairway1 bottom gold ring
+ painter
+ .cylinder(Aabb {
+ min: (center_s1 - (diameter / 4))
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 4)),
+ max: (center_s1 + (diameter / 4))
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 4) + 1),
+ })
+ .fill(gold.clone());
+ painter
+ .sphere(Aabb {
+ min: (center_s1 - (diameter / 4) + 1)
+ .with_z(base - (2 * (diameter / 3)) + 4 - (diameter / 2)),
+ max: (center_s1 + (diameter / 4) - 1).with_z(base - (2 * (diameter / 3)) + 2),
+ })
+ .clear();
+ // stairway1 bottom clear entry
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s1.x - 5,
+ center_s1.y - 5,
+ base - (2 * (diameter / 3)) + 1,
+ ),
+ max: Vec3::new(
+ center_s1.x + 5,
+ center_s1.y + 5,
+ base - (2 * (diameter / 3)) + 2,
+ ),
+ })
+ .clear();
+ // stairway1 bottom window to basin
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s1.x - 4,
+ center_s1.y - 4,
+ base - (2 * (diameter / 3)) + 4 - (diameter / 2),
+ ),
+ max: Vec3::new(
+ center_s1.x + 4,
+ center_s1.y + 4,
+ base - (2 * (diameter / 3)) + 5 - (diameter / 2),
+ ),
+ })
+ .fill(window_hor);
+ // stairway1 tube
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s1.x - 5,
+ center_s1.y - 5,
+ base - (2 * (diameter / 3)) + 1,
+ ),
+ max: Vec3::new(
+ center_s1.x + 5,
+ center_s1.y + 5,
+ base - (diameter / 8) + diameter - (diameter / 8),
+ ),
+ })
+ .fill(white.clone());
+
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s1.x - 4,
+ center_s1.y - 4,
+ base - (2 * (diameter / 3)) + 1,
+ ),
+ max: Vec3::new(
+ center_s1.x + 4,
+ center_s1.y + 4,
+ base - (diameter / 8) + diameter - (diameter / 8),
+ ),
+ })
+ .clear();
+ // stairway1 tube window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(center_s1.x - 5, center_s1.y - 1, base + (diameter / 6)),
+ max: Vec3::new(
+ center_s1.x - 4,
+ center_s1.y + 1,
+ base - (diameter / 8) + diameter - (diameter / 4) + 1,
+ ),
+ })
+ .fill(window_ver2.clone());
+
+ // stairway1 stairs
+ let stair_radius1 = 4.5;
+ let stairs_clear1 = painter.cylinder(Aabb {
+ min: (center_s1 - stair_radius1 as i32)
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 2)),
+ max: (center_s1 + stair_radius1 as i32)
+ .with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ });
+ stairs_clear1
+ .sample(spiral_staircase(
+ center_s1.with_z(base - (diameter / 8) + diameter - (diameter / 8)),
+ stair_radius1,
+ 0.5,
+ 7.0,
+ ))
+ .fill(white.clone());
+ // coral chest podium
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s1.x,
+ center_s1.y - 2,
+ base - (2 * (diameter / 3)) - (diameter / 2) + 12,
+ ),
+ max: Vec3::new(
+ center_s1.x + 1,
+ center_s1.y - 1,
+ base - (2 * (diameter / 3)) - (diameter / 2) + 13,
+ ),
+ })
+ .fill(gold_decor.clone());
+ // coral chest
+ painter.rotated_sprite(
+ Vec3::new(
+ center_s1.x,
+ center_s1.y - 2,
+ base - (2 * (diameter / 3)) - (diameter / 2) + 13,
+ ),
+ SpriteKind::CoralChest,
+ 2,
+ );
+ // cardinals room next to stairway1 bottom
+ let cr_center = Vec2::new(center.x - diameter - 3, center.y - (diameter / 5) + 1);
+ painter
+ .cylinder(Aabb {
+ min: (cr_center - (diameter / 3))
+ .with_z(base - (2 * (diameter / 3)) - (diameter / 4) - 5),
+ max: (cr_center + (diameter / 3)).with_z(base - (2 * (diameter / 3)) + 3),
+ })
+ .fill(white.clone());
+ // cardinals room gold ring
+ painter
+ .cylinder(Aabb {
+ min: (cr_center - (diameter / 3))
+ .with_z(base - (2 * (diameter / 3)) - (diameter / 4) + 3),
+ max: (cr_center + (diameter / 3))
+ .with_z(base - (2 * (diameter / 3)) - (diameter / 4) + 4),
+ })
+ .fill(gold.clone());
+ // clear cardinals room
+ painter
+ .cylinder(Aabb {
+ min: (cr_center - (diameter / 3) + 1)
+ .with_z(base - (2 * (diameter / 3)) - (diameter / 4) - 4),
+ max: (cr_center + (diameter / 3) - 1).with_z(base - (2 * (diameter / 3)) + 2),
+ })
+ .clear();
+ // Cardinals room chamber mobile1
+ painter
+ .cone(Aabb {
+ min: (cr_center - 2).with_z(base - (2 * (diameter / 3)) - 7),
+ max: (cr_center + 3).with_z(base - (2 * (diameter / 3)) - 5),
+ })
+ .fill(top.clone());
+ painter
+ .cylinder(Aabb {
+ min: (cr_center - 2).with_z(base - (2 * (diameter / 3)) - 8),
+ max: (cr_center + 3).with_z(base - (2 * (diameter / 3)) - 7),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: (cr_center - 1).with_z(base - (2 * (diameter / 3)) - 8),
+ max: (cr_center + 2).with_z(base - (2 * (diameter / 3)) - 7),
+ })
+ .clear();
+ // Cardinals room mobile1 chain
+ painter
+ .aabb(Aabb {
+ min: cr_center.with_z(base - (2 * (diameter / 3)) - 5),
+ max: (cr_center + 1).with_z(base - (2 * (diameter / 3)) + 2),
+ })
+ .fill(gold_chain.clone());
+ // passage from stairway1 bottom to cardinals room
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ cr_center.x + (diameter / 3),
+ cr_center.y - 3,
+ base - (2 * (diameter / 3)) - (diameter / 4),
+ ),
+ max: Vec3::new(
+ cr_center.x + (diameter / 3) + 5,
+ cr_center.y + 3,
+ base - (2 * (diameter / 3)) - (diameter / 4) + 5,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ cr_center.x + (diameter / 3),
+ cr_center.y - 2,
+ base - (2 * (diameter / 3)) - (diameter / 4) - 1,
+ ),
+ max: Vec3::new(
+ cr_center.x + (diameter / 3) + 5,
+ cr_center.y + 2,
+ base - (2 * (diameter / 3)) - (diameter / 4) + 6,
+ ),
+ })
+ .fill(white.clone());
+ // passage from stairway1 bottom to cardinals room gold stripes
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ cr_center.x + (diameter / 3),
+ cr_center.y - 3,
+ base - (2 * (diameter / 3)) - (diameter / 4) + 3,
+ ),
+ max: Vec3::new(
+ cr_center.x + (diameter / 3) + 5,
+ cr_center.y + 3,
+ base - (2 * (diameter / 3)) - (diameter / 4) + 4,
+ ),
+ })
+ .fill(gold.clone());
+ // clear passage from stairway1 bottom to cardinals room
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ cr_center.x + (diameter / 3) - 1,
+ cr_center.y - 2,
+ base - (2 * (diameter / 3)) - (diameter / 4),
+ ),
+ max: Vec3::new(
+ cr_center.x + (diameter / 3) + 6,
+ cr_center.y + 2,
+ base - (2 * (diameter / 3)) - (diameter / 4) + 5,
+ ),
+ })
+ .clear();
+ // Cardinals room Sea Clerics
+ let cr_sea_clerics_pos =
+ (cr_center - 2).with_z(base - (2 * (diameter / 3)) - (diameter / 4) - 4);
+ for _ in 0..(2 + ((RandomField::new(0).get((fl2_sea_clerics_pos).with_z(base))) % 3)) {
+ painter.spawn(
+ EntityInfo::at(cr_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ )
+ }
+ // Cardinal
+ let cr_cardinal_pos =
+ (cr_center + 2).with_z(base - (2 * (diameter / 3)) - (diameter / 4) - 4);
+ painter.spawn(
+ EntityInfo::at(cr_cardinal_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.cardinal", &mut rng),
+ );
+ // stairway2 bottom
+ painter
+ .sphere(Aabb {
+ min: (center_s2 - (diameter / 4))
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 2)),
+ max: (center_s2 + (diameter / 4)).with_z(base - (2 * (diameter / 3)) + 3),
+ })
+ .fill(white.clone());
+ // stairway2 bottom gold ring
+ painter
+ .cylinder(Aabb {
+ min: (center_s2 - (diameter / 4))
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 4)),
+ max: (center_s2 + (diameter / 4))
+ .with_z(base - (2 * (diameter / 3)) + 3 - (diameter / 4) + 1),
+ })
+ .fill(gold.clone());
+ painter
+ .sphere(Aabb {
+ min: (center_s2 - (diameter / 4) + 1)
+ .with_z(base - (2 * (diameter / 3)) + 4 - (diameter / 2)),
+ max: (center_s2 + (diameter / 4) - 1).with_z(base - (2 * (diameter / 3)) + 2),
+ })
+ .fill(water.clone());
+ // stairway2 bottom clear entry
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s2.x - 5,
+ center_s2.y - 5,
+ base - (2 * (diameter / 3)) + 1,
+ ),
+ max: Vec3::new(
+ center_s2.x + 5,
+ center_s2.y + 5,
+ base - (2 * (diameter / 3)) + 2,
+ ),
+ })
+ .clear();
+ // stairway2 bottom water to basin
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s2.x - 4,
+ center_s2.y - 4,
+ base - (2 * (diameter / 3)) + 4 - (diameter / 2),
+ ),
+ max: Vec3::new(
+ center_s2.x + 4,
+ center_s2.y + 4,
+ base - (2 * (diameter / 3)) + 5 - (diameter / 2),
+ ),
+ })
+ .fill(water.clone());
+ // stairway2 tube
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s2.x - 5,
+ center_s2.y - 5,
+ base - (2 * (diameter / 3)) + 1,
+ ),
+ max: Vec3::new(
+ center_s2.x + 5,
+ center_s2.y + 5,
+ base - (diameter / 8) + diameter + 2,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(
+ center_s2.x - 4,
+ center_s2.y - 4,
+ base - (2 * (diameter / 3)) + 1,
+ ),
+ max: Vec3::new(
+ center_s2.x + 4,
+ center_s2.y + 4,
+ base - (diameter / 8) + diameter + 2,
+ ),
+ })
+ .clear();
+ // stairway2 tube window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center_s2.x + 4,
+ center_s2.y - 1,
+ base + (diameter / 8) + (diameter / 2),
+ ),
+ max: Vec3::new(
+ center_s2.x + 5,
+ center_s2.y + 1,
+ base - (diameter / 8) + diameter - 4,
+ ),
+ })
+ .fill(window_ver2.clone());
+ // coral chest
+ painter.rotated_sprite(
+ Vec3::new(
+ center_s2.x - 5,
+ center_s2.y - 4,
+ base - (2 * (diameter / 3)) - (diameter / 2) + 11,
+ ),
+ SpriteKind::DungeonChest1,
+ 2,
+ );
+ // bottom 2 sea crocodiles
+ let bt_sea_croc_pos = center_s2.with_z(base - (2 * (diameter / 3)) - (diameter / 2) + 11);
+ for _ in 0..(2 + ((RandomField::new(0).get((bt_sea_croc_pos).with_z(base))) % 3)) {
+ painter.spawn(
+ EntityInfo::at(bt_sea_croc_pos.as_())
+ .with_asset_expect("common.entity.wild.aggressive.sea_crocodile", &mut rng),
+ )
+ }
+ // underwater chamber
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 3)).with_z(base - (4 * diameter / 3) - (diameter / 6)),
+ max: (center + (diameter / 3)).with_z(base - (2 * diameter / 3) - (diameter / 6)),
+ })
+ .without(
+ painter.sphere(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (4 * diameter / 3) - (diameter / 6) + 1),
+ max: (center + (diameter / 3) - 1)
+ .with_z(base - (2 * diameter / 3) - (diameter / 6) - 1),
+ }),
+ )
+ .fill(white.clone());
+ // underwater chamber entries
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 3),
+ center.y - 2,
+ base - (3 * diameter / 3) - (diameter / 3) + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 3),
+ center.y + 2,
+ base - (3 * diameter / 3) - (diameter / 6) - 2,
+ ),
+ })
+ .fill(water.clone());
+ // underwater chamber entries
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 3),
+ center.y - 1,
+ base - (3 * diameter / 3) - (diameter / 6) - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 3),
+ center.y + 1,
+ base - (3 * diameter / 3) - (diameter / 6) - 1,
+ ),
+ })
+ .fill(water.clone());
+ // underwater chamber gold ring white floor
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 3)).with_z(base - (3 * diameter / 3) - (diameter / 6)),
+ max: (center + (diameter / 3))
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 1),
+ })
+ .fill(gold.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (3 * diameter / 3) - (diameter / 6)),
+ max: (center + (diameter / 3) - 1)
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 1),
+ })
+ .fill(white.clone());
+ // underwater chamber floor entry
+ painter
+ .cylinder(Aabb {
+ min: (center - 2).with_z(base - (3 * diameter / 3) - (diameter / 6)),
+ max: (center + 2).with_z(base - (3 * diameter / 3) - (diameter / 6) + 1),
+ })
+ .fill(water.clone());
+ // fill underwater chamber halfway with air
+ painter
+ .sphere(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (4 * diameter / 3) - (diameter / 6) + 1),
+ max: (center + (diameter / 3) - 1)
+ .with_z(base - (2 * diameter / 3) - (diameter / 6) - 1),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (center - (diameter / 3) + 1)
+ .with_z(base - (4 * diameter / 3) - (diameter / 6) + 1),
+ max: (center + (diameter / 3) - 1)
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 1),
+ }),
+ )
+ .clear();
+ // chapel underwater chamber mobile1
+ painter
+ .cone(Aabb {
+ min: (center - 2).with_z(base - (2 * diameter / 3) - (diameter / 6) - 7),
+ max: (center + 3).with_z(base - (2 * diameter / 3) - (diameter / 6) - 5),
+ })
+ .fill(top.clone());
+ painter
+ .cylinder(Aabb {
+ min: (center - 2).with_z(base - (2 * diameter / 3) - (diameter / 6) - 8),
+ max: (center + 3).with_z(base - (2 * diameter / 3) - (diameter / 6) - 7),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: (center - 1).with_z(base - (2 * diameter / 3) - (diameter / 6) - 8),
+ max: (center + 2).with_z(base - (2 * diameter / 3) - (diameter / 6) - 7),
+ })
+ .clear();
+ // chapel underwater chamber mobile1 chain
+ painter
+ .aabb(Aabb {
+ min: center.with_z(base - (2 * diameter / 3) - (diameter / 6) - 5),
+ max: (center + 1).with_z(base - (2 * diameter / 3) - (diameter / 6) - 1),
+ })
+ .fill(gold_chain);
+ // underwater chamber coral chest
+ painter
+ .cylinder(Aabb {
+ min: (center - (diameter / 6) - 1)
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 1),
+ max: (center - (diameter / 6) + 3)
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 2),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: (center - (diameter / 6))
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 1),
+ max: (center - (diameter / 6) + 2)
+ .with_z(base - (3 * diameter / 3) - (diameter / 6) + 2),
+ })
+ .fill(white.clone());
+ // coral chest
+ painter.rotated_sprite(
+ (center - (diameter / 6)).with_z(base - (3 * diameter / 3) - (diameter / 6) + 2),
+ SpriteKind::CoralChest,
+ 2,
+ );
+ // underwater chamber sea crocodiles & sea clerics
+ let uwc_sea_croc_pos =
+ (center + (diameter / 8)).with_z(base - (3 * diameter / 3) - (diameter / 6) + 2);
+ for _ in 0..(3 + ((RandomField::new(0).get((uwc_sea_croc_pos).with_z(base))) % 5)) {
+ painter.spawn(
+ EntityInfo::at(uwc_sea_croc_pos.as_())
+ .with_asset_expect("common.entity.wild.aggressive.sea_crocodile", &mut rng),
+ )
+ }
+ let uwc_sea_clerics_pos =
+ (center + (diameter / 7)).with_z(base - (3 * diameter / 3) - (diameter / 6) + 2);
+ for _ in 0..(2 + ((RandomField::new(0).get((uwc_sea_clerics_pos).with_z(base))) % 2)) {
+ painter.spawn(
+ EntityInfo::at(uwc_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ );
+ }
+ // Holding Cell2
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8) - 1,
+ center.y + (diameter / 16) - 1,
+ base - (diameter / 4) - 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + (diameter / 8) + 1,
+ center.y + (diameter / 16) + (diameter / 4) + 1,
+ base,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8),
+ center.y + (diameter / 16),
+ base - (diameter / 8),
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + (diameter / 8),
+ center.y + (diameter / 16) + (diameter / 4),
+ base - (diameter / 8) + (diameter / 4),
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8) + 1,
+ center.y + (diameter / 16) - 1,
+ base - (diameter / 8) + 1,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) + (diameter / 8) - 1,
+ center.y + (diameter / 16) + (diameter / 4) + 1,
+ base - (diameter / 8) + (diameter / 4) - 1,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8) - 3,
+ center.y + (diameter / 16) + (diameter / 8) - 1,
+ base - (diameter / 8) + (diameter / 16) + 2,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8) + 1,
+ center.y + (diameter / 16) + (diameter / 4) - (diameter / 8) + 1,
+ base - (diameter / 8) + (diameter / 4) - (diameter / 16) - 2,
+ ),
+ })
+ .clear();
+ painter.sprite(
+ Vec3::new(
+ center.x - (diameter / 2) - (diameter / 16) + 4,
+ center.y + (diameter / 6) - 1,
+ base - (diameter / 8) + (diameter / 16) - 1,
+ ),
+ SpriteKind::DungeonChest1,
+ );
+ // Holding Cell2 glass barriers
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8),
+ center.y + (diameter / 16) + (diameter / 8) - 1,
+ base - (diameter / 8) + (diameter / 16) + 3,
+ ),
+ max: Vec3::new(
+ center.x - (diameter / 2) - (diameter / 8) + 1,
+ center.y + (diameter / 16) + (diameter / 4) - (diameter / 8) + 1,
+ base - (diameter / 8) + (diameter / 4) - (diameter / 16) - 3,
+ ),
+ })
+ .fill(glass_barrier.clone());
+ // Holding Cell3
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - (diameter / 8) - 1,
+ center.y - (diameter / 4) - (diameter / 16) - 1,
+ base - (diameter / 4) - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8) + 1,
+ center.y - (diameter / 16) + 1,
+ base,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - (diameter / 8),
+ center.y - (diameter / 4) - (diameter / 16),
+ base - (diameter / 8),
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8),
+ center.y - (diameter / 16),
+ base - (diameter / 8) + (diameter / 4),
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) - (diameter / 8) + 1,
+ center.y - (diameter / 4) - (diameter / 16) + 1,
+ base - (diameter / 8) + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8) - 1,
+ center.y - (diameter / 16) - 1,
+ base - (diameter / 8) + (diameter / 4) - 1,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8) - 1,
+ center.y - (diameter / 4) - (diameter / 16) + (diameter / 8) - 1,
+ base - (diameter / 8) + (diameter / 16) + 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8) + 3,
+ center.y - (diameter / 16) - (diameter / 8) + 1,
+ base - (diameter / 8) + (diameter / 4) - (diameter / 16) - 2,
+ ),
+ })
+ .clear();
+ painter.sprite(
+ Vec3::new(
+ center.x + (diameter / 2),
+ center.y - (diameter / 8) - (diameter / 16),
+ base - (diameter / 8) + 2,
+ ),
+ SpriteKind::DungeonChest1,
+ );
+ // Holding Cell3 glass barriers
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8) - 1,
+ center.y - (diameter / 4) - (diameter / 16) + (diameter / 8) - 1,
+ base - (diameter / 8) + (diameter / 16) + 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 2) + (diameter / 8),
+ center.y - (diameter / 16) - (diameter / 8) + 1,
+ base - (diameter / 8) + (diameter / 16) + 4,
+ ),
+ })
+ .fill(glass_barrier.clone());
+ // Holding Cell1
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 4),
+ center.y - (diameter / 2) - (diameter / 4),
+ base - (diameter / 4),
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 4),
+ center.y - (diameter / 2) + (diameter / 4),
+ base - (diameter / 4) + (diameter / 2),
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 4) + 1,
+ center.y - (diameter / 2) - (diameter / 4) + 1,
+ base - (diameter / 4) + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 4 - 1),
+ center.y - (diameter / 2) + (diameter / 4) - 1,
+ base - (diameter / 4) + (diameter / 2) - 1,
+ ),
+ })
+ .without(painter.cylinder(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 4) + 1,
+ center.y - (diameter / 2) - (diameter / 4) + 1,
+ base - (diameter / 4) + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 4 - 1),
+ center.y - (diameter / 2) + (diameter / 4) - 1,
+ base - 1,
+ ),
+ }))
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16),
+ center.y - (diameter / 2) - (diameter / 4) - 3,
+ base,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16),
+ center.y - (diameter / 2) - (diameter / 4) + 1,
+ base + 3,
+ ),
+ })
+ .clear();
+ // Holding Cell1 windows
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16),
+ center.y - (diameter / 2) - (diameter / 4),
+ base,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16),
+ center.y - (diameter / 2) - (diameter / 4) + 1,
+ base + 3,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y - (diameter / 2) - (diameter / 4),
+ base + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y - (diameter / 2) - (diameter / 4) + 1,
+ base + 2,
+ ),
+ })
+ .fill(window_ver.clone());
+ // chapel main room pulpit stairs1
+ painter
+ .ramp(
+ Aabb {
+ min: Vec3::new(center.x - 8, center.y - (diameter / 4) - 2, base - 3),
+ max: Vec3::new(center.x - 3, center.y - (diameter / 4) + 7, base + 2),
+ },
+ 5,
+ Dir::X,
+ )
+ .fill(white.clone());
+ // chapel main room pulpit stairs2
+ painter
+ .ramp(
+ Aabb {
+ min: Vec3::new(center.x + 3, center.y - (diameter / 4) - 2, base - 3),
+ max: Vec3::new(center.x + 8, center.y - (diameter / 4) + 7, base + 2),
+ },
+ 5,
+ Dir::NegX,
+ )
+ .fill(white.clone());
+ // chapel main room pulpit stairs2
+ painter
+ .ramp(
+ Aabb {
+ min: Vec3::new(center.x - 8, center.y + (diameter / 4) - 7, base - 3),
+ max: Vec3::new(center.x - 3, center.y + (diameter / 4) + 2, base + 2),
+ },
+ 5,
+ Dir::X,
+ )
+ .fill(white.clone());
+ // chapel main room pulpit stairs4
+ painter
+ .ramp(
+ Aabb {
+ min: Vec3::new(center.x + 3, center.y + (diameter / 4) - 7, base - 3),
+ max: Vec3::new(center.x + 8, center.y + (diameter / 4) + 2, base + 2),
+ },
+ 5,
+ Dir::NegX,
+ )
+ .fill(white.clone());
+ // Holding Cell1 passage to main room
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16),
+ center.y - (diameter / 3) + 3,
+ base - 4,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16),
+ center.y - (diameter / 20) - 1,
+ base + 3,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y - (diameter / 3) + 3,
+ base - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y - (diameter / 20) - 1,
+ base,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y - (diameter / 3),
+ base - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y - (diameter / 20) - 1,
+ base,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 2,
+ center.y - (diameter / 3) + 3,
+ base,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 2,
+ center.y - (diameter / 20) - 1,
+ base + 1,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y - (diameter / 3) + 3,
+ base - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y - (diameter / 3) + 4,
+ base + 1,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 2,
+ center.y - (diameter / 3) + 3,
+ base - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 2,
+ center.y - (diameter / 3) + 4,
+ base,
+ ),
+ })
+ .fill(window_ver.clone());
+ // holding cell1 coral chest
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x,
+ center.y - (diameter / 2) - (diameter / 4) + 7,
+ base - 1,
+ ),
+ max: Vec3::new(
+ center.x + 1,
+ center.y - (diameter / 2) - (diameter / 4) + 8,
+ base,
+ ),
+ })
+ .fill(gold_decor.clone());
+ painter.rotated_sprite(
+ Vec3::new(
+ center.x,
+ center.y - (diameter / 2) - (diameter / 4) + 7,
+ base,
+ ),
+ SpriteKind::CoralChest,
+ 0,
+ );
+
+ // Holding Cell1 Sea Clerics
+ let hc1_sea_clerics_pos = Vec3::new(center.x, center.y - (diameter / 3), base + 3);
+ for _ in 0..(3 + ((RandomField::new(0).get((hc1_sea_clerics_pos).with_z(base))) % 3)) {
+ painter.spawn(
+ EntityInfo::at(hc1_sea_clerics_pos.as_())
+ .with_asset_expect("common.entity.dungeon.sea_chapel.sea_cleric", &mut rng),
+ );
+ }
+ // Holding Cell
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 4),
+ center.y + (diameter / 2) - (diameter / 4),
+ base - (diameter / 4),
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 4),
+ center.y + (diameter / 2) + (diameter / 4),
+ base - (diameter / 4) + (diameter / 2),
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .sphere(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 4) + 1,
+ center.y + (diameter / 2) - (diameter / 4) + 1,
+ base - (diameter / 4) + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 4 - 1),
+ center.y + (diameter / 2) + (diameter / 4) - 1,
+ base - (diameter / 4) + (diameter / 2) - 1,
+ ),
+ })
+ .without(painter.cylinder(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 4) + 1,
+ center.y + (diameter / 2) - (diameter / 4) + 1,
+ base - (diameter / 4) + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 4 - 1),
+ center.y + (diameter / 2) + (diameter / 4) - 1,
+ base - 1,
+ ),
+ }))
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16),
+ center.y + (diameter / 2) + (diameter / 4) - 1,
+ base,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16),
+ center.y + (diameter / 2) + (diameter / 4) + 3,
+ base + 3,
+ ),
+ })
+ .clear();
+ // Holding Cell glass barriers
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16),
+ center.y + (diameter / 2) + (diameter / 4) - 2,
+ base + 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16),
+ center.y + (diameter / 2) + (diameter / 4) - 1,
+ base + 2,
+ ),
+ })
+ .fill(glass_barrier.clone());
+ // Holding Cell passage to main room
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16),
+ center.y + (diameter / 20) + 1,
+ base - 4,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16),
+ center.y + (diameter / 3) - 3,
+ base + 3,
+ ),
+ })
+ .fill(white.clone());
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y + (diameter / 20) + 1,
+ base - 3,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y + (diameter / 3) - 3,
+ base,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y + (diameter / 20) + 1,
+ base - 2,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y + (diameter / 3) - 1,
+ base,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 2,
+ center.y + (diameter / 20) + 1,
+ base,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 2,
+ center.y + (diameter / 3) - 3,
+ base + 1,
+ ),
+ })
+ .clear();
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ center.x - (diameter / 16) + 1,
+ center.y + (diameter / 3) - 4,
+ base - 1,
+ ),
+ max: Vec3::new(
+ center.x + (diameter / 16) - 1,
+ center.y + (diameter / 3) - 3,
+ base,
+ ),
+ })
+ .fill(glass_barrier.clone());
+ // Holding Cell Villagers
+ let hc_villagers_pos = Vec3::new(center.x, center.y + (diameter / 3), base + 3);
+ for _ in 0..(5 + ((RandomField::new(0).get((hc_villagers_pos).with_z(base))) % 5)) {
+ painter.spawn(
+ EntityInfo::at(hc_villagers_pos.as_())
+ .with_asset_expect("common.entity.village.villager", &mut rng),
+ );
+ }
+ // stairway3 tube
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(center_s3.x - 5, center_s3.y - 5, base + (diameter / 4)),
+ max: Vec3::new(
+ center_s3.x + 5,
+ center_s3.y + 5,
+ base - (diameter / 8) + (diameter / 2) + 2,
+ ),
+ })
+ .fill(white.clone());
+
+ painter
+ .cylinder(Aabb {
+ min: Vec3::new(center_s3.x - 4, center_s3.y - 4, base + 2),
+ max: Vec3::new(
+ center_s3.x + 4,
+ center_s3.y + 4,
+ base - (diameter / 8) + (diameter / 2) + 2,
+ ),
+ })
+ .clear();
+ // stairway3 tube window1
+ painter
+ .aabb(Aabb {
+ min: Vec3::new(center_s3.x - 1, center_s3.y - 5, base + (diameter / 4) + 1),
+ max: Vec3::new(
+ center_s3.x + 1,
+ center_s3.y - 4,
+ base - (diameter / 8) + (diameter / 2) - 2,
+ ),
+ })
+ .fill(window_ver.clone());
+
+ // stairway3 stairs
+ let stair_radius3 = 4.5;
+ let stairs_clear3 = painter.cylinder(Aabb {
+ min: (center_s3 - stair_radius3 as i32).with_z(base - 1),
+ max: (center_s3 + stair_radius3 as i32)
+ .with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ });
+ stairs_clear3
+ .sample(spiral_staircase(
+ center_s3.with_z(base - (diameter / 8) + (diameter / 2) + 2),
+ stair_radius3,
+ 0.5,
+ 7.0,
+ ))
+ .fill(white.clone());
+ // stairway4
+ let center_s4 = Vec2::new(center.x + (diameter / 2) + 2, center.y + (diameter / 8));
+ // stairway4 balcony2 entry
+ painter
+ .cylinder(Aabb {
+ min: (center_s4 - 2).with_z(base - (diameter / 8) + (diameter / 2) - 7),
+ max: (center_s4 + 3).with_z(base - (diameter / 8) + (diameter / 2) - 5),
+ })
+ .clear();
+ // stairway4 stairs
+ let stair_radius4 = 3.0;
+ let stairs_clear4 = painter.cylinder(Aabb {
+ min: (center_s4 - stair_radius4 as i32).with_z(base - (diameter / 8) - 4),
+ max: (center_s4 + stair_radius4 as i32)
+ .with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ });
+ stairs_clear4
+ .sample(spiral_staircase(
+ center_s4.with_z(base - (diameter / 8) + (diameter / 2) - 4),
+ stair_radius4,
+ 0.5,
+ 7.0,
+ ))
+ .fill(white.clone());
+ // entry lanterns
+ for dir in SQUARE_4 {
+ let sq_corner = Vec2::new(center.x - (diameter / 2) + 3, center.y - 5);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.x * (diameter - 7)),
+ sq_corner.y + (dir.y * 9),
+ base + 5,
+ );
+ painter.sprite(pos, SpriteKind::SeashellLantern);
+ }
+ // main room lanterns
+ for dir in SQUARE_4 {
+ let sq_corner = Vec2::new(center.x - 4, center.y - (diameter / 2) + 5);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.y * 7),
+ sq_corner.y + (dir.x * (diameter - 10)),
+ base + 12,
+ );
+ painter.sprite(pos, SpriteKind::SeashellLantern);
+ }
+ // first floor lanterns
+ for dir in SQUARE_4 {
+ for d in 0..2 {
+ let sq_corner = Vec2::new(center.x - 3 - d, center.y - (diameter / 8) - 2 - d);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.y * (5 + (2 * d))),
+ sq_corner.y + (dir.x * ((diameter / 4) + 2 + (2 * d))),
+ base - (diameter / 8) + (diameter / 2) + 2,
+ );
+ painter.sprite(pos, SpriteKind::SeashellLantern);
+ }
+ }
+ // small floor lanterns
+ for dir in SQUARE_4 {
+ for d in 0..2 {
+ let sq_corner = Vec2::new(center.x - 3 - d, center.y - (diameter / 8) - 2 - d);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.y * (5 + (2 * d))),
+ sq_corner.y + (dir.x * ((diameter / 4) + 2 + (2 * d))),
+ base + diameter - (diameter / 4) + 1,
+ );
+ painter.sprite(pos, SpriteKind::SeashellLantern);
+ }
+ }
+
+ // top floor lanterns
+ for dir in SQUARE_4 {
+ for d in 0..2 {
+ let sq_corner = Vec2::new(center.x - 3 - d, center.y - (diameter / 8) - 2 - d);
+ let pos = Vec3::new(
+ sq_corner.x + (dir.y * (5 + (2 * d))),
+ sq_corner.y + (dir.x * ((diameter / 4) + 2 + (2 * d))),
+ base - (diameter / 8) + diameter + 2,
+ );
+ painter.sprite(pos, SpriteKind::SeashellLantern);
+ }
+ }
+ // main room emblems 1
+ for d in 0..2 {
+ let emblem_pos = Vec3::new(
+ center.x - d,
+ center.y + (diameter / 3) + 6 - (d * (2 * (diameter / 3) + 10)),
+ base + (diameter / 4) + 1,
+ );
+ painter.rotated_sprite(emblem_pos, SpriteKind::SeaDecorEmblem, 4 - (4 * d) as u8);
+ }
+ // main room emblems 2
+ for d in 0..2 {
+ let emblem_pos = Vec3::new(
+ center.x - (diameter / 3) - 7 + (d * (2 * (diameter / 3) + 13)),
+ center.y - d,
+ base + (diameter / 4) + 1,
+ );
+ painter.rotated_sprite(emblem_pos, SpriteKind::SeaDecorEmblem, 6 - (4 * d) as u8);
+ }
+ // first floor emblems / top floor emblems
+ for d in 0..2 {
+ for e in 0..2 {
+ let emblem_pos = Vec3::new(
+ center.x - d,
+ center.y - (diameter / 8) - 4 + (d * ((diameter / 4) + 6)),
+ base + (diameter / 2) + 1 + (e * (diameter / 2)),
+ );
+ painter.rotated_sprite(emblem_pos, SpriteKind::SeaDecorEmblem, 4 - (4 * d) as u8);
+ }
+ }
+
+ // side buildings hut, pavillon, tower
+ let bldg_corner = center - (diameter / 2);
+ for dir in SQUARE_4 {
+ let bldg_center = bldg_corner + dir * diameter;
+ let bldg_variant = (RandomField::new(0).get((bldg_corner - dir).with_z(base))) % 10;
+ let tower_height = (diameter / 4) + (3 * (bldg_variant as i32));
+ let bldg_diameter = diameter;
+ let bldg_cellar = Aabb {
+ min: (bldg_center - (bldg_diameter / 4)).with_z(base - (bldg_diameter / 3)),
+ max: (bldg_center + (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 3) + (bldg_diameter / 2)),
+ };
+ let bldg_cellar_clear = Aabb {
+ min: (bldg_center - (bldg_diameter / 4) + 1).with_z(base - (bldg_diameter / 3) + 1),
+ max: (bldg_center + (bldg_diameter / 4) - 1)
+ .with_z(base - (bldg_diameter / 3) + (bldg_diameter / 2) - 1),
+ };
+ let bldg_room = Aabb {
+ min: (bldg_center - (bldg_diameter / 4)).with_z(base - (bldg_diameter / 15)),
+ max: (bldg_center + (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2)),
+ };
+ let bldg_hut_entry_clear1 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 4) - 2,
+ bldg_center.y - 2,
+ base + (bldg_diameter / 15),
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 4) + 2,
+ bldg_center.y + 2,
+ base + (bldg_diameter / 15) + 4,
+ ),
+ };
+ let bldg_hut_entry_clear2 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 4) - 2,
+ bldg_center.y - 1,
+ base + (bldg_diameter / 15) + 4,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 4) + 2,
+ bldg_center.y + 1,
+ base + (bldg_diameter / 15) + 5,
+ ),
+ };
+ let bldg_pavillon_entry_clear1 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 4),
+ bldg_center.y - 6,
+ base + (bldg_diameter / 15),
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 4),
+ bldg_center.y + 6,
+ base + (bldg_diameter / 15) + 4,
+ ),
+ };
+ let bldg_pavillon_entry_clear2 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 4),
+ bldg_center.y - 5,
+ base + (bldg_diameter / 15) + 4,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 4),
+ bldg_center.y + 5,
+ base + (bldg_diameter / 15) + 5,
+ ),
+ };
+ let bldg_pavillon_entry_clear3 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 4),
+ bldg_center.y - 4,
+ base + (bldg_diameter / 15) + 5,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 4),
+ bldg_center.y + 4,
+ base + (bldg_diameter / 15) + 6,
+ ),
+ };
+ let bldg_pavillon_entry_clear4 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 6,
+ bldg_center.y - (bldg_diameter / 4),
+ base + (bldg_diameter / 15),
+ ),
+ max: Vec3::new(
+ bldg_center.x + 6,
+ bldg_center.y + (bldg_diameter / 4),
+ base + (bldg_diameter / 15) + 4,
+ ),
+ };
+ let bldg_pavillon_entry_clear5 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 5,
+ bldg_center.y - (bldg_diameter / 4),
+ base + (bldg_diameter / 15) + 4,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 5,
+ bldg_center.y + (bldg_diameter / 4),
+ base + (bldg_diameter / 15) + 5,
+ ),
+ };
+ let bldg_pavillon_entry_clear6 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 4,
+ bldg_center.y - (bldg_diameter / 4),
+ base + (bldg_diameter / 15) + 5,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 4,
+ bldg_center.y + (bldg_diameter / 4),
+ base + (bldg_diameter / 15) + 6,
+ ),
+ };
+ let bldg_room_windows = painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y - (bldg_diameter / 4),
+ base - (bldg_diameter / 15) + (bldg_diameter / 4) - 2,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y + (bldg_diameter / 4),
+ base - (bldg_diameter / 15) + (bldg_diameter / 4) - 1,
+ ),
+ })
+ .without(painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y - (bldg_diameter / 4) + 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 4) - 2,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y + (bldg_diameter / 4) - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 4) - 1,
+ ),
+ }));
+ let bldg_top = painter
+ .sphere(Aabb {
+ min: (bldg_center - (bldg_diameter / 4)).with_z(base - (bldg_diameter / 15)),
+ max: (bldg_center + (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15)),
+ max: (bldg_center + (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4)),
+ }),
+ );
+ let bldg_washed_top = painter
+ .sphere(Aabb {
+ min: (bldg_center - (bldg_diameter / 4)).with_z(base - (bldg_diameter / 15)),
+ max: (bldg_center + (bldg_diameter / 4) - 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15)),
+ max: (bldg_center + (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4)),
+ }),
+ );
+ let bldg_room_goldring = painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 1),
+ max: (bldg_center + (bldg_diameter / 4))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2),
+ });
+ let bldg_room_goldring_clear = painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 4) + 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 1),
+ max: (bldg_center + (bldg_diameter / 4) - 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2),
+ });
+ let bldg_room_clear = Aabb {
+ min: (bldg_center - (bldg_diameter / 4) + 1)
+ .with_z(base - (bldg_diameter / 15) + 1),
+ max: (bldg_center + (bldg_diameter / 4) - 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 1),
+ };
+ let bldg_room_floor = Aabb {
+ min: (bldg_center - (bldg_diameter / 4) + 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 1),
+ max: (bldg_center + (bldg_diameter / 4) - 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2),
+ };
+ let bldg_hut_floors_clear = Aabb {
+ min: (bldg_center - 3).with_z(base - (bldg_diameter / 3) + 2),
+ max: (bldg_center + 3)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 2),
+ };
+ let bldg_room2 = Aabb {
+ min: (bldg_center - (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6),
+ ),
+ max: (bldg_center + (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ };
+ let bldg_room2_windows1 = painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y - (bldg_diameter / 6),
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y + (bldg_diameter / 6),
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 1,
+ ),
+ })
+ .without(painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y - (bldg_diameter / 6) + 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y + (bldg_diameter / 6) - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 1,
+ ),
+ }));
+ let bldg_room2_windows2 = painter
+ .aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 6),
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 6),
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 1,
+ ),
+ })
+ .without(painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 6) + 1,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 2,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 6) - 1,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - 1,
+ ),
+ }));
+ let bldg_room2_top = painter
+ .sphere(Aabb {
+ min: (bldg_center - (bldg_diameter / 6) + 1).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6),
+ ),
+ max: (bldg_center + (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6),
+ ),
+ max: (bldg_center + (bldg_diameter / 6))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2)),
+ }),
+ );
+ let bldg_room2_washed_top = painter
+ .sphere(Aabb {
+ min: (bldg_center - (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6),
+ ),
+ max: (bldg_center + (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 6)).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6),
+ ),
+ max: (bldg_center + (bldg_diameter / 6))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2)),
+ }),
+ );
+ let bldg_room2_goldring = painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 6))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) + 1),
+ max: (bldg_center + (bldg_diameter / 6))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) + 2),
+ });
+ let bldg_room2_goldring_clear = painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 6) + 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) + 1),
+ max: (bldg_center + (bldg_diameter / 6) - 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) + 2),
+ });
+ let bldg_room2_clear = Aabb {
+ min: (bldg_center - (bldg_diameter / 6) + 1).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6),
+ ),
+ max: (bldg_center + (bldg_diameter / 6) - 1).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ };
+ let bldg_room2_floor = Aabb {
+ min: (bldg_center - (bldg_diameter / 6) + 1).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10),
+ ),
+ max: (bldg_center + (bldg_diameter / 6) - 1).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 1,
+ ),
+ };
+ let bldg_tube = painter.cylinder(Aabb {
+ min: (bldg_center - 4).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6) - 1,
+ ),
+ max: (bldg_center + 4)
+ .with_z(base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4)),
+ });
+ let bldg_tube_clear = painter.cylinder(Aabb {
+ min: (bldg_center - 3).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 6) - 1,
+ ),
+ max: (bldg_center + 3)
+ .with_z(base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4)),
+ });
+ let bldg_tube_windows1 = Aabb {
+ min: Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ max: Vec3::new(
+ bldg_center.x + 4,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ };
+ let bldg_tube_windows2 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 4,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ max: Vec3::new(
+ bldg_center.x - 3,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ };
+ let bldg_tube_windows3 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y - 4,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y - 3,
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ };
+ let bldg_tube_windows4 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y + 3,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6),
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y + 4,
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ };
+ let bldg_room3 = Aabb {
+ min: (bldg_center - (bldg_diameter / 7))
+ .with_z(base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2),
+ max: (bldg_center + (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 2,
+ ),
+ };
+ let bldg_room3_washed_top = painter
+ .sphere(Aabb {
+ min: (bldg_center - (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ max: (bldg_center + (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 2,
+ ),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ max: (bldg_center + (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 2,
+ ),
+ }));
+ let bldg_room3_top = painter
+ .sphere(Aabb {
+ min: (bldg_center - (bldg_diameter / 7) + 1).with_z(
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ max: (bldg_center + (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 2,
+ ),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (bldg_center - (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 2,
+ ),
+ max: (bldg_center + (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 2,
+ ),
+ }));
+ let bldg_room3_goldring = Aabb {
+ min: (bldg_center - (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 1,
+ ),
+ max: (bldg_center + (bldg_diameter / 7)).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7),
+ ),
+ };
+ let bldg_room3_clear = Aabb {
+ min: (bldg_center - (bldg_diameter / 7) + 1)
+ .with_z(base - (bldg_diameter / 15) + tower_height + (bldg_diameter / 4) - 1),
+ max: (bldg_center + (bldg_diameter / 7) - 1).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 3,
+ ),
+ };
+ let bldg_room3_floor = painter
+ .sphere(Aabb {
+ min: (bldg_center - 3).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 8,
+ ),
+ max: (bldg_center + 3).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 7,
+ ),
+ })
+ .without(painter.cylinder(Aabb {
+ min: (bldg_center - 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 8,
+ ),
+ max: (bldg_center + 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 7,
+ ),
+ }));
+ let bldg_tower_floors_clear = Aabb {
+ min: (bldg_center - 3).with_z(base - (bldg_diameter / 3) + 2),
+ max: (bldg_center + 3).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 4)
+ - 3,
+ ),
+ };
+ let bldg_room3_entry_clear1 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 7),
+ bldg_center.y - 3,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 6,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 7),
+ bldg_center.y + 3,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 4,
+ ),
+ };
+ let bldg_room3_entry_clear2 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - (bldg_diameter / 7),
+ bldg_center.y - 2,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 4,
+ ),
+ max: Vec3::new(
+ bldg_center.x + (bldg_diameter / 7),
+ bldg_center.y + 2,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 3,
+ ),
+ };
+ let bldg_room3_entry_clear3 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 3,
+ bldg_center.y - (bldg_diameter / 7),
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 6,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y + (bldg_diameter / 7),
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 4,
+ ),
+ };
+ let bldg_room3_entry_clear4 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 2,
+ bldg_center.y - (bldg_diameter / 7),
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 4,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 2,
+ bldg_center.y + (bldg_diameter / 7),
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 3,
+ ),
+ };
+ let bldg_gold_top1 = Aabb {
+ min: (bldg_center - 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 3,
+ ),
+ max: (bldg_center + 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 1,
+ ),
+ };
+ let bldg_gold_top_pole = Aabb {
+ min: (bldg_center - 1).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 1,
+ ),
+ max: (bldg_center + 1).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 7,
+ ),
+ };
+ let bldg_gold_top_antlers1 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 2,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 1,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 2,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 2,
+ ),
+ };
+ let bldg_gold_top_antlers2 = painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 3,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 2,
+ ),
+
+ max: Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 3,
+ ),
+ });
+ let bldg_gold_top_antlers2_clear = painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 2,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 2,
+ ),
+
+ max: Vec3::new(
+ bldg_center.x + 2,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 3,
+ ),
+ });
+ let bldg_gold_top_antlers3 = Aabb {
+ min: Vec3::new(
+ bldg_center.x - 3,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 4,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 5,
+ ),
+ };
+ let bldg_gold_top_antlers4 = painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 5,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 5,
+ ),
+
+ max: Vec3::new(
+ bldg_center.x + 5,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 6,
+ ),
+ });
+ let bldg_gold_top_antlers4_clear = painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 2,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 5,
+ ),
+
+ max: Vec3::new(
+ bldg_center.x + 2,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 6,
+ ),
+ });
+ let bldg_gold_top_antlers5 = painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 2,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 7,
+ ),
+
+ max: Vec3::new(
+ bldg_center.x + 2,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 8,
+ ),
+ });
+ let bldg_gold_top_antlers5_clear = painter.aabb(Aabb {
+ min: Vec3::new(
+ bldg_center.x - 1,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 7,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 1,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ + 8,
+ ),
+ });
+ let bldg_tower_ropefix1 = Aabb {
+ min: (bldg_center - 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 4,
+ ),
+ max: (bldg_center + 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 3,
+ ),
+ };
+ let bldg_tower_ropefix2 = Aabb {
+ min: (bldg_center).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 5,
+ ),
+ max: (bldg_center + 1).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 4,
+ ),
+ };
+ let bldg_tower_rope = Aabb {
+ min: bldg_center.with_z(base - (bldg_diameter / 3) + 7),
+ max: (bldg_center + 1).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (2 * (bldg_diameter / 7))
+ - 5,
+ ),
+ };
+ let bldg_hut_ropefix1 = Aabb {
+ min: (bldg_center - 2)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 3),
+ max: (bldg_center + 2)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 2),
+ };
+ let bldg_hut_ropefix2 = Aabb {
+ min: bldg_center.with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 4),
+ max: (bldg_center + 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 3),
+ };
+ let bldg_hut_rope = Aabb {
+ min: bldg_center.with_z(base - (bldg_diameter / 3) + 7),
+ max: (bldg_center + 1)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 2) - 4),
+ };
+ let bldg_water_puddle = Aabb {
+ min: (bldg_center - 5).with_z(base - (bldg_diameter / 3) + 2),
+ max: (bldg_center + 5).with_z(base - (bldg_diameter / 3) + 3),
+ };
+ let bldg_connect_entry = Aabb {
+ min: (bldg_center - 4).with_z(base - (bldg_diameter / 3) + 2),
+ max: (bldg_center + 4).with_z(base - (bldg_diameter / 3) + 3),
+ };
+ let bldg_room_lantern_pos = (bldg_center + 2).with_z(base - (bldg_diameter / 15) + 2);
+ let bldg_floor_lantern_pos =
+ (bldg_center + 2).with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2);
+ let bldg_floor2_lantern_pos = Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y + 2,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 1,
+ );
+ let bldg_floor3_lantern_pos = (bldg_center + 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 7,
+ );
+ let bldg_floor3_drawer_pos = (bldg_center - 3).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 7,
+ );
+ let bldg_floor3_potion_pos = (bldg_center - 3).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 6,
+ );
+ let bldg_cellar_chest_pos = Vec3::new(
+ bldg_center.x - (bldg_diameter / 8),
+ bldg_center.y,
+ base - (bldg_diameter / 3) + 3,
+ );
+ let bldg_floor2_coral_chest_podium = Aabb {
+ min: (bldg_center - 5).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 1,
+ ),
+ max: (bldg_center - 4).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 2,
+ ),
+ };
+ let bldg_floor2_coral_chest_pos = (bldg_center - 5).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 2,
+ );
+ let bldg_floor_bed_pos = Vec3::new(
+ bldg_center.x - (bldg_diameter / 6),
+ bldg_center.y,
+ base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2,
+ );
+ let bldg_floor_drawer_pos = (bldg_center - (bldg_diameter / 8))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2);
+ let bldg_floor_potion_pos = (bldg_center - (bldg_diameter / 8))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 3);
+ let bldg_floor_glass_barriers = Aabb {
+ min: (bldg_center - 4)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2),
+ max: (bldg_center + 4)
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 3),
+ };
+ let bldg_floor2_wall = Aabb {
+ min: (bldg_center - 4).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 1,
+ ),
+ max: (bldg_center + 4).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) + (bldg_diameter / 6) - 2,
+ ),
+ };
+ let bldg_floor2_glass_barriers = Aabb {
+ min: Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 1,
+ ),
+ max: Vec3::new(
+ bldg_center.x + 4,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 4,
+ ),
+ };
+ let bldg_floor2_step = Aabb {
+ min: Vec3::new(
+ bldg_center.x + 2,
+ bldg_center.y - 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10),
+ ),
+ max: Vec3::new(
+ bldg_center.x + 3,
+ bldg_center.y + 1,
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 1,
+ ),
+ };
+ let bldg_connect_tube = Aabb {
+ min: (bldg_center - (bldg_diameter / 10))
+ .with_z(base - (2 * (bldg_diameter / 3)) + 1),
+ max: (bldg_center + (bldg_diameter / 10)).with_z(base - (bldg_diameter / 3) + 1),
+ };
+ let bldg_connect_water = Aabb {
+ min: (bldg_center - (bldg_diameter / 10) + 1)
+ .with_z(base - (2 * (bldg_diameter / 3)) + 1),
+ max: (bldg_center + (bldg_diameter / 10) - 1)
+ .with_z(base - (bldg_diameter / 3) + 2),
+ };
+ let bldg_connect_gate = Aabb {
+ min: (bldg_center - 2).with_z(base - (bldg_diameter / 3) + 2),
+ max: (bldg_center + 2).with_z(base - (bldg_diameter / 3) + 3),
+ };
+ let bldg_floor_sea_cleric_pos = (bldg_center + (bldg_diameter / 8))
+ .with_z(base - (bldg_diameter / 15) + (bldg_diameter / 4) + 2);
+ let bldg_floor3_sea_cleric_pos = (bldg_center + 2).with_z(
+ base - (bldg_diameter / 15)
+ + tower_height
+ + (bldg_diameter / 4)
+ + (bldg_diameter / 7)
+ - 6,
+ );
+ let bldg_floor2_sea_cleric_pos = (bldg_center + 5).with_z(
+ base - (bldg_diameter / 15) + (bldg_diameter / 2) - (bldg_diameter / 10) + 2,
+ );
+ // bldg cellar Sea Crocodiles
+ let bldg_cellar_sea_croc_pos = Vec3::new(
+ bldg_center.x - (bldg_diameter / 8),
+ bldg_center.y,
+ base - (bldg_diameter / 3) + 3,
+ );
+ for _ in
+ 0..(1 + ((RandomField::new(0).get((bldg_cellar_sea_croc_pos).with_z(base))) % 2))
+ {
+ painter.spawn(
+ EntityInfo::at(bldg_cellar_sea_croc_pos.as_())
+ .with_asset_expect("common.entity.wild.aggressive.sea_crocodile", &mut rng),
+ )
+ }
+ match bldg_variant {
+ 0..=2 => {
+ // paint SeaHut
+ painter.sphere(bldg_cellar).fill(white.clone());
+ painter.sphere(bldg_cellar_clear).clear();
+ painter.sphere(bldg_room).fill(white.clone());
+ painter.aabb(bldg_hut_entry_clear1).clear();
+ painter.aabb(bldg_hut_entry_clear2).clear();
+ bldg_room_windows.fill(window_ver.clone());
+ bldg_top.fill(top.clone());
+ bldg_washed_top.fill(washed.clone());
+ painter.sphere(bldg_room_clear).clear();
+ bldg_room_goldring.fill(gold.clone());
+ bldg_room_goldring_clear.clear();
+ painter.cylinder(bldg_room_floor).fill(white.clone());
+ painter.cylinder(bldg_hut_floors_clear).clear();
+ painter.cylinder(bldg_hut_ropefix1).fill(ropefix1.clone());
+ painter.aabb(bldg_hut_ropefix2).fill(ropefix2.clone());
+ painter.aabb(bldg_hut_rope).fill(rope.clone());
+ painter.cylinder(bldg_water_puddle).fill(water.clone());
+ painter.cylinder(bldg_connect_tube).fill(white.clone());
+ painter.cylinder(bldg_connect_water).fill(water.clone());
+ painter.cylinder(bldg_connect_entry).fill(white.clone());
+ painter.sprite(bldg_room_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_floor_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_cellar_chest_pos, SpriteKind::DungeonChest1);
+ painter.sprite(bldg_floor_bed_pos, SpriteKind::Bed);
+ painter.sprite(bldg_floor_drawer_pos, SpriteKind::DrawerSmall);
+ painter.sprite(bldg_floor_potion_pos, SpriteKind::PotionMinor);
+ // bldg floor Sea Clerics
+ for _ in 0..(1
+ + ((RandomField::new(0).get((bldg_floor_sea_cleric_pos).with_z(base))) % 2))
+ {
+ painter.spawn(
+ EntityInfo::at(bldg_floor_sea_cleric_pos.as_()).with_asset_expect(
+ "common.entity.dungeon.sea_chapel.sea_cleric",
+ &mut rng,
+ ),
+ )
+ }
+ },
+ 3..=5 => {
+ // paint SeaPavillon
+ painter.sphere(bldg_cellar).fill(white.clone());
+ painter.sphere(bldg_cellar_clear).clear();
+ painter.sphere(bldg_room).fill(white.clone());
+ painter.aabb(bldg_pavillon_entry_clear1).clear();
+ painter.aabb(bldg_pavillon_entry_clear2).clear();
+ painter.aabb(bldg_pavillon_entry_clear3).clear();
+ painter.aabb(bldg_pavillon_entry_clear4).clear();
+ painter.aabb(bldg_pavillon_entry_clear5).clear();
+ painter.aabb(bldg_pavillon_entry_clear6).clear();
+ bldg_top.fill(top.clone());
+ bldg_washed_top.fill(washed.clone());
+ painter.sphere(bldg_room_clear).clear();
+ bldg_room_goldring.fill(gold.clone());
+ bldg_room_goldring_clear.clear();
+ painter.cylinder(bldg_hut_floors_clear).clear();
+ painter.cylinder(bldg_hut_ropefix1).fill(ropefix1.clone());
+ painter.aabb(bldg_hut_ropefix2).fill(ropefix2.clone());
+ painter.aabb(bldg_hut_rope).fill(rope.clone());
+ painter.cylinder(bldg_water_puddle).fill(water.clone());
+ painter.cylinder(bldg_connect_tube).fill(white.clone());
+ painter.cylinder(bldg_connect_water).fill(water.clone());
+ painter.cylinder(bldg_connect_entry).fill(white.clone());
+ painter.sprite(bldg_room_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_cellar_chest_pos, SpriteKind::DungeonChest1);
+ },
+ 6..=9 => {
+ // paint SeaTower
+ painter.sphere(bldg_cellar).fill(white.clone());
+ painter.sphere(bldg_cellar_clear).clear();
+ painter.sphere(bldg_room).fill(white.clone());
+ painter.aabb(bldg_hut_entry_clear1).clear();
+ painter.aabb(bldg_hut_entry_clear2).clear();
+ bldg_room_windows.fill(window_ver.clone());
+ bldg_top.fill(top.clone());
+ bldg_washed_top.fill(washed.clone());
+ painter.sphere(bldg_room2).fill(white.clone());
+ bldg_room2_windows1.fill(window_ver.clone());
+ bldg_room2_windows2.fill(window_ver2.clone());
+ bldg_room2_washed_top.fill(washed.clone());
+ bldg_room2_top.fill(top.clone());
+ painter.sphere(bldg_room2_clear).clear();
+ bldg_room2_goldring.fill(gold.clone());
+ bldg_room2_goldring_clear.clear();
+ painter.sphere(bldg_room_clear).clear();
+ bldg_room_goldring.fill(gold.clone());
+ bldg_room_goldring_clear.clear();
+ painter.cylinder(bldg_room_floor).fill(white.clone());
+ painter.cylinder(bldg_room2_floor).fill(white.clone());
+ bldg_tube.fill(white.clone());
+ bldg_tube_clear.clear();
+ painter.aabb(bldg_tube_windows1).fill(window_ver2.clone());
+ painter.aabb(bldg_tube_windows2).fill(window_ver2.clone());
+ painter.aabb(bldg_tube_windows3).fill(window_ver.clone());
+ painter.aabb(bldg_tube_windows4).fill(window_ver.clone());
+ painter.sphere(bldg_room3).fill(white.clone());
+ bldg_room3_washed_top.fill(washed.clone());
+ bldg_room3_top.fill(top.clone());
+ painter.cylinder(bldg_room3_goldring).fill(gold.clone());
+ painter.sphere(bldg_room3_clear).clear();
+ painter.aabb(bldg_room3_entry_clear1).clear();
+ painter.aabb(bldg_room3_entry_clear2).clear();
+ painter.aabb(bldg_room3_entry_clear3).clear();
+ painter.aabb(bldg_room3_entry_clear4).clear();
+ painter
+ .cylinder(bldg_floor_glass_barriers)
+ .fill(glass_barrier.clone());
+ painter.cylinder(bldg_floor2_wall).fill(white.clone());
+ painter
+ .aabb(bldg_floor2_glass_barriers)
+ .fill(glass_barrier.clone());
+ painter.cylinder(bldg_tower_floors_clear).clear();
+ painter.aabb(bldg_floor2_step).fill(gold_decor.clone());
+ bldg_room3_floor.fill(white.clone());
+ painter.cylinder(bldg_tower_ropefix1).fill(ropefix1.clone());
+ painter.aabb(bldg_tower_ropefix2).fill(ropefix2.clone());
+ painter.aabb(bldg_tower_rope).fill(rope.clone());
+ bldg_gold_top_antlers2.fill(gold.clone());
+ bldg_gold_top_antlers2_clear.clear();
+ bldg_gold_top_antlers4.fill(gold.clone());
+ bldg_gold_top_antlers4_clear.clear();
+ bldg_gold_top_antlers5.fill(gold.clone());
+ bldg_gold_top_antlers5_clear.clear();
+ painter.sphere(bldg_gold_top1).fill(gold.clone());
+ painter.aabb(bldg_gold_top_pole).fill(gold.clone());
+ painter.aabb(bldg_gold_top_antlers1).fill(gold.clone());
+ painter.aabb(bldg_gold_top_antlers3).fill(gold.clone());
+ painter.cylinder(bldg_water_puddle).fill(water.clone());
+ painter.cylinder(bldg_connect_tube).fill(white.clone());
+ painter.cylinder(bldg_connect_water).fill(water.clone());
+ painter.cylinder(bldg_connect_entry).fill(white.clone());
+ painter.sprite(bldg_room_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_floor_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_floor2_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_floor3_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(bldg_floor3_drawer_pos, SpriteKind::DrawerSmall);
+ painter.sprite(bldg_floor3_potion_pos, SpriteKind::PotionMinor);
+ painter.sprite(bldg_cellar_chest_pos, SpriteKind::DungeonChest1);
+ painter
+ .aabb(bldg_floor2_coral_chest_podium)
+ .fill(gold_decor.clone());
+ painter.rotated_sprite(bldg_floor2_coral_chest_pos, SpriteKind::CoralChest, 0);
+ painter.sprite(bldg_floor_bed_pos, SpriteKind::Bed);
+ painter.sprite(bldg_floor_drawer_pos, SpriteKind::DrawerSmall);
+ painter.sprite(bldg_floor_potion_pos, SpriteKind::PotionMinor);
+ // bldg floor Sea Clerics
+ for _ in 0..(1
+ + ((RandomField::new(0).get((bldg_floor_sea_cleric_pos).with_z(base))) % 2))
+ {
+ painter.spawn(
+ EntityInfo::at(bldg_floor_sea_cleric_pos.as_()).with_asset_expect(
+ "common.entity.dungeon.sea_chapel.sea_cleric",
+ &mut rng,
+ ),
+ )
+ }
+ // bldg floor3 Sea Clerics
+ for _ in 0..(1
+ + ((RandomField::new(0).get((bldg_floor3_sea_cleric_pos).with_z(base)))
+ % 2))
+ {
+ painter.spawn(
+ EntityInfo::at(bldg_floor3_sea_cleric_pos.as_()).with_asset_expect(
+ "common.entity.dungeon.sea_chapel.sea_cleric",
+ &mut rng,
+ ),
+ )
+ }
+ // bldg floor2 Sea Clerics
+ for _ in 0..(1
+ + ((RandomField::new(0).get((bldg_floor2_sea_cleric_pos).with_z(base)))
+ % 2))
+ {
+ painter.spawn(
+ EntityInfo::at(bldg_floor2_sea_cleric_pos.as_()).with_asset_expect(
+ "common.entity.dungeon.sea_chapel.sea_cleric",
+ &mut rng,
+ ),
+ )
+ }
+ },
+ _ => {},
+ };
+ let connect_gate_type = connect_gate_types.swap_remove(
+ RandomField::new(0).get((center + dir).with_z(base)) as usize
+ % connect_gate_types.len(),
+ );
+ painter
+ .cylinder(bldg_connect_gate)
+ .fill(Fill::Block(Block::air(connect_gate_type)));
+ }
+ // surrounding buildings foundling, small hut, small pavillon
+ for dir in NEIGHBORS {
+ let su_bldg_variant =
+ ((RandomField::new(0).get((center - dir).with_z(base))) % 10) as i32;
+ let su_bldg_center = center + dir * (diameter + (3 * su_bldg_variant));
+ let su_bldg_base = base - 2 + ((su_bldg_variant / 2) as i32);
+ let su_bldg_diameter = diameter;
+
+ let foundling_bottom1 = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 8) - 3)
+ .with_z(su_bldg_base - (su_bldg_diameter / 5) - (su_bldg_diameter / 2)),
+ max: (su_bldg_center + (su_bldg_diameter / 8) + 3)
+ .with_z(su_bldg_base - (su_bldg_diameter / 5) - (su_bldg_diameter / 4) + 6),
+ };
+ let foundling_bottom2 = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 8) - 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 5) - (su_bldg_diameter / 4) + 2),
+ max: (su_bldg_center + (su_bldg_diameter / 8) + 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 5) + 2),
+ };
+ let foundling_top = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 8))
+ .with_z(su_bldg_base - (su_bldg_diameter / 5) - 1),
+ max: (su_bldg_center + (su_bldg_diameter / 8))
+ .with_z(su_bldg_base - (su_bldg_diameter / 5) + (su_bldg_diameter / 4) - 1),
+ };
+ let su_bldg_bottom1 = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6) - 1)
+ .with_z(su_bldg_base - (2 * (su_bldg_diameter / 3)) + 1),
+ max: (su_bldg_center + (su_bldg_diameter / 6) + 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 3) + 1),
+ };
+ let su_bldg_bottom2 = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 3)),
+ max: (su_bldg_center + (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 3) + (su_bldg_diameter / 3)),
+ };
+ let su_bldg_room = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15)),
+ max: (su_bldg_center + (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3)),
+ };
+ let su_bldg_hut_entries1 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - (su_bldg_diameter / 6) - 2,
+ su_bldg_center.y - 2,
+ su_bldg_base + (su_bldg_diameter / 15) - 2,
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + (su_bldg_diameter / 6) + 2,
+ su_bldg_center.y + 2,
+ su_bldg_base + (su_bldg_diameter / 15) + 1,
+ ),
+ };
+ let su_bldg_hut_entries2 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - (su_bldg_diameter / 6) - 2,
+ su_bldg_center.y - 1,
+ su_bldg_base + (su_bldg_diameter / 15) + 1,
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + (su_bldg_diameter / 6) + 2,
+ su_bldg_center.y + 1,
+ su_bldg_base + (su_bldg_diameter / 15) + 2,
+ ),
+ };
+ let su_bldg_top = painter
+ .sphere(Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15)),
+ max: (su_bldg_center + (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15)),
+ max: (su_bldg_center + (su_bldg_diameter / 6)).with_z(
+ su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6),
+ ),
+ }),
+ );
+ let su_bldg_washed_top = painter
+ .sphere(Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15)),
+ max: (su_bldg_center + (su_bldg_diameter / 6) - 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3)),
+ })
+ .without(
+ painter.cylinder(Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15)),
+ max: (su_bldg_center + (su_bldg_diameter / 6)).with_z(
+ su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6),
+ ),
+ }),
+ );
+ let su_bldg_goldring = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 1),
+ max: (su_bldg_center + (su_bldg_diameter / 6))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 2),
+ };
+ let su_bldg_room_clear = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6) + 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + 1),
+ max: (su_bldg_center + (su_bldg_diameter / 6) - 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3) - 1),
+ };
+ let su_bldg_floor = Aabb {
+ min: (su_bldg_center - (su_bldg_diameter / 6) + 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 1),
+ max: (su_bldg_center + (su_bldg_diameter / 6) - 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 2),
+ };
+ let su_bldg_room_lantern_pos =
+ (su_bldg_center + 2).with_z(su_bldg_base - (su_bldg_diameter / 15) + 2);
+ let su_bldg_floor_lantern_pos = (su_bldg_center + 2)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 2);
+ let su_bldg_floor_drawer_pos = (su_bldg_center - (su_bldg_diameter / 10))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 2);
+ let su_bldg_floor_potion_pos = (su_bldg_center - (su_bldg_diameter / 10))
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 3);
+ let su_bldg_floor_bed_pos = Vec3::new(
+ su_bldg_center.x - (su_bldg_diameter / 8),
+ su_bldg_center.y,
+ su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 2,
+ );
+ let su_bldg_floor_entry = Aabb {
+ min: (su_bldg_center - 3)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 1),
+ max: (su_bldg_center + 3)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 6) + 2),
+ };
+ let su_bldg_ropefix1 = Aabb {
+ min: (su_bldg_center - 2)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3) - 3),
+ max: (su_bldg_center + 2)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3) - 2),
+ };
+ let su_bldg_ropefix2 = Aabb {
+ min: (su_bldg_center)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3) - 4),
+ max: (su_bldg_center + 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3) - 3),
+ };
+ let su_bldg_rope = Aabb {
+ min: (su_bldg_center).with_z(su_bldg_base - (su_bldg_diameter / 15) + 5),
+ max: (su_bldg_center + 1)
+ .with_z(su_bldg_base - (su_bldg_diameter / 15) + (su_bldg_diameter / 3) - 4),
+ };
+ let su_bldg_pavillon_entries1 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - (su_bldg_diameter / 6),
+ su_bldg_center.y - 4,
+ su_bldg_base + (su_bldg_diameter / 15) - 2,
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + (su_bldg_diameter / 6),
+ su_bldg_center.y + 4,
+ su_bldg_base + (su_bldg_diameter / 15),
+ ),
+ };
+ let su_bldg_pavillon_entries2 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - (su_bldg_diameter / 6),
+ su_bldg_center.y - 3,
+ su_bldg_base + (su_bldg_diameter / 15),
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + (su_bldg_diameter / 6),
+ su_bldg_center.y + 3,
+ su_bldg_base + (su_bldg_diameter / 15) + 1,
+ ),
+ };
+ let su_bldg_pavillon_entries3 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - (su_bldg_diameter / 6),
+ su_bldg_center.y - 2,
+ su_bldg_base + (su_bldg_diameter / 15) + 1,
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + (su_bldg_diameter / 6),
+ su_bldg_center.y + 2,
+ su_bldg_base + (su_bldg_diameter / 15) + 2,
+ ),
+ };
+ let su_bldg_pavillon_entries4 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - 4,
+ su_bldg_center.y - (su_bldg_diameter / 6),
+ su_bldg_base + (su_bldg_diameter / 15) - 2,
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + 4,
+ su_bldg_center.y + (su_bldg_diameter / 6),
+ su_bldg_base + (su_bldg_diameter / 15),
+ ),
+ };
+ let su_bldg_pavillon_entries5 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - 3,
+ su_bldg_center.y - (su_bldg_diameter / 6),
+ su_bldg_base + (su_bldg_diameter / 15),
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + 3,
+ su_bldg_center.y + (su_bldg_diameter / 6),
+ su_bldg_base + (su_bldg_diameter / 15) + 1,
+ ),
+ };
+ let su_bldg_pavillon_entries6 = Aabb {
+ min: Vec3::new(
+ su_bldg_center.x - 2,
+ su_bldg_center.y - (su_bldg_diameter / 6),
+ su_bldg_base + (su_bldg_diameter / 15) + 1,
+ ),
+ max: Vec3::new(
+ su_bldg_center.x + 2,
+ su_bldg_center.y + (su_bldg_diameter / 6),
+ su_bldg_base + (su_bldg_diameter / 15) + 2,
+ ),
+ };
+ match su_bldg_variant {
+ 0..=5 => {
+ // common parts for small hut / small pavillon,
+ painter.sphere(su_bldg_bottom1).fill(white.clone());
+ painter.sphere(su_bldg_bottom2).fill(white.clone());
+ painter.sphere(su_bldg_room).fill(white.clone());
+ su_bldg_top.fill(top.clone());
+ su_bldg_washed_top.fill(washed.clone());
+ painter.cylinder(su_bldg_goldring).fill(gold.clone());
+ painter.sphere(su_bldg_room_clear).clear();
+ painter.sprite(su_bldg_room_lantern_pos, SpriteKind::SeashellLantern);
+ match su_bldg_variant {
+ 0..=3 => {
+ // small hut
+ painter.aabb(su_bldg_hut_entries1).clear();
+ painter.aabb(su_bldg_hut_entries2).clear();
+ painter.cylinder(su_bldg_floor).fill(white.clone());
+ painter.cylinder(su_bldg_floor_entry).clear();
+ painter.aabb(su_bldg_ropefix1).fill(ropefix1.clone());
+ painter.aabb(su_bldg_ropefix2).fill(ropefix2.clone());
+ painter.aabb(su_bldg_rope).fill(rope.clone());
+ painter.sprite(su_bldg_floor_lantern_pos, SpriteKind::SeashellLantern);
+ painter.sprite(su_bldg_floor_drawer_pos, SpriteKind::DrawerSmall);
+ painter.sprite(su_bldg_floor_potion_pos, SpriteKind::PotionMinor);
+ painter.sprite(su_bldg_floor_bed_pos, SpriteKind::Bed);
+ },
+ _ => {
+ // small pavillon
+ painter.aabb(su_bldg_pavillon_entries1).clear();
+ painter.aabb(su_bldg_pavillon_entries2).clear();
+ painter.aabb(su_bldg_pavillon_entries3).clear();
+ painter.aabb(su_bldg_pavillon_entries4).clear();
+ painter.aabb(su_bldg_pavillon_entries5).clear();
+ painter.aabb(su_bldg_pavillon_entries6).clear();
+ },
+ }
+ },
+ 6..=7 => {
+ // foundling
+ painter.sphere(foundling_bottom1).fill(white.clone());
+ painter.sphere(foundling_bottom2).fill(white.clone());
+ painter.sphere(foundling_top).fill(white.clone());
+ },
+ _ => {},
+ };
+ }
+ }
+}