From 5f4be4975c75bbc852d4a632dfbeb6b1b697a037 Mon Sep 17 00:00:00 2001 From: Wormbo Date: Sun, 6 Oct 2024 17:05:10 +0200 Subject: [PATCH] Loonium with data-driven structure loot (#4639) Implementation for structure detection and structure-specific loot tables and mob spawning pools, customizable via data packs. - structure-specific loot tables are identified by the structure ID (e.g. for `minecraft:pillager_outpost` the custom Loonium loot table is located at `data/botania/loot_tables/loonium/minecraft/pillager_outpost.json`), with a default loot table corresponding to dungeon loot (located at `data/botania/loot_tables/loonium/default.json`) - default loot tables are created with Datagen - loot tables usually just reference original chest or entity loot tables related to each structure, so Loonium loot can be modified separately from the loot found in those structures - structure-specific Loonium configurations are identified the same way (e.g. for `minecraft:pillager_outpost` the custom configuration is located at `data/minecraft/loonium_config/pillager_outpost.json`) with a default configuration (located at `data/botania/loonium_config/default.json`) acting as fallback - default configurations are created via Datagen - configurations can reference a parent configuration and only override individual aspects of the referenced configuration - configurations consist of mana cost to spawn a mob, how many mobs of spawnable types are allowed around the flower, whether the Loonium must be placed in the overall bounding box or an individual piece of the structure, the weighted list of mobs to spawn, a list of potion effects to apply to spawned mobs, and a list of attribute modifiers to apply to the mobs - attribute and effect lists can be overridden for individual mobs - custom NBT data can be defined for individual mobs (used to make a Creeper spawn charged) - equipment loot tables can be specified for each spawnable mob (this will be a vanilla feature in later Minecraft versions, although the implementation here is slightly tweaked from what Trial Chambers use) - expanded wand HUD to indicate whether a Loonium generates structure-specific loot - added lexicon mention of the structure-specific behavior - fixed the mob location selection logic to prevent mobs from immediately starting to suffocate - added a new challenge advancement for killing every mob type in the structure configurations added with this change - mobs spawned by the Loonium are put onto a unique team so they don't just start attacking each other (because there are zoglins in some of the mob spawn pools; Heisei Dream may need a future upgrade to support overriding teams allegiances) --------- Co-authored-by: Artemis System --- .../fabric/FabricCommonInitializer.java | 2 + .../fabric/data/FabricDatagenInitializer.java | 3 + .../CCAInternalEntityComponents.java | 7 +- .../fabric/mixin/LivingEntityFabricMixin.java | 4 +- .../botania/forge/ForgeCommonInitializer.java | 10 +- .../ForgeInternalEntityCapabilities.java | 9 +- .../0bff84ccd1f015523369ae53dac0c4959dd87d86 | 98 ++ .../3547e994b553d8eb42288bd4c3b48108cc98bacb | 32 + .../5e449fe289648869bd1f4d4d99715c8b4e0c057d | 2 + .../a864b94d006aba05700c96ad7a5769c8571473bc | 31 + .../ca0b139d7ffbdcad7e28a9e04c29c4ff458197e3 | 1 + .../challenge/all_loonium_mobs.json | 419 +++++++++ .../data/botania/loonium_config/default.json | 97 ++ .../botania/loonium_config/ocean_ruins.json | 4 + .../data/botania/loonium_config/village.json | 4 + .../equipment/loonium/armor_ancient_city.json | 65 ++ .../loonium/armor_bastion_remnant.json | 20 + .../loonium/armor_desert_pyramid.json | 25 + .../equipment/loonium/armor_end_city.json | 66 ++ .../equipment/loonium/armor_fortress.json | 26 + .../loonium/armor_jungle_temple.json | 25 + .../equipment/loonium/armor_mansion.json | 66 ++ .../equipment/loonium/armor_monument.json | 25 + .../equipment/loonium/armor_outpost.json | 25 + .../equipment/loonium/armor_portal.json | 61 ++ .../equipment/loonium/armor_shipwreck.json | 25 + .../equipment/loonium/armor_stronghold.json | 30 + .../equipment/loonium/armor_trail_ruins.json | 51 + .../loonium/armorset/coast_chain.json | 85 ++ .../loonium/armorset/coast_diamond.json | 85 ++ .../loonium/armorset/coast_iron.json | 85 ++ .../loonium/armorset/costume_enderman.json | 69 ++ .../loonium/armorset/costume_evoker.json | 53 ++ .../loonium/armorset/costume_illusioner.json | 109 +++ .../loonium/armorset/costume_vex.json | 68 ++ .../loonium/armorset/costume_vindicator.json | 80 ++ .../loonium/armorset/dune_diamond.json | 85 ++ .../equipment/loonium/armorset/dune_gold.json | 85 ++ .../equipment/loonium/armorset/dune_iron.json | 85 ++ .../loonium/armorset/eye_diamond.json | 85 ++ .../equipment/loonium/armorset/eye_gold.json | 85 ++ .../equipment/loonium/armorset/eye_iron.json | 85 ++ .../loonium/armorset/host_chain.json | 85 ++ .../equipment/loonium/armorset/host_iron.json | 85 ++ .../loonium/armorset/raiser_gold.json | 85 ++ .../loonium/armorset/raiser_iron.json | 85 ++ .../loonium/armorset/rib_diamond.json | 85 ++ .../equipment/loonium/armorset/rib_gold.json | 85 ++ .../equipment/loonium/armorset/rib_iron.json | 85 ++ .../loonium/armorset/sentry_chain.json | 85 ++ .../loonium/armorset/sentry_diamond.json | 85 ++ .../loonium/armorset/sentry_iron.json | 85 ++ .../loonium/armorset/shaper_diamond.json | 85 ++ .../loonium/armorset/shaper_gold.json | 85 ++ .../loonium/armorset/silence_diamond.json | 85 ++ .../loonium/armorset/silence_gold.json | 85 ++ .../loonium/armorset/snout_gold.json | 85 ++ .../loonium/armorset/snout_netherite.json | 85 ++ .../loonium/armorset/spire_diamond.json | 85 ++ .../loonium/armorset/spire_gold.json | 85 ++ .../loonium/armorset/spire_iron.json | 85 ++ .../loonium/armorset/tide_diamond.json | 85 ++ .../equipment/loonium/armorset/tide_iron.json | 85 ++ .../loonium/armorset/tide_leather.json | 85 ++ .../loonium/armorset/ward_diamond.json | 85 ++ .../equipment/loonium/armorset/ward_iron.json | 85 ++ .../loonium/armorset/wayfinder_chain.json | 85 ++ .../loonium/armorset/wayfinder_diamond.json | 85 ++ .../loonium/armorset/wild_chain.json | 85 ++ .../loonium/armorset/wild_diamond.json | 85 ++ .../equipment/loonium/armorset/wild_gold.json | 85 ++ .../loonium/drowned_ancient_city.json | 25 + .../loonium/drowned_jungle_temple.json | 25 + .../equipment/loonium/drowned_monument.json | 25 + .../equipment/loonium/drowned_portal.json | 25 + .../equipment/loonium/drowned_shipwreck.json | 25 + .../equipment/loonium/drowned_stronghold.json | 25 + .../loonium/drowned_trail_ruins.json | 25 + .../loonium/piglin_bastion_remnant.json | 25 + .../loonium/piglin_ruined_portal.json | 25 + .../loonium/skeleton_ancient_city.json | 25 + .../loonium/skeleton_desert_pyramid.json | 25 + .../equipment/loonium/skeleton_end_city.json | 25 + .../equipment/loonium/skeleton_fortress.json | 25 + .../loonium/skeleton_jungle_temple.json | 25 + .../equipment/loonium/skeleton_monument.json | 25 + .../equipment/loonium/skeleton_outpost.json | 25 + .../equipment/loonium/skeleton_portal.json | 25 + .../equipment/loonium/skeleton_shipwreck.json | 25 + .../loonium/skeleton_stronghold.json | 25 + .../loonium/skeleton_trail_ruins.json | 25 + .../equipment/loonium/weapon_axe.json | 26 + .../equipment/loonium/weapon_axe_gold.json | 26 + .../equipment/loonium/weapon_bow.json | 26 + .../loonium/weapon_by_profession.json | 98 ++ .../equipment/loonium/weapon_crossbow.json | 20 + .../equipment/loonium/weapon_for_piglin.json | 30 + .../loonium/weapon_for_wither_skeleton.json | 28 + .../equipment/loonium/weapon_sword.json | 31 + .../equipment/loonium/weapon_sword_gold.json | 26 + .../equipment/loonium/weapon_trident.json | 15 + .../loonium/zombie_ancient_city.json | 25 + .../loonium/zombie_desert_pyramid.json | 25 + .../equipment/loonium/zombie_end_city.json | 25 + .../equipment/loonium/zombie_fortress.json | 25 + .../loonium/zombie_jungle_temple.json | 25 + .../equipment/loonium/zombie_monument.json | 25 + .../equipment/loonium/zombie_outpost.json | 25 + .../equipment/loonium/zombie_portal.json | 25 + .../equipment/loonium/zombie_shipwreck.json | 25 + .../equipment/loonium/zombie_stronghold.json | 25 + .../equipment/loonium/zombie_trail_ruins.json | 25 + .../botania/loot_tables/loonium/default.json | 14 + .../loonium/minecraft/ancient_city.json | 19 + .../loonium/minecraft/bastion_remnant.json | 27 + .../loonium/minecraft/buried_treasure.json | 14 + .../loonium/minecraft/desert_pyramid.json | 24 + .../loonium/minecraft/end_city.json | 19 + .../loonium/minecraft/fortress.json | 14 + .../loonium/minecraft/jungle_pyramid.json | 19 + .../loonium/minecraft/mansion.json | 19 + .../loonium/minecraft/mineshaft.json | 14 + .../loonium/minecraft/mineshaft_mesa.json | 14 + .../loonium/minecraft/monument.json | 19 + .../loonium/minecraft/ocean_ruin_cold.json | 23 + .../loonium/minecraft/ocean_ruin_warm.json | 23 + .../loonium/minecraft/pillager_outpost.json | 14 + .../loonium/minecraft/ruined_portal.json | 14 + .../minecraft/ruined_portal_desert.json | 14 + .../minecraft/ruined_portal_jungle.json | 14 + .../minecraft/ruined_portal_mountain.json | 14 + .../minecraft/ruined_portal_nether.json | 14 + .../minecraft/ruined_portal_ocean.json | 14 + .../minecraft/ruined_portal_swamp.json | 14 + .../loonium/minecraft/shipwreck.json | 22 + .../loonium/minecraft/shipwreck_beached.json | 22 + .../loonium/minecraft/stronghold.json | 25 + .../loonium/minecraft/trail_ruins.json | 19 + .../loonium/minecraft/village_desert.json | 27 + .../loonium/minecraft/village_plains.json | 31 + .../loonium/minecraft/village_savanna.json | 35 + .../loonium/minecraft/village_snowy.json | 35 + .../loonium/minecraft/village_taiga.json | 35 + .../tags/items/loonium_offhand_equipment.json | 8 + .../loonium_config/ancient_city.json | 73 ++ .../loonium_config/bastion_remnant.json | 90 ++ .../loonium_config/desert_pyramid.json | 63 ++ .../minecraft/loonium_config/end_city.json | 88 ++ .../minecraft/loonium_config/fortress.json | 74 ++ .../loonium_config/jungle_pyramid.json | 63 ++ .../minecraft/loonium_config/mansion.json | 78 ++ .../minecraft/loonium_config/monument.json | 96 ++ .../loonium_config/ocean_ruin_cold.json | 92 ++ .../loonium_config/ocean_ruin_warm.json | 87 ++ .../loonium_config/pillager_outpost.json | 69 ++ .../loonium_config/ruined_portal.json | 114 +++ .../loonium_config/ruined_portal_desert.json | 100 ++ .../loonium_config/ruined_portal_jungle.json | 104 +++ .../ruined_portal_mountain.json | 104 +++ .../loonium_config/ruined_portal_nether.json | 98 ++ .../loonium_config/ruined_portal_ocean.json | 131 +++ .../loonium_config/ruined_portal_swamp.json | 104 +++ .../minecraft/loonium_config/shipwreck.json | 92 ++ .../loonium_config/shipwreck_beached.json | 3 + .../minecraft/loonium_config/stronghold.json | 77 ++ .../minecraft/loonium_config/trail_ruins.json | 73 ++ .../loonium_config/village_desert.json | 68 ++ .../loonium_config/village_plains.json | 68 ++ .../loonium_config/village_savanna.json | 73 ++ .../loonium_config/village_snowy.json | 73 ++ .../loonium_config/village_taiga.json | 73 ++ .../data/minecraft/tags/items/arrows.json | 4 + .../java/vazkii/botania/api/BotaniaAPI.java | 9 + .../api/configdata/ConfigDataManager.java | 11 + .../LooniumMobAttributeModifier.java | 67 ++ .../configdata/LooniumMobEffectToApply.java | 103 ++ .../api/configdata/LooniumMobSpawnData.java | 161 ++++ .../LooniumStructureConfiguration.java | 182 ++++ .../common/block/BotaniaFlowerBlocks.java | 3 +- .../flower/functional/LooniumBlockEntity.java | 632 ++++++++++--- .../common/config/ConfigDataManagerImpl.java | 124 +++ .../botania/common/impl/BotaniaAPIImpl.java | 14 + .../internal_caps/LooniumComponent.java | 49 +- .../botania/common/lib/BotaniaTags.java | 5 + .../common/loot/BotaniaLootTables.java | 153 +++ .../botania/data/AdvancementProvider.java | 44 + .../vazkii/botania/data/ItemTagProvider.java | 9 +- .../data/LooniumEquipmentLootProvider.java | 876 ++++++++++++++++++ ...LooniumStructureConfigurationProvider.java | 752 +++++++++++++++ .../data/LooniumStructureLootProvider.java | 251 +++++ .../vazkii/botania/mixin/EntityMixin.java | 17 + .../java/vazkii/botania/mixin/MobMixin.java | 40 + .../resources/assets/botania/lang/en_us.json | 41 +- .../entries/functional_flowers/loonium.json | 6 +- .../main/resources/botania_xplat.mixins.json | 1 + Xplat/src/main/resources/omake.md | 3 +- web/changelog.md | 5 +- 197 files changed, 12224 insertions(+), 142 deletions(-) create mode 100644 Xplat/src/generated/resources/.cache/0bff84ccd1f015523369ae53dac0c4959dd87d86 create mode 100644 Xplat/src/generated/resources/.cache/3547e994b553d8eb42288bd4c3b48108cc98bacb create mode 100644 Xplat/src/generated/resources/.cache/a864b94d006aba05700c96ad7a5769c8571473bc create mode 100644 Xplat/src/generated/resources/data/botania/advancements/challenge/all_loonium_mobs.json create mode 100644 Xplat/src/generated/resources/data/botania/loonium_config/default.json create mode 100644 Xplat/src/generated/resources/data/botania/loonium_config/ocean_ruins.json create mode 100644 Xplat/src/generated/resources/data/botania/loonium_config/village.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_ancient_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_bastion_remnant.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_desert_pyramid.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_end_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_fortress.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_jungle_temple.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_mansion.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_monument.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_outpost.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_portal.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_shipwreck.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_stronghold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_trail_ruins.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_chain.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_enderman.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_evoker.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_illusioner.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vex.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vindicator.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_chain.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_chain.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_netherite.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_leather.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_iron.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_chain.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_chain.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_diamond.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_ancient_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_jungle_temple.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_monument.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_portal.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_shipwreck.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_stronghold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_trail_ruins.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_bastion_remnant.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_ruined_portal.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_ancient_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_desert_pyramid.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_end_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_fortress.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_jungle_temple.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_monument.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_outpost.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_portal.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_shipwreck.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_stronghold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_trail_ruins.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_bow.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_by_profession.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_crossbow.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_piglin.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_wither_skeleton.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword_gold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_trident.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_ancient_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_desert_pyramid.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_end_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_fortress.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_jungle_temple.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_monument.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_outpost.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_portal.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_shipwreck.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_stronghold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_trail_ruins.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/default.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ancient_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/bastion_remnant.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/buried_treasure.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/desert_pyramid.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/end_city.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/fortress.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/jungle_pyramid.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mansion.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft_mesa.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/monument.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_cold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_warm.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/pillager_outpost.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_desert.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_jungle.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_mountain.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_nether.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_ocean.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_swamp.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck_beached.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/stronghold.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/trail_ruins.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_desert.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_plains.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_savanna.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_snowy.json create mode 100644 Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_taiga.json create mode 100644 Xplat/src/generated/resources/data/botania/tags/items/loonium_offhand_equipment.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ancient_city.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/bastion_remnant.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/desert_pyramid.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/end_city.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/fortress.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/jungle_pyramid.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/mansion.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/monument.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_cold.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_warm.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/pillager_outpost.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_desert.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_jungle.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_mountain.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_nether.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_ocean.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_swamp.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck_beached.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/stronghold.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/trail_ruins.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/village_desert.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/village_plains.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/village_savanna.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/village_snowy.json create mode 100644 Xplat/src/generated/resources/data/minecraft/loonium_config/village_taiga.json create mode 100644 Xplat/src/generated/resources/data/minecraft/tags/items/arrows.json create mode 100644 Xplat/src/main/java/vazkii/botania/api/configdata/ConfigDataManager.java create mode 100644 Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobAttributeModifier.java create mode 100644 Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobEffectToApply.java create mode 100644 Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobSpawnData.java create mode 100644 Xplat/src/main/java/vazkii/botania/api/configdata/LooniumStructureConfiguration.java create mode 100644 Xplat/src/main/java/vazkii/botania/common/config/ConfigDataManagerImpl.java create mode 100644 Xplat/src/main/java/vazkii/botania/common/loot/BotaniaLootTables.java create mode 100644 Xplat/src/main/java/vazkii/botania/data/LooniumEquipmentLootProvider.java create mode 100644 Xplat/src/main/java/vazkii/botania/data/LooniumStructureConfigurationProvider.java create mode 100644 Xplat/src/main/java/vazkii/botania/data/LooniumStructureLootProvider.java create mode 100644 Xplat/src/main/java/vazkii/botania/mixin/MobMixin.java diff --git a/Fabric/src/main/java/vazkii/botania/fabric/FabricCommonInitializer.java b/Fabric/src/main/java/vazkii/botania/fabric/FabricCommonInitializer.java index 8373f286bb..2d41c79736 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/FabricCommonInitializer.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/FabricCommonInitializer.java @@ -81,6 +81,7 @@ import vazkii.botania.common.brew.BotaniaBrews; import vazkii.botania.common.brew.BotaniaMobEffects; import vazkii.botania.common.command.SkyblockCommand; +import vazkii.botania.common.config.ConfigDataManagerImpl; import vazkii.botania.common.crafting.BotaniaRecipeTypes; import vazkii.botania.common.entity.BotaniaEntities; import vazkii.botania.common.entity.GaiaGuardianEntity; @@ -138,6 +139,7 @@ public void onInitialize() { PatchouliAPI.get().registerMultiblock(prefix("gaia_ritual"), GaiaGuardianEntity.ARENA_MULTIBLOCK.get()); OrechidManager.registerListener(); + ConfigDataManagerImpl.registerListener(); CraftyCrateBlockEntity.registerListener(); CorporeaNodeDetectors.register(new FabricTransferCorporeaNodeDetector()); diff --git a/Fabric/src/main/java/vazkii/botania/fabric/data/FabricDatagenInitializer.java b/Fabric/src/main/java/vazkii/botania/fabric/data/FabricDatagenInitializer.java index cf2fc0618a..37152ac047 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/data/FabricDatagenInitializer.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/data/FabricDatagenInitializer.java @@ -41,6 +41,9 @@ private static void configureFabricDatagen(FabricDataGenerator.Pack pack) { private static void configureXplatDatagen(FabricDataGenerator.Pack pack) { pack.addProvider((PackOutput output) -> new BlockLootProvider(output)); + pack.addProvider((PackOutput output) -> new LooniumStructureLootProvider(output)); + pack.addProvider((PackOutput output) -> new LooniumStructureConfigurationProvider(output)); + pack.addProvider(LooniumEquipmentLootProvider::new); BlockTagProvider blockTagProvider = pack.addProvider(BlockTagProvider::new); pack.addProvider((output, registriesFuture) -> new ItemTagProvider(output, registriesFuture, blockTagProvider.contentsGetter())); pack.addProvider(EntityTagProvider::new); diff --git a/Fabric/src/main/java/vazkii/botania/fabric/internal_caps/CCAInternalEntityComponents.java b/Fabric/src/main/java/vazkii/botania/fabric/internal_caps/CCAInternalEntityComponents.java index 4125d95cae..a13dcaf190 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/internal_caps/CCAInternalEntityComponents.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/internal_caps/CCAInternalEntityComponents.java @@ -15,12 +15,12 @@ import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer; import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.PrimedTnt; import net.minecraft.world.entity.monster.*; import net.minecraft.world.entity.vehicle.AbstractMinecart; -import vazkii.botania.common.block.flower.functional.LooniumBlockEntity; import vazkii.botania.common.internal_caps.*; import static vazkii.botania.common.lib.ResourceLocationHelper.prefix; @@ -36,10 +36,7 @@ public class CCAInternalEntityComponents implements EntityComponentInitializer { @Override public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) { - for (Class clz : LooniumBlockEntity.VALID_MOBS) { - registry.registerFor(clz, LOONIUM_DROP, e -> new CCALooniumComponent()); - } - + registry.registerFor(Mob.class, LOONIUM_DROP, e -> new CCALooniumComponent()); registry.registerFor(PrimedTnt.class, TNT_ETHICAL, CCAEthicalComponent::new); registry.registerFor(Slime.class, NARSLIMMUS, e -> new CCANarslimmusComponent()); registry.registerFor(ItemEntity.class, INTERNAL_ITEM, e -> new CCAItemFlagsComponent()); diff --git a/Fabric/src/main/java/vazkii/botania/fabric/mixin/LivingEntityFabricMixin.java b/Fabric/src/main/java/vazkii/botania/fabric/mixin/LivingEntityFabricMixin.java index 77fc8277e9..3834d002e7 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/mixin/LivingEntityFabricMixin.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/mixin/LivingEntityFabricMixin.java @@ -55,7 +55,9 @@ private void dropEnd(DamageSource source, CallbackInfo ci) { private void dropLoonium(DamageSource source, boolean causedByPlayer, CallbackInfo ci) { var self = (LivingEntity) (Object) this; LooniumBlockEntity.dropLooniumItems(self, stack -> { - self.spawnAtLocation(stack); + if (!stack.isEmpty()) { + self.spawnAtLocation(stack); + } ci.cancel(); }); } diff --git a/Forge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java b/Forge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java index 283e0ea270..46ec6f3ec6 100644 --- a/Forge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java +++ b/Forge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java @@ -94,6 +94,7 @@ import vazkii.botania.common.brew.BotaniaMobEffects; import vazkii.botania.common.brew.effect.SoulCrossMobEffect; import vazkii.botania.common.command.SkyblockCommand; +import vazkii.botania.common.config.ConfigDataManagerImpl; import vazkii.botania.common.crafting.BotaniaRecipeTypes; import vazkii.botania.common.entity.BotaniaEntities; import vazkii.botania.common.entity.GaiaGuardianEntity; @@ -166,6 +167,7 @@ public void commonSetup(FMLCommonSetupEvent evt) { PatchouliAPI.get().registerMultiblock(prefix("gaia_ritual"), GaiaGuardianEntity.ARENA_MULTIBLOCK.get()); OrechidManager.registerListener(); + ConfigDataManagerImpl.registerListener(); CraftyCrateBlockEntity.registerListener(); CorporeaNodeDetectors.register(new ForgeCapCorporeaNodeDetector()); if (ModList.get().isLoaded("inventorysorter")) { @@ -393,9 +395,11 @@ private void registerEvents() { }); LooniumBlockEntity.dropLooniumItems(living, stack -> { e.getDrops().clear(); - var ent = new ItemEntity(living.level(), living.getX(), living.getY(), living.getZ(), stack); - ent.setDefaultPickUpDelay(); - e.getDrops().add(ent); + if (!stack.isEmpty()) { + var ent = new ItemEntity(living.level(), living.getX(), living.getY(), living.getZ(), stack); + ent.setDefaultPickUpDelay(); + e.getDrops().add(ent); + } }); }); bus.addListener((LivingDeathEvent e) -> { diff --git a/Forge/src/main/java/vazkii/botania/forge/internal_caps/ForgeInternalEntityCapabilities.java b/Forge/src/main/java/vazkii/botania/forge/internal_caps/ForgeInternalEntityCapabilities.java index a5abd8fc52..22fa44c72a 100644 --- a/Forge/src/main/java/vazkii/botania/forge/internal_caps/ForgeInternalEntityCapabilities.java +++ b/Forge/src/main/java/vazkii/botania/forge/internal_caps/ForgeInternalEntityCapabilities.java @@ -1,6 +1,7 @@ package vazkii.botania.forge.internal_caps; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.PrimedTnt; import net.minecraft.world.entity.monster.Creeper; @@ -12,7 +13,6 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import vazkii.botania.common.block.flower.functional.LooniumBlockEntity; import vazkii.botania.common.internal_caps.*; import vazkii.botania.common.lib.LibMisc; import vazkii.botania.forge.CapabilityUtil; @@ -60,11 +60,8 @@ public static void attachCapabilities(AttachCapabilitiesEvent evt) { if (entity instanceof Player) { evt.addCapability(prefix("kept_items"), CapabilityUtil.makeSavedProvider(KEPT_ITEMS, new KeptItemsComponent())); } - for (Class clz : LooniumBlockEntity.VALID_MOBS) { - if (clz.isInstance(entity)) { - evt.addCapability(prefix("loonium_drop"), CapabilityUtil.makeSavedProvider(LOONIUM_DROP, new LooniumComponent())); - break; - } + if (entity instanceof Mob) { + evt.addCapability(prefix("loonium_drop"), CapabilityUtil.makeSavedProvider(LOONIUM_DROP, new LooniumComponent())); } if (entity instanceof Slime) { evt.addCapability(prefix("narslimmus"), CapabilityUtil.makeSavedProvider(NARSLIMMUS, new NarslimmusComponent())); diff --git a/Xplat/src/generated/resources/.cache/0bff84ccd1f015523369ae53dac0c4959dd87d86 b/Xplat/src/generated/resources/.cache/0bff84ccd1f015523369ae53dac0c4959dd87d86 new file mode 100644 index 0000000000..9f1bbe5e0e --- /dev/null +++ b/Xplat/src/generated/resources/.cache/0bff84ccd1f015523369ae53dac0c4959dd87d86 @@ -0,0 +1,98 @@ +// 1.20.1 Botania/Equipment tables for Loonium-spawned mobs +d2d97790090ee9148c5874dce5f8bb0bc0b91ddb data/botania/loot_tables/equipment/loonium/armor_ancient_city.json +c06c1a3ccc8ccb595950f08aaaa240868a681d85 data/botania/loot_tables/equipment/loonium/armor_bastion_remnant.json +197dfbd608b1f8761a35cde1bbfa4437dd396bce data/botania/loot_tables/equipment/loonium/armor_desert_pyramid.json +6c8f153b75966de1b47a89e66903c2733eeffcbc data/botania/loot_tables/equipment/loonium/armor_end_city.json +bbb294e3c587c6aadd91b6de179b16a55d2fc028 data/botania/loot_tables/equipment/loonium/armor_fortress.json +61b88ad4c3ced50cdfc8de265f1bab35b284fed8 data/botania/loot_tables/equipment/loonium/armor_jungle_temple.json +9a7bda203fde78ed212f9f42e153c2db95f9bb71 data/botania/loot_tables/equipment/loonium/armor_mansion.json +9023c47b8e0f2b3ed4bd6ec94f7b63d5e7278019 data/botania/loot_tables/equipment/loonium/armor_monument.json +65fec1f91f060f890366e8dd81d2ae6fc6144c59 data/botania/loot_tables/equipment/loonium/armor_outpost.json +e6467391bc3b6aceb5f13a32c9a1aaa9f4d4b4c2 data/botania/loot_tables/equipment/loonium/armor_portal.json +155849b4490ff9fc0c7cb4645799732c9f2a39f7 data/botania/loot_tables/equipment/loonium/armor_shipwreck.json +1ac5abff926dc65dd07ea1a5b3be1b4eab1f7420 data/botania/loot_tables/equipment/loonium/armor_stronghold.json +1810ab86916bf719cde65837601444d108fd9ba1 data/botania/loot_tables/equipment/loonium/armor_trail_ruins.json +64cdf979d34f80cc152e6d2585534637a9c0ab6a data/botania/loot_tables/equipment/loonium/armorset/coast_chain.json +a4062156d86f0e3118c737aaa15824cf939a8a5e data/botania/loot_tables/equipment/loonium/armorset/coast_diamond.json +b83a0957eafaec881f3834d8f6a2f6ce914b0fb7 data/botania/loot_tables/equipment/loonium/armorset/coast_iron.json +8b6a06d644dd18c79cfaeed5490f66f802178587 data/botania/loot_tables/equipment/loonium/armorset/costume_enderman.json +dd22cdb3c94b865bd7ffb127b7477e1f53196326 data/botania/loot_tables/equipment/loonium/armorset/costume_evoker.json +49269b75243e761cf3ee3c73b7892af6fbe3f99c data/botania/loot_tables/equipment/loonium/armorset/costume_illusioner.json +2f9b423eefa13c866fb93010779f0c4ddc1711f8 data/botania/loot_tables/equipment/loonium/armorset/costume_vex.json +0b73cebe599a21c8a491fa7ce31f92005ab0a808 data/botania/loot_tables/equipment/loonium/armorset/costume_vindicator.json +62b4a0a5d7cc87fb78c720381f50de85e2b25171 data/botania/loot_tables/equipment/loonium/armorset/dune_diamond.json +dee03b0097233fc14f47b00ea1ebff71ae73ea76 data/botania/loot_tables/equipment/loonium/armorset/dune_gold.json +7f51db8be2857081c5cb79ccd5f375322f4385b1 data/botania/loot_tables/equipment/loonium/armorset/dune_iron.json +1e380cf2ea44d74cee496df10cd3c9f86d304ea9 data/botania/loot_tables/equipment/loonium/armorset/eye_diamond.json +c33f9878395c5eab27c766d5be2ad1fc955b8fe7 data/botania/loot_tables/equipment/loonium/armorset/eye_gold.json +df0c65c5d6474d8218b94a2ed72667fff2a84f7f data/botania/loot_tables/equipment/loonium/armorset/eye_iron.json +15d092165619316f80fc055b3f3510942ee18eea data/botania/loot_tables/equipment/loonium/armorset/host_chain.json +5d9368f62b40e31a20bdbc068fb2b70b64e1ad1f data/botania/loot_tables/equipment/loonium/armorset/host_iron.json +18ab8a1947d4ae5f3b9c80703c0d13ede5e1921e data/botania/loot_tables/equipment/loonium/armorset/raiser_gold.json +e875f62f9487282245deb2e514e37d25e4813fc9 data/botania/loot_tables/equipment/loonium/armorset/raiser_iron.json +0adceb4ce9482a45a45f2a3635be711053afc7d9 data/botania/loot_tables/equipment/loonium/armorset/rib_diamond.json +c3f9146437887c9ccee17946ea5772d484fac428 data/botania/loot_tables/equipment/loonium/armorset/rib_gold.json +79f8602bab188cf2eaba5cebb1b5be576bfb78de data/botania/loot_tables/equipment/loonium/armorset/rib_iron.json +fababc8d774bfe1b0abd36d99e92eb1f633fbfbe data/botania/loot_tables/equipment/loonium/armorset/sentry_chain.json +ecf25cd2a32504cc0c25cc2fdf5773e1dde080af data/botania/loot_tables/equipment/loonium/armorset/sentry_diamond.json +1ee7e387838d153a9ce73302317b250273ff72c3 data/botania/loot_tables/equipment/loonium/armorset/sentry_iron.json +afe5bfe4c03564793ca4d1bc581b7c1cbf2c3a92 data/botania/loot_tables/equipment/loonium/armorset/shaper_diamond.json +4547c759f5bb824ed5ab072dcd39020e4fef638c data/botania/loot_tables/equipment/loonium/armorset/shaper_gold.json +d8b9f63fca55aced8f4497377837c659260fdbde data/botania/loot_tables/equipment/loonium/armorset/silence_diamond.json +832dc70e8af71f3a9a6a20bf4c03e57b44891f58 data/botania/loot_tables/equipment/loonium/armorset/silence_gold.json +d03310c712e1a18fbb055e7ec289c99ed06968d7 data/botania/loot_tables/equipment/loonium/armorset/snout_gold.json +fb17211351d534ae8b7d12ee98bbacc0f065ebd1 data/botania/loot_tables/equipment/loonium/armorset/snout_netherite.json +5612788810c9ee76e6cce41c3d2b68926f2ff09a data/botania/loot_tables/equipment/loonium/armorset/spire_diamond.json +49e343184818d17a75963a03eaf4e4585b188bbe data/botania/loot_tables/equipment/loonium/armorset/spire_gold.json +a07226b2c4d4e16dc8d221d6fd6ed53be17f8f33 data/botania/loot_tables/equipment/loonium/armorset/spire_iron.json +1b27407aabdcace073f95a9265ee45aa907b0a55 data/botania/loot_tables/equipment/loonium/armorset/tide_diamond.json +2f6727f2daab0cdcee6ec0931b0e5b9570661e3b data/botania/loot_tables/equipment/loonium/armorset/tide_iron.json +64d88957468cce4f80014cbaf001dd0fe45d463c data/botania/loot_tables/equipment/loonium/armorset/tide_leather.json +27b2e51aec7626ef3085861c959e6cd403ac8f94 data/botania/loot_tables/equipment/loonium/armorset/ward_diamond.json +82d0147c20406301841b5e240561f34040d3fc4f data/botania/loot_tables/equipment/loonium/armorset/ward_iron.json +09c583a95c65f194f157e2874f01acd866cb2e5a data/botania/loot_tables/equipment/loonium/armorset/wayfinder_chain.json +f693f82e1b419579aff3ddb356f8056d0eea045b data/botania/loot_tables/equipment/loonium/armorset/wayfinder_diamond.json +8b5869d12a3dfe73f018c49f095d46059782541b data/botania/loot_tables/equipment/loonium/armorset/wild_chain.json +7ef875de72ebba47568ae592a229dc0dc9d89167 data/botania/loot_tables/equipment/loonium/armorset/wild_diamond.json +226283d2a875bcf4aa7d75f2ebefc0a19fb24c5f data/botania/loot_tables/equipment/loonium/armorset/wild_gold.json +acb3558a9e9a8f4ce94e519f21e7a2bbd8dc6b31 data/botania/loot_tables/equipment/loonium/drowned_ancient_city.json +453432d6efe4299f9f4d18407e3b0a3c91acb276 data/botania/loot_tables/equipment/loonium/drowned_jungle_temple.json +0d974a59acf32a6d5183c80433f259837245e2f4 data/botania/loot_tables/equipment/loonium/drowned_monument.json +ee8aaeda7c9149a5003985e912973d1f4e0229d2 data/botania/loot_tables/equipment/loonium/drowned_portal.json +d94ec76d440f4374d17a547b31958489e69c25b0 data/botania/loot_tables/equipment/loonium/drowned_shipwreck.json +615ae2e7ef1919aeacdf40c5fe5f74e073f1524a data/botania/loot_tables/equipment/loonium/drowned_stronghold.json +3d268d995222e434cee429c935283cef479981a0 data/botania/loot_tables/equipment/loonium/drowned_trail_ruins.json +4c1dfb801ba21ceb2d95f6c7e8c7315eb2de276b data/botania/loot_tables/equipment/loonium/piglin_bastion_remnant.json +0fa752f016f96a8f070139520a01328416d62d3e data/botania/loot_tables/equipment/loonium/piglin_ruined_portal.json +4529a571d5d8b1e99ec82af3570eb649f1e027de data/botania/loot_tables/equipment/loonium/skeleton_ancient_city.json +f8d26c1eb15f9b523ee319f568da517a9ac42b77 data/botania/loot_tables/equipment/loonium/skeleton_desert_pyramid.json +98dde3ae66e2f769a08f77c6386f958e32c39d6e data/botania/loot_tables/equipment/loonium/skeleton_end_city.json +ac43d8215ae8ba53c8e36112f2cf540c4511d65e data/botania/loot_tables/equipment/loonium/skeleton_fortress.json +cb528917009d86e7f9a9390efd8722973233794d data/botania/loot_tables/equipment/loonium/skeleton_jungle_temple.json +3b3f04d1200b9d1dcfb406e0b24d4c0841deb3e7 data/botania/loot_tables/equipment/loonium/skeleton_monument.json +d1e4b4a1449f7fb32b006d3a366c4e3aa0e15413 data/botania/loot_tables/equipment/loonium/skeleton_outpost.json +aec2bfd13e0225e5b97caa4500cf5cdb82b2c33c data/botania/loot_tables/equipment/loonium/skeleton_portal.json +467fb3ddf9b00ca142b5cd36e64a3f836dbdf991 data/botania/loot_tables/equipment/loonium/skeleton_shipwreck.json +9a9522f614252c7f1ffc5c8a91688058c873b245 data/botania/loot_tables/equipment/loonium/skeleton_stronghold.json +da68cba7311b0491de3292f9839286b811978cde data/botania/loot_tables/equipment/loonium/skeleton_trail_ruins.json +4d90fc75701ca64b3dc1ca113a3241332c12dacd data/botania/loot_tables/equipment/loonium/weapon_axe.json +b0a054e7a5c5061d8f158c69c09736f1da96a6f8 data/botania/loot_tables/equipment/loonium/weapon_axe_gold.json +5fc5c5781d1b13e8120753688284c6bef1be5aef data/botania/loot_tables/equipment/loonium/weapon_bow.json +c197fd5bcbed8d185e3dafefb2829015a28ae6f6 data/botania/loot_tables/equipment/loonium/weapon_by_profession.json +810e9e9e3d1bdf67f5ae69d88702f8d264ab0598 data/botania/loot_tables/equipment/loonium/weapon_crossbow.json +5f44d78700ec5dc02bac5e8e2ae5eee455f9c232 data/botania/loot_tables/equipment/loonium/weapon_for_piglin.json +2b754c2dbecebb9fe890984c40cc2c54293ad6de data/botania/loot_tables/equipment/loonium/weapon_for_wither_skeleton.json +1d16d90dc387940cb4c26a2a9473fb3370284687 data/botania/loot_tables/equipment/loonium/weapon_sword.json +c769e1a46ce3e1684bf520099eb62365ae07ae07 data/botania/loot_tables/equipment/loonium/weapon_sword_gold.json +2777fc3f1cc95e99d1220d6e8cb8d06b4d4abdd9 data/botania/loot_tables/equipment/loonium/weapon_trident.json +c5eb14b815137526d5afebffc6101e75a02f7ee4 data/botania/loot_tables/equipment/loonium/zombie_ancient_city.json +818ba2505d70ec63d0dad65f007fa31ecbbbd4bc data/botania/loot_tables/equipment/loonium/zombie_desert_pyramid.json +7da85f3c4060eb361de9d73a7c3f659cef163d9c data/botania/loot_tables/equipment/loonium/zombie_end_city.json +360712cf81439555f12c31903a2c3a06ab429c5a data/botania/loot_tables/equipment/loonium/zombie_fortress.json +7208b89dfe549972a83afc30c7ac7f18f1c08ef7 data/botania/loot_tables/equipment/loonium/zombie_jungle_temple.json +c00bae89ae9f9c64e55a093353d7bb00325e93ef data/botania/loot_tables/equipment/loonium/zombie_monument.json +a496021cf9683d471e481564402e20321d105f7b data/botania/loot_tables/equipment/loonium/zombie_outpost.json +e2c191759bb9573543348c294b61205492cadfa9 data/botania/loot_tables/equipment/loonium/zombie_portal.json +f7df591afa16e5b8e2894486a4bfe78dd88a155f data/botania/loot_tables/equipment/loonium/zombie_shipwreck.json +3e34705ca4212a71301e911e38716aa28a84fe96 data/botania/loot_tables/equipment/loonium/zombie_stronghold.json +cf5952b919dcadc0ae2974fec273e9161a036df1 data/botania/loot_tables/equipment/loonium/zombie_trail_ruins.json diff --git a/Xplat/src/generated/resources/.cache/3547e994b553d8eb42288bd4c3b48108cc98bacb b/Xplat/src/generated/resources/.cache/3547e994b553d8eb42288bd4c3b48108cc98bacb new file mode 100644 index 0000000000..daa7bdabff --- /dev/null +++ b/Xplat/src/generated/resources/.cache/3547e994b553d8eb42288bd4c3b48108cc98bacb @@ -0,0 +1,32 @@ +// 1.20.1 Botania/Structure-specific loot tables for the Loonium +6c6809bce2449842eda497516397ecbe8e248df4 data/botania/loot_tables/loonium/default.json +267952295cf69e668286ae1bbeec2334c4edffe3 data/botania/loot_tables/loonium/minecraft/ancient_city.json +8fecd7949aa156ce411d58218d1b97c755535e6a data/botania/loot_tables/loonium/minecraft/bastion_remnant.json +1e75a9528dfcf3a5c0df85b75c3d369c267f77d5 data/botania/loot_tables/loonium/minecraft/buried_treasure.json +1cbf48dcdaf2af8351fb859d075ed2471dbd5f52 data/botania/loot_tables/loonium/minecraft/desert_pyramid.json +2d95f29b0eeeb7517c82df00bc21aff1b3597fe0 data/botania/loot_tables/loonium/minecraft/end_city.json +348f2833a2b7725e62c03900b8d8511b1fbfcb1b data/botania/loot_tables/loonium/minecraft/fortress.json +9c8d5d72012c2c8ee595515607c5abca0644c334 data/botania/loot_tables/loonium/minecraft/jungle_pyramid.json +5e2abaf4e3a107350d603e4628a1252bce12d03b data/botania/loot_tables/loonium/minecraft/mansion.json +4d8a8b2550a0990a532ed9f70345fa5e83b07de6 data/botania/loot_tables/loonium/minecraft/mineshaft.json +4d8a8b2550a0990a532ed9f70345fa5e83b07de6 data/botania/loot_tables/loonium/minecraft/mineshaft_mesa.json +f073cbe252275ea680254649fd76562bc90dcec6 data/botania/loot_tables/loonium/minecraft/monument.json +65539ebf73f516910d4bee33fe3d5b5e039c6ae8 data/botania/loot_tables/loonium/minecraft/ocean_ruin_cold.json +179e67b66efd46d1bde90a87faf31f204c183fb6 data/botania/loot_tables/loonium/minecraft/ocean_ruin_warm.json +dcc92e196579e50af5ba2210f7666565f15c6685 data/botania/loot_tables/loonium/minecraft/pillager_outpost.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal_desert.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal_jungle.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal_mountain.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal_nether.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal_ocean.json +329743f53ff7d033ece348dcfbed39486a37fd7b data/botania/loot_tables/loonium/minecraft/ruined_portal_swamp.json +eedca76b1bd188582858397700fa2b2b97be8ae9 data/botania/loot_tables/loonium/minecraft/shipwreck.json +eedca76b1bd188582858397700fa2b2b97be8ae9 data/botania/loot_tables/loonium/minecraft/shipwreck_beached.json +6f288919e482acaa3393c5414daec2ff32028e95 data/botania/loot_tables/loonium/minecraft/stronghold.json +7bee83bc1b0b65175d183f14616dc92762a2d21e data/botania/loot_tables/loonium/minecraft/trail_ruins.json +5929a698590cc3b760e4623216fc3f31fe83817c data/botania/loot_tables/loonium/minecraft/village_desert.json +5e3467c6ab990167715bd080daad32679c0ee875 data/botania/loot_tables/loonium/minecraft/village_plains.json +d53e1eb39b960c2a5a2a1358a2b97b6064579947 data/botania/loot_tables/loonium/minecraft/village_savanna.json +4bf269c31e2c2a8612593134bfb1ab88566ca032 data/botania/loot_tables/loonium/minecraft/village_snowy.json +ce9e974c10c29f8fd7c684b7bd54d833bb657217 data/botania/loot_tables/loonium/minecraft/village_taiga.json diff --git a/Xplat/src/generated/resources/.cache/5e449fe289648869bd1f4d4d99715c8b4e0c057d b/Xplat/src/generated/resources/.cache/5e449fe289648869bd1f4d4d99715c8b4e0c057d index 2d2993363f..54f52a6c65 100644 --- a/Xplat/src/generated/resources/.cache/5e449fe289648869bd1f4d4d99715c8b4e0c057d +++ b/Xplat/src/generated/resources/.cache/5e449fe289648869bd1f4d4d99715c8b4e0c057d @@ -17,6 +17,7 @@ ac3888e68025d31c8c109b225689e7d69ad7f603 data/botania/tags/items/lens.json dfbc18cbf412594282532933002d270b34b3f16f data/botania/tags/items/lens_glue.json bbb827430199d1a6f3b27fc25e2df941f22dc660 data/botania/tags/items/livingwood_logs.json 0f00c4dbb7edb499acbc720f3191a146183c01e7 data/botania/tags/items/loonium_blacklist.json +80976d0e035f6163de9d5c190a3061a5fb95591f data/botania/tags/items/loonium_offhand_equipment.json 8a23702b05296c8af5014d6aa6e9265ded85c7d9 data/botania/tags/items/magnet_ring_blacklist.json bebd5a92d011c3a431c16f368557850a1e108530 data/botania/tags/items/mana_diamond_gems.json 6cf780dc321928fdae9feeacae1c6689c815f40e data/botania/tags/items/mana_dusts.json @@ -55,6 +56,7 @@ f01c4f9608fc5e20c33e12d6862b6d8cee41cdd0 data/botania/tags/items/semi_disposable 2ead7838be1f063018e6e13e8300f3a183adf5f5 data/botania/tags/items/terrasteel_blocks.json 70a32077a4c06e2fc3ed8783037d4b6c659216be data/botania/tags/items/terrasteel_ingots.json de5556cc02036175ac731ce76827076c6b834d25 data/botania/tags/items/terrasteel_nuggets.json +8a23702b05296c8af5014d6aa6e9265ded85c7d9 data/minecraft/tags/items/arrows.json 43bfa13de3ebc0be372fc48b0e4be56a25cb1893 data/minecraft/tags/items/axes.json 65c35efa8dfbdc9f5a8c05624c492fba8408e3b2 data/minecraft/tags/items/bookshelf_books.json a101ef4ecfece48f1cdff62f34f30f9f25b3dbd3 data/minecraft/tags/items/cluster_max_harvestables.json diff --git a/Xplat/src/generated/resources/.cache/a864b94d006aba05700c96ad7a5769c8571473bc b/Xplat/src/generated/resources/.cache/a864b94d006aba05700c96ad7a5769c8571473bc new file mode 100644 index 0000000000..b41751152f --- /dev/null +++ b/Xplat/src/generated/resources/.cache/a864b94d006aba05700c96ad7a5769c8571473bc @@ -0,0 +1,31 @@ +// 1.20.1 Botania/Loonium structure configuration +0591cbe7698291e5638b866f3d85e70f58d1a344 data/botania/loonium_config/default.json +8957828d1e1f4fb2748cb4db623d290b89ab3f79 data/botania/loonium_config/ocean_ruins.json +8957828d1e1f4fb2748cb4db623d290b89ab3f79 data/botania/loonium_config/village.json +0c933b1278b153f59c7f189d7d6915c489340893 data/minecraft/loonium_config/ancient_city.json +4baa8c3fc3b3ad342326f1e207e6897ece6a04de data/minecraft/loonium_config/bastion_remnant.json +80b2e51b7d57879bf73aad1b23264032080e8e22 data/minecraft/loonium_config/desert_pyramid.json +0cabae7ec03b982c21a592f0924beb7a3700c59d data/minecraft/loonium_config/end_city.json +81aa1d20a8a656b5110984587367368c7206cfb7 data/minecraft/loonium_config/fortress.json +180b4009f85a3b534c8f55aafc6d5ec3cd2125b6 data/minecraft/loonium_config/jungle_pyramid.json +189f42c5d0b89c43e618e55b6cedd0f01c5fb00c data/minecraft/loonium_config/mansion.json +7bf132334dfc93b6c0a9d74bd4896782819fa3ee data/minecraft/loonium_config/monument.json +7bf474c5eca6f6cf63799e5d1e518dd81b39943c data/minecraft/loonium_config/ocean_ruin_cold.json +70760f4da963f17c462e0e264652776c74d7d178 data/minecraft/loonium_config/ocean_ruin_warm.json +690d302eb1c171f1caaf63d52275fc82b9c40431 data/minecraft/loonium_config/pillager_outpost.json +72a5b2a5af2bb9966f0ac15d00a2fa69e21aa7fc data/minecraft/loonium_config/ruined_portal.json +eaf7c2c1520cf16bb06ca9e6c1e76f32b1571fe2 data/minecraft/loonium_config/ruined_portal_desert.json +17dedb198a79feb28465164299f9e161d0621f72 data/minecraft/loonium_config/ruined_portal_jungle.json +77a93510dc75fe179568fe08cac9848965a7abf2 data/minecraft/loonium_config/ruined_portal_mountain.json +07a632775753dee383465d74d594775b22d68058 data/minecraft/loonium_config/ruined_portal_nether.json +a46cb70ba9a2ea3425f281ac56bdead53b4d121e data/minecraft/loonium_config/ruined_portal_ocean.json +6d6bec7132a26f85357c6c214edd3b3fb4f1e439 data/minecraft/loonium_config/ruined_portal_swamp.json +e07b347d00f8046a129aaa6c370d09051b5b64ec data/minecraft/loonium_config/shipwreck.json +69b7be4e05054ffe7d73ea4625581012af333cf2 data/minecraft/loonium_config/shipwreck_beached.json +daec043e2fd1892c030e279a01f03b36bec78545 data/minecraft/loonium_config/stronghold.json +884bcffda3cef17de3b826764761bf17923cc3a2 data/minecraft/loonium_config/trail_ruins.json +ca49a5ff59f404e97c78004a75404c335ff30385 data/minecraft/loonium_config/village_desert.json +c9e527140f4f775a3dd58af3acdd898b6e504991 data/minecraft/loonium_config/village_plains.json +8ccd5ddf38ead3ad53cc1b5a9f4780adee02cad0 data/minecraft/loonium_config/village_savanna.json +437d9a154644a9e62df0eab1fc07d86dbaf98b82 data/minecraft/loonium_config/village_snowy.json +c4562050c8a5429cb383144e9e57f5267387dbba data/minecraft/loonium_config/village_taiga.json diff --git a/Xplat/src/generated/resources/.cache/ca0b139d7ffbdcad7e28a9e04c29c4ff458197e3 b/Xplat/src/generated/resources/.cache/ca0b139d7ffbdcad7e28a9e04c29c4ff458197e3 index 16d6fc7b70..80d12c9ca4 100644 --- a/Xplat/src/generated/resources/.cache/ca0b139d7ffbdcad7e28a9e04c29c4ff458197e3 +++ b/Xplat/src/generated/resources/.cache/ca0b139d7ffbdcad7e28a9e04c29c4ff458197e3 @@ -1,5 +1,6 @@ // 1.20.1 Botania/Advancements ab08543643f1a531a05c7a8c557a3ac02791af95 data/botania/advancements/challenge/alf_portal_bread.json +88699a15ceee5f4d6b3da75b7fc8813d6ed7fecc data/botania/advancements/challenge/all_loonium_mobs.json 79ad7a7e7ea785cf536ec8396e1e11673650954b data/botania/advancements/challenge/flugel_eye.json 3e969f922b4184577d256b2c5e197c5dc8a50c4f data/botania/advancements/challenge/gaia_guardian_hardmode.json 90ca240ce76ccf798cf0fc68ba99c1623ed44af0 data/botania/advancements/challenge/gaia_guardian_no_armor.json diff --git a/Xplat/src/generated/resources/data/botania/advancements/challenge/all_loonium_mobs.json b/Xplat/src/generated/resources/data/botania/advancements/challenge/all_loonium_mobs.json new file mode 100644 index 0000000000..d15af8121b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/advancements/challenge/all_loonium_mobs.json @@ -0,0 +1,419 @@ +{ + "parent": "botania:challenge/root", + "criteria": { + "minecraft:blaze": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:blaze", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:cave_spider": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:cave_spider", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:creeper": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:creeper", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:drowned": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:drowned", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:enderman": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:enderman", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:evoker": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:evoker", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:guardian": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:guardian", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:hoglin": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:hoglin", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:husk": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:husk", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:piglin": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:piglin", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:piglin_brute": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:piglin_brute", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:pillager": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:pillager", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:shulker": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:shulker", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:silverfish": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:silverfish", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:skeleton": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:skeleton", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:stray": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:stray", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:vindicator": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:vindicator", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:wither_skeleton": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:wither_skeleton", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:zoglin": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:zoglin", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:zombie": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:zombie", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:zombie_villager": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:zombie_villager", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + }, + "minecraft:zombified_piglin": { + "conditions": { + "entity": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:zombified_piglin", + "team": "Loonium Monsters" + } + } + ] + }, + "trigger": "minecraft:player_killed_entity" + } + }, + "display": { + "announce_to_chat": true, + "description": { + "translate": "advancement.botania:allLooniumMobs.desc" + }, + "frame": "challenge", + "hidden": false, + "icon": { + "item": "botania:loonium" + }, + "show_toast": true, + "title": { + "translate": "advancement.botania:allLooniumMobs" + } + }, + "requirements": [ + [ + "minecraft:blaze" + ], + [ + "minecraft:cave_spider" + ], + [ + "minecraft:creeper" + ], + [ + "minecraft:drowned" + ], + [ + "minecraft:enderman" + ], + [ + "minecraft:evoker" + ], + [ + "minecraft:guardian" + ], + [ + "minecraft:hoglin" + ], + [ + "minecraft:husk" + ], + [ + "minecraft:piglin" + ], + [ + "minecraft:piglin_brute" + ], + [ + "minecraft:pillager" + ], + [ + "minecraft:shulker" + ], + [ + "minecraft:silverfish" + ], + [ + "minecraft:skeleton" + ], + [ + "minecraft:stray" + ], + [ + "minecraft:vindicator" + ], + [ + "minecraft:wither_skeleton" + ], + [ + "minecraft:zoglin" + ], + [ + "minecraft:zombie_villager" + ], + [ + "minecraft:zombie" + ], + [ + "minecraft:zombified_piglin" + ] + ], + "sends_telemetry_event": true +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loonium_config/default.json b/Xplat/src/generated/resources/data/botania/loonium_config/default.json new file mode 100644 index 0000000000..7fa38c2fa3 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loonium_config/default.json @@ -0,0 +1,97 @@ +{ + "attributeModifiers": [ + { + "amount": 2.0, + "attribute": "minecraft:generic.max_health", + "name": "Loonium Modifier Health", + "operation": "multiply_base" + }, + { + "amount": 1.5, + "attribute": "minecraft:generic.attack_damage", + "name": "Loonium Modifier Damage", + "operation": "multiply_base" + } + ], + "boundingBoxType": "piece", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "manaCost": 35000, + "maxNearbyMobs": 10, + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 59 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 106 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 423 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 59 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 529 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loonium_config/ocean_ruins.json b/Xplat/src/generated/resources/data/botania/loonium_config/ocean_ruins.json new file mode 100644 index 0000000000..2d6c6ee5fb --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loonium_config/ocean_ruins.json @@ -0,0 +1,4 @@ +{ + "parent": "botania:default", + "boundingBoxType": "full" +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loonium_config/village.json b/Xplat/src/generated/resources/data/botania/loonium_config/village.json new file mode 100644 index 0000000000..2d6c6ee5fb --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loonium_config/village.json @@ -0,0 +1,4 @@ +{ + "parent": "botania:default", + "boundingBoxType": "full" +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_ancient_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_ancient_city.json new file mode 100644 index 0000000000..ae6fe46979 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_ancient_city.json @@ -0,0 +1,65 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/ward_iron", + "weight": 11 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/ward_diamond", + "weight": 5 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/silence_gold", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/silence_diamond" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "equipment": { + "mainhand": { + "items": [ + "minecraft:bow" + ] + } + } + } + }, + { + "chance": 0.9, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{CustomPotionColor:2696993,CustomPotionEffects:[{Ambient:0b,Amplifier:0b,Duration:200,FactorCalculationData:{factor_current:0.0f,factor_previous_frame:0.0f,factor_start:0.0f,factor_target:1.0f,had_effect_last_tick:0b,padding_duration:22,ticks_active:0},Id:33,ShowIcon:1b,ShowParticles:1b}]}" + } + ], + "name": "minecraft:tipped_arrow" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_bastion_remnant.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_bastion_remnant.json new file mode 100644 index 0000000000..864d5edad7 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_bastion_remnant.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/snout_gold", + "weight": 4 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/snout_netherite" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_desert_pyramid.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_desert_pyramid.json new file mode 100644 index 0000000000..3e441989c9 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_desert_pyramid.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/dune_iron", + "weight": 5 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/dune_gold", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/dune_diamond" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_end_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_end_city.json new file mode 100644 index 0000000000..935f6c149c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_end_city.json @@ -0,0 +1,66 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/spire_iron", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/spire_gold", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/spire_diamond", + "weight": 2 + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:skeleton" + } + }, + { + "chance": 0.9, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{CustomPotionColor:13565951,CustomPotionEffects:[{Ambient:0b,Amplifier:0b,Duration:200,Id:25,ShowIcon:1b,ShowParticles:1b}]}" + } + ], + "name": "minecraft:tipped_arrow" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_fortress.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_fortress.json new file mode 100644 index 0000000000..d23393452b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_fortress.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/rib_iron", + "weight": 7 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/rib_gold", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/rib_diamond", + "weight": 2 + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_jungle_temple.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_jungle_temple.json new file mode 100644 index 0000000000..5e72cb06cf --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_jungle_temple.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/wild_chain", + "weight": 4 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/wild_gold", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/wild_diamond" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_mansion.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_mansion.json new file mode 100644 index 0000000000..ffb316cc30 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_mansion.json @@ -0,0 +1,66 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/costume_evoker", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/costume_vindicator", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/costume_illusioner" + }, + { + "type": "minecraft:loot_table", + "conditions": [ + { + "condition": "minecraft:any_of", + "terms": [ + { + "chance": 0.005, + "condition": "minecraft:random_chance" + }, + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "flags": { + "is_baby": true + } + } + } + ] + } + ], + "name": "botania:equipment/loonium/armorset/costume_vex", + "weight": 45 + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "chance": 0.05, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:totem_of_undying" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_monument.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_monument.json new file mode 100644 index 0000000000..2dd7ef3d01 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_monument.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/tide_leather", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/tide_iron", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/tide_diamond" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_outpost.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_outpost.json new file mode 100644 index 0000000000..8438e47782 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_outpost.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/sentry_chain", + "weight": 5 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/sentry_iron", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/sentry_diamond" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_portal.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_portal.json new file mode 100644 index 0000000000..dfc4534f4c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_portal.json @@ -0,0 +1,61 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_shipwreck.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_shipwreck.json new file mode 100644 index 0000000000..b4252eacc8 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_shipwreck.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/coast_chain", + "weight": 4 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/coast_iron", + "weight": 4 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/coast_diamond" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_stronghold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_stronghold.json new file mode 100644 index 0000000000..40144be68a --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_stronghold.json @@ -0,0 +1,30 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/eye_iron", + "weight": 5 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/eye_gold", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/eye_diamond", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/costume_enderman" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_trail_ruins.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_trail_ruins.json new file mode 100644 index 0000000000..1cc7f80eeb --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armor_trail_ruins.json @@ -0,0 +1,51 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/host_chain", + "weight": 7 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/wayfinder_chain", + "weight": 7 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/raiser_iron", + "weight": 8 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/host_iron", + "weight": 8 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/raiser_gold", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/shaper_gold", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/shaper_diamond", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armorset/wayfinder_diamond", + "weight": 2 + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_chain.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_chain.json new file mode 100644 index 0000000000..5d1755a24a --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_chain.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:chainmail_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:chainmail_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:chainmail_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:chainmail_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_diamond.json new file mode 100644 index 0000000000..6e43476813 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_iron.json new file mode 100644 index 0000000000..4cacb92ce7 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/coast_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:coast\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_enderman.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_enderman.json new file mode 100644 index 0000000000..65b8f69675 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_enderman.json @@ -0,0 +1,69 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:eye\"},display:{color:1908001}}" + } + ], + "name": "minecraft:leather_helmet" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{display:{color:1908001}}" + } + ], + "name": "minecraft:leather_chestplate" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{display:{color:1908001}}" + } + ], + "name": "minecraft:leather_leggings" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{display:{color:1908001}}" + } + ], + "name": "minecraft:leather_boots" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_evoker.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_evoker.json new file mode 100644 index 0000000000..67848cd509 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_evoker.json @@ -0,0 +1,53 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:vex\"},display:{color:3290681}}" + } + ], + "name": "minecraft:leather_chestplate" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:vex\"},display:{color:3290681}}" + } + ], + "name": "minecraft:leather_leggings" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "chance": 0.2, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:totem_of_undying" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_illusioner.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_illusioner.json new file mode 100644 index 0000000000..5d8fffe322 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_illusioner.json @@ -0,0 +1,109 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:vex\"},display:{color:3898306}}" + } + ], + "name": "minecraft:leather_helmet" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:vex\"},display:{color:3898306}}" + } + ], + "name": "minecraft:leather_chestplate" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:vex\"},display:{color:3898306}}" + } + ], + "name": "minecraft:leather_leggings" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "chance": 0.9, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "name": "minecraft:bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "type": "minecraft:skeleton" + } + }, + { + "chance": 0.9, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{CustomPotionColor:2039587,CustomPotionEffects:[{Ambient:0b,Amplifier:0b,Duration:100,Id:15,ShowIcon:1b,ShowParticles:1b}]}" + } + ], + "name": "minecraft:tipped_arrow" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vex.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vex.json new file mode 100644 index 0000000000..7e806cfd70 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vex.json @@ -0,0 +1,68 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:vex\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:diamond_leggings" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "chance": 0.9, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "name": "minecraft:iron_sword" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vindicator.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vindicator.json new file mode 100644 index 0000000000..1b82ec83ff --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/costume_vindicator.json @@ -0,0 +1,80 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:netherite\",pattern:\"minecraft:vex\"},display:{color:4673362}}" + } + ], + "name": "minecraft:leather_chestplate" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{display:{color:1477772}}" + } + ], + "name": "minecraft:leather_leggings" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{display:{color:3290681}}" + } + ], + "name": "minecraft:leather_boots" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "conditions": [ + { + "chance": 0.9, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "name": "minecraft:iron_axe" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_diamond.json new file mode 100644 index 0000000000..b2f603ae64 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_gold.json new file mode 100644 index 0000000000..7f66886fb4 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_iron.json new file mode 100644 index 0000000000..73c5d528d2 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/dune_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:dune\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_diamond.json new file mode 100644 index 0000000000..ff503d4ffc --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_gold.json new file mode 100644 index 0000000000..7c6be606e7 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_iron.json new file mode 100644 index 0000000000..ee997b2029 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/eye_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:eye\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_chain.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_chain.json new file mode 100644 index 0000000000..49f0c22950 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_chain.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:chainmail_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:chainmail_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:chainmail_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:chainmail_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_iron.json new file mode 100644 index 0000000000..254856801d --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/host_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:host\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_gold.json new file mode 100644 index 0000000000..4827a0c952 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_iron.json new file mode 100644 index 0000000000..75f02c95f0 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/raiser_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:raiser\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_diamond.json new file mode 100644 index 0000000000..09e0bd13f6 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_gold.json new file mode 100644 index 0000000000..8e1c140b0c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_iron.json new file mode 100644 index 0000000000..53841d6200 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/rib_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:iron\",pattern:\"minecraft:rib\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_chain.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_chain.json new file mode 100644 index 0000000000..c980bd7607 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_chain.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:chainmail_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:chainmail_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:chainmail_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:chainmail_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_diamond.json new file mode 100644 index 0000000000..66aae08a09 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_iron.json new file mode 100644 index 0000000000..607c691ee6 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/sentry_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:sentry\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_diamond.json new file mode 100644 index 0000000000..bdcd86dc43 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_gold.json new file mode 100644 index 0000000000..cf52ce83da --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/shaper_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:lapis\",pattern:\"minecraft:shaper\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_diamond.json new file mode 100644 index 0000000000..a180eb0a3b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_gold.json new file mode 100644 index 0000000000..c964063859 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/silence_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:silence\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_gold.json new file mode 100644 index 0000000000..f65b894468 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:netherite\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:netherite\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:netherite\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:netherite\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_netherite.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_netherite.json new file mode 100644 index 0000000000..4f602652b2 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/snout_netherite.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:netherite_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:netherite_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:netherite_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:snout\"}}" + } + ], + "name": "minecraft:netherite_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_diamond.json new file mode 100644 index 0000000000..453bb72fe9 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_gold.json new file mode 100644 index 0000000000..623f614dcc --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_iron.json new file mode 100644 index 0000000000..7f0fa0cd28 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/spire_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:amethyst\",pattern:\"minecraft:spire\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_diamond.json new file mode 100644 index 0000000000..1a43efcc94 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:gold\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_iron.json new file mode 100644 index 0000000000..ad5e47954d --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:diamond\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:diamond\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:diamond\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:diamond\",pattern:\"minecraft:tide\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_leather.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_leather.json new file mode 100644 index 0000000000..7bca535a1b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/tide_leather.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:tide\"},display:{color:1481884}}" + } + ], + "name": "minecraft:leather_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:tide\"},display:{color:1481884}}" + } + ], + "name": "minecraft:leather_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:tide\"},display:{color:1481884}}" + } + ], + "name": "minecraft:leather_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:copper\",pattern:\"minecraft:tide\"},display:{color:1481884}}" + } + ], + "name": "minecraft:leather_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_diamond.json new file mode 100644 index 0000000000..29c15d7c28 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_iron.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_iron.json new file mode 100644 index 0000000000..96cf845419 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/ward_iron.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:iron_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:iron_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:iron_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:quartz\",pattern:\"minecraft:ward\"}}" + } + ], + "name": "minecraft:iron_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_chain.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_chain.json new file mode 100644 index 0000000000..23f9d7fba8 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_chain.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:chainmail_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:chainmail_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:chainmail_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:chainmail_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_diamond.json new file mode 100644 index 0000000000..9679924856 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wayfinder_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:redstone\",pattern:\"minecraft:wayfinder\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_chain.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_chain.json new file mode 100644 index 0000000000..3209b1a8d6 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_chain.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:chainmail_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:chainmail_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:chainmail_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:chainmail_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_diamond.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_diamond.json new file mode 100644 index 0000000000..ad3959eedb --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_diamond.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:diamond_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:diamond_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:diamond_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:diamond_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_gold.json new file mode 100644 index 0000000000..e426259cf7 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/armorset/wild_gold.json @@ -0,0 +1,85 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:golden_helmet" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:golden_chestplate" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:golden_leggings" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:set_nbt", + "tag": "{Trim:{material:\"minecraft:emerald\",pattern:\"minecraft:wild\"}}" + } + ], + "name": "minecraft:golden_boots" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": 0.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_ancient_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_ancient_city.json new file mode 100644 index 0000000000..020aea76e9 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_ancient_city.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_ancient_city" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_jungle_temple.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_jungle_temple.json new file mode 100644 index 0000000000..2d5398c1c1 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_jungle_temple.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_jungle_temple" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_monument.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_monument.json new file mode 100644 index 0000000000..599209df6b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_monument.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_monument" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_portal.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_portal.json new file mode 100644 index 0000000000..f2e65bc93e --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_portal.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_portal" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_shipwreck.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_shipwreck.json new file mode 100644 index 0000000000..7aef99664a --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_shipwreck.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_shipwreck" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_stronghold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_stronghold.json new file mode 100644 index 0000000000..1de3f55f59 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_stronghold.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_stronghold" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_trail_ruins.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_trail_ruins.json new file mode 100644 index 0000000000..ff146f049b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/drowned_trail_ruins.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_trident" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_trail_ruins" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_bastion_remnant.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_bastion_remnant.json new file mode 100644 index 0000000000..ba9e451dba --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_bastion_remnant.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_for_piglin" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_bastion_remnant" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_ruined_portal.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_ruined_portal.json new file mode 100644 index 0000000000..0fd2cf390d --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/piglin_ruined_portal.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_portal" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_for_piglin" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_ancient_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_ancient_city.json new file mode 100644 index 0000000000..2f171d1229 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_ancient_city.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_ancient_city" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_desert_pyramid.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_desert_pyramid.json new file mode 100644 index 0000000000..52c8e2c967 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_desert_pyramid.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_desert_pyramid" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_end_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_end_city.json new file mode 100644 index 0000000000..7e3b0b43d4 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_end_city.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_end_city" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_fortress.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_fortress.json new file mode 100644 index 0000000000..ebc788c2f6 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_fortress.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_for_wither_skeleton" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_fortress" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_jungle_temple.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_jungle_temple.json new file mode 100644 index 0000000000..a3cc20b317 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_jungle_temple.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_jungle_temple" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_monument.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_monument.json new file mode 100644 index 0000000000..a6099e605c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_monument.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_monument" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_outpost.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_outpost.json new file mode 100644 index 0000000000..8e6987faba --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_outpost.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_outpost" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_portal.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_portal.json new file mode 100644 index 0000000000..c7d6d8c940 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_portal.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_portal" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_shipwreck.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_shipwreck.json new file mode 100644 index 0000000000..24842ebd3e --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_shipwreck.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_shipwreck" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_stronghold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_stronghold.json new file mode 100644 index 0000000000..1aa541befc --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_stronghold.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_stronghold" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_trail_ruins.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_trail_ruins.json new file mode 100644 index 0000000000..017ff1bcbd --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/skeleton_trail_ruins.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_bow" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_trail_ruins" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe.json new file mode 100644 index 0000000000..2c30a76ee1 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:iron_axe" + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe_gold.json new file mode 100644 index 0000000000..c09e4c5b01 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_axe_gold.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:golden_axe" + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_bow.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_bow.json new file mode 100644 index 0000000000..0f27b7882e --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_bow.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:bow" + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_by_profession.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_by_profession.json new file mode 100644 index 0000000000..b4deea70a1 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_by_profession.json @@ -0,0 +1,98 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "nbt": "{VillagerData:{profession:\"minecraft:butcher\"}}" + } + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "name": "botania:equipment/loonium/weapon_axe" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "nbt": "{VillagerData:{profession:\"minecraft:farmer\"}}" + } + } + ], + "name": "minecraft:iron_hoe" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "nbt": "{VillagerData:{profession:\"minecraft:fisherman\"}}" + } + } + ], + "name": "minecraft:fishing_rod" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "nbt": "{VillagerData:{profession:\"minecraft:toolsmith\"}}" + } + } + ], + "name": "minecraft:iron_pickaxe" + }, + { + "type": "minecraft:loot_table", + "conditions": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "nbt": "{VillagerData:{profession:\"minecraft:weaponsmith\"}}" + } + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_crossbow.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_crossbow.json new file mode 100644 index 0000000000..503494bd41 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_crossbow.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:crossbow" + } + ], + "functions": [ + { + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_piglin.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_piglin.json new file mode 100644 index 0000000000..45476a3180 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_piglin.json @@ -0,0 +1,30 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword_gold" + }, + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_crossbow" + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_wither_skeleton.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_wither_skeleton.json new file mode 100644 index 0000000000..87bf10ef97 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_for_wither_skeleton.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:stone_sword" + }, + { + "type": "minecraft:item", + "name": "minecraft:bow" + } + ], + "functions": [ + { + "function": "minecraft:enchant_randomly" + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 1.0, + "min": -1.0 + } + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword.json new file mode 100644 index 0000000000..42e29e30f7 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:iron_sword", + "weight": 4 + }, + { + "type": "minecraft:item", + "name": "minecraft:diamond_sword" + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword_gold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword_gold.json new file mode 100644 index 0000000000..9c653987e6 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_sword_gold.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:golden_sword" + } + ], + "functions": [ + { + "conditions": [ + { + "chance": 0.3, + "condition": "minecraft:random_chance" + } + ], + "function": "minecraft:enchant_randomly" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_trident.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_trident.json new file mode 100644 index 0000000000..462c4bad44 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/weapon_trident.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:trident" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_ancient_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_ancient_city.json new file mode 100644 index 0000000000..c1b7b7d98c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_ancient_city.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_ancient_city" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_desert_pyramid.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_desert_pyramid.json new file mode 100644 index 0000000000..d7e237f9ee --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_desert_pyramid.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_desert_pyramid" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_end_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_end_city.json new file mode 100644 index 0000000000..0508220bb5 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_end_city.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_end_city" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_fortress.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_fortress.json new file mode 100644 index 0000000000..9267470c1a --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_fortress.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword_gold" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_fortress" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_jungle_temple.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_jungle_temple.json new file mode 100644 index 0000000000..44314ccfd4 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_jungle_temple.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_jungle_temple" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_monument.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_monument.json new file mode 100644 index 0000000000..481e32b332 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_monument.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_monument" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_outpost.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_outpost.json new file mode 100644 index 0000000000..135f8f5234 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_outpost.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_outpost" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_portal.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_portal.json new file mode 100644 index 0000000000..78c17d78c7 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_portal.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_portal" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword_gold" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_shipwreck.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_shipwreck.json new file mode 100644 index 0000000000..f3f8965ff9 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_shipwreck.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_shipwreck" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_stronghold.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_stronghold.json new file mode 100644 index 0000000000..f2aa134451 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_stronghold.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_stronghold" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_trail_ruins.json b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_trail_ruins.json new file mode 100644 index 0000000000..7e77d24eb5 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/equipment/loonium/zombie_trail_ruins.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:selector", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/weapon_sword" + } + ], + "rolls": 1.0 + }, + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "botania:equipment/loonium/armor_trail_ruins" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/default.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/default.json new file mode 100644 index 0000000000..c988592205 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/default.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/simple_dungeon" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ancient_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ancient_city.json new file mode 100644 index 0000000000..e77e010e43 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ancient_city.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ancient_city", + "weight": 9 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ancient_city_ice_box" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/bastion_remnant.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/bastion_remnant.json new file mode 100644 index 0000000000..04fcfd8e75 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/bastion_remnant.json @@ -0,0 +1,27 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/bastion_bridge" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/bastion_hoglin_stable" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/bastion_treasure" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/bastion_other", + "weight": 7 + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/buried_treasure.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/buried_treasure.json new file mode 100644 index 0000000000..e75af77ba4 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/buried_treasure.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/buried_treasure" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/desert_pyramid.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/desert_pyramid.json new file mode 100644 index 0000000000..688a4b1e7c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/desert_pyramid.json @@ -0,0 +1,24 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/desert_pyramid", + "weight": 37 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:archaeology/desert_pyramid", + "weight": 2 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:archaeology/desert_well" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/end_city.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/end_city.json new file mode 100644 index 0000000000..0479514e35 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/end_city.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/end_city_treasure", + "weight": 49 + }, + { + "type": "minecraft:item", + "name": "minecraft:elytra" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/fortress.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/fortress.json new file mode 100644 index 0000000000..bb7ace7980 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/fortress.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/nether_bridge" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/jungle_pyramid.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/jungle_pyramid.json new file mode 100644 index 0000000000..7ea7c7351b --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/jungle_pyramid.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/jungle_temple", + "weight": 9 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/jungle_temple_dispenser" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mansion.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mansion.json new file mode 100644 index 0000000000..f86fc80e83 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mansion.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/woodland_mansion", + "weight": 99 + }, + { + "type": "minecraft:item", + "name": "minecraft:totem_of_undying" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft.json new file mode 100644 index 0000000000..3481e7498d --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/abandoned_mineshaft" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft_mesa.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft_mesa.json new file mode 100644 index 0000000000..3481e7498d --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/mineshaft_mesa.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/abandoned_mineshaft" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/monument.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/monument.json new file mode 100644 index 0000000000..bfa5db3c2c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/monument.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:entities/elder_guardian", + "weight": 5 + }, + { + "type": "minecraft:item", + "name": "minecraft:wet_sponge" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_cold.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_cold.json new file mode 100644 index 0000000000..68d20a5cf4 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_cold.json @@ -0,0 +1,23 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/underwater_ruin_big" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/underwater_ruin_small", + "weight": 8 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:archaeology/ocean_ruin_cold" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_warm.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_warm.json new file mode 100644 index 0000000000..ac1ec6eff3 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ocean_ruin_warm.json @@ -0,0 +1,23 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/underwater_ruin_big" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/underwater_ruin_small", + "weight": 8 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:archaeology/ocean_ruin_warm" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/pillager_outpost.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/pillager_outpost.json new file mode 100644 index 0000000000..bfe102562a --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/pillager_outpost.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/pillager_outpost" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_desert.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_desert.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_desert.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_jungle.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_jungle.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_jungle.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_mountain.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_mountain.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_mountain.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_nether.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_nether.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_nether.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_ocean.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_ocean.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_ocean.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_swamp.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_swamp.json new file mode 100644 index 0000000000..eb2f3cf020 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/ruined_portal_swamp.json @@ -0,0 +1,14 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/ruined_portal" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck.json new file mode 100644 index 0000000000..6d61c4adda --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck.json @@ -0,0 +1,22 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/shipwreck_map" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/shipwreck_supply" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/shipwreck_treasure" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck_beached.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck_beached.json new file mode 100644 index 0000000000..6d61c4adda --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/shipwreck_beached.json @@ -0,0 +1,22 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/shipwreck_map" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/shipwreck_supply" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/shipwreck_treasure" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/stronghold.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/stronghold.json new file mode 100644 index 0000000000..5b103e1575 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/stronghold.json @@ -0,0 +1,25 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/stronghold_corridor", + "weight": 4 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/stronghold_crossing", + "weight": 6 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/stronghold_library", + "weight": 3 + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/trail_ruins.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/trail_ruins.json new file mode 100644 index 0000000000..d0f1c11895 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/trail_ruins.json @@ -0,0 +1,19 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:archaeology/trail_ruins_common", + "weight": 9 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:archaeology/trail_ruins_rare" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_desert.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_desert.json new file mode 100644 index 0000000000..d940537892 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_desert.json @@ -0,0 +1,27 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_desert_house", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_weaponsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_toolsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_temple" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_plains.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_plains.json new file mode 100644 index 0000000000..ecb2ea84b3 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_plains.json @@ -0,0 +1,31 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_plains_house", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_weaponsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_cartographer" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_fisher" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_tannery" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_savanna.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_savanna.json new file mode 100644 index 0000000000..245c6929ed --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_savanna.json @@ -0,0 +1,35 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_savanna_house", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_weaponsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_cartographer" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_mason" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_butcher" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_tannery" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_snowy.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_snowy.json new file mode 100644 index 0000000000..01abbd4ca2 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_snowy.json @@ -0,0 +1,35 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_snowy_house", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_weaponsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_armorer" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_cartographer" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_shepherd" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_tannery" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_taiga.json b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_taiga.json new file mode 100644 index 0000000000..4ff55cf07c --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/loot_tables/loonium/minecraft/village_taiga.json @@ -0,0 +1,35 @@ +{ + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_taiga_house", + "weight": 3 + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_weaponsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_toolsmith" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_cartographer" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_fletcher" + }, + { + "type": "minecraft:loot_table", + "name": "minecraft:chests/village/village_tannery" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/botania/tags/items/loonium_offhand_equipment.json b/Xplat/src/generated/resources/data/botania/tags/items/loonium_offhand_equipment.json new file mode 100644 index 0000000000..21a303bd43 --- /dev/null +++ b/Xplat/src/generated/resources/data/botania/tags/items/loonium_offhand_equipment.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "minecraft:firework_rocket", + "minecraft:totem_of_undying", + "#minecraft:arrows" + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ancient_city.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ancient_city.json new file mode 100644 index 0000000000..ca37fbef70 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ancient_city.json @@ -0,0 +1,73 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 30 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 99 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/zombie_ancient_city", + "weight": 40 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_ancient_city", + "weight": 80 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_ancient_city", + "weight": 410 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_ancient_city", + "weight": 60 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_ancient_city", + "weight": 440 + }, + { + "type": "minecraft:cave_spider", + "weight": 100 + }, + { + "type": "minecraft:spider", + "weight": 200 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/bastion_remnant.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/bastion_remnant.json new file mode 100644 index 0000000000..42f5bb89f4 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/bastion_remnant.json @@ -0,0 +1,90 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 30 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 99 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_bastion_remnant", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + } + }, + "spawnAsBaby": false, + "weight": 450 + }, + { + "type": "minecraft:piglin_brute", + "attributeModifiers": [ + { + "amount": 1.5, + "attribute": "minecraft:generic.max_health", + "name": "Loonium Modifier Health", + "operation": "multiply_base" + }, + { + "amount": 1.5, + "attribute": "minecraft:generic.attack_damage", + "name": "Loonium Modifier Damage", + "operation": "multiply_base" + } + ], + "equipmentTable": "botania:equipment/loonium/weapon_axe_gold", + "weight": 50 + }, + { + "type": "minecraft:hoglin", + "spawnAsBaby": false, + "weight": 300 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/desert_pyramid.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/desert_pyramid.json new file mode 100644 index 0000000000..e2ee96418a --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/desert_pyramid.json @@ -0,0 +1,63 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 50 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 149 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/zombie_desert_pyramid", + "weight": 450 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_desert_pyramid", + "weight": 50 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_desert_pyramid", + "weight": 500 + }, + { + "type": "minecraft:cave_spider", + "weight": 40 + }, + { + "type": "minecraft:spider", + "weight": 360 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/end_city.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/end_city.json new file mode 100644 index 0000000000..ce96aa96b4 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/end_city.json @@ -0,0 +1,88 @@ +{ + "parent": "botania:default", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:slow_falling" + } + ], + "spawnedMobs": [ + { + "type": "minecraft:shulker", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 100 + }, + { + "type": "minecraft:enderman", + "weight": 300 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "duration": 400, + "effect": "minecraft:slow_falling" + } + ], + "weight": 99 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "duration": 400, + "effect": "minecraft:slow_falling" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_end_city", + "weight": 300 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_end_city", + "weight": 300 + }, + { + "type": "minecraft:spider", + "weight": 300 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/fortress.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/fortress.json new file mode 100644 index 0000000000..94063e7fcf --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/fortress.json @@ -0,0 +1,74 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 30 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 99 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:blaze", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 300 + }, + { + "type": "minecraft:wither_skeleton", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/skeleton_fortress", + "weight": 450 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_fortress", + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/zombie_fortress", + "weight": 400 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/jungle_pyramid.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/jungle_pyramid.json new file mode 100644 index 0000000000..b5c5781b99 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/jungle_pyramid.json @@ -0,0 +1,63 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 30 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 149 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_jungle_temple", + "weight": 40 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_jungle_temple", + "weight": 360 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_jungle_temple", + "weight": 500 + }, + { + "type": "minecraft:cave_spider", + "weight": 300 + }, + { + "type": "minecraft:spider", + "weight": 300 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/mansion.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/mansion.json new file mode 100644 index 0000000000..75930d670f --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/mansion.json @@ -0,0 +1,78 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:vindicator", + "equipmentTable": "botania:equipment/loonium/weapon_axe", + "weight": 600 + }, + { + "type": "minecraft:pillager", + "equipmentTable": "botania:equipment/loonium/weapon_crossbow", + "weight": 200 + }, + { + "type": "minecraft:evoker", + "weight": 100 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/armor_mansion", + "weight": 150 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/armor_mansion", + "spawnAsBaby": true, + "weight": 50 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/armor_mansion", + "weight": 200 + }, + { + "type": "minecraft:cave_spider", + "weight": 30 + }, + { + "type": "minecraft:spider", + "weight": 270 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/monument.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/monument.json new file mode 100644 index 0000000000..9b9111560f --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/monument.json @@ -0,0 +1,96 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:guardian", + "weight": 200 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_monument", + "weight": 540 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_monument", + "weight": 60 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_monument", + "weight": 40 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_monument", + "weight": 360 + }, + { + "type": "minecraft:cave_spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 30 + }, + { + "type": "minecraft:spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 270 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_cold.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_cold.json new file mode 100644 index 0000000000..8c63ecaee1 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_cold.json @@ -0,0 +1,92 @@ +{ + "parent": "botania:ocean_ruins", + "spawnedMobs": [ + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 540 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 60 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 40 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 360 + }, + { + "type": "minecraft:cave_spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 30 + }, + { + "type": "minecraft:spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 270 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_warm.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_warm.json new file mode 100644 index 0000000000..b31d7b0060 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ocean_ruin_warm.json @@ -0,0 +1,87 @@ +{ + "parent": "botania:ocean_ruins", + "spawnedMobs": [ + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 540 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 60 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 400 + }, + { + "type": "minecraft:cave_spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 30 + }, + { + "type": "minecraft:spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 270 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/pillager_outpost.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/pillager_outpost.json new file mode 100644 index 0000000000..775f265856 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/pillager_outpost.json @@ -0,0 +1,69 @@ +{ + "parent": "botania:default", + "boundingBoxType": "full", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:pillager", + "equipmentTable": "botania:equipment/loonium/weapon_crossbow", + "weight": 900 + }, + { + "type": "minecraft:vindicator", + "equipmentTable": "botania:equipment/loonium/weapon_axe", + "weight": 175 + }, + { + "type": "minecraft:evoker", + "weight": 25 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_outpost", + "weight": 200 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_outpost", + "weight": 200 + }, + { + "type": "minecraft:spider", + "weight": 200 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal.json new file mode 100644 index 0000000000..31ecae69ba --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal.json @@ -0,0 +1,114 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 25 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + }, + "IsImmuneToZombification": 1 + }, + "spawnAsBaby": false, + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 59 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_portal", + "weight": 106 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 423 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 59 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 529 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_desert.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_desert.json new file mode 100644 index 0000000000..5a8e30c96c --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_desert.json @@ -0,0 +1,100 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 25 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + }, + "IsImmuneToZombification": 1 + }, + "spawnAsBaby": false, + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:enderman", + "weight": 50 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 149 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 450 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 450 + }, + { + "type": "minecraft:spider", + "weight": 360 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_jungle.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_jungle.json new file mode 100644 index 0000000000..73246e160e --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_jungle.json @@ -0,0 +1,104 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 25 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + }, + "IsImmuneToZombification": 1 + }, + "spawnAsBaby": false, + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:enderman", + "weight": 30 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 149 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_portal", + "weight": 40 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 360 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 500 + }, + { + "type": "minecraft:cave_spider", + "weight": 250 + }, + { + "type": "minecraft:spider", + "weight": 50 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_mountain.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_mountain.json new file mode 100644 index 0000000000..9d9d760abb --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_mountain.json @@ -0,0 +1,104 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 25 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + }, + "IsImmuneToZombification": 1 + }, + "spawnAsBaby": false, + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 529 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 59 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 529 + }, + { + "type": "minecraft:silverfish", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_nether.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_nether.json new file mode 100644 index 0000000000..aadda5b735 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_nether.json @@ -0,0 +1,98 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 125 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + } + }, + "spawnAsBaby": false, + "weight": 500 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 450 + }, + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 200 + }, + { + "type": "minecraft:cave_spider", + "weight": 10 + }, + { + "type": "minecraft:spider", + "weight": 90 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_ocean.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_ocean.json new file mode 100644 index 0000000000..2fa7397ce3 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_ocean.json @@ -0,0 +1,131 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 25 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + }, + "IsImmuneToZombification": 1 + }, + "spawnAsBaby": false, + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_portal", + "weight": 540 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 60 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 400 + }, + { + "type": "minecraft:cave_spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 30 + }, + { + "type": "minecraft:spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 270 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_swamp.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_swamp.json new file mode 100644 index 0000000000..e0d8709eee --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/ruined_portal_swamp.json @@ -0,0 +1,104 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:zoglin", + "effectsToApply": [ + { + "effect": "minecraft:regeneration" + } + ], + "weight": 25 + }, + { + "type": "minecraft:piglin", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + } + ], + "equipmentTable": "botania:equipment/loonium/piglin_ruined_portal", + "nbt": { + "Brain": { + "memories": { + "minecraft:admiring_disabled": { + "value": 1 + }, + "minecraft:universal_anger": { + "value": 1 + } + } + }, + "IsImmuneToZombification": 1 + }, + "spawnAsBaby": false, + "weight": 50 + }, + { + "type": "minecraft:zombified_piglin", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 50 + }, + { + "type": "minecraft:enderman", + "weight": 30 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 149 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_portal", + "weight": 40 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_portal", + "weight": 360 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_portal", + "weight": 500 + }, + { + "type": "minecraft:cave_spider", + "weight": 50 + }, + { + "type": "minecraft:spider", + "weight": 250 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck.json new file mode 100644 index 0000000000..e153fc825f --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck.json @@ -0,0 +1,92 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 199 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_shipwreck", + "weight": 540 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_shipwreck", + "weight": 60 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_shipwreck", + "weight": 40 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_shipwreck", + "weight": 360 + }, + { + "type": "minecraft:cave_spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 30 + }, + { + "type": "minecraft:spider", + "effectsToApply": [ + { + "effect": "minecraft:fire_resistance" + }, + { + "effect": "minecraft:regeneration" + }, + { + "effect": "minecraft:water_breathing" + } + ], + "weight": 270 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck_beached.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck_beached.json new file mode 100644 index 0000000000..4cec9eceb9 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/shipwreck_beached.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:shipwreck" +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/stronghold.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/stronghold.json new file mode 100644 index 0000000000..433353e4cf --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/stronghold.json @@ -0,0 +1,77 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 80 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 149 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/zombie_stronghold", + "weight": 40 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_stronghold", + "weight": 40 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_stronghold", + "weight": 410 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_stronghold", + "weight": 60 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_stronghold", + "weight": 440 + }, + { + "type": "minecraft:cave_spider", + "weight": 100 + }, + { + "type": "minecraft:silverfish", + "weight": 100 + }, + { + "type": "minecraft:spider", + "weight": 400 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/trail_ruins.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/trail_ruins.json new file mode 100644 index 0000000000..c914ac379b --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/trail_ruins.json @@ -0,0 +1,73 @@ +{ + "parent": "botania:default", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/zombie_trail_ruins", + "weight": 59 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/drowned_trail_ruins", + "weight": 106 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/zombie_trail_ruins", + "weight": 423 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/skeleton_trail_ruins", + "weight": 59 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/skeleton_trail_ruins", + "weight": 529 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/village_desert.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_desert.json new file mode 100644 index 0000000000..e34d6a19a6 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_desert.json @@ -0,0 +1,68 @@ +{ + "parent": "botania:village", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 423 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 59 + }, + { + "type": "minecraft:zombie_villager", + "equipmentTable": "botania:equipment/loonium/weapon_by_profession", + "weight": 106 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 600 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/village_plains.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_plains.json new file mode 100644 index 0000000000..0741b193ba --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_plains.json @@ -0,0 +1,68 @@ +{ + "parent": "botania:village", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 59 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 423 + }, + { + "type": "minecraft:zombie_villager", + "equipmentTable": "botania:equipment/loonium/weapon_by_profession", + "weight": 106 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 600 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/village_savanna.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_savanna.json new file mode 100644 index 0000000000..03f13ad323 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_savanna.json @@ -0,0 +1,73 @@ +{ + "parent": "botania:village", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 30 + }, + { + "type": "minecraft:husk", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 30 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 423 + }, + { + "type": "minecraft:zombie_villager", + "equipmentTable": "botania:equipment/loonium/weapon_by_profession", + "weight": 106 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 600 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/village_snowy.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_snowy.json new file mode 100644 index 0000000000..638cfd9b16 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_snowy.json @@ -0,0 +1,73 @@ +{ + "parent": "botania:village", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 59 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 423 + }, + { + "type": "minecraft:zombie_villager", + "equipmentTable": "botania:equipment/loonium/weapon_by_profession", + "weight": 106 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 529 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 59 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/loonium_config/village_taiga.json b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_taiga.json new file mode 100644 index 0000000000..e7761d6068 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/loonium_config/village_taiga.json @@ -0,0 +1,73 @@ +{ + "parent": "botania:village", + "spawnedMobs": [ + { + "type": "minecraft:enderman", + "weight": 40 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "weight": 195 + }, + { + "type": "minecraft:creeper", + "effectsToApply": [ + { + "duration": 100, + "effect": "minecraft:fire_resistance" + }, + { + "duration": 100, + "effect": "minecraft:regeneration" + } + ], + "nbt": { + "powered": 1 + }, + "weight": 1 + }, + { + "type": "minecraft:drowned", + "equipmentTable": "botania:equipment/loonium/weapon_trident", + "weight": 59 + }, + { + "type": "minecraft:zombie", + "equipmentTable": "botania:equipment/loonium/weapon_sword", + "weight": 423 + }, + { + "type": "minecraft:zombie_villager", + "equipmentTable": "botania:equipment/loonium/weapon_by_profession", + "weight": 106 + }, + { + "type": "minecraft:stray", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 106 + }, + { + "type": "minecraft:skeleton", + "equipmentTable": "botania:equipment/loonium/weapon_bow", + "weight": 423 + }, + { + "type": "minecraft:cave_spider", + "weight": 59 + }, + { + "type": "minecraft:spider", + "weight": 529 + } + ] +} \ No newline at end of file diff --git a/Xplat/src/generated/resources/data/minecraft/tags/items/arrows.json b/Xplat/src/generated/resources/data/minecraft/tags/items/arrows.json new file mode 100644 index 0000000000..5e8aecc986 --- /dev/null +++ b/Xplat/src/generated/resources/data/minecraft/tags/items/arrows.json @@ -0,0 +1,4 @@ +{ + "replace": false, + "values": [] +} \ No newline at end of file diff --git a/Xplat/src/main/java/vazkii/botania/api/BotaniaAPI.java b/Xplat/src/main/java/vazkii/botania/api/BotaniaAPI.java index 6700c5467c..bd89587840 100644 --- a/Xplat/src/main/java/vazkii/botania/api/BotaniaAPI.java +++ b/Xplat/src/main/java/vazkii/botania/api/BotaniaAPI.java @@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory; import vazkii.botania.api.brew.Brew; +import vazkii.botania.api.configdata.ConfigDataManager; import vazkii.botania.api.corporea.CorporeaNodeDetector; import vazkii.botania.api.internal.DummyManaNetwork; import vazkii.botania.api.internal.ManaNetwork; @@ -216,4 +217,12 @@ default void sparkleFX(Level world, double x, double y, double z, float r, float default void registerCorporeaNodeDetector(CorporeaNodeDetector detector) { } + + default ConfigDataManager getConfigData() { + return null; + } + + default void setConfigData(ConfigDataManager configDataManager) { + + } } diff --git a/Xplat/src/main/java/vazkii/botania/api/configdata/ConfigDataManager.java b/Xplat/src/main/java/vazkii/botania/api/configdata/ConfigDataManager.java new file mode 100644 index 0000000000..af430685e8 --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/api/configdata/ConfigDataManager.java @@ -0,0 +1,11 @@ +package vazkii.botania.api.configdata; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.PreparableReloadListener; + +import org.jetbrains.annotations.Nullable; + +public interface ConfigDataManager extends PreparableReloadListener { + @Nullable + LooniumStructureConfiguration getEffectiveLooniumStructureConfiguration(ResourceLocation id); +} diff --git a/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobAttributeModifier.java b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobAttributeModifier.java new file mode 100644 index 0000000000..51102f9d8c --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobAttributeModifier.java @@ -0,0 +1,67 @@ +package vazkii.botania.api.configdata; + +import com.google.gson.JsonSyntaxException; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; + +public class LooniumMobAttributeModifier { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.STRING.fieldOf("name").forGetter(mam -> mam.name), + BuiltInRegistries.ATTRIBUTE.byNameCodec().fieldOf("attribute").forGetter(mam -> mam.attribute), + Codec.DOUBLE.fieldOf("amount").forGetter(mam -> mam.amount), + Codec.STRING.xmap(LooniumMobAttributeModifier::operationFromString, + LooniumMobAttributeModifier::operationToString) + .fieldOf("operation").forGetter(mam -> mam.operation) + ).apply(instance, LooniumMobAttributeModifier::new) + ); + + private final String name; + public final Attribute attribute; + private final double amount; + private final AttributeModifier.Operation operation; + + public LooniumMobAttributeModifier(String name, Attribute attribute, double amount, + AttributeModifier.Operation operation) { + this.name = name; + this.attribute = attribute; + this.amount = amount; + this.operation = operation; + } + + public AttributeModifier createAttributeModifier() { + return new AttributeModifier(name, amount, operation); + } + + private static String operationToString(AttributeModifier.Operation operation) { + return switch (operation) { + case ADDITION -> "addition"; + case MULTIPLY_BASE -> "multiply_base"; + case MULTIPLY_TOTAL -> "multiply_total"; + default -> throw new IllegalArgumentException("Unknown operation " + operation); + }; + } + + private static AttributeModifier.Operation operationFromString(String operation) { + return switch (operation) { + case "addition" -> AttributeModifier.Operation.ADDITION; + case "multiply_base" -> AttributeModifier.Operation.MULTIPLY_BASE; + case "multiply_total" -> AttributeModifier.Operation.MULTIPLY_TOTAL; + default -> throw new JsonSyntaxException("Unknown attribute modifier operation " + operation); + }; + } + + @Override + public String toString() { + return "MobAttributeModifier{" + + "name='" + name + '\'' + + ", attribute=" + attribute + + ", amount=" + amount + + ", operation=" + operation + + '}'; + } +} diff --git a/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobEffectToApply.java b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobEffectToApply.java new file mode 100644 index 0000000000..cc5e9c118f --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobEffectToApply.java @@ -0,0 +1,103 @@ +package vazkii.botania.api.configdata; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; + +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class LooniumMobEffectToApply { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + BuiltInRegistries.MOB_EFFECT.byNameCodec().fieldOf("effect").forGetter(me -> me.effect), + ExtraCodecs.POSITIVE_INT.optionalFieldOf("duration", MobEffectInstance.INFINITE_DURATION) + .forGetter(me -> me.duration), + Codec.intRange(0, 255).optionalFieldOf("amplifier", 0) + .forGetter(me -> me.amplifier) + ).apply(instance, LooniumMobEffectToApply::new) + ); + + private final MobEffect effect; + private final int duration; + private final int amplifier; + + private LooniumMobEffectToApply(MobEffect effect, int duration, int amplifier) { + this.effect = effect; + this.duration = duration; + this.amplifier = amplifier; + } + + public static Builder effect(MobEffect effect) { + return new Builder(effect); + } + + @NotNull + public MobEffectInstance createMobEffectInstance() { + return new MobEffectInstance(effect, duration, amplifier); + } + + @Override + public String toString() { + return "MobEffectToApply{" + + "effect=" + effect + + ", duration=" + duration + + ", amplifier=" + amplifier + + '}'; + } + + public MobEffect getEffect() { + return effect; + } + + public int getDuration() { + return duration; + } + + public int getAmplifier() { + return amplifier; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + return obj instanceof LooniumMobEffectToApply that && Objects.equals(this.effect, that.effect) + && this.duration == that.duration && this.amplifier == that.amplifier; + } + + @Override + public int hashCode() { + return Objects.hash(effect, duration, amplifier); + } + + public static class Builder { + private final MobEffect effect; + private int duration = MobEffectInstance.INFINITE_DURATION; + private int amplifier = 0; + + private Builder(MobEffect effect) { + this.effect = effect; + } + + public Builder duration(int duration) { + this.duration = duration; + return this; + } + + public Builder amplifier(int amplifier) { + this.amplifier = amplifier; + return this; + } + + public LooniumMobEffectToApply build() { + return new LooniumMobEffectToApply(effect, duration, amplifier); + } + } +} diff --git a/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobSpawnData.java b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobSpawnData.java new file mode 100644 index 0000000000..90be93636d --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumMobSpawnData.java @@ -0,0 +1,161 @@ +package vazkii.botania.api.configdata; + +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.random.Weight; +import net.minecraft.util.random.WeightedEntry; +import net.minecraft.world.entity.EntityType; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Optional; + +public class LooniumMobSpawnData extends WeightedEntry.IntrusiveBase { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + BuiltInRegistries.ENTITY_TYPE.byNameCodec().fieldOf("type").forGetter(msd -> msd.type), + Weight.CODEC.fieldOf("weight").forGetter(IntrusiveBase::getWeight), + Codec.BOOL.optionalFieldOf("spawnAsBaby").forGetter(msd -> Optional.ofNullable(msd.spawnAsBaby)), + CompoundTag.CODEC.optionalFieldOf("nbt").forGetter(msd -> Optional.ofNullable(msd.nbt)), + ResourceLocation.CODEC.optionalFieldOf("equipmentTable") + .forGetter(msd -> Optional.ofNullable(msd.equipmentTable)), + Codec.list(LooniumMobEffectToApply.CODEC) + .optionalFieldOf("effectsToApply") + .forGetter(msd -> Optional.ofNullable(msd.effectsToApply)), + Codec.list(LooniumMobAttributeModifier.CODEC) + .optionalFieldOf("attributeModifiers") + .forGetter(msd -> Optional.ofNullable(msd.attributeModifiers)) + ).apply(instance, LooniumMobSpawnData::create) + ); + + public final EntityType type; + public final Boolean spawnAsBaby; + public final CompoundTag nbt; + public final ResourceLocation equipmentTable; + public final List effectsToApply; + public final List attributeModifiers; + + private LooniumMobSpawnData(EntityType type, Weight weight, Boolean spawnAsBaby, @Nullable CompoundTag nbt, + @Nullable ResourceLocation equipmentTable, + @Nullable List effectsToApply, + @Nullable List attributeModifiers) { + super(weight); + this.type = type; + this.spawnAsBaby = spawnAsBaby; + this.nbt = nbt != null ? nbt.copy() : null; + this.equipmentTable = equipmentTable; + this.effectsToApply = effectsToApply != null ? ImmutableList.copyOf(effectsToApply) : null; + this.attributeModifiers = attributeModifiers != null ? ImmutableList.copyOf(attributeModifiers) : null; + } + + public static Builder entityWeight(EntityType type, int weight) { + return new Builder(type, weight); + } + + @Override + public String toString() { + return "MobSpawnData{" + + "type=" + type + + ", spawnAsBaby=" + spawnAsBaby + + ", nbt=" + nbt + + ", equipmentTable=" + equipmentTable + + ", effectsToApply=" + effectsToApply + + ", attributeModifiers=" + attributeModifiers + + '}'; + } + + // Codecs don't support setting null as intentional default value for optional fields, so we do this. + // (blame com.mojang.datafixers.util.Either::getLeft using Optional::of instead Optional.ofNullable) + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private static LooniumMobSpawnData create(EntityType type, Weight weight, + Optional spawnAsBaby, + Optional nbt, + Optional equipmentTable, + Optional> effectsToApply, + Optional> attributeModifiers) { + return new LooniumMobSpawnData(type, weight, + spawnAsBaby.orElse(null), + nbt.orElse(null), + equipmentTable.orElse(null), + effectsToApply.orElse(null), + attributeModifiers.orElse(null)); + } + + public static class Builder { + private final EntityType type; + private final int weight; + private @Nullable Boolean spawnAsBaby; + private @Nullable CompoundTag nbt; + private @Nullable ResourceLocation equipmentTable; + private @Nullable List effectsToApply; + private @Nullable List attributeModifiers; + + private Builder(EntityType type, int weight) { + this.type = type; + this.weight = weight; + } + + /** + * Make the mob spawn as a baby. (This will not prevent AgeableMobs from growing up.) + */ + public Builder spawnAsBaby() { + this.spawnAsBaby = true; + return this; + } + + /** + * Force conversion of a baby mob to be reverted. This may have unintended side effects, + * like an adult zombie sitting on a chicken or an adult piglin not having a weapon. + * The latter case can usually be taken care of via an equipment table. + */ + public Builder spawnAsAdult() { + this.spawnAsBaby = false; + return this; + } + + /** + * Custom NBT data to apply to the mob before finalizing its spawning. + */ + public Builder nbt(CompoundTag nbt) { + this.nbt = nbt; + return this; + } + + /** + * A loot table to define equipment to apply to the mob after it spawned. + */ + public Builder equipmentTable(ResourceLocation equipmentTable) { + this.equipmentTable = equipmentTable; + return this; + } + + /** + * A list of potion effects to apply to the mob. + * (These are applied instead of any mob effects from the structure configuration.) + */ + public Builder effectsToApply(LooniumMobEffectToApply... effectsToApply) { + this.effectsToApply = List.of(effectsToApply); + return this; + } + + /** + * A list of attribute modifiers to apply to the mob. + * (These are applied instead of any attribute modifiers from the structure configuration.) + */ + public Builder attributeModifiers(LooniumMobAttributeModifier... attributeModifiers) { + this.attributeModifiers = List.of(attributeModifiers); + return this; + } + + public LooniumMobSpawnData build() { + return new LooniumMobSpawnData(type, Weight.of(weight), spawnAsBaby, nbt, equipmentTable, + effectsToApply, attributeModifiers); + } + } +} diff --git a/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumStructureConfiguration.java b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumStructureConfiguration.java new file mode 100644 index 0000000000..22235279ff --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/api/configdata/LooniumStructureConfiguration.java @@ -0,0 +1,182 @@ +package vazkii.botania.api.configdata; + +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.random.WeightedRandomList; +import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride; + +import vazkii.botania.api.BotaniaAPI; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public class LooniumStructureConfiguration { + public static final int DEFAULT_COST = 35000; + public static final int DEFAULT_MAX_NEARBY_MOBS = 10; + public static final Codec CODEC = ExtraCodecs.validate( + RecordCodecBuilder.create( + instance -> instance.group( + ResourceLocation.CODEC.optionalFieldOf("parent") + .forGetter(lsc -> Optional.ofNullable(lsc.parent)), + ExtraCodecs.NON_NEGATIVE_INT.optionalFieldOf("manaCost") + .forGetter(lsc -> Optional.ofNullable(lsc.manaCost)), + ExtraCodecs.POSITIVE_INT.optionalFieldOf("maxNearbyMobs") + .forGetter(lsc -> Optional.ofNullable(lsc.maxNearbyMobs)), + StructureSpawnOverride.BoundingBoxType.CODEC + .optionalFieldOf("boundingBoxType") + .forGetter(lsc -> Optional.ofNullable(lsc.boundingBoxType)), + WeightedRandomList.codec(LooniumMobSpawnData.CODEC) + .optionalFieldOf("spawnedMobs") + .forGetter(lsc -> Optional.ofNullable(lsc.spawnedMobs)), + Codec.list(LooniumMobAttributeModifier.CODEC) + .optionalFieldOf("attributeModifiers") + .forGetter(lsc -> Optional.ofNullable(lsc.attributeModifiers)), + Codec.list(LooniumMobEffectToApply.CODEC) + .optionalFieldOf("effectsToApply") + .forGetter(lsc -> Optional.ofNullable(lsc.effectsToApply)) + ).apply(instance, LooniumStructureConfiguration::create) + ), lsc -> { + if (lsc.parent == null && (lsc.manaCost == null || lsc.boundingBoxType == null || lsc.spawnedMobs == null)) { + return DataResult.error(() -> "Mana cost, bounding box type, and spawned mobs must be specified if there is no parent configuration"); + } + if (lsc.spawnedMobs != null && lsc.spawnedMobs.isEmpty()) { + return DataResult.error(() -> "Spawned mobs cannot be empty"); + } + if (lsc.manaCost != null && lsc.manaCost > DEFAULT_COST) { + return DataResult.error(() -> "Mana costs above %d are currently not supported" + .formatted(DEFAULT_COST)); + } + return DataResult.success(lsc); + }); + public static final ResourceLocation DEFAULT_CONFIG_ID = new ResourceLocation(BotaniaAPI.MODID, "default"); + + public final Integer manaCost; + public final Integer maxNearbyMobs; + public final StructureSpawnOverride.BoundingBoxType boundingBoxType; + public final WeightedRandomList spawnedMobs; + public final List attributeModifiers; + public final List effectsToApply; + public final ResourceLocation parent; + + private LooniumStructureConfiguration(ResourceLocation parent, Integer manaCost, Integer maxNearbyMobs, + StructureSpawnOverride.BoundingBoxType boundingBoxType, WeightedRandomList spawnedMobs, + List attributeModifiers, List effectsToApply) { + this.manaCost = manaCost; + this.maxNearbyMobs = maxNearbyMobs; + this.spawnedMobs = spawnedMobs; + this.boundingBoxType = boundingBoxType; + this.attributeModifiers = attributeModifiers != null ? ImmutableList.copyOf(attributeModifiers) : null; + this.effectsToApply = effectsToApply != null ? ImmutableList.copyOf(effectsToApply) : null; + this.parent = parent; + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder forParent(ResourceLocation parent) { + return builder().parent(parent); + } + + public LooniumStructureConfiguration getEffectiveConfig( + Function parentSupplier) { + if (parent == null) { + return this; + } + var parentConfig = parentSupplier.apply(parent).getEffectiveConfig(parentSupplier); + + return new LooniumStructureConfiguration(null, + manaCost != null ? manaCost : parentConfig.manaCost, + maxNearbyMobs != null ? maxNearbyMobs : parentConfig.maxNearbyMobs, + boundingBoxType != null ? boundingBoxType : parentConfig.boundingBoxType, + spawnedMobs != null ? spawnedMobs : parentConfig.spawnedMobs, + attributeModifiers != null ? attributeModifiers : parentConfig.attributeModifiers, + effectsToApply != null ? effectsToApply : parentConfig.effectsToApply); + } + + @Override + public String toString() { + return "LooniumStructureConfiguration{" + + "manaCost=" + manaCost + + ", maxNearbyMobs=" + maxNearbyMobs + + ", boundingBoxType=" + boundingBoxType + + ", spawnedMobs=" + (spawnedMobs != null ? spawnedMobs.unwrap() : null) + + ", attributeModifiers=" + attributeModifiers + + ", effectsToApply=" + effectsToApply + + ", parent=" + parent + + '}'; + } + + // Codecs don't support setting null as intentional default value for optional fields, so we do this. + // (blame com.mojang.datafixers.util.Either::getLeft using Optional::of instead Optional.ofNullable) + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private static LooniumStructureConfiguration create(Optional parent, + Optional manaCost, Optional maxNearbyMobs, + Optional boundingBoxType, + Optional> spawnedMobs, + Optional> attributeModifiers, + Optional> effectsToApply) { + return new LooniumStructureConfiguration( + parent.orElse(null), manaCost.orElse(null), maxNearbyMobs.orElse(null), + boundingBoxType.orElse(null), spawnedMobs.orElse(null), + attributeModifiers.orElse(null), effectsToApply.orElse(null)); + } + + public static class Builder { + private ResourceLocation parent; + private Integer manaCost; + private Integer maxNearbyMobs; + private StructureSpawnOverride.BoundingBoxType boundingBoxType; + private WeightedRandomList spawnedMobs; + private List attributeModifiers; + private List effectsToApply; + + private Builder() {} + + private Builder parent(ResourceLocation parent) { + this.parent = parent; + return this; + } + + public Builder manaCost(Integer manaCost) { + this.manaCost = manaCost; + return this; + } + + public Builder maxNearbyMobs(Integer maxNearbyMobs) { + this.maxNearbyMobs = maxNearbyMobs; + return this; + } + + public Builder boundingBoxType(StructureSpawnOverride.BoundingBoxType boundingBoxType) { + this.boundingBoxType = boundingBoxType; + return this; + } + + public Builder spawnedMobs(LooniumMobSpawnData... spawnedMobs) { + this.spawnedMobs = WeightedRandomList.create(spawnedMobs); + return this; + } + + public Builder attributeModifiers(LooniumMobAttributeModifier... attributeModifiers) { + this.attributeModifiers = List.of(attributeModifiers); + return this; + } + + public Builder effectsToApply(LooniumMobEffectToApply... effectsToApply) { + this.effectsToApply = List.of(effectsToApply); + return this; + } + + public LooniumStructureConfiguration build() { + return new LooniumStructureConfiguration(parent, manaCost, maxNearbyMobs, boundingBoxType, spawnedMobs, + attributeModifiers, effectsToApply); + } + } +} diff --git a/Xplat/src/main/java/vazkii/botania/common/block/BotaniaFlowerBlocks.java b/Xplat/src/main/java/vazkii/botania/common/block/BotaniaFlowerBlocks.java index da2f89d4ba..be9043414a 100644 --- a/Xplat/src/main/java/vazkii/botania/common/block/BotaniaFlowerBlocks.java +++ b/Xplat/src/main/java/vazkii/botania/common/block/BotaniaFlowerBlocks.java @@ -733,11 +733,12 @@ public static void registerWandHudCaps(BotaniaBlockEntities.BECapConsumer new HopperhockBlockEntity.WandHud((HopperhockBlockEntity) be), HOPPERHOCK, HOPPERHOCK_CHIBI); consumer.accept(be -> new PollidisiacBlockEntity.WandHud((PollidisiacBlockEntity) be), POLLIDISIAC); consumer.accept(be -> new RannuncarpusBlockEntity.WandHud((RannuncarpusBlockEntity) be), RANNUNCARPUS, RANNUNCARPUS_CHIBI); + consumer.accept(be -> new LooniumBlockEntity.WandHud((LooniumBlockEntity) be), LOONIUM); consumer.accept(be -> new BindableSpecialFlowerBlockEntity.BindableFlowerWandHud<>((FunctionalFlowerBlockEntity) be), BELLETHORNE, BELLETHORNE_CHIBI, DREADTHORN, HEISEI_DREAM, TIGERSEYE, JADED_AMARANTHUS, ORECHID, FALLEN_KANADE, EXOFLAME, AGRICARNATION, AGRICARNATION_CHIBI, TANGLEBERRIE, TANGLEBERRIE_CHIBI, JIYUULIA, JIYUULIA_CHIBI, HYACIDUS, - CLAYCONIA, CLAYCONIA_CHIBI, LOONIUM, DAFFOMILL, VINCULOTUS, SPECTRANTHEMUM, MEDUMONE, + CLAYCONIA, CLAYCONIA_CHIBI, DAFFOMILL, VINCULOTUS, SPECTRANTHEMUM, MEDUMONE, MARIMORPHOSIS, MARIMORPHOSIS_CHIBI, BUBBELL, BUBBELL_CHIBI, SOLEGNOLIA, SOLEGNOLIA_CHIBI, ORECHID_IGNEM, LABELLIA); } diff --git a/Xplat/src/main/java/vazkii/botania/common/block/flower/functional/LooniumBlockEntity.java b/Xplat/src/main/java/vazkii/botania/common/block/flower/functional/LooniumBlockEntity.java index d279e93e40..e6ba74fd9f 100644 --- a/Xplat/src/main/java/vazkii/botania/common/block/flower/functional/LooniumBlockEntity.java +++ b/Xplat/src/main/java/vazkii/botania/common/block/flower/functional/LooniumBlockEntity.java @@ -8,59 +8,158 @@ */ package vazkii.botania.common.block.flower.functional; +import com.google.common.base.Suppliers; + +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.objects.*; + +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.resources.language.I18n; import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.Difficulty; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.MobSpawnType; -import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.Attributes; -import net.minecraft.world.entity.monster.CaveSpider; -import net.minecraft.world.entity.monster.Creeper; -import net.minecraft.world.entity.monster.Drowned; -import net.minecraft.world.entity.monster.EnderMan; -import net.minecraft.world.entity.monster.Husk; -import net.minecraft.world.entity.monster.Monster; -import net.minecraft.world.entity.monster.Skeleton; -import net.minecraft.world.entity.monster.Spider; -import net.minecraft.world.entity.monster.Stray; -import net.minecraft.world.entity.monster.Zombie; +import net.minecraft.world.entity.monster.PatrollingMonster; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.item.TieredItem; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.block.LevelEvent; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride; +import net.minecraft.world.level.levelgen.structure.StructureStart; +import net.minecraft.world.level.storage.loot.LootDataManager; import net.minecraft.world.level.storage.loot.LootParams; +import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.scores.Team; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.block_entity.FunctionalFlowerBlockEntity; import vazkii.botania.api.block_entity.RadiusDescriptor; +import vazkii.botania.api.configdata.ConfigDataManager; +import vazkii.botania.api.configdata.LooniumMobAttributeModifier; +import vazkii.botania.api.configdata.LooniumMobEffectToApply; +import vazkii.botania.api.configdata.LooniumMobSpawnData; +import vazkii.botania.api.configdata.LooniumStructureConfiguration; import vazkii.botania.common.block.BotaniaFlowerBlocks; +import vazkii.botania.common.internal_caps.LooniumComponent; import vazkii.botania.common.lib.BotaniaTags; +import vazkii.botania.common.loot.BotaniaLootTables; import vazkii.botania.xplat.XplatAbstractions; import java.util.*; import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static vazkii.botania.common.lib.ResourceLocationHelper.prefix; public class LooniumBlockEntity extends FunctionalFlowerBlockEntity { - private static final int COST = 35000; private static final int RANGE = 5; + private static final int CHECK_RANGE = 9; private static final String TAG_LOOT_TABLE = "lootTable"; - public static final Set> VALID_MOBS = Set.of( - Creeper.class, - EnderMan.class, - Skeleton.class, - Stray.class, - Spider.class, - Zombie.class - ); + private static final String TAG_DETECTED_STRUCTURE = "detectedStructure"; + private static final String TAG_CONFIG_OVERRIDE = "configOverride"; + private static final String TAG_ATTUNE_DISPLAY_OVERRIDE = "attuneDisplayOverride"; + private static final Supplier FALLBACK_CONFIG = + Suppliers.memoize(() -> LooniumStructureConfiguration.builder() + .manaCost(LooniumStructureConfiguration.DEFAULT_COST) + .maxNearbyMobs(LooniumStructureConfiguration.DEFAULT_MAX_NEARBY_MOBS) + .boundingBoxType(StructureSpawnOverride.BoundingBoxType.PIECE) + .spawnedMobs(LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 1).build()) + .attributeModifiers() + .effectsToApply( + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).build(), + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).build(), + LooniumMobEffectToApply.effect(MobEffects.DAMAGE_RESISTANCE).build(), + LooniumMobEffectToApply.effect(MobEffects.DAMAGE_BOOST).build() + ) + .build()); - private ResourceLocation lootTable = new ResourceLocation("minecraft", "chests/simple_dungeon"); + // this should never collide with the /team command, since space is not allowed in scoreboard team names + public static final String LOONIUM_TEAM_NAME = "Loonium Monsters"; + public static final Team LOONIUM_TEAM = new Team() { + @NotNull + @Override + public String getName() { + return LOONIUM_TEAM_NAME; + } + + @NotNull + @Override + public MutableComponent getFormattedName(Component component) { + return component.copy(); + } + + @Override + public boolean canSeeFriendlyInvisibles() { + return true; + } + + @Override + public boolean isAllowFriendlyFire() { + return true; + } + + @NotNull + @Override + public Visibility getNameTagVisibility() { + return Visibility.ALWAYS; + } + + @NotNull + @Override + public ChatFormatting getColor() { + return ChatFormatting.RESET; + } + + @NotNull + @Override + public Collection getPlayers() { + return List.of(); + } + + @NotNull + @Override + public Visibility getDeathMessageVisibility() { + return Visibility.ALWAYS; + } + + @NotNull + @Override + public CollisionRule getCollisionRule() { + return CollisionRule.ALWAYS; + } + }; + + @Nullable + private ResourceLocation lootTableOverride; + @Nullable + private Object2BooleanMap detectedStructures; + @Nullable + private ResourceLocation configOverride; + @Nullable + private String attuneDisplayOverride; public LooniumBlockEntity(BlockPos pos, BlockState state) { super(BotaniaFlowerBlocks.LOONIUM, pos, state); @@ -70,111 +169,329 @@ public LooniumBlockEntity(BlockPos pos, BlockState state) { public void tickFlower() { super.tickFlower(); - Level world = getLevel(); - if (!world.isClientSide && redstoneSignal == 0 && ticksExisted % 100 == 0 - && getMana() >= COST && world.getDifficulty() != Difficulty.PEACEFUL) { - var rand = world.random; - - ItemStack stack; - do { - LootParams ctx = new LootParams.Builder((ServerLevel) world).create(LootContextParamSets.EMPTY); - List stacks = ((ServerLevel) world).getServer().getLootData() - .getLootTable(lootTable).getRandomItems(ctx); - if (stacks.isEmpty()) { + if (!(getLevel() instanceof ServerLevel world)) { + return; + } + + if (detectedStructures == null) { + // Detection intentionally uses the flower position, not the effective position, + // since the latter could change while this detection is only executed once. + detectStructure(world); + } + + if (redstoneSignal != 0 || ticksExisted % 100 != 0 || world.getDifficulty() == Difficulty.PEACEFUL + // so mobs won't spawn in unloaded or border chunks + || !world.isPositionEntityTicking(getEffectivePos())) { + return; + } + + ConfigDataManager configData = BotaniaAPI.instance().getConfigData(); + Map structureConfigs = determineStructureConfigs(configData, detectedStructures); + List> lootTables = determineLootTables(world, structureConfigs.keySet()); + + if (lootTables.isEmpty()) { + return; + } + + Pair randomPick = lootTables.get(world.random.nextInt(lootTables.size())); + LooniumStructureConfiguration pickedConfig = structureConfigs.getOrDefault(randomPick.key(), + structureConfigs.get(LooniumStructureConfiguration.DEFAULT_CONFIG_ID)); + LootTable pickedLootTable = randomPick.value(); + + if (getMana() < pickedConfig.manaCost) { + return; + } + + int numberOfMobsAround = countNearbyMobs(world, pickedConfig); + if (numberOfMobsAround >= pickedConfig.maxNearbyMobs) { + return; + } + + LooniumMobSpawnData pickedMobType = pickedConfig.spawnedMobs.getRandom(world.random).orElse(null); + if (pickedMobType == null) { + return; + } + + spawnMob(world, pickedMobType, pickedConfig, pickedLootTable); + } + + private void spawnMob(ServerLevel world, LooniumMobSpawnData pickedMobType, + LooniumStructureConfiguration pickedConfig, LootTable pickedLootTable) { + + ItemStack lootStack = pickRandomLootItem(world, pickedLootTable); + if (lootStack.isEmpty()) { + return; + } + + RandomSource random = world.random; + double x = getEffectivePos().getX() + 0.5 - RANGE + 2 * RANGE * random.nextDouble(); + double y = getEffectivePos().getY(); + double z = getEffectivePos().getZ() + 0.5 - RANGE + 2 * RANGE * random.nextDouble(); + + while (!world.noCollision(pickedMobType.type.getAABB(x, y, z))) { + y += 1.0; + if (y >= world.getMaxBuildHeight()) { + return; + } + } + + Entity entity = pickedMobType.type.create(world); + if (!(entity instanceof Mob mob)) { + return; + } + + if (pickedMobType.nbt != null) { + mob.readAdditionalSaveData(pickedMobType.nbt); + } + if (pickedMobType.spawnAsBaby != null) { + mob.setBaby(pickedMobType.spawnAsBaby); + } + + mob.absMoveTo(x, y, z, random.nextFloat() * 360F, 0); + mob.setDeltaMovement(Vec3.ZERO); + + applyAttributesAndEffects(pickedMobType, pickedConfig, mob); + + LooniumComponent looniumComponent = XplatAbstractions.INSTANCE.looniumComponent(mob); + if (looniumComponent != null) { + looniumComponent.setSlowDespawn(true); + looniumComponent.setOverrideDrop(true); + looniumComponent.setDrop(lootStack); + } + + mob.finalizeSpawn(world, world.getCurrentDifficultyAt(mob.blockPosition()), MobSpawnType.SPAWNER, null, null); + if (Boolean.FALSE.equals(pickedMobType.spawnAsBaby) && mob.isBaby()) { + // Note: might have already affected initial equipment/attribute selection, or even caused a special + // mob configuration (such as chicken jockey) to spawn, which may look weird when reverting to adult. + mob.setBaby(false); + } + + if (pickedMobType.equipmentTable != null) { + LootTable equipmentTable = world.getServer().getLootData().getLootTable(pickedMobType.equipmentTable); + if (equipmentTable != LootTable.EMPTY) { + LootParams lootParams = new LootParams.Builder(world) + .withParameter(LootContextParams.THIS_ENTITY, mob) + .withParameter(LootContextParams.ORIGIN, mob.position()) + // TODO 1.21: replace with LootContextParamSets.EQUIPMENT + .create(LootContextParamSets.SELECTOR); + var equippedSlots = new HashSet(); + equipmentTable.getRandomItems(lootParams, equipmentStack -> { + EquipmentSlot slot = equipmentStack.is(BotaniaTags.Items.LOONIUM_OFFHAND_EQUIPMENT) + ? EquipmentSlot.OFFHAND + : LivingEntity.getEquipmentSlotForItem(equipmentStack); + if (equippedSlots.contains(slot)) { + slot = equippedSlots.contains(EquipmentSlot.MAINHAND) + && !(equipmentStack.getItem() instanceof TieredItem) + ? EquipmentSlot.OFFHAND + : EquipmentSlot.MAINHAND; + } + if (!equippedSlots.add(slot)) { + return; + } + mob.setItemSlot(slot, slot.isArmor() ? equipmentStack.copyWithCount(1) : equipmentStack); + }); + } + } + + // in case the mob spawned with a vehicle or passenger(s), ensure those don't drop unexpected loot + mob.getRootVehicle().getPassengersAndSelf().forEach(e -> { + if (e instanceof Mob otherMob) { + // prevent armor/weapon drops on player kill, also no nautilus shells from drowned: + Arrays.stream(EquipmentSlot.values()).forEach(slot -> otherMob.setDropChance(slot, 0)); + + if (mob instanceof PatrollingMonster patroller && patroller.isPatrolLeader()) { + // Loonium may be presenting challenges, but not that type of challenge + patroller.setPatrolLeader(false); + patroller.setItemSlot(EquipmentSlot.HEAD, ItemStack.EMPTY); + } + + if (e == mob) { return; - } else { - Collections.shuffle(stacks); - stack = stacks.get(0); } - } while (stack.isEmpty() || stack.is(BotaniaTags.Items.LOONIUM_BLACKLIST)); - int bound = RANGE * 2 + 1; - int xp = getEffectivePos().getX() - RANGE + rand.nextInt(bound); - int yp = getEffectivePos().getY(); - int zp = getEffectivePos().getZ() - RANGE + rand.nextInt(bound); + Optional mobType = pickedConfig.spawnedMobs.unwrap().stream() + .filter(mobSpawnData -> mobSpawnData.type.tryCast(otherMob) != null).findFirst(); - BlockPos pos = new BlockPos(xp, yp - 1, zp); - do { - pos = pos.above(); - if (pos.getY() >= world.getMaxBuildHeight()) { - return; + ItemStack bonusLoot; + if (mobType.isPresent()) { + applyAttributesAndEffects(mobType.get(), pickedConfig, mob); + bonusLoot = pickRandomLootItem(world, pickedLootTable); + } else { + bonusLoot = ItemStack.EMPTY; } - } while (world.getBlockState(pos).isSuffocating(world, pos)); - pos = pos.above(); - - double x = pos.getX() + Math.random(); - double y = pos.getY() + Math.random(); - double z = pos.getZ() + Math.random(); - - Monster entity = null; - if (world.random.nextInt(50) == 0) { - entity = new EnderMan(EntityType.ENDERMAN, world); - } else if (world.random.nextInt(10) == 0) { - entity = new Creeper(EntityType.CREEPER, world); - if (world.random.nextInt(200) == 0) { - CompoundTag charged = new CompoundTag(); - charged.putBoolean("powered", true); - entity.readAdditionalSaveData(charged); + + LooniumComponent otherLooniumComponent = XplatAbstractions.INSTANCE.looniumComponent(otherMob); + if (otherLooniumComponent != null) { + otherLooniumComponent.setSlowDespawn(true); + otherLooniumComponent.setOverrideDrop(true); + otherLooniumComponent.setDrop(bonusLoot); } - } else { - switch (world.random.nextInt(3)) { - case 0: - if (world.random.nextInt(10) == 0) { - entity = new Husk(EntityType.HUSK, world); - } else if (world.random.nextInt(5) == 0) { - entity = new Drowned(EntityType.DROWNED, world); - } else { - entity = new Zombie(world); - } - break; - case 1: - if (world.random.nextInt(10) == 0) { - entity = new Stray(EntityType.STRAY, world); - } else { - entity = new Skeleton(EntityType.SKELETON, world); - } - break; - case 2: - if (world.random.nextInt(10) == 0) { - entity = new CaveSpider(EntityType.CAVE_SPIDER, world); - } else { - entity = new Spider(EntityType.SPIDER, world); - } - break; + } + }); + + if (!world.tryAddFreshEntityWithPassengers(mob)) { + return; + } + + mob.spawnAnim(); + world.levelEvent(LevelEvent.PARTICLES_MOBBLOCK_SPAWN, getBlockPos(), 0); + world.gameEvent(mob, GameEvent.ENTITY_PLACE, mob.position()); + + addMana(-pickedConfig.manaCost); + sync(); + } + + private static void applyAttributesAndEffects(LooniumMobSpawnData mobSpawnData, + LooniumStructureConfiguration pickedConfig, Mob mob) { + List attributeModifiers = mobSpawnData.attributeModifiers != null + ? mobSpawnData.attributeModifiers + : pickedConfig.attributeModifiers; + for (LooniumMobAttributeModifier attributeModifier : attributeModifiers) { + AttributeInstance attribute = mob.getAttribute(attributeModifier.attribute); + if (attribute != null) { + attribute.addPermanentModifier(attributeModifier.createAttributeModifier()); + if (attribute.getAttribute() == Attributes.MAX_HEALTH) { + mob.setHealth(mob.getMaxHealth()); } } + } + + List effectsToApply = mobSpawnData.effectsToApply != null + ? mobSpawnData.effectsToApply + : pickedConfig.effectsToApply; + for (LooniumMobEffectToApply effectToApply : effectsToApply) { + mob.addEffect(effectToApply.createMobEffectInstance()); + } + } + + private int countNearbyMobs(ServerLevel world, LooniumStructureConfiguration pickedConfig) { + var setOfMobTypes = pickedConfig.spawnedMobs.unwrap().stream().map(msd -> msd.type).collect(Collectors.toSet()); + return world.getEntitiesOfClass(Mob.class, new AABB(getEffectivePos()).inflate(CHECK_RANGE), + m -> setOfMobTypes.contains(m.getType())).size(); + } + + private static ItemStack pickRandomLootItem(ServerLevel world, LootTable pickedLootTable) { + LootParams params = new LootParams.Builder(world).create(LootContextParamSets.EMPTY); + List stacks = pickedLootTable.getRandomItems(params, world.random.nextLong()); + stacks.removeIf(s -> s.isEmpty() || s.is(BotaniaTags.Items.LOONIUM_BLACKLIST)); + if (stacks.isEmpty()) { + return ItemStack.EMPTY; + } else { + Collections.shuffle(stacks); + return stacks.get(0); + } + } - entity.absMoveTo(x, y, z, world.random.nextFloat() * 360F, 0); - entity.setDeltaMovement(Vec3.ZERO); + @NotNull + private List> determineLootTables(ServerLevel world, + Set structureIds) { + var lootTables = new ArrayList>(); + LootDataManager lootData = world.getServer().getLootData(); + Supplier defaultLootTableSupplier = Suppliers.memoize(() -> lootData.getLootTable( + BotaniaLootTables.LOONIUM_DEFAULT_LOOT)); + if (lootTableOverride != null) { + LootTable lootTable = lootData.getLootTable(lootTableOverride); + if (lootTable != LootTable.EMPTY) { + lootTables.add(Pair.of(LooniumStructureConfiguration.DEFAULT_CONFIG_ID, lootTable)); + } + } else { + for (ResourceLocation structureId : structureIds) { + if (structureId.equals(LooniumStructureConfiguration.DEFAULT_CONFIG_ID)) { + continue; + } + ResourceLocation lootTableId = prefix("loonium/%s/%s".formatted(structureId.getNamespace(), structureId.getPath())); + LootTable lootTable = lootData.getLootTable(lootTableId); + if (lootTable != LootTable.EMPTY) { + lootTables.add(Pair.of(structureId, lootTable)); + } else { + LootTable defaultLootTable = defaultLootTableSupplier.get(); + if (defaultLootTable != LootTable.EMPTY) { + lootTables.add(Pair.of(structureId, defaultLootTable)); + } + } + } + } + if (lootTables.isEmpty()) { + LootTable defaultLootTable = defaultLootTableSupplier.get(); + if (defaultLootTable != LootTable.EMPTY) { + lootTables.add(Pair.of(LooniumStructureConfiguration.DEFAULT_CONFIG_ID, defaultLootTable)); + } + } + return lootTables; + } - entity.getAttribute(Attributes.MAX_HEALTH).addPermanentModifier(new AttributeModifier("Loonium Modififer Health", 2, AttributeModifier.Operation.MULTIPLY_BASE)); - entity.setHealth(entity.getMaxHealth()); - entity.getAttribute(Attributes.ATTACK_DAMAGE).addPermanentModifier(new AttributeModifier("Loonium Modififer Damage", 1.5, AttributeModifier.Operation.MULTIPLY_BASE)); + /** + * Build a map of structure IDs to resolved Loonium configurations, i.e. no need to traverse any parents. + * + * @param configData Configuration data to read from. + * @param structures Detected structures to work with. + * @return The map, which is guaranteed to not be empty. + */ + @NotNull + private Map determineStructureConfigs( + @NotNull ConfigDataManager configData, @NotNull Object2BooleanMap structures) { + if (configOverride != null) { + LooniumStructureConfiguration overrideConfig = + configData.getEffectiveLooniumStructureConfiguration(configOverride); + return Map.of(LooniumStructureConfiguration.DEFAULT_CONFIG_ID, + overrideConfig != null ? overrideConfig : getDefaultConfig(configData)); + } - entity.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, - entity instanceof Creeper ? 100 : Integer.MAX_VALUE, 0)); - entity.addEffect(new MobEffectInstance(MobEffects.REGENERATION, - entity instanceof Creeper ? 100 : Integer.MAX_VALUE, 0)); + LooniumStructureConfiguration defaultConfig = getDefaultConfig(configData); + var structureConfigs = new HashMap(); + for (Object2BooleanMap.Entry structureEntry : structures.object2BooleanEntrySet()) { + LooniumStructureConfiguration structureSpecificConfig = + configData.getEffectiveLooniumStructureConfiguration(structureEntry.getKey()); + LooniumStructureConfiguration structureConfig = structureSpecificConfig != null ? structureSpecificConfig : defaultConfig; + if (structureConfig != null && (structureEntry.getBooleanValue() + || structureConfig.boundingBoxType == StructureSpawnOverride.BoundingBoxType.STRUCTURE)) { + structureConfigs.put(structureEntry.getKey(), structureConfig); + } + } - XplatAbstractions.INSTANCE.looniumComponent(entity).setDrop(stack); + structureConfigs.put(LooniumStructureConfiguration.DEFAULT_CONFIG_ID, defaultConfig); + return structureConfigs; + } - entity.finalizeSpawn((ServerLevelAccessor) world, world.getCurrentDifficultyAt(pos), MobSpawnType.SPAWNER, null, null); - world.addFreshEntity(entity); - entity.spawnAnim(); + private static LooniumStructureConfiguration getDefaultConfig(ConfigDataManager configData) { + LooniumStructureConfiguration defaultConfig = configData.getEffectiveLooniumStructureConfiguration( + LooniumStructureConfiguration.DEFAULT_CONFIG_ID); + return defaultConfig != null ? defaultConfig : FALLBACK_CONFIG.get(); + } - addMana(-COST); - sync(); + private void detectStructure(ServerLevel world) { + // structure ID and whether the position is inside a structure piece (false = only overall bounding box) + var structureMap = new Object2BooleanRBTreeMap(); + StructureManager structureManager = world.structureManager(); + BlockPos pos = getBlockPos(); + Map structures = structureManager.getAllStructuresAt(pos); + for (Map.Entry entry : structures.entrySet()) { + Structure structure = entry.getKey(); + StructureStart start = structureManager.getStructureAt(pos, structure); + if (start.isValid()) { + ResourceLocation structureId = + world.registryAccess().registryOrThrow(Registries.STRUCTURE).getKey(structure); + boolean insidePiece = structureManager.structureHasPieceAt(pos, start); + if (insidePiece || !structureMap.getBoolean(structureId)) { + structureMap.put(structureId, insidePiece); + } + } } + + detectedStructures = new Object2BooleanArrayMap<>(structureMap); + + setChanged(); + sync(); } @Override public int getColor() { - return 0x274A00; + return 0xC29D62; } @Override public int getMaxMana() { - return COST; + return LooniumStructureConfiguration.DEFAULT_COST; } @Override @@ -187,24 +504,113 @@ public RadiusDescriptor getRadius() { return RadiusDescriptor.Rectangle.square(getEffectivePos(), RANGE); } + @Override + public RadiusDescriptor getSecondaryRadius() { + return RadiusDescriptor.Rectangle.square(getEffectivePos(), CHECK_RANGE); + } + @Override public void readFromPacketNBT(CompoundTag cmp) { super.readFromPacketNBT(cmp); if (cmp.contains(TAG_LOOT_TABLE)) { - lootTable = new ResourceLocation(cmp.getString(TAG_LOOT_TABLE)); + lootTableOverride = new ResourceLocation(cmp.getString(TAG_LOOT_TABLE)); + } + if (cmp.contains(TAG_CONFIG_OVERRIDE)) { + configOverride = new ResourceLocation(cmp.getString(TAG_CONFIG_OVERRIDE)); + } + if (cmp.contains(TAG_ATTUNE_DISPLAY_OVERRIDE)) { + attuneDisplayOverride = cmp.getString(TAG_ATTUNE_DISPLAY_OVERRIDE); + } + if (cmp.contains(TAG_DETECTED_STRUCTURE)) { + String rawString = cmp.getString(TAG_DETECTED_STRUCTURE); + if (rawString.isEmpty()) { + detectedStructures = Object2BooleanMaps.emptyMap(); + } else { + List> structureList = Arrays.stream(rawString.split(",")).map(part -> { + if (part.contains("|")) { + String[] components = part.split("\\|", 2); + return ObjectBooleanPair.of(new ResourceLocation(components[0]), Boolean.parseBoolean(components[1])); + } else { + return ObjectBooleanPair.of(new ResourceLocation(part), false); + } + }).toList(); + // list should never contain more than a few entries, so array is fine and retains entry order + var map = new Object2BooleanArrayMap(structureList.size()); + structureList.forEach(entry -> map.put(entry.key(), entry.valueBoolean())); + detectedStructures = map; + } } } @Override public void writeToPacketNBT(CompoundTag cmp) { super.writeToPacketNBT(cmp); - cmp.putString(TAG_LOOT_TABLE, lootTable.toString()); + if (lootTableOverride != null) { + cmp.putString(TAG_LOOT_TABLE, lootTableOverride.toString()); + } + if (configOverride != null) { + cmp.putString(TAG_CONFIG_OVERRIDE, configOverride.toString()); + } + if (attuneDisplayOverride != null) { + cmp.putString(TAG_ATTUNE_DISPLAY_OVERRIDE, attuneDisplayOverride); + } + if (detectedStructures != null) { + var stringBuilder = new StringBuilder(); + boolean first = true; + for (Object2BooleanMap.Entry entry : detectedStructures.object2BooleanEntrySet()) { + if (first) { + first = false; + } else { + stringBuilder.append(','); + } + stringBuilder.append(entry.getKey()).append('|').append(entry.getBooleanValue()); + } + cmp.putString(TAG_DETECTED_STRUCTURE, stringBuilder.toString()); + } } public static void dropLooniumItems(LivingEntity living, Consumer consumer) { - var comp = XplatAbstractions.INSTANCE.looniumComponent(living); - if (comp != null && !comp.getDrop().isEmpty()) { + LooniumComponent comp = XplatAbstractions.INSTANCE.looniumComponent(living); + if (comp != null && comp.isOverrideDrop()) { consumer.accept(comp.getDrop()); } } + + public static class WandHud extends BindableFlowerWandHud { + public WandHud(LooniumBlockEntity flower) { + super(flower); + } + + @Override + public void renderHUD(GuiGraphics gui, Minecraft mc) { + String lootType; + String structureName = ""; + if (flower.attuneDisplayOverride != null) { + lootType = flower.attuneDisplayOverride; + } else if (flower.lootTableOverride != null) { + lootType = "attuned"; + } else if (flower.detectedStructures == null || flower.detectedStructures.isEmpty()) { + lootType = "not_attuned"; + } else { + if (flower.detectedStructures.size() == 1) { + lootType = "attuned_one"; + structureName = flower.detectedStructures + .keySet().stream().findFirst() + .map(rl -> I18n.get("structure." + rl.getNamespace() + "." + rl.getPath().replace("/", "."))) + .orElseGet(() -> ""); + } else { + lootType = "attuned_many"; + } + } + + String lootTypeMessage = I18n.get("botaniamisc.loonium." + lootType, structureName); + int lootTypeWidth = mc.font.width(lootTypeMessage); + int lootTypeTextStart = (mc.getWindow().getGuiScaledWidth() - lootTypeWidth) / 2; + int halfMinWidth = (lootTypeWidth + 4) / 2; + int centerY = mc.getWindow().getGuiScaledHeight() / 2; + + super.renderHUD(gui, mc, halfMinWidth, halfMinWidth, 40); + gui.drawString(mc.font, lootTypeMessage, lootTypeTextStart, centerY + 30, flower.getColor()); + } + } } diff --git a/Xplat/src/main/java/vazkii/botania/common/config/ConfigDataManagerImpl.java b/Xplat/src/main/java/vazkii/botania/common/config/ConfigDataManagerImpl.java new file mode 100644 index 0000000000..72201ec2a9 --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/common/config/ConfigDataManagerImpl.java @@ -0,0 +1,124 @@ +package vazkii.botania.common.config; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.profiling.ProfilerFiller; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import vazkii.botania.api.BotaniaAPI; +import vazkii.botania.api.configdata.ConfigDataManager; +import vazkii.botania.api.configdata.LooniumStructureConfiguration; +import vazkii.botania.xplat.XplatAbstractions; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import static vazkii.botania.common.lib.ResourceLocationHelper.prefix; + +public class ConfigDataManagerImpl implements ConfigDataManager { + public static void registerListener() { + XplatAbstractions.INSTANCE.registerReloadListener(PackType.SERVER_DATA, prefix("configdata"), new ConfigDataManagerImpl()); + } + + private final Map looniumConfigs = new HashMap<>(); + + @Override + public @Nullable LooniumStructureConfiguration getEffectiveLooniumStructureConfiguration(ResourceLocation id) { + LooniumStructureConfiguration configuration = this.looniumConfigs.get(id); + return configuration != null ? configuration.getEffectiveConfig(looniumConfigs::get) : null; + } + + private static void validateLooniumConfig(Map map) { + Set errorEntries = new HashSet<>(); + Set visitedEntries = new LinkedHashSet<>(); + do { + errorEntries.clear(); + for (Map.Entry entry : map.entrySet()) { + ResourceLocation id = entry.getKey(); + ResourceLocation parent = entry.getValue().parent; + if (id.equals(parent)) { + BotaniaAPI.LOGGER.warn("Ignoring Loonium structure configuration, because it specified itself as parent: {}", id); + errorEntries.add(id); + } else { + visitedEntries.clear(); + if (!findTopmostParent(map, id, parent, visitedEntries)) { + BotaniaAPI.LOGGER.warn("Ignoring Loonium structure configuration(s) without top-most parent: {}", visitedEntries); + errorEntries.addAll(visitedEntries); + break; + } + } + } + errorEntries.forEach(map::remove); + } while (!errorEntries.isEmpty() && !map.isEmpty()); + + if (!map.containsKey(LooniumStructureConfiguration.DEFAULT_CONFIG_ID)) { + BotaniaAPI.LOGGER.error("Default Loonium configuration not found!"); + } + } + + private static boolean findTopmostParent(Map map, + ResourceLocation id, ResourceLocation parent, Set visitedEntries) { + if (!visitedEntries.add(id)) { + BotaniaAPI.LOGGER.warn("Cyclic dependency between Loonium structure configurations detected: {}", visitedEntries); + return false; + } + if (parent == null) { + return true; + } + var parentConfig = map.get(parent); + return parentConfig != null && findTopmostParent(map, parent, parentConfig.parent, visitedEntries); + } + + private void applyLooniumConfig(Map looniumConfigs) { + BotaniaAPI.LOGGER.info("Loaded {} Loonium configurations", looniumConfigs.size()); + this.looniumConfigs.putAll(looniumConfigs); + } + + @NotNull + @Override + public CompletableFuture reload(@NotNull PreparationBarrier barrier, @NotNull ResourceManager manager, + @NotNull ProfilerFiller prepProfiler, @NotNull ProfilerFiller reloadProfiler, + @NotNull Executor backgroundExecutor, @NotNull Executor gameExecutor) { + var looniumTask = scheduleConfigParse(barrier, manager, backgroundExecutor, gameExecutor, ConfigDataType.LOONUIM); + + return CompletableFuture.allOf(looniumTask).thenRun(() -> BotaniaAPI.instance().setConfigData(this)); + } + + private CompletableFuture scheduleConfigParse(PreparationBarrier barrier, ResourceManager manager, + Executor backgroundExecutor, Executor gameExecutor, ConfigDataType type) { + return CompletableFuture.supplyAsync(() -> { + Map resourceMap = new HashMap<>(); + SimpleJsonResourceReloadListener.scanDirectory(manager, type.directory, new Gson(), resourceMap); + Map configs = new HashMap<>(resourceMap.size()); + resourceMap.forEach((id, jsonElement) -> { + BotaniaAPI.LOGGER.debug("Parsing {} config '{}'", type.directory, id); + type.codec.parse(JsonOps.INSTANCE, jsonElement).result().ifPresent(c -> configs.put(id, c)); + }); + type.validateFunction.accept(configs); + return configs; + }, backgroundExecutor) + .thenCompose(barrier::wait) + .thenAcceptAsync(c -> type.applyFunction.accept(this, c), gameExecutor); + } + + private record ConfigDataType (Codec codec, String directory, + Consumer> validateFunction, + BiConsumer> applyFunction) { + private static final ConfigDataType LOONUIM = + new ConfigDataType<>(LooniumStructureConfiguration.CODEC, "loonium_config", + ConfigDataManagerImpl::validateLooniumConfig, ConfigDataManagerImpl::applyLooniumConfig); + + } +} diff --git a/Xplat/src/main/java/vazkii/botania/common/impl/BotaniaAPIImpl.java b/Xplat/src/main/java/vazkii/botania/common/impl/BotaniaAPIImpl.java index 93002e5c98..c7e867f415 100644 --- a/Xplat/src/main/java/vazkii/botania/common/impl/BotaniaAPIImpl.java +++ b/Xplat/src/main/java/vazkii/botania/common/impl/BotaniaAPIImpl.java @@ -28,10 +28,12 @@ import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.BotaniaRegistries; import vazkii.botania.api.brew.Brew; +import vazkii.botania.api.configdata.ConfigDataManager; import vazkii.botania.api.corporea.CorporeaNodeDetector; import vazkii.botania.api.internal.ManaNetwork; import vazkii.botania.client.fx.SparkleParticleData; import vazkii.botania.common.block.flower.functional.SolegnoliaBlockEntity; +import vazkii.botania.common.config.ConfigDataManagerImpl; import vazkii.botania.common.handler.BotaniaSounds; import vazkii.botania.common.handler.EquipmentHandler; import vazkii.botania.common.handler.ManaNetworkHandler; @@ -202,6 +204,8 @@ public Ingredient getRepairIngredient() { } } + private ConfigDataManager configDataManager = new ConfigDataManagerImpl(); + @Override public int apiVersion() { return 2; @@ -291,4 +295,14 @@ public void registerPaintableBlock(ResourceLocation block, Function LOONIUM_BLACKLIST = tag("loonium_blacklist"); + /** + * Items that should be equipped in the offhand slot if rolled as Loonium mob equipment, + * instead of the default slot for the item. + */ + public static final TagKey LOONIUM_OFFHAND_EQUIPMENT = tag("loonium_offhand_equipment"); /** * Items in this tag are voided by the Elementium Pick diff --git a/Xplat/src/main/java/vazkii/botania/common/loot/BotaniaLootTables.java b/Xplat/src/main/java/vazkii/botania/common/loot/BotaniaLootTables.java new file mode 100644 index 0000000000..980c2e319d --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/common/loot/BotaniaLootTables.java @@ -0,0 +1,153 @@ +package vazkii.botania.common.loot; + +import com.google.common.collect.Sets; + +import net.minecraft.resources.ResourceLocation; + +import java.util.Collections; +import java.util.Set; + +import static vazkii.botania.common.lib.ResourceLocationHelper.prefix; + +public class BotaniaLootTables { + private static final Set LOCATIONS = Sets.newHashSet(); + private static final Set IMMUTABLE_LOCATIONS = Collections.unmodifiableSet(LOCATIONS); + + public static final ResourceLocation LOONIUM_DEFAULT_LOOT = register("loonium/default"); + + // TODO 1.21: embed armor set and weapon equipment tables + public static final ResourceLocation LOONIUM_ARMORSET_COAST_CHAIN = register("equipment/loonium/armorset/coast_chain"); + public static final ResourceLocation LOONIUM_ARMORSET_COAST_IRON = register("equipment/loonium/armorset/coast_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_COAST_DIAMOND = register("equipment/loonium/armorset/coast_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_DUNE_GOLD = register("equipment/loonium/armorset/dune_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_DUNE_IRON = register("equipment/loonium/armorset/dune_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_DUNE_DIAMOND = register("equipment/loonium/armorset/dune_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_EYE_GOLD = register("equipment/loonium/armorset/eye_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_EYE_IRON = register("equipment/loonium/armorset/eye_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_EYE_DIAMOND = register("equipment/loonium/armorset/eye_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_HOST_CHAIN = register("equipment/loonium/armorset/host_chain"); + public static final ResourceLocation LOONIUM_ARMORSET_HOST_IRON = register("equipment/loonium/armorset/host_iron"); + + public static final ResourceLocation LOONIUM_ARMORSET_RAISER_IRON = register("equipment/loonium/armorset/raiser_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_RAISER_GOLD = register("equipment/loonium/armorset/raiser_gold"); + + public static final ResourceLocation LOONIUM_ARMORSET_RIB_IRON = register("equipment/loonium/armorset/rib_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_RIB_GOLD = register("equipment/loonium/armorset/rib_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_RIB_DIAMOND = register("equipment/loonium/armorset/rib_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_SENTRY_CHAIN = register("equipment/loonium/armorset/sentry_chain"); + public static final ResourceLocation LOONIUM_ARMORSET_SENTRY_IRON = register("equipment/loonium/armorset/sentry_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_SENTRY_DIAMOND = register("equipment/loonium/armorset/sentry_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_SHAPER_GOLD = register("equipment/loonium/armorset/shaper_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_SHAPER_DIAMOND = register("equipment/loonium/armorset/shaper_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_SILENCE_GOLD = register("equipment/loonium/armorset/silence_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_SILENCE_DIAMOND = register("equipment/loonium/armorset/silence_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_SNOUT_GOLD = register("equipment/loonium/armorset/snout_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_SNOUT_NETHERITE = register("equipment/loonium/armorset/snout_netherite"); + + public static final ResourceLocation LOONIUM_ARMORSET_SPIRE_IRON = register("equipment/loonium/armorset/spire_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_SPIRE_GOLD = register("equipment/loonium/armorset/spire_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_SPIRE_DIAMOND = register("equipment/loonium/armorset/spire_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_TIDE_LEATHER = register("equipment/loonium/armorset/tide_leather"); + public static final ResourceLocation LOONIUM_ARMORSET_TIDE_GOLD = register("equipment/loonium/armorset/tide_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_TIDE_DIAMOND = register("equipment/loonium/armorset/tide_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_WARD_IRON = register("equipment/loonium/armorset/ward_iron"); + public static final ResourceLocation LOONIUM_ARMORSET_WARD_DIAMOND = register("equipment/loonium/armorset/ward_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_WAYFINDER_CHAIN = register("equipment/loonium/armorset/wayfinder_chain"); + public static final ResourceLocation LOONIUM_ARMORSET_WAYFINDER_DIAMOND = register("equipment/loonium/armorset/wayfinder_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_WILD_CHAIN = register("equipment/loonium/armorset/wild_chain"); + public static final ResourceLocation LOONIUM_ARMORSET_WILD_GOLD = register("equipment/loonium/armorset/wild_gold"); + public static final ResourceLocation LOONIUM_ARMORSET_WILD_DIAMOND = register("equipment/loonium/armorset/wild_diamond"); + + public static final ResourceLocation LOONIUM_ARMORSET_COSTUME_ENDERMAN = register("equipment/loonium/armorset/costume_enderman"); + public static final ResourceLocation LOONIUM_ARMORSET_COSTUME_EVOKER = register("equipment/loonium/armorset/costume_evoker"); + public static final ResourceLocation LOONIUM_ARMORSET_COSTUME_VINDICATOR = register("equipment/loonium/armorset/costume_vindicator"); + public static final ResourceLocation LOONIUM_ARMORSET_COSTUME_ILLUSIONER = register("equipment/loonium/armorset/costume_illusioner"); + public static final ResourceLocation LOONIUM_ARMORSET_COSTUME_VEX = register("equipment/loonium/armorset/costume_vex"); + + public static final ResourceLocation LOONIUM_WEAPON_AXE = register("equipment/loonium/weapon_axe"); + public static final ResourceLocation LOONIUM_WEAPON_AXE_GOLD = register("equipment/loonium/weapon_axe_gold"); + public static final ResourceLocation LOONIUM_WEAPON_BOW = register("equipment/loonium/weapon_bow"); + public static final ResourceLocation LOONIUM_WEAPON_CROSSBOW = register("equipment/loonium/weapon_crossbow"); + public static final ResourceLocation LOONIUM_WEAPON_SWORD = register("equipment/loonium/weapon_sword"); + public static final ResourceLocation LOONIUM_WEAPON_SWORD_GOLD = register("equipment/loonium/weapon_sword_gold"); + public static final ResourceLocation LOONIUM_WEAPON_TRIDENT = register("equipment/loonium/weapon_trident"); + public static final ResourceLocation LOONIUM_WEAPON_BY_PROFESSION = register("equipment/loonium/weapon_by_profession"); + public static final ResourceLocation LOONIUM_WEAPON_FOR_PIGLIN = register("equipment/loonium/weapon_for_piglin"); + public static final ResourceLocation LOONIUM_WEAPON_FOR_WITHER_SKELETON = register("equipment/loonium/weapon_for_wither_skeleton"); + + public static final ResourceLocation LOONIUM_ARMOR_ANCIENT_CITY = register("equipment/loonium/armor_ancient_city"); + public static final ResourceLocation LOONIUM_ARMOR_BASTION_REMNANT = register("equipment/loonium/armor_bastion_remnant"); + public static final ResourceLocation LOONIUM_ARMOR_DESERT_PYRAMID = register("equipment/loonium/armor_desert_pyramid"); + public static final ResourceLocation LOONIUM_ARMOR_END_CITY = register("equipment/loonium/armor_end_city"); + public static final ResourceLocation LOONIUM_ARMOR_FORTRESS = register("equipment/loonium/armor_fortress"); + public static final ResourceLocation LOONIUM_ARMOR_JUNGLE_TEMPLE = register("equipment/loonium/armor_jungle_temple"); + public static final ResourceLocation LOONIUM_ARMOR_MANSION = register("equipment/loonium/armor_mansion"); + public static final ResourceLocation LOONIUM_ARMOR_MONUMENT = register("equipment/loonium/armor_monument"); + public static final ResourceLocation LOONIUM_ARMOR_OUTPOST = register("equipment/loonium/armor_outpost"); + public static final ResourceLocation LOONIUM_ARMOR_PORTAL = register("equipment/loonium/armor_portal"); + public static final ResourceLocation LOONIUM_ARMOR_SHIPWRECK = register("equipment/loonium/armor_shipwreck"); + public static final ResourceLocation LOONIUM_ARMOR_STRONGHOLD = register("equipment/loonium/armor_stronghold"); + public static final ResourceLocation LOONIUM_ARMOR_TRAIL_RUINS = register("equipment/loonium/armor_trail_ruins"); + + public static final ResourceLocation LOONIUM_DROWNED_ANCIENT_CITY = register("equipment/loonium/drowned_ancient_city"); + public static final ResourceLocation LOONIUM_DROWNED_JUNGLE_TEMPLE = register("equipment/loonium/drowned_jungle_temple"); + public static final ResourceLocation LOONIUM_DROWNED_MONUMENT = register("equipment/loonium/drowned_monument"); + public static final ResourceLocation LOONIUM_DROWNED_PORTAL = register("equipment/loonium/drowned_portal"); + public static final ResourceLocation LOONIUM_DROWNED_SHIPWRECK = register("equipment/loonium/drowned_shipwreck"); + public static final ResourceLocation LOONIUM_DROWNED_STRONGHOLD = register("equipment/loonium/drowned_stronghold"); + public static final ResourceLocation LOONIUM_DROWNED_TRAIL_RUINS = register("equipment/loonium/drowned_trail_ruins"); + + public static final ResourceLocation LOONIUM_PIGLIN_BASTION_REMNANT = register("equipment/loonium/piglin_bastion_remnant"); + public static final ResourceLocation LOONIUM_PIGLIN_PORTAL = register("equipment/loonium/piglin_ruined_portal"); + + public static final ResourceLocation LOONIUM_SKELETON_ANCIENT_CITY = register("equipment/loonium/skeleton_ancient_city"); + public static final ResourceLocation LOONIUM_SKELETON_DESERT_PYRAMID = register("equipment/loonium/skeleton_desert_pyramid"); + public static final ResourceLocation LOONIUM_SKELETON_JUNGLE_TEMPLE = register("equipment/loonium/skeleton_jungle_temple"); + public static final ResourceLocation LOONIUM_SKELETON_END_CITY = register("equipment/loonium/skeleton_end_city"); + public static final ResourceLocation LOONIUM_SKELETON_FORTRESS = register("equipment/loonium/skeleton_fortress"); + public static final ResourceLocation LOONIUM_SKELETON_MONUMENT = register("equipment/loonium/skeleton_monument"); + public static final ResourceLocation LOONIUM_SKELETON_OUTPOST = register("equipment/loonium/skeleton_outpost"); + public static final ResourceLocation LOONIUM_SKELETON_PORTAL = register("equipment/loonium/skeleton_portal"); + public static final ResourceLocation LOONIUM_SKELETON_SHIPWRECK = register("equipment/loonium/skeleton_shipwreck"); + public static final ResourceLocation LOONIUM_SKELETON_STRONGHOLD = register("equipment/loonium/skeleton_stronghold"); + public static final ResourceLocation LOONIUM_SKELETON_TRAIL_RUINS = register("equipment/loonium/skeleton_trail_ruins"); + + public static final ResourceLocation LOONIUM_ZOMBIE_ANCIENT_CITY = register("equipment/loonium/zombie_ancient_city"); + public static final ResourceLocation LOONIUM_ZOMBIE_DESERT_PYRAMID = register("equipment/loonium/zombie_desert_pyramid"); + public static final ResourceLocation LOONIUM_ZOMBIE_END_CITY = register("equipment/loonium/zombie_end_city"); + public static final ResourceLocation LOONIUM_ZOMBIE_FORTRESS = register("equipment/loonium/zombie_fortress"); + public static final ResourceLocation LOONIUM_ZOMBIE_JUNGLE_TEMPLE = register("equipment/loonium/zombie_jungle_temple"); + public static final ResourceLocation LOONIUM_ZOMBIE_MONUMENT = register("equipment/loonium/zombie_monument"); + public static final ResourceLocation LOONIUM_ZOMBIE_OUTPOST = register("equipment/loonium/zombie_outpost"); + public static final ResourceLocation LOONIUM_ZOMBIE_PORTAL = register("equipment/loonium/zombie_portal"); + public static final ResourceLocation LOONIUM_ZOMBIE_SHIPWRECK = register("equipment/loonium/zombie_shipwreck"); + public static final ResourceLocation LOONIUM_ZOMBIE_STRONGHOLD = register("equipment/loonium/zombie_stronghold"); + public static final ResourceLocation LOONIUM_ZOMBIE_TRAIL_RUINS = register("equipment/loonium/zombie_trail_ruins"); + + private static ResourceLocation register(String path) { + return register(prefix(path)); + } + + private static ResourceLocation register(ResourceLocation location) { + if (LOCATIONS.add(location)) { + return location; + } else { + throw new IllegalArgumentException(location + " is already a registered built-in loot table"); + } + } + + public static Set all() { + return IMMUTABLE_LOCATIONS; + } +} diff --git a/Xplat/src/main/java/vazkii/botania/data/AdvancementProvider.java b/Xplat/src/main/java/vazkii/botania/data/AdvancementProvider.java index f80f07f5e2..d92204403e 100644 --- a/Xplat/src/main/java/vazkii/botania/data/AdvancementProvider.java +++ b/Xplat/src/main/java/vazkii/botania/data/AdvancementProvider.java @@ -18,6 +18,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -28,6 +29,7 @@ import vazkii.botania.common.block.BotaniaBlocks; import vazkii.botania.common.block.BotaniaFlowerBlocks; import vazkii.botania.common.block.block_entity.corporea.CorporeaIndexBlockEntity; +import vazkii.botania.common.block.flower.functional.LooniumBlockEntity; import vazkii.botania.common.entity.BotaniaEntities; import vazkii.botania.common.item.BotaniaItems; import vazkii.botania.common.item.LexicaBotaniaItem; @@ -320,6 +322,31 @@ public void generate(HolderLookup.Provider lookup, Consumer consume public static class BotaniaChallengeAdvancements implements AdvancementSubProvider { + private static final EntityType[] LOONIUM_MOBS_TO_KILL = { + EntityType.BLAZE, + EntityType.CAVE_SPIDER, + EntityType.CREEPER, + EntityType.DROWNED, + EntityType.ENDERMAN, + EntityType.EVOKER, + EntityType.GUARDIAN, + EntityType.HOGLIN, + EntityType.HUSK, + EntityType.PIGLIN, + EntityType.PIGLIN_BRUTE, + EntityType.PILLAGER, + EntityType.SHULKER, + EntityType.SILVERFISH, + EntityType.SKELETON, + EntityType.STRAY, + EntityType.VINDICATOR, + EntityType.WITHER_SKELETON, + EntityType.ZOGLIN, + EntityType.ZOMBIE_VILLAGER, + EntityType.ZOMBIE, + EntityType.ZOMBIFIED_PIGLIN + }; + @Override public void generate(HolderLookup.Provider lookup, Consumer consumer) { Advancement root = Advancement.Builder.advancement() @@ -413,6 +440,23 @@ ContextAwarePredicate.ANY, matchItems(BotaniaItems.pinkinator), LocationPredicat .rewards(AdvancementRewards.Builder.experience(40)) .addCriterion("code_triggered", new ImpossibleTrigger.TriggerInstance()) .save(consumer, challengeId("tiny_potato_birthday")); + addLooniumMobsToKill(Advancement.Builder.advancement()) + .display(simple(BotaniaFlowerBlocks.loonium, "allLooniumMobs", FrameType.CHALLENGE)) + .parent(root) + .requirements(RequirementsStrategy.AND) + .save(consumer, challengeId("all_loonium_mobs")); + } + + private static Advancement.Builder addLooniumMobsToKill(Advancement.Builder builder) { + for (EntityType entityType : LOONIUM_MOBS_TO_KILL) { + builder.addCriterion( + BuiltInRegistries.ENTITY_TYPE.getKey(entityType).toString(), + KilledTrigger.TriggerInstance.playerKilledEntity(EntityPredicate.Builder.entity() + .of(entityType).team(LooniumBlockEntity.LOONIUM_TEAM_NAME)) + ); + } + + return builder; } } diff --git a/Xplat/src/main/java/vazkii/botania/data/ItemTagProvider.java b/Xplat/src/main/java/vazkii/botania/data/ItemTagProvider.java index bdcf1dbb42..3a2e0a613c 100644 --- a/Xplat/src/main/java/vazkii/botania/data/ItemTagProvider.java +++ b/Xplat/src/main/java/vazkii/botania/data/ItemTagProvider.java @@ -141,8 +141,13 @@ protected void addTags(HolderLookup.Provider provider) { allPetals.addTag(petalTag); } - this.tag(BotaniaTags.Items.LOONIUM_BLACKLIST).add(lexicon, overgrowthSeed, - blackLotus, blackerLotus).addTag(ItemTags.MUSIC_DISCS); + this.tag(BotaniaTags.Items.LOONIUM_BLACKLIST) + .add(lexicon, overgrowthSeed, blackLotus, blackerLotus) + .addTag(ItemTags.MUSIC_DISCS); + this.tag(ItemTags.ARROWS); + this.tag(BotaniaTags.Items.LOONIUM_OFFHAND_EQUIPMENT) + .add(Items.FIREWORK_ROCKET, Items.TOTEM_OF_UNDYING) + .addTag(ItemTags.ARROWS); this.tag(BotaniaTags.Items.MAGNET_RING_BLACKLIST); this.tag(BotaniaTags.Items.RODS).add( dirtRod, diff --git a/Xplat/src/main/java/vazkii/botania/data/LooniumEquipmentLootProvider.java b/Xplat/src/main/java/vazkii/botania/data/LooniumEquipmentLootProvider.java new file mode 100644 index 0000000000..738607d861 --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/data/LooniumEquipmentLootProvider.java @@ -0,0 +1,876 @@ +package vazkii.botania.data; + +import com.google.gson.JsonElement; + +import net.minecraft.advancements.critereon.*; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.item.*; +import net.minecraft.world.item.alchemy.PotionUtils; +import net.minecraft.world.item.armortrim.*; +import net.minecraft.world.level.storage.loot.Deserializers; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.entries.LootTableReference; +import net.minecraft.world.level.storage.loot.functions.EnchantRandomlyFunction; +import net.minecraft.world.level.storage.loot.functions.SetNbtFunction; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraft.world.level.storage.loot.predicates.AnyOfCondition; +import net.minecraft.world.level.storage.loot.predicates.LootItemEntityPropertyCondition; +import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; + +import org.apache.commons.lang3.function.TriFunction; +import org.jetbrains.annotations.NotNull; + +import vazkii.botania.api.BotaniaAPI; +import vazkii.botania.common.loot.BotaniaLootTables; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; + +public class LooniumEquipmentLootProvider implements DataProvider { + public static final int COLOR_ENDERMAN_BODY = 0x1d1d21; // (black) + public static final int COLOR_TIDE_LEATHER = 0x169c9c; // (cyan) + public static final int COLOR_EVOKER_COAT = 0x323639; // (black + gray) + public static final int COLOR_VINDICATOR_BOOTS = 0x323639; // (black + gray( + public static final int COLOR_VINDICATOR_JACKET = 0x474f52; // (gray) + public static final int COLOR_VINDICATOR_LEGWEAR = 0x168c8c; // (black + 7 cyan) + public static final int COLOR_ILLUSIONER_COAT = 0x3b7bc2; // (blue + light blue) + + private final PackOutput.PathProvider pathProvider; + private final CompletableFuture registryLookupFuture; + + public LooniumEquipmentLootProvider(PackOutput packOutput, CompletableFuture registryLookupFuture) { + // NOTE: equipment loot tables become a vanilla feature in future versions + this.pathProvider = packOutput.createPathProvider(PackOutput.Target.DATA_PACK, "loot_tables"); + this.registryLookupFuture = registryLookupFuture; + } + + @NotNull + @Override + public CompletableFuture run(@NotNull CachedOutput cache) { + return registryLookupFuture.thenCompose(registryLookup -> this.run(cache, registryLookup)); + } + + private CompletableFuture run(@NotNull CachedOutput cache, HolderLookup.Provider registryLookup) { + HolderLookup.RegistryLookup patternRegistry = registryLookup.lookupOrThrow(Registries.TRIM_PATTERN); + HolderLookup.RegistryLookup materialRegistry = registryLookup.lookupOrThrow(Registries.TRIM_MATERIAL); + BiFunction, ResourceKey, ArmorTrim> trimFactory = + (pattern, material) -> getTrim(patternRegistry, materialRegistry, pattern, material); + BiConsumer trimSetter = (trim, tag) -> addTrimToTag(registryLookup, trim).accept(tag); + BiFunction randomizedSetFactory = + (trim, armorItems) -> createArmorSet(addTrimToTag(registryLookup, trim), true, armorItems); + TriFunction randomizedDyedSetFactory = + (trim, color, armorItems) -> createArmorSet(addTrimToTag(registryLookup, trim) + .andThen(addDyedColorToTag(color)), true, armorItems); + TriFunction fixedDyedSetFactory = + (trim, color, armorItems) -> createArmorSet(addTrimToTag(registryLookup, trim) + .andThen(addDyedColorToTag(color)), false, armorItems); + + Map armorItems = Map.of( + ArmorMaterials.LEATHER, new Item[] { + Items.LEATHER_HELMET, Items.LEATHER_CHESTPLATE, Items.LEATHER_LEGGINGS, Items.LEATHER_BOOTS + }, + ArmorMaterials.CHAIN, new Item[] { + Items.CHAINMAIL_HELMET, Items.CHAINMAIL_CHESTPLATE, Items.CHAINMAIL_LEGGINGS, Items.CHAINMAIL_BOOTS + }, + ArmorMaterials.IRON, new Item[] { + Items.IRON_HELMET, Items.IRON_CHESTPLATE, Items.IRON_LEGGINGS, Items.IRON_BOOTS + }, + ArmorMaterials.GOLD, new Item[] { + Items.GOLDEN_HELMET, Items.GOLDEN_CHESTPLATE, Items.GOLDEN_LEGGINGS, Items.GOLDEN_BOOTS + }, + ArmorMaterials.DIAMOND, new Item[] { + Items.DIAMOND_HELMET, Items.DIAMOND_CHESTPLATE, Items.DIAMOND_LEGGINGS, Items.DIAMOND_BOOTS + }, + ArmorMaterials.NETHERITE, new Item[] { + Items.NETHERITE_HELMET, Items.NETHERITE_CHESTPLATE, Items.NETHERITE_LEGGINGS, Items.NETHERITE_BOOTS + } + ); + + Map tables = new HashMap<>(); + + defineWeaponEquipmentTables(tables); + defineAncientCityEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineBastionRemnantEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineDesertPyramidEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineEndCityEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineJungleTempleEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineFortressEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineOceanMonumentEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory, randomizedDyedSetFactory); + definePillagerOutpostEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineRuinedPortalEquipmentTables(tables); + defineShipwreckEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineStrongholdEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory, trimSetter); + defineTrailRuinsEquipmentTables(tables, armorItems, trimFactory, randomizedSetFactory); + defineWoodlandMansionEquipmentTables(tables, trimFactory, fixedDyedSetFactory, trimSetter); + + // TODO: we should be using LootTableSubProvider implementations instead of three individual loot providers + var output = new ArrayList>(tables.size()); + for (Map.Entry e : tables.entrySet()) { + Path path = pathProvider.json(e.getKey()); + LootTable.Builder builder = e.getValue(); + // TODO 1.21: use LootContextParamSets.EQUIPMENT instead + LootTable lootTable = builder.setParamSet(LootContextParamSets.SELECTOR).build(); + JsonElement jsonTree = Deserializers.createLootTableSerializer().create().toJsonTree(lootTable); + output.add(DataProvider.saveStable(cache, jsonTree, path)); + } + return CompletableFuture.allOf(output.toArray(CompletableFuture[]::new)); + } + + private void defineWeaponEquipmentTables(Map tables) { + tables.put(BotaniaLootTables.LOONIUM_WEAPON_AXE, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootItem.lootTableItem(Items.IRON_AXE)) + // no need to add diamond axe, it's the same base damage, but actually less enchantable + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_AXE_GOLD, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootItem.lootTableItem(Items.GOLDEN_AXE)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_BOW, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootItem.lootTableItem(Items.BOW)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_CROSSBOW, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment()) + .add(LootItem.lootTableItem(Items.CROSSBOW)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_SWORD, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootItem.lootTableItem(Items.IRON_SWORD).setWeight(4)) + .add(LootItem.lootTableItem(Items.DIAMOND_SWORD)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_SWORD_GOLD, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootItem.lootTableItem(Items.GOLDEN_SWORD)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT, + LootTable.lootTable().withPool(LootPool.lootPool() + // no useful enchantments for mob usage + .add(LootItem.lootTableItem(Items.TRIDENT)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_BY_PROFESSION, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_AXE) + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity().nbt( + new NbtPredicate(getProfessionNbt(VillagerProfession.BUTCHER)))))) + .add(LootItem.lootTableItem(Items.IRON_HOE) + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity().nbt( + new NbtPredicate(getProfessionNbt(VillagerProfession.FARMER)))))) + .add(LootItem.lootTableItem(Items.FISHING_ROD) + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity().nbt( + new NbtPredicate(getProfessionNbt(VillagerProfession.FISHERMAN)))))) + .add(LootItem.lootTableItem(Items.IRON_PICKAXE) + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity().nbt( + new NbtPredicate(getProfessionNbt(VillagerProfession.TOOLSMITH)))))) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD) + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity().nbt( + new NbtPredicate(getProfessionNbt(VillagerProfession.WEAPONSMITH)))))) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_FOR_PIGLIN, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD_GOLD)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_CROSSBOW)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_WEAPON_FOR_WITHER_SKELETON, + LootTable.lootTable().withPool(LootPool.lootPool().setRolls(UniformGenerator.between(-1, 1)) + .apply(EnchantRandomlyFunction.randomApplicableEnchantment()) + .add(LootItem.lootTableItem(Items.STONE_SWORD)) + .add(LootItem.lootTableItem(Items.BOW)) + ) + ); + } + + private CompoundTag getProfessionNbt(VillagerProfession profession) { + var villagerDataTag = new CompoundTag(); + BuiltInRegistries.VILLAGER_PROFESSION.byNameCodec().encodeStart(NbtOps.INSTANCE, profession).resultOrPartial( + BotaniaAPI.LOGGER::error).ifPresent(data -> villagerDataTag.put("profession", data)); + var tag = new CompoundTag(); + tag.put("VillagerData", villagerDataTag); + return tag; + } + + private void defineAncientCityEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimWardQuartz = trimFactory.apply(TrimPatterns.WARD, TrimMaterials.QUARTZ); + ArmorTrim trimSilenceCopper = trimFactory.apply(TrimPatterns.SILENCE, TrimMaterials.COPPER); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WARD_IRON, + randomizedSetFactory.apply(trimWardQuartz, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WARD_DIAMOND, + randomizedSetFactory.apply(trimWardQuartz, armorItems.get(ArmorMaterials.DIAMOND))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SILENCE_GOLD, + randomizedSetFactory.apply(trimSilenceCopper, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SILENCE_DIAMOND, + randomizedSetFactory.apply(trimSilenceCopper, armorItems.get(ArmorMaterials.DIAMOND))); + + CompoundTag darknessEffectTag = getPotionEffectTag(MobEffects.DARKNESS, 200); + tables.put(BotaniaLootTables.LOONIUM_ARMOR_ANCIENT_CITY, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WARD_IRON).setWeight(11)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WARD_DIAMOND).setWeight(5)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SILENCE_GOLD).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SILENCE_DIAMOND).setWeight(1)) + ).withPool(LootPool.lootPool() + // Note: Slowness from Strays stacks with tipped arrow effects, so just checking for bow here + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity().equipment(EntityEquipmentPredicate.Builder.equipment() + .mainhand(ItemPredicate.Builder.item().of(Items.BOW).build()).build()))) + .when(LootItemRandomChanceCondition.randomChance(0.9f)) + .add(LootItem.lootTableItem(Items.TIPPED_ARROW).apply(SetNbtFunction.setTag(darknessEffectTag))) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_DROWNED_ANCIENT_CITY, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_ANCIENT_CITY))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_ANCIENT_CITY, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_ANCIENT_CITY))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_ANCIENT_CITY, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_ANCIENT_CITY))) + ); + } + + private void defineBastionRemnantEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimSnoutGold = trimFactory.apply(TrimPatterns.SNOUT, TrimMaterials.GOLD); + ArmorTrim trimSnoutNetherite = trimFactory.apply(TrimPatterns.SNOUT, TrimMaterials.NETHERITE); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SNOUT_GOLD, + randomizedSetFactory.apply(trimSnoutNetherite, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SNOUT_NETHERITE, + randomizedSetFactory.apply(trimSnoutGold, armorItems.get(ArmorMaterials.NETHERITE))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_BASTION_REMNANT, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SNOUT_GOLD).setWeight(4)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SNOUT_NETHERITE).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_PIGLIN_BASTION_REMNANT, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_FOR_PIGLIN))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_BASTION_REMNANT))) + ); + } + + private void defineDesertPyramidEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimDuneRedstone = trimFactory.apply(TrimPatterns.DUNE, TrimMaterials.REDSTONE); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_DUNE_IRON, + randomizedSetFactory.apply(trimDuneRedstone, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_DUNE_GOLD, + randomizedSetFactory.apply(trimDuneRedstone, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_DUNE_DIAMOND, + randomizedSetFactory.apply(trimDuneRedstone, armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_DESERT_PYRAMID, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_DUNE_IRON).setWeight(5)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_DUNE_GOLD).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_DUNE_DIAMOND).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_DESERT_PYRAMID, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_DESERT_PYRAMID))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_DESERT_PYRAMID, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_DESERT_PYRAMID))) + ); + } + + private void defineEndCityEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimSpireAmethyst = trimFactory.apply(TrimPatterns.SPIRE, TrimMaterials.AMETHYST); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SPIRE_IRON, + randomizedSetFactory.apply(trimSpireAmethyst, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SPIRE_GOLD, + randomizedSetFactory.apply(trimSpireAmethyst, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SPIRE_DIAMOND, + randomizedSetFactory.apply(trimSpireAmethyst, armorItems.get(ArmorMaterials.DIAMOND))); + + CompoundTag levitationEffectTag = getPotionEffectTag(MobEffects.LEVITATION, 200); + tables.put(BotaniaLootTables.LOONIUM_ARMOR_END_CITY, + LootTable.lootTable().withPool(LootPool.lootPool() + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SPIRE_IRON).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SPIRE_GOLD).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SPIRE_DIAMOND).setWeight(2)) + ).withPool(LootPool.lootPool() + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity() + .entityType(EntityTypePredicate.of(EntityType.SKELETON)))) + .when(LootItemRandomChanceCondition.randomChance(0.9f)) + .add(LootItem.lootTableItem(Items.TIPPED_ARROW) + .apply(SetNbtFunction.setTag(levitationEffectTag))) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_END_CITY, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_END_CITY))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_END_CITY, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_END_CITY))) + ); + } + + private static CompoundTag getPotionEffectTag(MobEffect mobEffect, int duration) { + // [VanillaCopy] based on PotionUtils::setCustomEffects + ListTag effects = new ListTag(); + effects.add(new MobEffectInstance(mobEffect, duration).save(new CompoundTag())); + + CompoundTag effectTag = new CompoundTag(); + effectTag.put(PotionUtils.TAG_CUSTOM_POTION_EFFECTS, effects); + effectTag.putInt(PotionUtils.TAG_CUSTOM_POTION_COLOR, mobEffect.getColor()); + + return effectTag; + } + + private void defineFortressEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimRibIron = trimFactory.apply(TrimPatterns.RIB, TrimMaterials.IRON); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_RIB_IRON, + randomizedSetFactory.apply(trimRibIron, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_RIB_GOLD, + randomizedSetFactory.apply(trimRibIron, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_RIB_DIAMOND, + randomizedSetFactory.apply(trimRibIron, armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_FORTRESS, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_RIB_IRON).setWeight(7)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_RIB_GOLD).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_RIB_DIAMOND).setWeight(2)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_FORTRESS, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_FOR_WITHER_SKELETON))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_FORTRESS))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_FORTRESS, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD_GOLD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_FORTRESS))) + ); + } + + private void defineJungleTempleEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimWildEmerald = trimFactory.apply(TrimPatterns.WILD, TrimMaterials.EMERALD); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WILD_CHAIN, + randomizedSetFactory.apply(trimWildEmerald, armorItems.get(ArmorMaterials.CHAIN))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WILD_GOLD, + randomizedSetFactory.apply(trimWildEmerald, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WILD_DIAMOND, + randomizedSetFactory.apply(trimWildEmerald, armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_JUNGLE_TEMPLE, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WILD_CHAIN).setWeight(4)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WILD_GOLD).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WILD_DIAMOND).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_DROWNED_JUNGLE_TEMPLE, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_JUNGLE_TEMPLE))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_JUNGLE_TEMPLE, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_JUNGLE_TEMPLE))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_JUNGLE_TEMPLE, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_JUNGLE_TEMPLE))) + ); + } + + private void defineOceanMonumentEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory, + TriFunction randomizedDyedSetFactory) { + + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_TIDE_LEATHER, randomizedDyedSetFactory.apply( + trimFactory.apply(TrimPatterns.TIDE, TrimMaterials.COPPER), COLOR_TIDE_LEATHER, armorItems.get(ArmorMaterials.LEATHER))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_TIDE_GOLD, randomizedSetFactory.apply( + trimFactory.apply(TrimPatterns.TIDE, TrimMaterials.DIAMOND), armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_TIDE_DIAMOND, randomizedSetFactory.apply( + trimFactory.apply(TrimPatterns.TIDE, TrimMaterials.GOLD), armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_MONUMENT, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_TIDE_LEATHER).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_TIDE_GOLD).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_TIDE_DIAMOND).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_DROWNED_MONUMENT, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_MONUMENT))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_MONUMENT, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_MONUMENT))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_MONUMENT, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_MONUMENT))) + ); + } + + private void definePillagerOutpostEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimSentryEmerald = trimFactory.apply(TrimPatterns.SENTRY, TrimMaterials.EMERALD); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SENTRY_CHAIN, + randomizedSetFactory.apply(trimSentryEmerald, armorItems.get(ArmorMaterials.CHAIN))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SENTRY_IRON, + randomizedSetFactory.apply(trimSentryEmerald, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SENTRY_DIAMOND, + randomizedSetFactory.apply(trimSentryEmerald, armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_OUTPOST, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SENTRY_CHAIN).setWeight(5)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SENTRY_IRON).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SENTRY_DIAMOND).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_OUTPOST, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_OUTPOST))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_OUTPOST, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_OUTPOST))) + ); + } + + private void defineRuinedPortalEquipmentTables(Map tables) { + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_PORTAL, + LootTable.lootTable() + .withPool(LootPool.lootPool().add( + LootItem.lootTableItem(Items.GOLDEN_HELMET)).setRolls(UniformGenerator.between(0, 1))) + .withPool(LootPool.lootPool().add( + LootItem.lootTableItem(Items.GOLDEN_CHESTPLATE)).setRolls(UniformGenerator.between(0, 1))) + .withPool(LootPool.lootPool().add( + LootItem.lootTableItem(Items.GOLDEN_LEGGINGS)).setRolls(UniformGenerator.between(0, 1))) + .withPool(LootPool.lootPool().add( + LootItem.lootTableItem(Items.GOLDEN_BOOTS)).setRolls(UniformGenerator.between(0, 1))) + ); + + tables.put(BotaniaLootTables.LOONIUM_DROWNED_PORTAL, + LootTable.lootTable() + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_PORTAL))) + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + ); + tables.put(BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, + LootTable.lootTable() + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_PORTAL))) + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_FOR_PIGLIN))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_PORTAL, + LootTable.lootTable() + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_PORTAL))) + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL, + LootTable.lootTable() + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_PORTAL))) + .withPool(LootPool.lootPool().add( + LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD_GOLD))) + ); + } + + private void defineShipwreckEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimCoastEmerald = trimFactory.apply(TrimPatterns.COAST, TrimMaterials.EMERALD); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COAST_CHAIN, + randomizedSetFactory.apply(trimCoastEmerald, armorItems.get(ArmorMaterials.CHAIN))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COAST_IRON, + randomizedSetFactory.apply(trimCoastEmerald, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COAST_DIAMOND, + randomizedSetFactory.apply(trimCoastEmerald, armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_SHIPWRECK, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COAST_CHAIN).setWeight(4)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COAST_IRON).setWeight(4)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COAST_DIAMOND).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_DROWNED_SHIPWRECK, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_SHIPWRECK))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_SHIPWRECK, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_SHIPWRECK))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_SHIPWRECK, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_SHIPWRECK))) + ); + } + + private void defineStrongholdEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory, + BiConsumer trimSetter) { + + ArmorTrim trimEyeRedstone = trimFactory.apply(TrimPatterns.EYE, TrimMaterials.REDSTONE); + ArmorTrim trimEyeLapis = trimFactory.apply(TrimPatterns.EYE, TrimMaterials.LAPIS); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_EYE_IRON, + randomizedSetFactory.apply(trimEyeLapis, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_EYE_GOLD, + randomizedSetFactory.apply(trimEyeRedstone, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_EYE_DIAMOND, + randomizedSetFactory.apply(trimEyeLapis, armorItems.get(ArmorMaterials.DIAMOND))); + + // Enderman cosplay + var endermanHeadTag = new CompoundTag(); + trimSetter.accept(trimFactory.apply(TrimPatterns.EYE, TrimMaterials.AMETHYST), endermanHeadTag); + addDyedColorToTag(COLOR_ENDERMAN_BODY).accept(endermanHeadTag); + var endermanBodyTag = new CompoundTag(); + addDyedColorToTag(COLOR_ENDERMAN_BODY).accept(endermanBodyTag); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_ENDERMAN, LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_HELMET) + .apply(SetNbtFunction.setTag(endermanHeadTag)))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_CHESTPLATE) + .apply(SetNbtFunction.setTag(endermanBodyTag)))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_LEGGINGS) + .apply(SetNbtFunction.setTag(endermanBodyTag)))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_BOOTS) + .apply(SetNbtFunction.setTag(endermanBodyTag)))) + ); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_STRONGHOLD, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_EYE_IRON).setWeight(5)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_EYE_GOLD).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_EYE_DIAMOND).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_ENDERMAN).setWeight(1)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_DROWNED_STRONGHOLD, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_STRONGHOLD))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_STRONGHOLD, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_STRONGHOLD))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_STRONGHOLD, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_STRONGHOLD))) + ); + } + + private void defineTrailRuinsEquipmentTables(Map tables, + Map armorItems, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + BiFunction randomizedSetFactory) { + + ArmorTrim trimHostEmerald = trimFactory.apply(TrimPatterns.HOST, TrimMaterials.EMERALD); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_HOST_CHAIN, + randomizedSetFactory.apply(trimHostEmerald, armorItems.get(ArmorMaterials.CHAIN))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_HOST_IRON, + randomizedSetFactory.apply(trimHostEmerald, armorItems.get(ArmorMaterials.IRON))); + + ArmorTrim trimRaiserAmethyst = trimFactory.apply(TrimPatterns.RAISER, TrimMaterials.AMETHYST); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_RAISER_IRON, + randomizedSetFactory.apply(trimRaiserAmethyst, armorItems.get(ArmorMaterials.IRON))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_RAISER_GOLD, + randomizedSetFactory.apply(trimRaiserAmethyst, armorItems.get(ArmorMaterials.GOLD))); + + ArmorTrim trimShaperLapis = trimFactory.apply(TrimPatterns.SHAPER, TrimMaterials.LAPIS); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SHAPER_GOLD, + randomizedSetFactory.apply(trimShaperLapis, armorItems.get(ArmorMaterials.GOLD))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_SHAPER_DIAMOND, + randomizedSetFactory.apply(trimShaperLapis, armorItems.get(ArmorMaterials.DIAMOND))); + + ArmorTrim trimWayfinderRedstone = trimFactory.apply(TrimPatterns.WAYFINDER, TrimMaterials.REDSTONE); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WAYFINDER_CHAIN, + randomizedSetFactory.apply(trimWayfinderRedstone, armorItems.get(ArmorMaterials.CHAIN))); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_WAYFINDER_DIAMOND, + randomizedSetFactory.apply(trimWayfinderRedstone, armorItems.get(ArmorMaterials.DIAMOND))); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_TRAIL_RUINS, + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_HOST_CHAIN).setWeight(7)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WAYFINDER_CHAIN).setWeight(7)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_RAISER_IRON).setWeight(8)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_HOST_IRON).setWeight(8)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_RAISER_GOLD).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SHAPER_GOLD).setWeight(3)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_SHAPER_DIAMOND).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_WAYFINDER_DIAMOND).setWeight(2)) + ) + ); + tables.put(BotaniaLootTables.LOONIUM_DROWNED_TRAIL_RUINS, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_TRAIL_RUINS))) + ); + tables.put(BotaniaLootTables.LOONIUM_SKELETON_TRAIL_RUINS, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_BOW))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_TRAIL_RUINS))) + ); + tables.put(BotaniaLootTables.LOONIUM_ZOMBIE_TRAIL_RUINS, + LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_WEAPON_SWORD))) + .withPool(LootPool.lootPool().add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMOR_TRAIL_RUINS))) + ); + } + + private void defineWoodlandMansionEquipmentTables(Map tables, + BiFunction, ResourceKey, ArmorTrim> trimFactory, + TriFunction fixedDyedSetFactory, + BiConsumer trimSetter) { + + // Evoker cosplay, with higher likelihood of holding a totem + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_EVOKER, fixedDyedSetFactory.apply( + trimFactory.apply(TrimPatterns.VEX, TrimMaterials.GOLD), COLOR_EVOKER_COAT, + new Item[] { Items.LEATHER_CHESTPLATE, Items.LEATHER_LEGGINGS }) + .withPool(LootPool.lootPool() + .when(LootItemRandomChanceCondition.randomChance(0.2f)) + .add(LootItem.lootTableItem(Items.TOTEM_OF_UNDYING)) + ) + ); + + // Vindicator cosplay, usually including axe (even for ranged mobs) + var vindicatorChestTag = new CompoundTag(); + trimSetter.accept(trimFactory.apply(TrimPatterns.VEX, TrimMaterials.NETHERITE), vindicatorChestTag); + addDyedColorToTag(COLOR_VINDICATOR_JACKET).accept(vindicatorChestTag); + var vindicatorLegsTag = new CompoundTag(); + addDyedColorToTag(COLOR_VINDICATOR_LEGWEAR).accept(vindicatorLegsTag); + var vindicatorBootsTag = new CompoundTag(); + addDyedColorToTag(COLOR_VINDICATOR_BOOTS).accept(vindicatorBootsTag); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_VINDICATOR, LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_CHESTPLATE) + .apply(SetNbtFunction.setTag(vindicatorChestTag)))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_LEGGINGS) + .apply(SetNbtFunction.setTag(vindicatorLegsTag)))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.LEATHER_BOOTS) + .apply(SetNbtFunction.setTag(vindicatorBootsTag)))) + .withPool(LootPool.lootPool() + .when(LootItemRandomChanceCondition.randomChance(0.9f)) + .add(LootItem.lootTableItem(Items.IRON_AXE) + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))))) + ); + + // Illusioner cosplay, including bow and blindness arrows, even for mobs that don't know how to use bows + CompoundTag blindnessEffectTag = getPotionEffectTag(MobEffects.BLINDNESS, 100); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_ILLUSIONER, fixedDyedSetFactory.apply( + trimFactory.apply(TrimPatterns.VEX, TrimMaterials.LAPIS), COLOR_ILLUSIONER_COAT, + new Item[] { Items.LEATHER_HELMET, Items.LEATHER_CHESTPLATE, Items.LEATHER_LEGGINGS }) + .withPool(LootPool.lootPool() + .when(LootItemRandomChanceCondition.randomChance(0.9f)) + .add(LootItem.lootTableItem(Items.BOW) + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))))) + .withPool(LootPool.lootPool() + .when(LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity() + .entityType(EntityTypePredicate.of(EntityType.SKELETON)))) + .when(LootItemRandomChanceCondition.randomChance(0.9f)) + .add(LootItem.lootTableItem(Items.TIPPED_ARROW) + .apply(SetNbtFunction.setTag(blindnessEffectTag)))) + ); + + // Vex cosplay, including sword (even for ranged mobs) + var vexHeadTag = new CompoundTag(); + trimSetter.accept(trimFactory.apply(TrimPatterns.VEX, TrimMaterials.AMETHYST), vexHeadTag); + tables.put(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_VEX, LootTable.lootTable() + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.DIAMOND_HELMET) + .apply(SetNbtFunction.setTag(vexHeadTag)))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.DIAMOND_CHESTPLATE))) + .withPool(LootPool.lootPool().add(LootItem.lootTableItem(Items.DIAMOND_LEGGINGS))) + .withPool(LootPool.lootPool() + .when(LootItemRandomChanceCondition.randomChance(0.9f)) + .add(LootItem.lootTableItem(Items.IRON_SWORD) + .apply(EnchantRandomlyFunction.randomApplicableEnchantment() + .when(LootItemRandomChanceCondition.randomChance(0.3f))))) + ); + + tables.put(BotaniaLootTables.LOONIUM_ARMOR_MANSION, + LootTable.lootTable().withPool(LootPool.lootPool() + // it's cosplays all the way down + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_EVOKER).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_VINDICATOR).setWeight(2)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_ILLUSIONER).setWeight(1)) + .add(LootTableReference.lootTableReference(BotaniaLootTables.LOONIUM_ARMORSET_COSTUME_VEX).setWeight(45) + .when(AnyOfCondition.anyOf( + // focus Vex cosplay on baby mobs, reduce chance for everyone else + LootItemRandomChanceCondition.randomChance(0.005f), + LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, + EntityPredicate.Builder.entity() + .flags(EntityFlagsPredicate.Builder.flags().setIsBaby(true).build())) + ))) + ).withPool(LootPool.lootPool() + .when(LootItemRandomChanceCondition.randomChance(0.05f)) + .add(LootItem.lootTableItem(Items.TOTEM_OF_UNDYING)) + ) + ); + } + + private static ArmorTrim getTrim(HolderLookup.RegistryLookup patternRegistry, + HolderLookup.RegistryLookup materialRegistry, + ResourceKey pattern, ResourceKey material) { + Holder.Reference tidePattern = patternRegistry.get(pattern).orElseThrow(); + Holder.Reference goldMaterial = materialRegistry.get(material).orElseThrow(); + return new ArmorTrim(goldMaterial, tidePattern); + } + + private static Consumer addTrimToTag(HolderLookup.Provider registryLookup, ArmorTrim trim) { + // [VanillaCopy] from ArmorTrim::setTrim, because no access to item tags here + return tag -> tag.put(ArmorTrim.TAG_TRIM_ID, + ArmorTrim.CODEC.encodeStart(RegistryOps.create(NbtOps.INSTANCE, registryLookup), trim) + .result().orElseThrow()); + } + + private static Consumer addDyedColorToTag(int color) { + // [VanillaCopy] implementation based on DyeableLeatherItem::setColor + CompoundTag displayTag = new CompoundTag(); + displayTag.putInt("color", color); + return tag -> tag.put("display", displayTag); + } + + private LootTable.Builder createArmorSet(Consumer tagModifier, boolean randomized, Item... armorItems) { + CompoundTag tag = new CompoundTag(); + tagModifier.accept(tag); + LootTable.Builder lootTable = LootTable.lootTable(); + for (Item armorItem : armorItems) { + lootTable.withPool(LootPool.lootPool() + .setRolls(randomized ? UniformGenerator.between(0, 1) : ConstantValue.exactly(1)) + .add(LootItem.lootTableItem(armorItem).apply(SetNbtFunction.setTag(tag)))); + } + return lootTable; + } + + @NotNull + @Override + public String getName() { + return "Equipment tables for Loonium-spawned mobs"; + } +} diff --git a/Xplat/src/main/java/vazkii/botania/data/LooniumStructureConfigurationProvider.java b/Xplat/src/main/java/vazkii/botania/data/LooniumStructureConfigurationProvider.java new file mode 100644 index 0000000000..c6f06d8582 --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/data/LooniumStructureConfigurationProvider.java @@ -0,0 +1,752 @@ +package vazkii.botania.data; + +import com.google.gson.JsonElement; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.JsonOps; + +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.level.levelgen.structure.BuiltinStructures; +import net.minecraft.world.level.levelgen.structure.StructureSpawnOverride; + +import org.jetbrains.annotations.NotNull; + +import vazkii.botania.api.BotaniaAPI; +import vazkii.botania.api.configdata.LooniumMobAttributeModifier; +import vazkii.botania.api.configdata.LooniumMobEffectToApply; +import vazkii.botania.api.configdata.LooniumMobSpawnData; +import vazkii.botania.api.configdata.LooniumStructureConfiguration; +import vazkii.botania.common.loot.BotaniaLootTables; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import static vazkii.botania.common.lib.ResourceLocationHelper.prefix; + +public class LooniumStructureConfigurationProvider implements DataProvider { + + public static final String LOONIUM_MODIFIER_DAMAGE = "Loonium Modifier Damage"; + public static final String LOONIUM_MODIFIER_HEALTH = "Loonium Modifier Health"; + private final PackOutput.PathProvider pathProvider; + + public LooniumStructureConfigurationProvider(PackOutput packOutput) { + pathProvider = packOutput.createPathProvider(PackOutput.Target.DATA_PACK, "loonium_config"); + } + + @NotNull + @Override + public CompletableFuture run(@NotNull CachedOutput cache) { + Map configs = new HashMap<>(); + addConfigs(configs); + + var output = new ArrayList>(configs.size()); + for (Map.Entry e : configs.entrySet()) { + Path path = pathProvider.json(e.getKey()); + LooniumStructureConfiguration config = e.getValue(); + JsonElement jsonTree = LooniumStructureConfiguration.CODEC.encodeStart(JsonOps.INSTANCE, config) + .getOrThrow(false, BotaniaAPI.LOGGER::error); + output.add(DataProvider.saveStable(cache, jsonTree, path)); + } + return CompletableFuture.allOf(output.toArray(CompletableFuture[]::new)); + } + + private void addConfigs(Map configs) { + ResourceLocation defaultConfigId = LooniumStructureConfiguration.DEFAULT_CONFIG_ID; + configs.put(defaultConfigId, getDefaultConfig()); + + configs.put(BuiltinStructures.ANCIENT_CITY.location(), getConfigAncientCity(defaultConfigId)); + configs.put(BuiltinStructures.BASTION_REMNANT.location(), getConfigBastionRemnant(defaultConfigId)); + configs.put(BuiltinStructures.DESERT_PYRAMID.location(), getConfigDesertPyramid(defaultConfigId)); + configs.put(BuiltinStructures.END_CITY.location(), getConfigEndCity(defaultConfigId)); + configs.put(BuiltinStructures.FORTRESS.location(), getConfigFortress(defaultConfigId)); + configs.put(BuiltinStructures.JUNGLE_TEMPLE.location(), getConfigJungleTemple(defaultConfigId)); + configs.put(BuiltinStructures.OCEAN_MONUMENT.location(), getConfigOceanMonument(defaultConfigId)); + + ResourceLocation oceanRuinId = prefix("ocean_ruins"); + configs.put(oceanRuinId, + LooniumStructureConfiguration.forParent(defaultConfigId) + .boundingBoxType(StructureSpawnOverride.BoundingBoxType.STRUCTURE).build() + ); + configs.put(BuiltinStructures.OCEAN_RUIN_COLD.location(), getConfigOceanRuinCold(oceanRuinId)); + configs.put(BuiltinStructures.OCEAN_RUIN_WARM.location(), getConfigOceanRuinWarm(oceanRuinId)); + + configs.put(BuiltinStructures.PILLAGER_OUTPOST.location(), getConfigPillagerOutpost(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_DESERT.location(), getConfigRuinedPortalDesert(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_JUNGLE.location(), getConfigRuinedPortalJungle(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_MOUNTAIN.location(), getConfigRuinedPortalMountain(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_NETHER.location(), getConfigRuinedPortalNether(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_OCEAN.location(), getConfigRuinedPortalOcean(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_STANDARD.location(), getConfigRuinedPortalStandard(defaultConfigId)); + configs.put(BuiltinStructures.RUINED_PORTAL_SWAMP.location(), getConfigRuinedPortalSwamp(defaultConfigId)); + + configs.put(BuiltinStructures.SHIPWRECK.location(), getConfigShipwreck(defaultConfigId)); + configs.put(BuiltinStructures.SHIPWRECK_BEACHED.location(), + LooniumStructureConfiguration.forParent(BuiltinStructures.SHIPWRECK.location()).build()); + + configs.put(BuiltinStructures.STRONGHOLD.location(), getConfigStronghold(defaultConfigId)); + configs.put(BuiltinStructures.TRAIL_RUINS.location(), getConfigTrailRuins(defaultConfigId)); + + ResourceLocation villageId = prefix("village"); + configs.put(villageId, LooniumStructureConfiguration.forParent(defaultConfigId) + .boundingBoxType(StructureSpawnOverride.BoundingBoxType.STRUCTURE).build() + ); + configs.put(BuiltinStructures.VILLAGE_DESERT.location(), getConfigVillageDesert(villageId)); + configs.put(BuiltinStructures.VILLAGE_PLAINS.location(), getConfigVillagePlains(villageId)); + configs.put(BuiltinStructures.VILLAGE_SAVANNA.location(), getConfigVillageSavanna(villageId)); + configs.put(BuiltinStructures.VILLAGE_SNOWY.location(), getConfigVillageSnowy(villageId)); + configs.put(BuiltinStructures.VILLAGE_TAIGA.location(), getConfigVillageTaiga(villageId)); + + configs.put(BuiltinStructures.WOODLAND_MANSION.location(), getConfigWoodlandMansion(defaultConfigId)); + } + + public static LooniumStructureConfiguration getDefaultConfig() { + return LooniumStructureConfiguration.builder() + .manaCost(LooniumStructureConfiguration.DEFAULT_COST) + .maxNearbyMobs(LooniumStructureConfiguration.DEFAULT_MAX_NEARBY_MOBS) + .boundingBoxType(StructureSpawnOverride.BoundingBoxType.PIECE) + .spawnedMobs( + // weights roughly based on original Loonium mob selection logic + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 529) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ) + .attributeModifiers( + new LooniumMobAttributeModifier(LOONIUM_MODIFIER_HEALTH, + Attributes.MAX_HEALTH, 2, AttributeModifier.Operation.MULTIPLY_BASE), + new LooniumMobAttributeModifier(LOONIUM_MODIFIER_DAMAGE, + Attributes.ATTACK_DAMAGE, 1.5, AttributeModifier.Operation.MULTIPLY_BASE) + ) + .effectsToApply(getStandardEffects(false, true)) + .build(); + } + + public static LooniumStructureConfiguration getConfigAncientCity(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 30).build(), + getCreeperSpawnData(99, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_ANCIENT_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 80) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_ANCIENT_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 410) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_ANCIENT_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_ANCIENT_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 440) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_ANCIENT_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 100).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 200).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigBastionRemnant(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 30).build(), + getCreeperSpawnData(99, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + getPiglinSpawnData(450, BotaniaLootTables.LOONIUM_PIGLIN_BASTION_REMNANT, false, false), + LooniumMobSpawnData.entityWeight(EntityType.PIGLIN_BRUTE, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_AXE_GOLD) + .attributeModifiers( + new LooniumMobAttributeModifier(LOONIUM_MODIFIER_HEALTH, + Attributes.MAX_HEALTH, 1.5, AttributeModifier.Operation.MULTIPLY_BASE), + new LooniumMobAttributeModifier(LOONIUM_MODIFIER_DAMAGE, + Attributes.ATTACK_DAMAGE, 1.5, AttributeModifier.Operation.MULTIPLY_BASE) + ) + .build(), + LooniumMobSpawnData.entityWeight(EntityType.HOGLIN, 300).spawnAsAdult().build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigDesertPyramid(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 50).build(), + getCreeperSpawnData(149, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 450) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_DESERT_PYRAMID).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_DESERT_PYRAMID).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 500) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_DESERT_PYRAMID).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 40).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 360).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigEndCity(ResourceLocation parentId) { + LooniumMobEffectToApply[] creeperEffects = { + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).duration(100).build(), + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).duration(100).build(), + LooniumMobEffectToApply.effect(MobEffects.SLOW_FALLING).duration(400).build() + }; + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.SHULKER, 100) + .effectsToApply(getStandardEffects(true, true)).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 300).build(), + getCreeperSpawnData(99, false, creeperEffects), + getCreeperSpawnData(1, true, creeperEffects), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 300) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_END_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 300) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_END_CITY).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 300).build() + ).effectsToApply( + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).build(), + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).build(), + LooniumMobEffectToApply.effect(MobEffects.SLOW_FALLING).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigFortress(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 30).build(), + getCreeperSpawnData(99, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.BLAZE, 300) + .effectsToApply(getStandardEffects(false, false)).build(), + LooniumMobSpawnData.entityWeight(EntityType.WITHER_SKELETON, 450) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_FORTRESS) + .effectsToApply(getStandardEffects(false, false)).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_FORTRESS).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 400) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_FORTRESS) + .effectsToApply(getStandardEffects(false, false)).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigJungleTemple(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 30).build(), + getCreeperSpawnData(149, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_JUNGLE_TEMPLE).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 360) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_JUNGLE_TEMPLE).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 500) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_JUNGLE_TEMPLE).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 300).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 300).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigOceanMonument(ResourceLocation parentId) { + LooniumMobEffectToApply[] standardEffectsInWater = getStandardEffects(true, true); + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.GUARDIAN, 200).build(), + getCreeperSpawnData(199, false, getCreeperEffects(true)), + getCreeperSpawnData(1, true, getCreeperEffects(true)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 540) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_MONUMENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_MONUMENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_MONUMENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 360) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_MONUMENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 30) + .effectsToApply(standardEffectsInWater).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 270) + .effectsToApply(standardEffectsInWater).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigOceanRuinCold(ResourceLocation parentId) { + LooniumMobEffectToApply[] standardEffectsInWater = getStandardEffects(true, true); + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + getCreeperSpawnData(199, false, getCreeperEffects(true)), + getCreeperSpawnData(1, true, getCreeperEffects(true)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 540) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 360) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 30) + .effectsToApply(standardEffectsInWater).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 270) + .effectsToApply(standardEffectsInWater).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigOceanRuinWarm(ResourceLocation parentId) { + LooniumMobEffectToApply[] standardEffectsInWater = getStandardEffects(true, true); + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + getCreeperSpawnData(199, false, getCreeperEffects(true)), + getCreeperSpawnData(1, true, getCreeperEffects(true)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 540) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 400) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 30) + .effectsToApply(standardEffectsInWater).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 270) + .effectsToApply(standardEffectsInWater).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigPillagerOutpost(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId) + .boundingBoxType(StructureSpawnOverride.BoundingBoxType.STRUCTURE).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(199, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.PILLAGER, 900) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_CROSSBOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.VINDICATOR, 175) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_AXE).build(), + LooniumMobSpawnData.entityWeight(EntityType.EVOKER, 25).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 200) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_OUTPOST).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 200) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_OUTPOST).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 200).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalDesert(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 25) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(50, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, false, true), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 50).build(), + getCreeperSpawnData(149, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 450) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 450) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 360).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalJungle(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 25) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(50, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, false, true), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 30).build(), + getCreeperSpawnData(149, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 360) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 500) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 250).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 50).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalMountain(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 25) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(50, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, false, true), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 529) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 529) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SILVERFISH, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalNether(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 125) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(500, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, false, false), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 450) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 200) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 10).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 90).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalOcean(ResourceLocation parentId) { + LooniumMobEffectToApply[] standardEffectsInWater = getStandardEffects(true, true); + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 25) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(50, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, true, true), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + getCreeperSpawnData(199, false, getCreeperEffects(true)), + getCreeperSpawnData(1, true, getCreeperEffects(true)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 540) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 400) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 30) + .effectsToApply(standardEffectsInWater).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 270) + .effectsToApply(standardEffectsInWater).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalStandard(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 25) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(50, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, false, true), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 529) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigRuinedPortalSwamp(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ZOGLIN, 25) + .effectsToApply(getStandardEffects(false, false)).build(), + getPiglinSpawnData(50, BotaniaLootTables.LOONIUM_PIGLIN_PORTAL, false, true), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIFIED_PIGLIN, 50) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 30).build(), + getCreeperSpawnData(149, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 360) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 500) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_PORTAL).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 50).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 250).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigShipwreck(ResourceLocation parentId) { + LooniumMobEffectToApply[] standardEffectsInWater = getStandardEffects(true, true); + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + getCreeperSpawnData(199, false, getCreeperEffects(true)), + getCreeperSpawnData(1, true, getCreeperEffects(true)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 540) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_SHIPWRECK).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_SHIPWRECK).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_SHIPWRECK).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 360) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_SHIPWRECK).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 30) + .effectsToApply(standardEffectsInWater).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 270) + .effectsToApply(standardEffectsInWater).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigStronghold(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 80).build(), + getCreeperSpawnData(149, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_STRONGHOLD).build(), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 40) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_STRONGHOLD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 410) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_STRONGHOLD).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 60) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_STRONGHOLD).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 440) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_STRONGHOLD).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 100).build(), + LooniumMobSpawnData.entityWeight(EntityType.SILVERFISH, 100).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 400).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigTrailRuins(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_TRAIL_RUINS).build(), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_DROWNED_TRAIL_RUINS).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_ZOMBIE_TRAIL_RUINS).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_TRAIL_RUINS).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 529) + .equipmentTable(BotaniaLootTables.LOONIUM_SKELETON_TRAIL_RUINS).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigVillageDesert(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE_VILLAGER, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BY_PROFESSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 600) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigVillagePlains(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE_VILLAGER, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BY_PROFESSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 600) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigVillageSavanna(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 30) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.HUSK, 30) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE_VILLAGER, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BY_PROFESSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 600) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigVillageSnowy(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE_VILLAGER, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BY_PROFESSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 529) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigVillageTaiga(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(195, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.DROWNED, 59) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_TRIDENT).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_SWORD).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE_VILLAGER, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BY_PROFESSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.STRAY, 106) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 423) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_BOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 59).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 529).build() + ).build(); + } + + public static LooniumStructureConfiguration getConfigWoodlandMansion(ResourceLocation parentId) { + return LooniumStructureConfiguration.forParent(parentId).spawnedMobs( + LooniumMobSpawnData.entityWeight(EntityType.ENDERMAN, 40).build(), + getCreeperSpawnData(199, false, getCreeperEffects(false)), + getCreeperSpawnData(1, true, getCreeperEffects(false)), + LooniumMobSpawnData.entityWeight(EntityType.VINDICATOR, 600) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_AXE).build(), + LooniumMobSpawnData.entityWeight(EntityType.PILLAGER, 200) + .equipmentTable(BotaniaLootTables.LOONIUM_WEAPON_CROSSBOW).build(), + LooniumMobSpawnData.entityWeight(EntityType.EVOKER, 100).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 150) + .equipmentTable(BotaniaLootTables.LOONIUM_ARMOR_MANSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.ZOMBIE, 50).spawnAsBaby() + .equipmentTable(BotaniaLootTables.LOONIUM_ARMOR_MANSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.SKELETON, 200) + .equipmentTable(BotaniaLootTables.LOONIUM_ARMOR_MANSION).build(), + LooniumMobSpawnData.entityWeight(EntityType.CAVE_SPIDER, 30).build(), + LooniumMobSpawnData.entityWeight(EntityType.SPIDER, 270).build() + ).build(); + } + + public static LooniumMobEffectToApply[] getStandardEffects(boolean withWaterBreathing, boolean withFireResistance) { + return withFireResistance + ? (withWaterBreathing + ? new LooniumMobEffectToApply[] { + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).build(), + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).build(), + LooniumMobEffectToApply.effect(MobEffects.WATER_BREATHING).build() + } + : new LooniumMobEffectToApply[] { + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).build(), + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).build() + }) + : (withWaterBreathing + ? new LooniumMobEffectToApply[] { + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).build(), + LooniumMobEffectToApply.effect(MobEffects.WATER_BREATHING).build() + } + : new LooniumMobEffectToApply[] { + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).build() + }); + } + + public static LooniumMobEffectToApply[] getCreeperEffects(boolean withWaterBreathing) { + return withWaterBreathing + ? new LooniumMobEffectToApply[] { + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).duration(100).build(), + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).duration(100).build(), + LooniumMobEffectToApply.effect(MobEffects.WATER_BREATHING).build() + } + : new LooniumMobEffectToApply[] { + LooniumMobEffectToApply.effect(MobEffects.FIRE_RESISTANCE).duration(100).build(), + LooniumMobEffectToApply.effect(MobEffects.REGENERATION).duration(100).build() + }; + } + + public static LooniumMobSpawnData getCreeperSpawnData(int weight, boolean charged, + LooniumMobEffectToApply... creeperEffects) { + CompoundTag chargedCreeperNbt; + if (charged) { + chargedCreeperNbt = new CompoundTag(); + chargedCreeperNbt.putBoolean("powered", true); + } else { + chargedCreeperNbt = null; + } + + return LooniumMobSpawnData.entityWeight(EntityType.CREEPER, weight) + .nbt(chargedCreeperNbt) + .effectsToApply(creeperEffects) + .build(); + } + + public static LooniumMobSpawnData getPiglinSpawnData(int weight, ResourceLocation equipmentTable, + boolean needWaterBreathing, boolean zombificationImmune) { + CompoundTag piglinNbt = new CompoundTag(); + if (zombificationImmune) { + piglinNbt.putBoolean("IsImmuneToZombification", true); + } + + Brain piglinBrain = Brain.provider(List.of(MemoryModuleType.UNIVERSAL_ANGER, + MemoryModuleType.ADMIRING_DISABLED, MemoryModuleType.ATE_RECENTLY), List.of()) + .makeBrain(new Dynamic<>(NbtOps.INSTANCE)); + piglinBrain.setMemory(MemoryModuleType.UNIVERSAL_ANGER, true); + piglinBrain.setMemory(MemoryModuleType.ADMIRING_DISABLED, true); + piglinBrain.setMemory(MemoryModuleType.ATE_RECENTLY, true); + + DataResult dataResult = piglinBrain.serializeStart(NbtOps.INSTANCE); + dataResult.resultOrPartial(BotaniaAPI.LOGGER::error).ifPresent(tag -> piglinNbt.put("Brain", tag)); + + return LooniumMobSpawnData.entityWeight(EntityType.PIGLIN, weight) + .spawnAsAdult() + .nbt(piglinNbt) + .equipmentTable(equipmentTable) + .effectsToApply(getStandardEffects(needWaterBreathing, true)) + .build(); + } + + @NotNull + @Override + public String getName() { + return "Loonium structure configuration"; + } +} diff --git a/Xplat/src/main/java/vazkii/botania/data/LooniumStructureLootProvider.java b/Xplat/src/main/java/vazkii/botania/data/LooniumStructureLootProvider.java new file mode 100644 index 0000000000..b75114ef20 --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/data/LooniumStructureLootProvider.java @@ -0,0 +1,251 @@ +package vazkii.botania.data; + +import com.google.gson.JsonElement; + +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.levelgen.structure.BuiltinStructures; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.storage.loot.BuiltInLootTables; +import net.minecraft.world.level.storage.loot.Deserializers; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.entries.LootTableReference; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; + +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.CompletableFuture; + +import static vazkii.botania.common.lib.ResourceLocationHelper.prefix; + +public class LooniumStructureLootProvider implements DataProvider { + // loot collections based on which village type hoses can actually have chests + public static final EnumSet PLAINS_VILLAGE_LOOT = EnumSet + .of(VillageLoot.CARTOGRAPHER, VillageLoot.FISHER, VillageLoot.TANNERY, VillageLoot.WEAPONSMITH); + public static final EnumSet DESERT_VILLAGE_LOOT = EnumSet + .of(VillageLoot.TEMPLE, VillageLoot.TOOLSMITH, VillageLoot.WEAPONSMITH); + public static final EnumSet SAVANNA_VILLAGE_LOOT = EnumSet + .of(VillageLoot.BUTCHER, VillageLoot.CARTOGRAPHER, VillageLoot.MASON, VillageLoot.TANNERY, VillageLoot.WEAPONSMITH); + public static final EnumSet SNOWY_VILLAGE_LOOT = EnumSet + .of(VillageLoot.ARMORER, VillageLoot.CARTOGRAPHER, VillageLoot.SHEPHERD, VillageLoot.TANNERY, VillageLoot.WEAPONSMITH); + public static final EnumSet TAIGA_VILLAGE_LOOT = EnumSet + .of(VillageLoot.CARTOGRAPHER, VillageLoot.FLETCHER, VillageLoot.TANNERY, VillageLoot.TOOLSMITH, VillageLoot.WEAPONSMITH); + + private final PackOutput.PathProvider pathProvider; + + public LooniumStructureLootProvider(PackOutput packOutput) { + this.pathProvider = packOutput.createPathProvider(PackOutput.Target.DATA_PACK, "loot_tables/loonium"); + } + + public static ResourceLocation getStructureId(ResourceKey structureKey) { + return getStructureId(structureKey.location()); + } + + public static ResourceLocation getStructureId(ResourceLocation structureId) { + return prefix("%s/%s".formatted(structureId.getNamespace(), structureId.getPath())); + } + + @NotNull + @Override + public CompletableFuture run(@NotNull CachedOutput cache) { + Map tables = new HashMap<>(); + addLootTables(tables); + + var output = new ArrayList>(tables.size()); + for (Map.Entry e : tables.entrySet()) { + Path path = pathProvider.json(e.getKey()); + LootTable.Builder builder = e.getValue(); + LootTable lootTable = builder.setParamSet(LootContextParamSets.ALL_PARAMS).build(); + JsonElement jsonTree = Deserializers.createLootTableSerializer().create().toJsonTree(lootTable); + output.add(DataProvider.saveStable(cache, jsonTree, path)); + } + return CompletableFuture.allOf(output.toArray(CompletableFuture[]::new)); + } + + private void addLootTables(Map tables) { + // Note: As far as world generating is concerned, dungeons are "features" (i.e. like trees or geodes), + // not "structures" (like everything else the Loonium might care about). + tables.put(prefix("default"), buildDelegateLootTable(BuiltInLootTables.SIMPLE_DUNGEON)); + + /* + Note: Be careful about adding individual items instead of loot table references. + The Loonium will randomly either generate a virtual chest full of loot from any referenced table, or put just + one of the defined item entries into the "chest". Either way it only picks a single stack from that "chest". + Individual item entries need to be weighted accordingly to not have them picked too often. + Also, archaeology loot tables need to be handled carefully, due to their limited loot pool options. + */ + + tables.put(getStructureId(BuiltinStructures.ANCIENT_CITY), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.ANCIENT_CITY).setWeight(9)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.ANCIENT_CITY_ICE_BOX).setWeight(1)) + ) + ); + tables.put(getStructureId(BuiltinStructures.BASTION_REMNANT), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.BASTION_BRIDGE).setWeight(1)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.BASTION_HOGLIN_STABLE).setWeight(1)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.BASTION_TREASURE).setWeight(1)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.BASTION_OTHER).setWeight(7)) + ) + ); + tables.put(getStructureId(BuiltinStructures.BURIED_TREASURE), buildDelegateLootTable(BuiltInLootTables.BURIED_TREASURE)); + tables.put(getStructureId(BuiltinStructures.DESERT_PYRAMID), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.DESERT_PYRAMID).setWeight(37)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.DESERT_PYRAMID_ARCHAEOLOGY).setWeight(2)) + // desert wells are features, so not detectable by the Loonium + .add(LootTableReference.lootTableReference(BuiltInLootTables.DESERT_WELL_ARCHAEOLOGY)) + ) + ); + tables.put(getStructureId(BuiltinStructures.END_CITY), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.END_CITY_TREASURE).setWeight(49)) + .add(LootItem.lootTableItem(Items.ELYTRA)) + ) + ); + tables.put(getStructureId(BuiltinStructures.FORTRESS), buildDelegateLootTable(BuiltInLootTables.NETHER_BRIDGE)); + // skipping igloo, because the laboratory piece, which is the only part that has loot, can't be detected reliably + tables.put(getStructureId(BuiltinStructures.JUNGLE_TEMPLE), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.JUNGLE_TEMPLE).setWeight(9)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.JUNGLE_TEMPLE_DISPENSER)) + ) + ); + tables.put(getStructureId(BuiltinStructures.MINESHAFT), buildDelegateLootTable(BuiltInLootTables.ABANDONED_MINESHAFT)); + tables.put(getStructureId(BuiltinStructures.MINESHAFT_MESA), buildDelegateLootTable(BuiltInLootTables.ABANDONED_MINESHAFT)); + tables.put(getStructureId(BuiltinStructures.OCEAN_MONUMENT), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(EntityType.ELDER_GUARDIAN.getDefaultLootTable()).setWeight(5)) + // sponge is a player-kill drop and won't be rolled for the elder guardian table by the Loonium + .add(LootItem.lootTableItem(Items.WET_SPONGE)) + + ) + ); + tables.put(getStructureId(BuiltinStructures.OCEAN_RUIN_COLD), + buildOceanRuinLootTable(BuiltInLootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY) + ); + tables.put(getStructureId(BuiltinStructures.OCEAN_RUIN_WARM), + buildOceanRuinLootTable(BuiltInLootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY) + ); + tables.put(getStructureId(BuiltinStructures.PILLAGER_OUTPOST), buildDelegateLootTable(BuiltInLootTables.PILLAGER_OUTPOST)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_DESERT), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_JUNGLE), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_MOUNTAIN), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_NETHER), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_OCEAN), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_STANDARD), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.RUINED_PORTAL_SWAMP), buildDelegateLootTable(BuiltInLootTables.RUINED_PORTAL)); + tables.put(getStructureId(BuiltinStructures.SHIPWRECK), buildShipwreckLootTable()); + tables.put(getStructureId(BuiltinStructures.SHIPWRECK_BEACHED), buildShipwreckLootTable()); + tables.put(getStructureId(BuiltinStructures.STRONGHOLD), + // Strongholds generate up to 4 corridor chests, up to 6 crossings, and up to 2 libraries with 1 or 2 chests + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.STRONGHOLD_CORRIDOR).setWeight(4)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.STRONGHOLD_CROSSING).setWeight(6)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.STRONGHOLD_LIBRARY).setWeight(3)) + ) + ); + // skipping swamp hut, because it doesn't contain unique loot (could merge witch/cat tables, I guess) + tables.put(getStructureId(BuiltinStructures.TRAIL_RUINS), + // Trail ruins have 2 common suspicious gravel for the tower top and each road section, + // and 6 common plus 3 rare suspicious gravel per building and for the tower bottom. + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.TRAIL_RUINS_ARCHAEOLOGY_COMMON).setWeight(9)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.TRAIL_RUINS_ARCHAEOLOGY_RARE)) + ) + ); + tables.put(getStructureId(BuiltinStructures.VILLAGE_PLAINS), + buildVillageLootTable(BuiltInLootTables.VILLAGE_PLAINS_HOUSE, PLAINS_VILLAGE_LOOT) + ); + tables.put(getStructureId(BuiltinStructures.VILLAGE_DESERT), + buildVillageLootTable(BuiltInLootTables.VILLAGE_DESERT_HOUSE, DESERT_VILLAGE_LOOT) + ); + tables.put(getStructureId(BuiltinStructures.VILLAGE_SAVANNA), + buildVillageLootTable(BuiltInLootTables.VILLAGE_SAVANNA_HOUSE, SAVANNA_VILLAGE_LOOT) + ); + tables.put(getStructureId(BuiltinStructures.VILLAGE_SNOWY), + buildVillageLootTable(BuiltInLootTables.VILLAGE_SNOWY_HOUSE, SNOWY_VILLAGE_LOOT) + ); + tables.put(getStructureId(BuiltinStructures.VILLAGE_TAIGA), + buildVillageLootTable(BuiltInLootTables.VILLAGE_TAIGA_HOUSE, TAIGA_VILLAGE_LOOT) + ); + tables.put(getStructureId(BuiltinStructures.WOODLAND_MANSION), + LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.WOODLAND_MANSION).setWeight(99)) + .add(LootItem.lootTableItem(Items.TOTEM_OF_UNDYING).setWeight(1)) + ) + ); + } + + public static LootTable.Builder buildVillageLootTable(ResourceLocation house, Set villageLootSet) { + LootPool.Builder lootPool = LootPool.lootPool().add(LootTableReference.lootTableReference(house).setWeight(3)); + for (VillageLoot loot : villageLootSet) { + lootPool.add(LootTableReference.lootTableReference(loot.lootTable)); + } + return LootTable.lootTable().withPool(lootPool); + } + + @NotNull + public static LootTable.Builder buildShipwreckLootTable() { + return LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(BuiltInLootTables.SHIPWRECK_MAP)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.SHIPWRECK_SUPPLY)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.SHIPWRECK_TREASURE)) + ); + } + + @NotNull + public static LootTable.Builder buildDelegateLootTable(ResourceLocation reference) { + return LootTable.lootTable().withPool(LootPool.lootPool() + .add(LootTableReference.lootTableReference(reference)) + ); + } + + @NotNull + public static LootTable.Builder buildOceanRuinLootTable(ResourceLocation archaeology) { + // Note: since the Loonium does not supply a location, treasure maps will roll as empty maps + return LootTable.lootTable().withPool(LootPool.lootPool() + // 30% of ocean ruin sites generate with a big ruin instead of a small one, + // but 90% of those big ruin sites additionally generate 4-8 small ruins around the big one. + .add(LootTableReference.lootTableReference(BuiltInLootTables.UNDERWATER_RUIN_BIG)) + .add(LootTableReference.lootTableReference(BuiltInLootTables.UNDERWATER_RUIN_SMALL).setWeight(8)) + .add(LootTableReference.lootTableReference(archaeology)) + ); + } + + @NotNull + @Override + public String getName() { + return "Structure-specific loot tables for the Loonium"; + } + + public enum VillageLoot { + WEAPONSMITH(BuiltInLootTables.VILLAGE_WEAPONSMITH), + TOOLSMITH(BuiltInLootTables.VILLAGE_TOOLSMITH), + ARMORER(BuiltInLootTables.VILLAGE_ARMORER), + CARTOGRAPHER(BuiltInLootTables.VILLAGE_CARTOGRAPHER), + MASON(BuiltInLootTables.VILLAGE_MASON), + SHEPHERD(BuiltInLootTables.VILLAGE_SHEPHERD), + BUTCHER(BuiltInLootTables.VILLAGE_BUTCHER), + FLETCHER(BuiltInLootTables.VILLAGE_FLETCHER), + FISHER(BuiltInLootTables.VILLAGE_FISHER), + TANNERY(BuiltInLootTables.VILLAGE_TANNERY), + TEMPLE(BuiltInLootTables.VILLAGE_TEMPLE); + + public final ResourceLocation lootTable; + + VillageLoot(ResourceLocation lootTable) { + this.lootTable = lootTable; + } + } +} diff --git a/Xplat/src/main/java/vazkii/botania/mixin/EntityMixin.java b/Xplat/src/main/java/vazkii/botania/mixin/EntityMixin.java index 1c7cf770cb..0465a5a039 100644 --- a/Xplat/src/main/java/vazkii/botania/mixin/EntityMixin.java +++ b/Xplat/src/main/java/vazkii/botania/mixin/EntityMixin.java @@ -12,6 +12,8 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.scores.Team; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -20,9 +22,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import vazkii.botania.common.BotaniaDamageTypes; +import vazkii.botania.common.block.flower.functional.LooniumBlockEntity; import vazkii.botania.common.item.EquestrianVirusItem; import vazkii.botania.common.item.equipment.bauble.CrimsonPendantItem; import vazkii.botania.common.lib.BotaniaTags; +import vazkii.botania.xplat.XplatAbstractions; @Mixin(Entity.class) public abstract class EntityMixin { @@ -49,4 +53,17 @@ private void checkInvulnerabilities(DamageSource source, CallbackInfoReturnable< } } + /** + * Puts Loonium-spawned mobs on their own team. + * This is used both for easier identification in advancements and to prevent in-fighting. + */ + @Inject(at = @At("HEAD"), method = "getTeam", cancellable = true) + private void getLooniumTeam(CallbackInfoReturnable cir) { + if (((Object) this) instanceof Mob self) { + var looniumComponent = XplatAbstractions.INSTANCE.looniumComponent(self); + if (looniumComponent != null && looniumComponent.isSlowDespawn() && !looniumComponent.getDrop().isEmpty()) { + cir.setReturnValue(LooniumBlockEntity.LOONIUM_TEAM); + } + } + } } diff --git a/Xplat/src/main/java/vazkii/botania/mixin/MobMixin.java b/Xplat/src/main/java/vazkii/botania/mixin/MobMixin.java new file mode 100644 index 0000000000..4d55f5a1fd --- /dev/null +++ b/Xplat/src/main/java/vazkii/botania/mixin/MobMixin.java @@ -0,0 +1,40 @@ +package vazkii.botania.mixin; + +import net.minecraft.world.entity.Mob; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.Slice; + +import vazkii.botania.xplat.XplatAbstractions; + +@Mixin(Mob.class) +public class MobMixin { + /** + * Prevent instant despawning when outside the nearest player's despawn sphere by pretending the mob is closer to + * that player than it actually is. + * + * @param distToNearestPlayerSquared Squared distance to the nearest player. + * @return If mob should not despawn instantly (e.g. because it was spawned by a Loonium or by a monster spawner + * with an active Life Imbuer) but is farther away than its despawn distance, return a distance just under + * the (squared) despawn distance, otherwise return the original value. + */ + @ModifyVariable( + method = "checkDespawn", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/MobCategory;getDespawnDistance()I", ordinal = 0), + slice = @Slice( + from = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;distanceToSqr(Lnet/minecraft/world/entity/Entity;)D"), + to = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;removeWhenFarAway(D)Z") + ) + ) + private double reduceDistToNearestPlayer(double distToNearestPlayerSquared) { + Mob thisMob = (Mob) (Object) this; + var looniumComponent = XplatAbstractions.INSTANCE.looniumComponent(thisMob); + if (looniumComponent != null && looniumComponent.isSlowDespawn()) { + double justUnderDespawnDistance = thisMob.getType().getCategory().getDespawnDistance() - 1; + return Math.min(justUnderDespawnDistance * justUnderDespawnDistance, distToNearestPlayerSquared); + } + return distToNearestPlayerSquared; + } +} diff --git a/Xplat/src/main/resources/assets/botania/lang/en_us.json b/Xplat/src/main/resources/assets/botania/lang/en_us.json index 1021948e4f..9966eced1b 100644 --- a/Xplat/src/main/resources/assets/botania/lang/en_us.json +++ b/Xplat/src/main/resources/assets/botania/lang/en_us.json @@ -132,6 +132,10 @@ "botaniamisc.rannuncarpus.state_sensitive": "Match Exact State", "botaniamisc.rannuncarpus.state_insensitive": "Match Block Only", "botaniamisc.lokiRingLimitReached": "Selection limit reached", + "botaniamisc.loonium.not_attuned": "Not attuned", + "botaniamisc.loonium.attuned": "Attuned", + "botaniamisc.loonium.attuned_one": "Attuned to structure: %s", + "botaniamisc.loonium.attuned_many": "Attuned to multiple structures", "botaniamisc.pollidisiac.feed_adults": "Feeding adult animals", "botaniamisc.pollidisiac.feed_babies": "Feeding baby animals", "botaniamisc.pollidisiac.feed_all": "Feeding all animals", @@ -238,6 +242,38 @@ "tag.botania.mana_dusts": "Mana Dusts", "tag.botania.burst_viewers": "Burst Viewers", "tag.botania.seed_apothecary_reagent": "Seed Reagents", + "tag.botania.loonium_offhand_equipment": "Loonium Off-hand Equipment", + + "structure.minecraft.ancient_city": "Ancient City", + "structure.minecraft.bastion_remnant": "Bastion Remnant", + "structure.minecraft.buried_treasure": "Buried Treasure", + "structure.minecraft.desert_pyramid": "Desert Pyramid", + "structure.minecraft.end_city": "End City", + "structure.minecraft.fortress": "Nether Fortress", + "structure.minecraft.jungle_pyramid": "Jungle Pyramid", + "structure.minecraft.mansion": "Woodland Mansion", + "structure.minecraft.mineshaft_mesa": "Badlands Mineshaft", + "structure.minecraft.mineshaft": "Mineshaft", + "structure.minecraft.monument": "Ocean Monument", + "structure.minecraft.ocean_ruin_cold": "Cold Ocean Ruin", + "structure.minecraft.ocean_ruin_warm": "Warm Ocean Ruin", + "structure.minecraft.pillager_outpost": "Pillager Outpost", + "structure.minecraft.ruined_portal_desert": "Desert Ruined Portal", + "structure.minecraft.ruined_portal_jungle": "Jungle Ruined Portal", + "structure.minecraft.ruined_portal_mountain": "Mountain Ruined Portal", + "structure.minecraft.ruined_portal_nether": "Nether Ruined Portal", + "structure.minecraft.ruined_portal_ocean": "Ocean Ruined Portal", + "structure.minecraft.ruined_portal_swamp": "Swamp Ruined Portal", + "structure.minecraft.ruined_portal": "Ruined Portal", + "structure.minecraft.shipwreck_beached": "Beached Shipwreck", + "structure.minecraft.shipwreck": "Shipwreck", + "structure.minecraft.stronghold": "Stronghold", + "structure.minecraft.trail_ruins": "Trail Ruins", + "structure.minecraft.village_desert": "Desert Village", + "structure.minecraft.village_plains": "Plains Village", + "structure.minecraft.village_savanna": "Savanna Village", + "structure.minecraft.village_snowy": "Snowy Village", + "structure.minecraft.village_taiga": "Taiga Village", "key.botania_corporea_request": "Corporea Request", @@ -541,6 +577,8 @@ "advancement.botania:tinyPotatoBirthday": "Blessing", "advancement.botania:tinyPotatoBirthday.desc": "Celebrate Tiny Potato's Birthday on July 19th", + "advancement.botania:allLooniumMobs": "King", + "advancement.botania:allLooniumMobs.desc": "Kill one of every Loonium-spawned monster", "botania.challengelevel.easy": "Easy", "botania.challengelevel.normal": "Normal", @@ -2373,7 +2411,8 @@ "botania.entry.loonium": "Loonium", "botania.tagline.loonium": "Conjures dungeon loot", - "botania.page.loonium0": "Any adventurer knows that $(thing)Dungeons$(0) can hold valuable goodies. The $(item)Loonium$(0) will, when fed quite a bit of $(thing)Mana$(0), summon these items for said adventurers to collect.$(p)There's a catch, though: each item is held by a monster protecting it. These monsters are extra-strong, but will drop their precious $(thing)dungeon loot$(0) when killed.", + "botania.page.loonium0": "Any adventurer knows that the great structures of the world can hold valuable goodies. The $(item)Loonium$(0) will, when fed quite a bit of $(thing)Mana$(0), summon these items for said adventurers to collect.$(p)There's a catch, though: each item is held by a monster protecting it. These monsters are extra-strong, but will drop valuable loot when killed.", + "botania.page.looniumStructures": "Ordinarily the Loonium will summon treasure of the sort you would find in a $(thing)Dungeon$(0). However, the Loonium is sensitive to the large structures you can find in the world; if planted in one such structure, it'll instead summon treasure appropriate for its surroundings.$(p)It seems the Loonium is a bit picky, though-- there may be some items that never drop from the monsters it spawns.", "botania.page.loonium1": "$(o)I CAN HAZ PHAT LOOTZ$()?", "botania.entry.daffomill": "Daffomill", diff --git a/Xplat/src/main/resources/assets/botania/patchouli_books/lexicon/en_us/entries/functional_flowers/loonium.json b/Xplat/src/main/resources/assets/botania/patchouli_books/lexicon/en_us/entries/functional_flowers/loonium.json index e0f03ded8f..f53adf3565 100644 --- a/Xplat/src/main/resources/assets/botania/patchouli_books/lexicon/en_us/entries/functional_flowers/loonium.json +++ b/Xplat/src/main/resources/assets/botania/patchouli_books/lexicon/en_us/entries/functional_flowers/loonium.json @@ -9,6 +9,10 @@ "type": "text", "text": "botania.page.loonium0" }, + { + "type": "text", + "text": "botania.page.looniumStructures" + }, { "type": "botania:petal_apothecary", "text": "botania.page.loonium1", @@ -16,6 +20,6 @@ } ], "extra_recipe_mappings": { - "botania:floating_loonium": 1 + "botania:floating_loonium": 2 } } diff --git a/Xplat/src/main/resources/botania_xplat.mixins.json b/Xplat/src/main/resources/botania_xplat.mixins.json index db8a3f57e2..85b1a7b2fa 100644 --- a/Xplat/src/main/resources/botania_xplat.mixins.json +++ b/Xplat/src/main/resources/botania_xplat.mixins.json @@ -37,6 +37,7 @@ "LoomMenuPatternSlotMixin", "LootTableMixin", "MobAccessor", + "MobMixin", "MushroomCowAccessor", "NaturalSpawnerMixin", "NearestAttackableTargetGoalAccessor", diff --git a/Xplat/src/main/resources/omake.md b/Xplat/src/main/resources/omake.md index 6d71abfa25..3ba0deb02d 100644 --- a/Xplat/src/main/resources/omake.md +++ b/Xplat/src/main/resources/omake.md @@ -1207,11 +1207,12 @@ WARNING: Some songs are 18+ and inappropriate for children. | Hand in Hand | Place >255 extra blocks at once with Loki Ring | [https://vocadb.net/S/89726](https://vocadb.net/S/89726) | | Innocentia | Obtain Fruit of Grisaia | [https://vocadb.net/S/13385](https://vocadb.net/S/13385) | | One Step Layered | Obtain Thor Ring | [https://vocadb.net/S/365](https://vocadb.net/S/365) | -| Angel of Death | Obtain Flugel Eye | [https://vocadb.net/S/28559](https://vocadb.net/S/28559) | +| Angel of Death | Obtain Flügel Eye | [https://vocadb.net/S/28559](https://vocadb.net/S/28559) | | A Fake, Fake Psychotropic | Obtain King Key | [https://vocadb.net/S/37948](https://vocadb.net/S/37948) | | Lost Time Memory | Obtain Odin Ring | [https://vocadb.net/S/25896](https://vocadb.net/S/25896) | | Decorator | Use Pinkinator | [https://vocadb.net/S/45245](https://vocadb.net/S/45245) | | Blessing | Wish Tiny Potato happy birthday | [https://vocadb.net/S/50703](https://vocadb.net/S/50703) | +| King | Kill one of every Loonium-spawned monster | [https://vocadb.net/S/290384](https://vocadb.net/S/290384) | ## Favorites Hm? You want to know my favorites? diff --git a/web/changelog.md b/web/changelog.md index 01af6433a0..6d0468b289 100644 --- a/web/changelog.md +++ b/web/changelog.md @@ -17,7 +17,10 @@ and start a new "Upcoming" section. {% include changelog_header.html version="Upcoming" %} -(none yet) +* Add: Looniums can now give different loot and mob spawns based on which +structure it's placed in, also further customizable with datapacks. Huuuuge +thanks to Wormbo for a lot of work on this feature! +* Change: More readable color in Loonium tooltip ---