From 523cba5958c28e62e2b6e2c8984607078a2b30c1 Mon Sep 17 00:00:00 2001 From: Mrbysco Date: Mon, 11 Mar 2024 19:17:59 +0100 Subject: [PATCH] Add the Engineers House back --- .../103d9f3f36b01595f1aa5172191e60eff02e6924 | 3 +- .../59eb3dbb5f86130e09b3c62d89b9525ee01cf52d | 3 +- .../74807d958079a027731c973b9550985af6711175 | 3 +- .../loot_tables/engineer_house.json | 119 +++++++++ .../tags/items/crystal_blocks.json | 10 + .../processor_list/engineer_house.json | 249 ++++++++++++++++++ .../actuallyadditions/api/ActuallyTags.java | 1 + .../data/ActuallyAdditionsData.java | 2 + .../data/ItemTagsGenerator.java | 4 + .../data/LootTableGenerator.java | 33 ++- .../mod/ActuallyAdditions.java | 4 +- .../mod/gen/ActuallyProcessorLists.java | 49 ++++ ...illageCrops.java => ActuallyVillages.java} | 70 ++++- .../mod/misc/DungeonLoot.java | 5 +- .../resources/META-INF/accesstransformer.cfg | 4 +- .../andrew_period_house.nbt | Bin .../structures/andrew_period_house.nbt | Bin 0 -> 6403 bytes 17 files changed, 549 insertions(+), 10 deletions(-) create mode 100644 src/generated/resources/data/actuallyadditions/loot_tables/engineer_house.json create mode 100644 src/generated/resources/data/actuallyadditions/tags/items/crystal_blocks.json create mode 100644 src/generated/resources/data/actuallyadditions/worldgen/processor_list/engineer_house.json create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyProcessorLists.java rename src/main/java/de/ellpeck/actuallyadditions/mod/gen/{ActuallyVillageCrops.java => ActuallyVillages.java} (50%) rename src/main/resources/assets/actuallyadditions/{structures => old_structures}/andrew_period_house.nbt (100%) create mode 100644 src/main/resources/data/actuallyadditions/structures/andrew_period_house.nbt diff --git a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 index ccdfa3305..d06e33ccb 100644 --- a/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 +++ b/src/generated/resources/.cache/103d9f3f36b01595f1aa5172191e60eff02e6924 @@ -1,5 +1,6 @@ -// 1.20.4 2024-03-05T16:59:47.0535355 Registries +// 1.20.4 2024-03-11T17:48:44.6414485 Registries 020d2b1f1c21d6c6663ef8126a52e2b9deb0e52e data/actuallyadditions/damage_type/atomicreconstructor.json 4ba41428fdcf03f52855029153722e22e8702823 data/actuallyadditions/neoforge/biome_modifier/add_black_quartz.json 3c9f4fbfed04f0e75ea7b370aa2f8acc531a63bb data/actuallyadditions/worldgen/configured_feature/ore_black_quartz.json fce2111f746f4c6ddef5444d84a5c2b574efaaa0 data/actuallyadditions/worldgen/placed_feature/ore_black_quartz.json +7cf126882346a296f045db75facf741c77b7d3b1 data/actuallyadditions/worldgen/processor_list/engineer_house.json diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d index 6dc43ddd6..23c6099bd 100644 --- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -1,4 +1,4 @@ -// 1.20.4 2024-03-05T17:10:52.5254064 Loot Tables +// 1.20.4 2024-03-11T19:15:36.5038055 Loot Tables f6655bb234dbcf1041fe8ad95c976ddddda2b02a data/actuallyadditions/loot_tables/blocks/atomic_reconstructor.json e15c868b26b669c30365bfb93e7d9274e07df16d data/actuallyadditions/loot_tables/blocks/battery_box.json 745d64af3b0203a138f9eca7de21ed4988b35c95 data/actuallyadditions/loot_tables/blocks/bio_reactor.json @@ -120,3 +120,4 @@ d43769e7f20448bf87952664a3ddd12db0804627 data/actuallyadditions/loot_tables/bloc 58ebb57d3470800107617d0cc84250750834b675 data/actuallyadditions/loot_tables/blocks/void_crystal_cluster.json d3498d690b7d9170fecdc2dd9825519b680cfeec data/actuallyadditions/loot_tables/blocks/wood_casing.json e1ebdde950a7f730c423a16143ad5598e3b6e3a7 data/actuallyadditions/loot_tables/blocks/xp_solidifier.json +860b2c007cf8a1942e3f2934e1385a3a75d3a940 data/actuallyadditions/loot_tables/engineer_house.json diff --git a/src/generated/resources/.cache/74807d958079a027731c973b9550985af6711175 b/src/generated/resources/.cache/74807d958079a027731c973b9550985af6711175 index 81a4f6c5f..a83039d51 100644 --- a/src/generated/resources/.cache/74807d958079a027731c973b9550985af6711175 +++ b/src/generated/resources/.cache/74807d958079a027731c973b9550985af6711175 @@ -1,6 +1,7 @@ -// 1.20.4 2024-03-09T22:54:38.6848812 Tags for minecraft:item mod id actuallyadditions +// 1.20.4 2024-03-11T17:20:46.9018598 Tags for minecraft:item mod id actuallyadditions 87327118c2f16da245b76de4fdcaab149456d9b8 data/actuallyadditions/tags/items/coffee_beans.json f3ee78cd8c9563bd1828de2b4b336735f289f9f2 data/actuallyadditions/tags/items/crystals.json +441008b49b4bab00125100fc969cb6582eff7271 data/actuallyadditions/tags/items/crystal_blocks.json 7e6e49c3eb5302af147a2d6ba439e83bd4831cbc data/actuallyadditions/tags/items/drills.json ae55da193b94fd6375c05d5aa46cafdda9d335cd data/actuallyadditions/tags/items/tiny_coals.json 31cd008db3c44a9c3f643f296e1c7688ca45e2e5 data/forge/tags/items/crops.json diff --git a/src/generated/resources/data/actuallyadditions/loot_tables/engineer_house.json b/src/generated/resources/data/actuallyadditions/loot_tables/engineer_house.json new file mode 100644 index 000000000..37cc1d864 --- /dev/null +++ b/src/generated/resources/data/actuallyadditions/loot_tables/engineer_house.json @@ -0,0 +1,119 @@ +{ + "type": "minecraft:chest", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 10.0, + "min": 3.0 + }, + "function": "minecraft:set_count" + } + ], + "name": "actuallyadditions:wood_casing", + "weight": 60 + }, + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 3.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + } + ], + "name": "actuallyadditions:iron_casing", + "weight": 40 + }, + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 5.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + } + ], + "name": "actuallyadditions:black_quartz", + "weight": 20 + }, + { + "type": "minecraft:item", + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 2.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + } + ], + "name": "actuallyadditions:bats_wing", + "weight": 5 + }, + { + "type": "minecraft:item", + "name": "actuallyadditions:drill_core", + "weight": 5 + }, + { + "type": "minecraft:tag", + "expand": true, + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 3.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + } + ], + "name": "actuallyadditions:crystals", + "weight": 20 + }, + { + "type": "minecraft:tag", + "expand": true, + "functions": [ + { + "add": false, + "count": { + "type": "minecraft:uniform", + "max": 3.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + } + ], + "name": "actuallyadditions:crystals", + "weight": 3 + } + ], + "rolls": { + "type": "minecraft:uniform", + "max": 7.0, + "min": 4.0 + } + } + ], + "random_sequence": "actuallyadditions:engineer_house" +} \ No newline at end of file diff --git a/src/generated/resources/data/actuallyadditions/tags/items/crystal_blocks.json b/src/generated/resources/data/actuallyadditions/tags/items/crystal_blocks.json new file mode 100644 index 000000000..db84fad81 --- /dev/null +++ b/src/generated/resources/data/actuallyadditions/tags/items/crystal_blocks.json @@ -0,0 +1,10 @@ +{ + "values": [ + "actuallyadditions:restonia_crystal_block", + "actuallyadditions:palis_crystal_block", + "actuallyadditions:diamatine_crystal_block", + "actuallyadditions:void_crystal_block", + "actuallyadditions:emeradic_crystal_block", + "actuallyadditions:enori_crystal_block" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/actuallyadditions/worldgen/processor_list/engineer_house.json b/src/generated/resources/data/actuallyadditions/worldgen/processor_list/engineer_house.json new file mode 100644 index 000000000..333619c92 --- /dev/null +++ b/src/generated/resources/data/actuallyadditions/worldgen/processor_list/engineer_house.json @@ -0,0 +1,249 @@ +{ + "processors": [ + { + "processor_type": "minecraft:rule", + "rules": [ + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_orange", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_magenta", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_light_blue", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_yellow", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_lime", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_pink", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_gray", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_light_gray", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_cyan", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_purple", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_blue", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_brown", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_green", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_red", + "Properties": { + "lit": "true" + } + } + }, + { + "input_predicate": { + "block": "actuallyadditions:lamp_white", + "predicate_type": "minecraft:random_block_match", + "probability": 0.0625 + }, + "location_predicate": { + "predicate_type": "minecraft:always_true" + }, + "output_state": { + "Name": "actuallyadditions:lamp_black", + "Properties": { + "lit": "true" + } + } + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyTags.java b/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyTags.java index 32b5370b3..76367a1cf 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyTags.java +++ b/src/main/java/de/ellpeck/actuallyadditions/api/ActuallyTags.java @@ -24,6 +24,7 @@ public final class ActuallyTags { public static final TagKey TINY_COALS = tag("tiny_coals"); public static final TagKey HOLDS_ITEMS = ItemTags.create(new ResourceLocation("forge", "holds_items")); public static final TagKey CRYSTALS = tag("crystals"); + public static final TagKey CRYSTAL_BLOCKS = tag("crystal_blocks"); public static final TagKey SEEDS_RICE = ItemTags.create(new ResourceLocation("forge", "seeds/rice")); public static final TagKey SEEDS_COFFEE = ItemTags.create(new ResourceLocation("forge", "seeds/coffee")); public static final TagKey SEEDS_CANOLA = ItemTags.create(new ResourceLocation("forge", "seeds/canola")); diff --git a/src/main/java/de/ellpeck/actuallyadditions/data/ActuallyAdditionsData.java b/src/main/java/de/ellpeck/actuallyadditions/data/ActuallyAdditionsData.java index cfd65a3f7..d95cbb2e5 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/data/ActuallyAdditionsData.java +++ b/src/main/java/de/ellpeck/actuallyadditions/data/ActuallyAdditionsData.java @@ -5,6 +5,7 @@ import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.gen.ActuallyBiomeModifiers; import de.ellpeck.actuallyadditions.mod.gen.ActuallyConfiguredFeatures; import de.ellpeck.actuallyadditions.mod.gen.ActuallyPlacedFeatures; +import de.ellpeck.actuallyadditions.mod.gen.ActuallyProcessorLists; import de.ellpeck.actuallyadditions.mod.misc.ActuallyDamageTypes; import net.minecraft.core.Cloner; import net.minecraft.core.HolderLookup; @@ -75,6 +76,7 @@ public class ActuallyAdditionsData { }); registryBuilder.add(Registries.CONFIGURED_FEATURE, ActuallyConfiguredFeatures::bootstrap); registryBuilder.add(Registries.PLACED_FEATURE, ActuallyPlacedFeatures::bootstrap); + registryBuilder.add(Registries.PROCESSOR_LIST, ActuallyProcessorLists::bootstrap); registryBuilder.add(NeoForgeRegistries.Keys.BIOME_MODIFIERS, ActuallyBiomeModifiers::bootstrap); // We need the BIOME registry to be present, so we can use a biome tag, doesn't matter that it's empty registryBuilder.add(Registries.BIOME, $ -> { diff --git a/src/main/java/de/ellpeck/actuallyadditions/data/ItemTagsGenerator.java b/src/main/java/de/ellpeck/actuallyadditions/data/ItemTagsGenerator.java index 70f689faf..38dec1cc3 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/data/ItemTagsGenerator.java +++ b/src/main/java/de/ellpeck/actuallyadditions/data/ItemTagsGenerator.java @@ -39,6 +39,10 @@ public class ItemTagsGenerator extends ItemTagsProvider { .add(ActuallyItems.RESTONIA_CRYSTAL.get(), ActuallyItems.PALIS_CRYSTAL.get(), ActuallyItems.DIAMATINE_CRYSTAL.get(), ActuallyItems.VOID_CRYSTAL.get(), ActuallyItems.EMERADIC_CRYSTAL.get(), ActuallyItems.ENORI_CRYSTAL.get()); + this.tag(ActuallyTags.Items.CRYSTAL_BLOCKS) + .add(ActuallyBlocks.RESTONIA_CRYSTAL.getItem(), ActuallyBlocks.PALIS_CRYSTAL.getItem(), + ActuallyBlocks.DIAMATINE_CRYSTAL.getItem(), ActuallyBlocks.VOID_CRYSTAL.getItem(), + ActuallyBlocks.EMERADIC_CRYSTAL.getItem(), ActuallyBlocks.ENORI_CRYSTAL.getItem()); tag(Tags.Items.SLIMEBALLS) .add(ActuallyItems.RICE_SLIMEBALL.get()); diff --git a/src/main/java/de/ellpeck/actuallyadditions/data/LootTableGenerator.java b/src/main/java/de/ellpeck/actuallyadditions/data/LootTableGenerator.java index 689fbeebb..51b1d3b4f 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/data/LootTableGenerator.java +++ b/src/main/java/de/ellpeck/actuallyadditions/data/LootTableGenerator.java @@ -2,13 +2,16 @@ package de.ellpeck.actuallyadditions.data; import com.google.common.collect.ImmutableSet; +import de.ellpeck.actuallyadditions.api.ActuallyTags; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; import de.ellpeck.actuallyadditions.mod.items.ActuallyItems; +import de.ellpeck.actuallyadditions.mod.misc.DungeonLoot; import net.minecraft.advancements.critereon.StatePropertiesPredicate; import net.minecraft.data.PackOutput; import net.minecraft.data.loot.BlockLootSubProvider; import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.data.loot.LootTableSubProvider; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.item.Item; @@ -19,17 +22,21 @@ import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.ValidationContext; import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.entries.TagEntry; import net.minecraft.world.level.storage.loot.functions.CopyNbtFunction; +import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition; import net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider; import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; import net.neoforged.neoforge.registries.DeferredHolder; import javax.annotation.Nonnull; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -37,7 +44,8 @@ import java.util.stream.Collectors; public class LootTableGenerator extends LootTableProvider { public LootTableGenerator(PackOutput packOutput) { super(packOutput, Set.of(), List.of( - new SubProviderEntry(Blocks::new, LootContextParamSets.BLOCK) + new SubProviderEntry(Blocks::new, LootContextParamSets.BLOCK), + new SubProviderEntry(Dungeon::new, LootContextParamSets.CHEST) )); } @@ -240,4 +248,27 @@ public class LootTableGenerator extends LootTableProvider { return ActuallyBlocks.BLOCKS.getEntries().stream().map(DeferredHolder::get).filter(e -> !ignoreForNow.contains(e)).collect(Collectors.toList()); } } + + public static class Dungeon implements LootTableSubProvider { + @Override + public void generate(BiConsumer pOutput) { + // addCrystals = true; + + pOutput.accept( + DungeonLoot.ENGINEER_HOUSE, + LootTable.lootTable() + .withPool( + LootPool.lootPool() + .setRolls(UniformGenerator.between(4.0F, 7.0F)) + .add(LootItem.lootTableItem(ActuallyBlocks.WOOD_CASING.getItem()).setWeight(60).apply(SetItemCountFunction.setCount(UniformGenerator.between(3.0F, 10.0F)))) + .add(LootItem.lootTableItem(ActuallyBlocks.IRON_CASING.getItem()).setWeight(40).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 3.0F)))) + .add(LootItem.lootTableItem(ActuallyItems.BLACK_QUARTZ.get()).setWeight(20).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 5.0F)))) + .add(LootItem.lootTableItem(ActuallyItems.BATS_WING.get()).setWeight(5).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 2.0F)))) + .add(LootItem.lootTableItem(ActuallyItems.DRILL_CORE.get()).setWeight(5)) + .add(TagEntry.expandTag(ActuallyTags.Items.CRYSTALS).setWeight(20).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 3.0F)))) + .add(TagEntry.expandTag(ActuallyTags.Items.CRYSTALS).setWeight(3).apply(SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 3.0F)))) + ) + ); + } + } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java index efaa129db..aaff4bff6 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java @@ -26,7 +26,7 @@ import de.ellpeck.actuallyadditions.mod.entity.EntityWorm; import de.ellpeck.actuallyadditions.mod.entity.InitEntities; import de.ellpeck.actuallyadditions.mod.event.CommonEvents; import de.ellpeck.actuallyadditions.mod.fluids.InitFluids; -import de.ellpeck.actuallyadditions.mod.gen.ActuallyVillageCrops; +import de.ellpeck.actuallyadditions.mod.gen.ActuallyVillages; import de.ellpeck.actuallyadditions.mod.gen.modifier.BoolConfigFeatureBiomeModifier; import de.ellpeck.actuallyadditions.mod.inventory.ActuallyContainers; import de.ellpeck.actuallyadditions.mod.items.ActuallyItems; @@ -125,7 +125,7 @@ public class ActuallyAdditions { // NeoForge.EVENT_BUS.register(new DungeonLoot()); NeoForge.EVENT_BUS.addListener(ActuallyAdditions::reloadEvent); NeoForge.EVENT_BUS.addListener(Worm::onHoe); - NeoForge.EVENT_BUS.addListener(ActuallyVillageCrops::addNewVillageCrop); + NeoForge.EVENT_BUS.addListener(ActuallyVillages::modifyVillageStructures); InitFluids.init(eventBus); eventBus.addListener(PacketHandler::register); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyProcessorLists.java b/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyProcessorLists.java new file mode 100644 index 000000000..6353c96dd --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyProcessorLists.java @@ -0,0 +1,49 @@ +package de.ellpeck.actuallyadditions.mod.gen; + +import com.google.common.collect.ImmutableList; +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.worldgen.BootstapContext; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.levelgen.structure.templatesystem.AlwaysTrueTest; +import net.minecraft.world.level.levelgen.structure.templatesystem.ProcessorRule; +import net.minecraft.world.level.levelgen.structure.templatesystem.RandomBlockMatchTest; +import net.minecraft.world.level.levelgen.structure.templatesystem.RuleProcessor; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList; + +import java.util.List; + +public class ActuallyProcessorLists { + public static final ResourceKey ENGINEER_HOUSE_PROCESSOR_LIST_KEY = ResourceKey.create( + Registries.PROCESSOR_LIST, new ResourceLocation(ActuallyAdditions.MODID, "engineer_house")); + + public static void bootstrap(BootstapContext context) { + register(context, ENGINEER_HOUSE_PROCESSOR_LIST_KEY, ImmutableList.of(new RuleProcessor(ImmutableList.of( + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_ORANGE.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_MAGENTA.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_LIGHT_BLUE.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_YELLOW.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_LIME.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_PINK.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_GRAY.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_LIGHT_GRAY.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_CYAN.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_PURPLE.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_BLUE.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_BROWN.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_GREEN.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_RED.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)), + new ProcessorRule(new RandomBlockMatchTest(ActuallyBlocks.LAMP_WHITE.get(), 0.0625F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.LAMP_BLACK.get().defaultBlockState().setValue(BlockStateProperties.LIT, true)) + )))); + } + + private static void register(BootstapContext bootstapContext, + ResourceKey processorListResourceKey, + List structureProcessorList) { + bootstapContext.register(processorListResourceKey, new StructureProcessorList(structureProcessorList)); + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyVillageCrops.java b/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyVillages.java similarity index 50% rename from src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyVillageCrops.java rename to src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyVillages.java index 4d4aa99b8..a9bf57fd3 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyVillageCrops.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/gen/ActuallyVillages.java @@ -1,10 +1,16 @@ package de.ellpeck.actuallyadditions.mod.gen; +import com.mojang.datafixers.util.Pair; +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement; +import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement; +import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool; import net.minecraft.world.level.levelgen.structure.templatesystem.AlwaysTrueTest; import net.minecraft.world.level.levelgen.structure.templatesystem.ProcessorRule; import net.minecraft.world.level.levelgen.structure.templatesystem.RandomBlockMatchTest; @@ -16,11 +22,71 @@ import net.neoforged.neoforge.event.server.ServerAboutToStartEvent; import java.util.ArrayList; import java.util.List; -public class ActuallyVillageCrops { +public class ActuallyVillages { - public static void addNewVillageCrop(final ServerAboutToStartEvent event) { + + private static void addBuildingToPool(Registry templatePoolRegistry, + Registry processorListRegistry, + ResourceLocation poolRL, + String nbtPieceRL, + int weight) { + + // Grabs the processor list we want to use along with our piece. + // This is a requirement as using the ProcessorLists.EMPTY field will cause the game to throw errors. + // The reason why is the empty processor list in the world's registry is not the same instance as in that field once the world is started up. + Holder emptyProcessorList = processorListRegistry.getHolderOrThrow(ActuallyProcessorLists.ENGINEER_HOUSE_PROCESSOR_LIST_KEY); + + // Grab the pool we want to add to + StructureTemplatePool pool = templatePoolRegistry.get(poolRL); + if (pool == null) return; + + // Grabs the nbt piece and creates a SinglePoolElement of it that we can add to a structure's pool. + // Use .legacy( for villages/outposts and .single( for everything else + SinglePoolElement piece = SinglePoolElement.legacy(nbtPieceRL, emptyProcessorList).apply(StructureTemplatePool.Projection.RIGID); + + // Use AccessTransformer or Accessor Mixin to make StructureTemplatePool's templates field public for us to see. + // Weight is handled by how many times the entry appears in this list. + // We do not need to worry about immutability as this field is created using Lists.newArrayList(); which makes a mutable list. + for (int i = 0; i < weight; i++) { + pool.templates.add(piece); + } + + // Use AccessTransformer or Accessor Mixin to make StructureTemplatePool's rawTemplates field public for us to see. + // This list of pairs of pieces and weights is not used by vanilla by default but another mod may need it for efficiency. + // So lets add to this list for completeness. We need to make a copy of the array as it can be an immutable list. + // NOTE: This is a com.mojang.datafixers.util.Pair. It is NOT a fastUtil pair class. Use the mojang class. + List> listOfPieceEntries = new ArrayList<>(pool.rawTemplates); + listOfPieceEntries.add(new Pair<>(piece, weight)); + pool.rawTemplates = listOfPieceEntries; + } + + + public static void modifyVillageStructures(final ServerAboutToStartEvent event) { + Registry templatePoolRegistry = event.getServer().registryAccess().registry(Registries.TEMPLATE_POOL).orElseThrow(); Registry processorListRegistry = event.getServer().registryAccess().registry(Registries.PROCESSOR_LIST).orElseThrow(); + //Add Engineer house to villages + addBuildingToPool(templatePoolRegistry, processorListRegistry, + new ResourceLocation("minecraft:village/plains/houses"), + ActuallyAdditions.MODID + ":andrew_period_house", 10); + + addBuildingToPool(templatePoolRegistry, processorListRegistry, + new ResourceLocation("minecraft:village/snowy/houses"), + ActuallyAdditions.MODID + ":andrew_period_house", 10); + + addBuildingToPool(templatePoolRegistry, processorListRegistry, + new ResourceLocation("minecraft:village/savanna/houses"), + ActuallyAdditions.MODID + ":andrew_period_house", 10); + + addBuildingToPool(templatePoolRegistry, processorListRegistry, + new ResourceLocation("minecraft:village/taiga/houses"), + ActuallyAdditions.MODID + ":andrew_period_house", 10); + + addBuildingToPool(templatePoolRegistry, processorListRegistry, + new ResourceLocation("minecraft:village/desert/houses"), + ActuallyAdditions.MODID + ":andrew_period_house", 50); + + //Add Actually Additions crops to village farms StructureProcessor cropProcessor = new RuleProcessor(List.of( new ProcessorRule(new RandomBlockMatchTest(Blocks.WHEAT, 0.30F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.RICE.get().defaultBlockState()), new ProcessorRule(new RandomBlockMatchTest(Blocks.WHEAT, 0.25F), AlwaysTrueTest.INSTANCE, ActuallyBlocks.COFFEE.get().defaultBlockState()), diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/misc/DungeonLoot.java b/src/main/java/de/ellpeck/actuallyadditions/mod/misc/DungeonLoot.java index 6213849d9..8e9d7a70f 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/misc/DungeonLoot.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/misc/DungeonLoot.java @@ -10,13 +10,16 @@ package de.ellpeck.actuallyadditions.mod.misc; +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.resources.ResourceLocation; + // TODO: [port] MOVE OVER TO DATA GENS @Deprecated public class DungeonLoot { // // public static final ResourceLocation JAM_HOUSE = new ResourceLocation(ActuallyAdditions.MODID, "jam_house"); // public static final ResourceLocation LUSH_CAVES = new ResourceLocation(ActuallyAdditions.MODID, "lush_caves"); - // public static final ResourceLocation ENGINEER_HOUSE = new ResourceLocation(ActuallyAdditions.MODID, "engineer_house"); + public static final ResourceLocation ENGINEER_HOUSE = new ResourceLocation(ActuallyAdditions.MODID, "engineer_house"); // // public DungeonLoot() { // LootTableList.register(JAM_HOUSE); diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index c0f898e08..6312b21b9 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -3,4 +3,6 @@ public net.minecraft.world.damagesource.DamageSources damageTypes public-f net.minecraft.data.recipes.RecipeProvider getName()Ljava/lang/String; public-f net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList list public net.minecraft.world.item.crafting.ShapedRecipe pattern -public net.minecraft.world.inventory.InventoryMenu TEXTURE_EMPTY_SLOTS \ No newline at end of file +public net.minecraft.world.inventory.InventoryMenu TEXTURE_EMPTY_SLOTS +public net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool templates +public-f net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool rawTemplates \ No newline at end of file diff --git a/src/main/resources/assets/actuallyadditions/structures/andrew_period_house.nbt b/src/main/resources/assets/actuallyadditions/old_structures/andrew_period_house.nbt similarity index 100% rename from src/main/resources/assets/actuallyadditions/structures/andrew_period_house.nbt rename to src/main/resources/assets/actuallyadditions/old_structures/andrew_period_house.nbt diff --git a/src/main/resources/data/actuallyadditions/structures/andrew_period_house.nbt b/src/main/resources/data/actuallyadditions/structures/andrew_period_house.nbt new file mode 100644 index 0000000000000000000000000000000000000000..6c06dfe581e6e866f5c8e51e0a9d6b0190e7a9b7 GIT binary patch literal 6403 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 literal 0 HcmV?d00001