From e882e62c080918270cbb08d91ca957a116eb9d04 Mon Sep 17 00:00:00 2001 From: flo Date: Wed, 24 Aug 2022 21:50:53 +0000 Subject: [PATCH] seachapel --- .../common/abilities/ability_set_manifest.ron | 19 + .../custom/cardinal/summonseacrocs.ron | 18 + .../abilities/custom/dagon/dagonbombs.ron | 16 + .../abilities/custom/dagon/seaurchins.ron | 8 + .../abilities/custom/organ/organaura.ron | 19 + .../entity/dungeon/sea_chapel/cardinal.ron | 16 + .../entity/dungeon/sea_chapel/dagon.ron | 11 + .../entity/dungeon/sea_chapel/organ.ron | 11 + .../entity/dungeon/sea_chapel/sea_cleric.ron | 21 + .../dungeon/sea_chapel/sea_cleric_sceptre.ron | 18 + assets/common/items/armor/cardinal/belt.ron | 18 + assets/common/items/armor/cardinal/chest.ron | 18 + assets/common/items/armor/cardinal/foot.ron | 18 + assets/common/items/armor/cardinal/hand.ron | 18 + assets/common/items/armor/cardinal/pants.ron | 18 + .../common/items/armor/cardinal/shoulder.ron | 18 + .../items/armor/misc/neck/abyssal_gorget.ron | 17 + .../items/crafting_ing/abyssal_heart.ron | 9 + .../items/crafting_ing/coral_branch.ron | 9 + .../items/npc_weapons/unique/cardinal.ron | 21 + .../common/items/npc_weapons/unique/dagon.ron | 21 + .../common/items/npc_weapons/unique/organ.ron | 21 + .../loadout/dungeon/sea_chapel/cardinal.ron | 14 + .../loadout/dungeon/sea_chapel/sea_cleric.ron | 13 + .../dungeon/sea_chapel/cardinal.ron | 5 + .../dungeon/sea_chapel/chest_coral.ron | 5 + .../loot_tables/dungeon/sea_chapel/dagon.ron | 4 + .../dungeon/sea_chapel/sea_cleric.ron | 4 + assets/common/npc_names.ron | 4 + assets/common/recipe_book.ron | 11 +- assets/voxygen/audio/sfx.ron | 14 +- .../audio/sfx/abilities/barrel_organ.ogg | 3 + .../element/ui/map/buttons/sea_chapel.png | 3 + .../element/ui/map/buttons/sea_chapel_bg.png | 3 + .../ui/map/buttons/sea_chapel_hover.png | 3 + assets/voxygen/i18n/en/common.ftl | 1 + assets/voxygen/i18n/en/common.ron | 130 + assets/voxygen/i18n/en/hud/map.ftl | 1 + assets/voxygen/item_image_manifest.ron | 37 + assets/voxygen/voxel/armor/cardinal/belt.vox | 3 + assets/voxygen/voxel/armor/cardinal/chest.vox | 3 + assets/voxygen/voxel/armor/cardinal/foot.vox | 3 + assets/voxygen/voxel/armor/cardinal/hand.vox | 3 + assets/voxygen/voxel/armor/cardinal/pants.vox | 3 + .../voxygen/voxel/armor/cardinal/shoulder.vox | 3 + .../voxel/armor/misc/neck/abyssal_gorget.vox | 3 + .../voxygen/voxel/biped_weapon_manifest.ron | 4 + .../voxel/humanoid_armor_belt_manifest.ron | 4 + .../voxel/humanoid_armor_chest_manifest.ron | 4 + .../voxel/humanoid_armor_foot_manifest.ron | 4 + .../voxel/humanoid_armor_hand_manifest.ron | 10 + .../voxel/humanoid_armor_pants_manifest.ron | 4 + .../humanoid_armor_shoulder_manifest.ron | 10 + assets/voxygen/voxel/item_drop_manifest.ron | 3 + assets/voxygen/voxel/npc/dagon/male/chest.vox | 3 + .../voxygen/voxel/npc/dagon/male/foot_br.vox | 3 + .../voxygen/voxel/npc/dagon/male/foot_fr.vox | 3 + .../voxel/npc/dagon/male/head_lower.vox | 3 + .../voxel/npc/dagon/male/head_upper.vox | 3 + assets/voxygen/voxel/npc/dagon/male/jaw.vox | 3 + .../voxel/npc/dagon/male/tail_front.vox | 3 + .../voxel/npc/dagon/male/tail_rear.vox | 3 + assets/voxygen/voxel/object/dagon_bomb.vox | 3 + assets/voxygen/voxel/object/sea_urchin.vox | 3 + .../voxygen/voxel/object/seashell_lantern.vox | 3 + assets/voxygen/voxel/object_manifest.ron | 20 + .../voxel/quadruped_low_central_manifest.ron | 52 + .../voxel/quadruped_low_lateral_manifest.ron | 36 + .../voxel/sprite/chests/chest_coral.vox | 3 + .../sprite/crafting_ing/abyssal_heart.vox | 3 + .../sprite/crafting_ing/coral_branch.vox | 3 + .../voxel/sprite/misc/barrel_organ.vox | 3 + .../voxel/sprite/misc/glass_barrier.vox | 3 + assets/voxygen/voxel/sprite/misc/rope.vox | 3 + .../voxel/sprite/misc/sea_decor_block.vox | 3 + .../voxel/sprite/misc/sea_decor_chain.vox | 3 + .../voxel/sprite/misc/sea_decor_emblem.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-0.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-1.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-2.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-3.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-4.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-5.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-6.vox | 3 + .../voxel/sprite/misc/sea_decor_pillar-7.vox | 3 + .../sprite/misc/sea_decor_window_hor.vox | 3 + .../sprite/misc/sea_decor_window_ver.vox | 3 + assets/voxygen/voxel/sprite_manifest.ron | 156 + common/net/src/msg/world_msg.rs | 1 + common/src/bin/csv_export/main.rs | 1 + common/src/comp/body.rs | 3 + common/src/comp/body/object.rs | 22 +- common/src/comp/body/quadruped_low.rs | 6 +- common/src/comp/inventory/item/tool.rs | 2 + common/src/comp/inventory/loadout_builder.rs | 6 + common/src/comp/projectile.rs | 71 + common/src/states/sprite_summon.rs | 18 +- common/src/states/utils.rs | 1 + common/src/terrain/block.rs | 15 +- common/src/terrain/sprite.rs | 28 +- common/systems/src/buff.rs | 15 + server/src/persistence/json_models.rs | 6 +- server/src/sys/agent.rs | 17 + server/src/sys/agent/attack.rs | 224 + server/src/sys/agent/data.rs | 3 + voxygen/anim/src/quadruped_low/mod.rs | 11 + voxygen/src/hud/diary.rs | 1 + voxygen/src/hud/img_ids.rs | 3 + voxygen/src/hud/map.rs | 29 +- voxygen/src/hud/minimap.rs | 3 + voxygen/src/hud/mod.rs | 2 + voxygen/src/hud/util.rs | 2 +- voxygen/src/render/pipelines/particle.rs | 1 + voxygen/src/scene/particle.rs | 36 + world/src/civ/mod.rs | 74 +- world/src/lib.rs | 1 + world/src/site/economy/context.rs | 1 + world/src/site/mod.rs | 14 + world/src/site/namegen.rs | 5 +- world/src/site2/mod.rs | 33 + world/src/site2/plot.rs | 4 +- world/src/site2/plot/sea_chapel.rs | 4995 +++++++++++++++++ 122 files changed, 6636 insertions(+), 54 deletions(-) create mode 100644 assets/common/abilities/custom/cardinal/summonseacrocs.ron create mode 100644 assets/common/abilities/custom/dagon/dagonbombs.ron create mode 100644 assets/common/abilities/custom/dagon/seaurchins.ron create mode 100644 assets/common/abilities/custom/organ/organaura.ron create mode 100644 assets/common/entity/dungeon/sea_chapel/cardinal.ron create mode 100644 assets/common/entity/dungeon/sea_chapel/dagon.ron create mode 100644 assets/common/entity/dungeon/sea_chapel/organ.ron create mode 100644 assets/common/entity/dungeon/sea_chapel/sea_cleric.ron create mode 100644 assets/common/entity/dungeon/sea_chapel/sea_cleric_sceptre.ron create mode 100644 assets/common/items/armor/cardinal/belt.ron create mode 100644 assets/common/items/armor/cardinal/chest.ron create mode 100644 assets/common/items/armor/cardinal/foot.ron create mode 100644 assets/common/items/armor/cardinal/hand.ron create mode 100644 assets/common/items/armor/cardinal/pants.ron create mode 100644 assets/common/items/armor/cardinal/shoulder.ron create mode 100644 assets/common/items/armor/misc/neck/abyssal_gorget.ron create mode 100644 assets/common/items/crafting_ing/abyssal_heart.ron create mode 100644 assets/common/items/crafting_ing/coral_branch.ron create mode 100644 assets/common/items/npc_weapons/unique/cardinal.ron create mode 100644 assets/common/items/npc_weapons/unique/dagon.ron create mode 100644 assets/common/items/npc_weapons/unique/organ.ron create mode 100644 assets/common/loadout/dungeon/sea_chapel/cardinal.ron create mode 100644 assets/common/loadout/dungeon/sea_chapel/sea_cleric.ron create mode 100644 assets/common/loot_tables/dungeon/sea_chapel/cardinal.ron create mode 100644 assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron create mode 100644 assets/common/loot_tables/dungeon/sea_chapel/dagon.ron create mode 100644 assets/common/loot_tables/dungeon/sea_chapel/sea_cleric.ron create mode 100644 assets/voxygen/audio/sfx/abilities/barrel_organ.ogg create mode 100644 assets/voxygen/element/ui/map/buttons/sea_chapel.png create mode 100644 assets/voxygen/element/ui/map/buttons/sea_chapel_bg.png create mode 100644 assets/voxygen/element/ui/map/buttons/sea_chapel_hover.png create mode 100644 assets/voxygen/i18n/en/common.ron create mode 100644 assets/voxygen/voxel/armor/cardinal/belt.vox create mode 100644 assets/voxygen/voxel/armor/cardinal/chest.vox create mode 100644 assets/voxygen/voxel/armor/cardinal/foot.vox create mode 100644 assets/voxygen/voxel/armor/cardinal/hand.vox create mode 100644 assets/voxygen/voxel/armor/cardinal/pants.vox create mode 100644 assets/voxygen/voxel/armor/cardinal/shoulder.vox create mode 100644 assets/voxygen/voxel/armor/misc/neck/abyssal_gorget.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/chest.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/foot_br.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/foot_fr.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/head_lower.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/head_upper.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/jaw.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/tail_front.vox create mode 100644 assets/voxygen/voxel/npc/dagon/male/tail_rear.vox create mode 100644 assets/voxygen/voxel/object/dagon_bomb.vox create mode 100644 assets/voxygen/voxel/object/sea_urchin.vox create mode 100644 assets/voxygen/voxel/object/seashell_lantern.vox create mode 100644 assets/voxygen/voxel/sprite/chests/chest_coral.vox create mode 100644 assets/voxygen/voxel/sprite/crafting_ing/abyssal_heart.vox create mode 100644 assets/voxygen/voxel/sprite/crafting_ing/coral_branch.vox create mode 100644 assets/voxygen/voxel/sprite/misc/barrel_organ.vox create mode 100644 assets/voxygen/voxel/sprite/misc/glass_barrier.vox create mode 100644 assets/voxygen/voxel/sprite/misc/rope.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_block.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_chain.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_emblem.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-0.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-1.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-2.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-3.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-4.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-5.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-6.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_pillar-7.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_window_hor.vox create mode 100644 assets/voxygen/voxel/sprite/misc/sea_decor_window_ver.vox create mode 100644 world/src/site2/plot/sea_chapel.rs 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()); + }, + _ => {}, + }; + } + } +}