From 2b9becda1849476fcdf0f6cb84ad2392b9ce864b Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Mon, 20 Jul 2020 22:39:30 -0400 Subject: [PATCH] Structure Generation! --- build.gradle | 10 +++ gradle.properties | 1 + .../energonrelics/EnergonRelics.java | 26 ++++-- .../energonrelics/block/TestBlock.java | 28 ------- .../ResearchComplexGeneratorBlockEntity.java | 52 ++++++++++++ .../ResearchComplexGeneratorBlock.java | 41 ++++++++++ .../block/util/EnergyProviderBlock.java | 6 +- .../energonrelics/block/util/SimpleBlock.java | 8 +- .../component/NetworkComponent.java | 36 ++++---- .../core/EnergyProviderBlockEntity.java | 30 ++++--- .../core/EnergyReceiverBlockEntity.java | 15 +++- .../energy/core/util/EnergyProvider.java | 3 + .../structure/StructurePart.java | 15 ++-- .../feature/ResearchComplexFeature.java | 39 +++++++++ .../feature/ResearchComplexGenerator.java | 82 +++++++++++++++++++ .../ResearchComplexStartPart.java | 2 +- .../util/BlockPosWithDimension.java | 26 ++++++ 17 files changed, 346 insertions(+), 74 deletions(-) delete mode 100644 src/main/java/com/thebrokenrail/energonrelics/block/TestBlock.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/block/entity/structure/ResearchComplexGeneratorBlockEntity.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/block/structure/ResearchComplexGeneratorBlock.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexFeature.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexGenerator.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/util/BlockPosWithDimension.java diff --git a/build.gradle b/build.gradle index fac9e77..068d798 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,13 @@ group = project.maven_group minecraft { } +repositories { + maven { + name = 'Earthcomputer Mods' + url = 'https://dl.bintray.com/earthcomputer/mods' + } +} + dependencies { minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.minecraft_version}+build.${project.yarn_build}:v2" @@ -27,6 +34,9 @@ dependencies { modImplementation "me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig_version}" include "me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig_version}" + + modImplementation "net.earthcomputer:libstructure:${project.libstructure_version}" + include "net.earthcomputer:libstructure:${project.libstructure_version}" } processResources { diff --git a/gradle.properties b/gradle.properties index a9dd889..c28d6fb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,3 +17,4 @@ org.gradle.jvmargs = -Xmx1G modmenu_version = 1.14.5+build.30 cloth_config_version = 4.6.0 autoconfig_version = 3.2.0-unstable + libstructure_version = 1.3 diff --git a/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java b/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java index 5000640..cbaf9f9 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java +++ b/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java @@ -1,7 +1,7 @@ package com.thebrokenrail.energonrelics; import com.thebrokenrail.energonrelics.block.DefensiveLaserBlock; -import com.thebrokenrail.energonrelics.block.TestBlock; +import com.thebrokenrail.energonrelics.block.structure.ResearchComplexGeneratorBlock; import com.thebrokenrail.energonrelics.block.ThermalGlassBlock; import com.thebrokenrail.energonrelics.block.battery.ActiveBatteryControllerBlock; import com.thebrokenrail.energonrelics.block.reactor.ReactorControllerBlock; @@ -14,11 +14,11 @@ import com.thebrokenrail.energonrelics.block.EnergonLightBlock; import com.thebrokenrail.energonrelics.block.SolarPanelBlock; import com.thebrokenrail.energonrelics.block.SwitchBlock; import com.thebrokenrail.energonrelics.block.util.SimpleBlock; -import com.thebrokenrail.energonrelics.client.config.UserConfig; import com.thebrokenrail.energonrelics.item.MultimeterItem; import com.thebrokenrail.energonrelics.item.NetworkChipItem; -import me.sargunvohra.mcmods.autoconfig1u.AutoConfig; -import me.sargunvohra.mcmods.autoconfig1u.serializer.GsonConfigSerializer; +import com.thebrokenrail.energonrelics.structure.feature.ResearchComplexFeature; +import com.thebrokenrail.energonrelics.structure.feature.ResearchComplexGenerator; +import net.earthcomputer.libstructure.LibStructure; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; @@ -28,12 +28,19 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.structure.StructurePieceType; import net.minecraft.util.Identifier; import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.chunk.StructureConfig; import net.minecraft.world.gen.feature.ConfiguredFeature; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.FeatureConfig; import net.minecraft.world.gen.feature.OreFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; public class EnergonRelics implements ModInitializer { public static final String NAMESPACE = "energonrelics"; @@ -68,6 +75,11 @@ public class EnergonRelics implements ModInitializer { public static final Item DEFENSIVE_LASER_CORE_ITEM = new Item(new Item.Settings().group(ITEM_GROUP)); public static final DefensiveLaserBlock DEFENSIVE_LASER_BLOCK = new DefensiveLaserBlock(); + public static final ResearchComplexGeneratorBlock RESEARCH_COMPLEX_GENERATOR_BLOCK = new ResearchComplexGeneratorBlock(); + + public static StructureFeature RESEARCH_COMPLEX_STRUCTURE_FEATURE = new ResearchComplexFeature(DefaultFeatureConfig.CODEC); + public static StructurePieceType RESEARCH_COMPLEX_STRUCTURE_PIECE = (structureManager, tag) -> new ResearchComplexGenerator.Piece(tag); + @Override public void onInitialize() { NETWORK_CHIP_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "network_chip"), new NetworkChipItem()); @@ -97,6 +109,10 @@ public class EnergonRelics implements ModInitializer { Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "defensive_laser_core"), DEFENSIVE_LASER_CORE_ITEM); DEFENSIVE_LASER_BLOCK.register("defensive_laser"); - new TestBlock().register("test_block"); + RESEARCH_COMPLEX_GENERATOR_BLOCK.register("research_complex_generator"); + + Registry.register(Registry.STRUCTURE_PIECE, new Identifier(NAMESPACE, "research_complex_piece"), RESEARCH_COMPLEX_STRUCTURE_PIECE); + Biomes.PLAINS.addStructureFeature(RESEARCH_COMPLEX_STRUCTURE_FEATURE.configure(FeatureConfig.DEFAULT)); + LibStructure.registerStructure(new Identifier(NAMESPACE, "research_complex"), RESEARCH_COMPLEX_STRUCTURE_FEATURE, GenerationStep.Feature.UNDERGROUND_STRUCTURES, new StructureConfig(32, 8, 14357618), RESEARCH_COMPLEX_STRUCTURE_FEATURE.configure(FeatureConfig.DEFAULT)); } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/TestBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/TestBlock.java deleted file mode 100644 index f2b675d..0000000 --- a/src/main/java/com/thebrokenrail/energonrelics/block/TestBlock.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.thebrokenrail.energonrelics.block; - -import com.thebrokenrail.energonrelics.block.util.SimpleBlock; -import com.thebrokenrail.energonrelics.structure.StructurePlacer; -import com.thebrokenrail.energonrelics.structure.researchcomplex.ResearchComplexStartPart; -import com.thebrokenrail.energonrelics.structure.researchcomplex.ResearchComplexState; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.block.BlockState; -import net.minecraft.block.Material; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import java.util.Collections; - -public class TestBlock extends SimpleBlock { - public TestBlock() { - super(FabricBlockSettings.of(Material.STONE)); - } - - @SuppressWarnings("deprecation") - @Override - public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) { - super.onBlockAdded(state, world, pos, oldState, notify); - if (!world.isClient()) { - new StructurePlacer(new ResearchComplexStartPart(new ResearchComplexState(world, world.random), Collections.emptyList())).place(world, pos); - } - } -} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/entity/structure/ResearchComplexGeneratorBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/block/entity/structure/ResearchComplexGeneratorBlockEntity.java new file mode 100644 index 0000000..642728b --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/entity/structure/ResearchComplexGeneratorBlockEntity.java @@ -0,0 +1,52 @@ +package com.thebrokenrail.energonrelics.block.entity.structure; + +import com.thebrokenrail.energonrelics.block.structure.ResearchComplexGeneratorBlock; +import com.thebrokenrail.energonrelics.structure.StructurePart; +import com.thebrokenrail.energonrelics.structure.StructurePlacer; +import com.thebrokenrail.energonrelics.structure.researchcomplex.ResearchComplexStartPart; +import com.thebrokenrail.energonrelics.structure.researchcomplex.ResearchComplexState; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Tickable; +import net.minecraft.util.math.Direction; + +import java.util.Collections; +import java.util.Objects; +import java.util.Random; + +public class ResearchComplexGeneratorBlockEntity extends BlockEntity implements Tickable { + private long seed = 0; + + public ResearchComplexGeneratorBlockEntity(BlockEntityType type) { + super(type); + } + + public void setSeed(long seed) { + this.seed = seed; + } + + @Override + public CompoundTag toTag(CompoundTag tag) { + super.toTag(tag); + tag.putLong("Seed", seed); + return tag; + } + + @Override + public void fromTag(BlockState state, CompoundTag tag) { + super.fromTag(state, tag); + seed = tag.getLong("Seed"); + } + + @Override + public void tick() { + if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) { + Direction facing = getCachedState().get(ResearchComplexGeneratorBlock.HORIZONTAL_FACING); + getWorld().setBlockState(getPos(), Blocks.STONE.getDefaultState()); + new StructurePlacer(new ResearchComplexStartPart(new ResearchComplexState(getWorld(), new Random(seed)), Collections.singletonList(StructurePart.getTransformationFromDirection(facing)))).place(getWorld(), getPos()); + } + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/structure/ResearchComplexGeneratorBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/structure/ResearchComplexGeneratorBlock.java new file mode 100644 index 0000000..4e15a13 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/structure/ResearchComplexGeneratorBlock.java @@ -0,0 +1,41 @@ +package com.thebrokenrail.energonrelics.block.structure; + +import com.thebrokenrail.energonrelics.block.entity.structure.ResearchComplexGeneratorBlockEntity; +import com.thebrokenrail.energonrelics.block.util.SimpleBlockWithEntity; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Material; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.DirectionProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.util.math.Direction; + +import java.util.function.Function; + +public class ResearchComplexGeneratorBlock extends SimpleBlockWithEntity { + public static DirectionProperty HORIZONTAL_FACING = Properties.HORIZONTAL_FACING; + + public ResearchComplexGeneratorBlock() { + super(FabricBlockSettings.of(Material.STONE).strength(-1.0F, 3600000.0F).dropsNothing()); + setDefaultState(getDefaultState().with(HORIZONTAL_FACING, Direction.NORTH)); + } + + @Override + protected boolean registerItem() { + return false; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(HORIZONTAL_FACING); + } + + @Override + protected Function, BlockEntity> getFactory() { + return ResearchComplexGeneratorBlockEntity::new; + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/util/EnergyProviderBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/util/EnergyProviderBlock.java index 17ddbcd..d1b7d9b 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/util/EnergyProviderBlock.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/util/EnergyProviderBlock.java @@ -2,7 +2,6 @@ package com.thebrokenrail.energonrelics.block.util; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.client.block.entity.render.HighlightBlockEntityRenderer; -import com.thebrokenrail.energonrelics.component.NetworkComponent; import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -13,7 +12,6 @@ import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; @@ -58,7 +56,7 @@ public abstract class EnergyProviderBlock extends SimpleBlockWithEntity { if (stack.getItem() == EnergonRelics.NETWORK_CHIP_ITEM) { if (!((EnergyProviderBlockEntity) entity).hasStack()) { if (!world.isClient()) { - ((EnergyProviderBlockEntity) entity).placeStack(stack); + ((EnergyProviderBlockEntity) entity).placeStack(stack, world); stack.setCount(0); } return ActionResult.SUCCESS; @@ -68,7 +66,7 @@ public abstract class EnergyProviderBlock extends SimpleBlockWithEntity { } else if (stack.isEmpty() && hand == Hand.MAIN_HAND) { if (((EnergyProviderBlockEntity) entity).hasStack()) { if (!world.isClient()) { - ItemStack newStack = ((EnergyProviderBlockEntity) entity).takeStack(); + ItemStack newStack = ((EnergyProviderBlockEntity) entity).takeStack(world); player.setStackInHand(hand, newStack); } return ActionResult.SUCCESS; diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/util/SimpleBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/util/SimpleBlock.java index d650861..836029e 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/util/SimpleBlock.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/util/SimpleBlock.java @@ -14,6 +14,12 @@ public class SimpleBlock extends Block { public void register(String name) { Registry.register(Registry.BLOCK, new Identifier(EnergonRelics.NAMESPACE, name), this); - Registry.register(Registry.ITEM, new Identifier(EnergonRelics.NAMESPACE, name), new BlockItem(this, new Item.Settings().group(EnergonRelics.ITEM_GROUP))); + if (registerItem()) { + Registry.register(Registry.ITEM, new Identifier(EnergonRelics.NAMESPACE, name), new BlockItem(this, new Item.Settings().group(EnergonRelics.ITEM_GROUP))); + } + } + + protected boolean registerItem() { + return true; } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java b/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java index 77bd601..20571ba 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java +++ b/src/main/java/com/thebrokenrail/energonrelics/component/NetworkComponent.java @@ -2,12 +2,16 @@ package com.thebrokenrail.energonrelics.component; import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider; +import com.thebrokenrail.energonrelics.util.BlockPosWithDimension; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.datafixer.NbtOps; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.RegistryKey; import net.minecraft.world.PersistentState; import net.minecraft.world.World; @@ -19,7 +23,7 @@ import java.util.Objects; public class NetworkComponent extends PersistentState { private static class Entry { - private final List sources = new ArrayList<>(); + private final List sources = new ArrayList<>(); private int id = 0; } @@ -52,7 +56,8 @@ public class NetworkComponent extends PersistentState { int x = sources.getCompound(i).getInt("X"); int y = sources.getCompound(i).getInt("Y"); int z = sources.getCompound(i).getInt("Z"); - entry.sources.add(new BlockPos(x, y, z)); + RegistryKey dimension = World.CODEC.parse(NbtOps.INSTANCE, sources.getCompound(i).get("Dimension")).result().orElse(World.OVERWORLD); + entry.sources.add(new BlockPosWithDimension(new BlockPos(x, y, z), dimension)); } } return entry; @@ -62,11 +67,12 @@ public class NetworkComponent extends PersistentState { CompoundTag tag = new CompoundTag(); tag.putInt("ID", entry.id); ListTag sources = new ListTag(); - for (BlockPos pos : entry.sources) { + for (BlockPosWithDimension pos : entry.sources) { CompoundTag posTag = new CompoundTag(); - posTag.putInt("X", pos.getX()); - posTag.putInt("Y", pos.getY()); - posTag.putInt("Z", pos.getZ()); + posTag.putInt("X", pos.pos.getX()); + posTag.putInt("Y", pos.pos.getY()); + posTag.putInt("Z", pos.pos.getZ()); + Identifier.CODEC.encodeStart(NbtOps.INSTANCE, pos.dimension.getValue()).result().ifPresent(tags -> posTag.put("Dimension", tags)); sources.add(posTag); } tag.put("Sources", sources); @@ -101,21 +107,21 @@ public class NetworkComponent extends PersistentState { return Objects.requireNonNull(world.getServer().getWorld(World.OVERWORLD)).getPersistentStateManager().getOrCreate(NetworkComponent::new, EnergonRelics.NAMESPACE); } - public List getSourcePos(int id) { + public List getSourcePos(int id) { Entry entry = getOrCreate(id); return entry.sources; } public List getSource(World world, int id) { - List sources = getSourcePos(id); - List valid = new ArrayList<>(); - Iterator iterator = sources.iterator(); + List sources = getSourcePos(id); + List valid = new ArrayList<>(); + Iterator iterator = sources.iterator(); List providers = new ArrayList<>(); boolean dirty = false; while (iterator.hasNext()) { - BlockPos pos = iterator.next(); + BlockPosWithDimension pos = iterator.next(); if (!valid.contains(pos)) { - BlockEntity entity = world.getBlockEntity(pos); + BlockEntity entity = Objects.requireNonNull(Objects.requireNonNull(world.getServer()).getWorld(pos.dimension)).getBlockEntity(pos.pos); if (entity instanceof EnergyProvider && ((EnergyProvider) entity).isNetwork(id)) { providers.add((EnergyProvider) entity); } else { @@ -135,7 +141,7 @@ public class NetworkComponent extends PersistentState { return providers; } - public void addSource(int id, BlockPos pos) { + public void addSource(int id, BlockPosWithDimension pos) { Entry entry = getOrCreate(id); if (!entry.sources.contains(pos)) { entry.sources.add(pos); @@ -143,7 +149,7 @@ public class NetworkComponent extends PersistentState { markDirty(); } - public void removeSource(int id, BlockPos pos) { + public void removeSource(int id, BlockPosWithDimension pos) { Entry entry = getOrCreate(id); entry.sources.remove(pos); markDirty(); @@ -160,7 +166,7 @@ public class NetworkComponent extends PersistentState { @Override public void markDirty() { List ids = new ArrayList<>(); - List positions = new ArrayList<>(); + List positions = new ArrayList<>(); Iterator iterator = networks.iterator(); while (iterator.hasNext()) { Entry entry = iterator.next(); diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java index 9ea49db..b802ea5 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyProviderBlockEntity.java @@ -5,6 +5,7 @@ import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.component.NetworkComponent; import com.thebrokenrail.energonrelics.energy.core.util.Action; import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider; +import com.thebrokenrail.energonrelics.util.BlockPosWithDimension; import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -16,6 +17,7 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Tickable; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.RegistryKey; import net.minecraft.world.World; import java.util.ArrayList; @@ -59,6 +61,11 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv return getPos().isWithinDistance(pos, HardcodedConfig.POWER_RANGE); } + @Override + public RegistryKey getRegistryKey() { + return Objects.requireNonNull(getWorld()).getRegistryKey(); + } + private ItemStack stack = ItemStack.EMPTY; @Override @@ -99,9 +106,9 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv } NetworkComponent component = NetworkComponent.getInstance((ServerWorld) Objects.requireNonNull(getWorld())); - List sources = component.getSourcePos(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack)); - if (!sources.contains(getPos())) { - takeStack(); + List sources = component.getSourcePos(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack)); + if (!sources.contains(new BlockPosWithDimension(getPos(), getWorld().getRegistryKey()))) { + takeStack(getWorld()); } } pendingPropagatedActions.clear(); @@ -121,23 +128,24 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv private static void setEnergyProviderSource(World world, BlockPos pos, ItemStack stack, boolean remove) { ServerWorld serverWorld = (ServerWorld) world; NetworkComponent component = NetworkComponent.getInstance(serverWorld); + BlockPosWithDimension newPos = new BlockPosWithDimension(pos, world.getRegistryKey()); if (remove) { - component.removeSource(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack), pos); + component.removeSource(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack), newPos); } else { - component.addSource(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack), pos); + component.addSource(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack), newPos); } } - public ItemStack takeStack() { + public ItemStack takeStack(World world) { ItemStack newStack = stack.copy(); - setEnergyProviderSource(getWorld(), getPos(), newStack, true); + setEnergyProviderSource(world, getPos(), newStack, true); stack = ItemStack.EMPTY; markDirty(); return newStack; } - public void placeStack(ItemStack newStack) { - setEnergyProviderSource(getWorld(), getPos(), newStack, false); + public void placeStack(ItemStack newStack, World world) { + setEnergyProviderSource(world, getPos(), newStack, false); stack = newStack.copy(); markDirty(); } @@ -159,6 +167,8 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv @Override public void markDirty() { super.markDirty(); - sync(); + if (hasWorld()) { + sync(); + } } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java index 782ecad..2c285e8 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/energy/core/EnergyReceiverBlockEntity.java @@ -10,6 +10,8 @@ import net.minecraft.nbt.IntArrayTag; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Tickable; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.RegistryKey; +import net.minecraft.world.World; import java.util.ArrayList; import java.util.Collections; @@ -32,6 +34,11 @@ public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntit public boolean isWithinDistance(Vec3d pos) { return true; } + + @Override + public RegistryKey getRegistryKey() { + return Objects.requireNonNull(getWorld()).getRegistryKey(); + } } public EnergyReceiverBlockEntity(BlockEntityType type) { @@ -74,9 +81,11 @@ public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntit for (int network : networks) { List potentialProviders = component.getSource(world, network); for (EnergyProvider provider : potentialProviders) { - Vec3d pos = new Vec3d(getPos().getX() + 0.5d, getPos().getY() + 0.5d, getPos().getZ() + 0.5d); - if (provider.isWithinDistance(pos)) { - providers.add(provider); + if (provider.getRegistryKey().equals(getWorld().getRegistryKey())) { + Vec3d pos = new Vec3d(getPos().getX() + 0.5d, getPos().getY() + 0.5d, getPos().getZ() + 0.5d); + if (provider.isWithinDistance(pos)) { + providers.add(provider); + } } } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java b/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java index b7edcdd..3079e87 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java +++ b/src/main/java/com/thebrokenrail/energonrelics/energy/core/util/EnergyProvider.java @@ -1,9 +1,12 @@ package com.thebrokenrail.energonrelics.energy.core.util; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.RegistryKey; +import net.minecraft.world.World; public interface EnergyProvider { void addPropagatedAction(Action.PropagatedAction action); boolean isNetwork(int network); boolean isWithinDistance(Vec3d pos); + RegistryKey getRegistryKey(); } diff --git a/src/main/java/com/thebrokenrail/energonrelics/structure/StructurePart.java b/src/main/java/com/thebrokenrail/energonrelics/structure/StructurePart.java index c3b6920..ce78571 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/structure/StructurePart.java +++ b/src/main/java/com/thebrokenrail/energonrelics/structure/StructurePart.java @@ -7,6 +7,7 @@ import net.minecraft.state.property.Properties; import net.minecraft.util.BlockMirror; import net.minecraft.util.BlockRotation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.world.World; import java.util.ArrayList; @@ -152,22 +153,22 @@ public abstract class StructurePart { protected abstract void handleBlockPlace(World world, BlockPos pos, BlockState state); - public static Transformation getTransformationFromBlockRotation(BlockRotation rotation) { - switch (rotation) { - case NONE: { + public static Transformation getTransformationFromDirection(Direction direction) { + switch (direction) { + case NORTH: { return NONE; } - case CLOCKWISE_90: { + case EAST: { return CLOCKWISE_90; } - case CLOCKWISE_180: { + case SOUTH: { return CLOCKWISE_180; } - case COUNTERCLOCKWISE_90: { + case WEST: { return COUNTERCLOCKWISE_90; } default: { - throw new MissingCaseException(rotation); + throw new MissingCaseException(direction); } } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexFeature.java b/src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexFeature.java new file mode 100644 index 0000000..618ce04 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexFeature.java @@ -0,0 +1,39 @@ +package com.thebrokenrail.energonrelics.structure.feature; + +import com.mojang.serialization.Codec; +import net.minecraft.structure.StructureManager; +import net.minecraft.structure.StructureStart; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.DynamicRegistryManager; +import net.minecraft.world.Heightmap; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; + +public class ResearchComplexFeature extends StructureFeature { + public ResearchComplexFeature(Codec codec) { + super(codec); + } + + @Override + public StructureStartFactory getStructureStartFactory() { + return Start::new; + } + + public static class Start extends StructureStart { + public Start(StructureFeature structureFeature, int i, int j, BlockBox blockBox, int k, long l) { + super(structureFeature, i, j, blockBox, k, l); + } + + @Override + public void init(DynamicRegistryManager dynamicRegistryManager, ChunkGenerator chunkGenerator, StructureManager structureManager, int x, int z, Biome biome, DefaultFeatureConfig defaultFeatureConfig) { + BlockPos blockPos = new BlockPos(x * 16, chunkGenerator.getHeight(x, z, Heightmap.Type.WORLD_SURFACE) / 2, z * 16); + BlockRotation blockRotation = BlockRotation.random(random); + ResearchComplexGenerator.addPieces(blockPos, blockRotation, children); + setBoundingBoxFromChildren(); + } + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexGenerator.java b/src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexGenerator.java new file mode 100644 index 0000000..9baea27 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/structure/feature/ResearchComplexGenerator.java @@ -0,0 +1,82 @@ +package com.thebrokenrail.energonrelics.structure.feature; + +import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.entity.structure.ResearchComplexGeneratorBlockEntity; +import com.thebrokenrail.energonrelics.block.structure.ResearchComplexGeneratorBlock; +import com.thebrokenrail.energonrelics.util.MissingCaseException; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.structure.StructurePiece; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.ServerWorldAccess; +import net.minecraft.world.gen.StructureAccessor; +import net.minecraft.world.gen.chunk.ChunkGenerator; + +import java.util.List; +import java.util.Random; + +public class ResearchComplexGenerator { + static void addPieces(BlockPos pos, BlockRotation rotation, List pieces) { + pieces.add(new Piece(rotation, pos)); + } + + public static class Piece extends StructurePiece { + private final BlockRotation rotation; + private final BlockPos pos; + + private Piece(BlockRotation rotation, BlockPos pos) { + super(EnergonRelics.RESEARCH_COMPLEX_STRUCTURE_PIECE, 0); + this.rotation = rotation; + this.pos = pos; + boundingBox = BlockBox.create(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); + } + + public Piece(CompoundTag tag) { + super(EnergonRelics.RESEARCH_COMPLEX_STRUCTURE_PIECE, tag); + rotation = BlockRotation.valueOf(tag.getString("Rot")); + pos = new BlockPos(tag.getInt("X"), tag.getInt("Y"), tag.getInt("Z")); + } + + @Override + protected void toNbt(CompoundTag tag) { + tag.putString("Rot", rotation.name()); + tag.putInt("X", pos.getX()); + tag.putInt("Y", pos.getY()); + tag.putInt("Z", pos.getZ()); + } + + @Override + public boolean generate(ServerWorldAccess world, StructureAccessor structureAccessor, ChunkGenerator chunkGenerator, Random random, BlockBox boundingBox, ChunkPos chunkPos, BlockPos blockPos) { + world.setBlockState(pos, EnergonRelics.RESEARCH_COMPLEX_GENERATOR_BLOCK.getDefaultState().with(ResearchComplexGeneratorBlock.HORIZONTAL_FACING, blockRotationToDirection(rotation)), 4); + BlockEntity entity = world.getBlockEntity(pos); + if (entity instanceof ResearchComplexGeneratorBlockEntity) { + ((ResearchComplexGeneratorBlockEntity) entity).setSeed(random.nextLong()); + } + return true; + } + + private static Direction blockRotationToDirection(BlockRotation rotation) { + switch (rotation) { + case NONE: { + return Direction.NORTH; + } + case CLOCKWISE_90: { + return Direction.EAST; + } + case CLOCKWISE_180: { + return Direction.SOUTH; + } + case COUNTERCLOCKWISE_90: { + return Direction.WEST; + } + default: { + throw new MissingCaseException(rotation); + } + } + } + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/structure/researchcomplex/ResearchComplexStartPart.java b/src/main/java/com/thebrokenrail/energonrelics/structure/researchcomplex/ResearchComplexStartPart.java index 33e7280..35aa3b6 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/structure/researchcomplex/ResearchComplexStartPart.java +++ b/src/main/java/com/thebrokenrail/energonrelics/structure/researchcomplex/ResearchComplexStartPart.java @@ -108,7 +108,7 @@ public class ResearchComplexStartPart extends BaseResearchComplexPart { if (state.getBlock() == EnergonRelics.REACTOR_CONTROLLER_BLOCK) { BlockEntity entity = world.getBlockEntity(pos); if (entity instanceof ReactorControllerBlockEntity) { - ((ReactorControllerBlockEntity) entity).placeStack(EnergonRelics.NETWORK_CHIP_ITEM.create(getState().getMainNetwork())); + ((ReactorControllerBlockEntity) entity).placeStack(EnergonRelics.NETWORK_CHIP_ITEM.create(getState().getMainNetwork()), world); } } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/util/BlockPosWithDimension.java b/src/main/java/com/thebrokenrail/energonrelics/util/BlockPosWithDimension.java new file mode 100644 index 0000000..5add7b7 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/util/BlockPosWithDimension.java @@ -0,0 +1,26 @@ +package com.thebrokenrail.energonrelics.util; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.RegistryKey; +import net.minecraft.world.World; + +public class BlockPosWithDimension { + public final BlockPos pos; + public final RegistryKey dimension; + + public BlockPosWithDimension(BlockPos pos, RegistryKey dimension) { + this.pos = pos; + this.dimension = dimension; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj instanceof BlockPosWithDimension) { + return pos.equals(((BlockPosWithDimension) obj).pos) && dimension.equals(((BlockPosWithDimension) obj).dimension); + } else { + return false; + } + } +}