From 0999964f1ac556c6e63f97d968bb07ad1fee2ec0 Mon Sep 17 00:00:00 2001 From: reign Date: Mon, 7 Apr 2025 21:03:28 -0400 Subject: [PATCH 1/6] Add removing and updating modes to ItemConstructableTrigger --- .github/scripts/test_no_error_reports | 0 addon.gradle | 3 +- dependencies.gradle | 4 + gradlew | 0 .../structurelib/ClientProxy.java | 40 ++++ .../structurelib/CommonProxy.java | 3 + .../structurelib/StructureLib.java | 12 + .../constructable/ConstructableUtility.java | 17 +- .../item/ItemConstructableTrigger.java | 68 +++++- .../StructureProjectorCycleModeMessage.java | 37 ++++ .../structure/IStructureDefinition.java | 100 +++------ .../structure/IStructureElement.java | 6 +- .../structure/StructureUtility.java | 207 +++++++++++++++--- .../assets/structurelib/lang/en_US.lang | 5 + .../BUILDING.png} | Bin .../items/constructableTrigger/REMOVING.png | Bin 0 -> 821 bytes .../items/constructableTrigger/UPDATING.png | Bin 0 -> 724 bytes 17 files changed, 392 insertions(+), 110 deletions(-) mode change 100755 => 100644 .github/scripts/test_no_error_reports mode change 100755 => 100644 gradlew create mode 100644 src/main/java/com/gtnewhorizon/structurelib/net/StructureProjectorCycleModeMessage.java rename src/main/resources/assets/structurelib/textures/items/{itemConstructableTrigger.png => constructableTrigger/BUILDING.png} (100%) create mode 100644 src/main/resources/assets/structurelib/textures/items/constructableTrigger/REMOVING.png create mode 100644 src/main/resources/assets/structurelib/textures/items/constructableTrigger/UPDATING.png diff --git a/.github/scripts/test_no_error_reports b/.github/scripts/test_no_error_reports old mode 100755 new mode 100644 diff --git a/addon.gradle b/addon.gradle index 32cd6394..30e78921 100644 --- a/addon.gradle +++ b/addon.gradle @@ -1,7 +1,7 @@ javadoc { javadocTool = javaToolchains.javadocToolFor { // Last version with frames, but it also has search - languageVersion = JavaLanguageVersion.of(11) + languageVersion = JavaLanguageVersion.of(21) vendor = JvmVendorSpec.ADOPTIUM } @@ -20,7 +20,6 @@ javadoc { overview "src/main/javadoc/overview.html" links 'https://docs.oracle.com/javase/8/docs/api/' links 'https://skmedix.github.io/ForgeJavaDocs/javadoc/forge/1.7.10-10.13.4.1614/' - addBooleanOption("-frames", true) } } diff --git a/dependencies.gradle b/dependencies.gradle index eaa0cd18..147e7467 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -6,4 +6,8 @@ dependencies { testImplementation(platform('org.junit:junit-bom:5.9.2')) testImplementation('org.junit.jupiter:junit-jupiter') + + runtimeOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.227:dev") { + exclude group: "com.github.GTNewHorizons", module: "StructureLib" + } } diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java b/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java index 7fdf3bfe..21dc68b4 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java +++ b/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java @@ -20,6 +20,7 @@ import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.culling.Frustrum; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.resources.I18n; +import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -42,17 +43,23 @@ import org.lwjgl.opengl.GL11; import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX; import com.gtnewhorizon.structurelib.net.RegistryOrderSyncMessage; import com.gtnewhorizon.structurelib.net.SetChannelDataMessage; +import com.gtnewhorizon.structurelib.net.StructureProjectorCycleModeMessage; import cpw.mods.fml.client.config.GuiConfig; import cpw.mods.fml.client.event.ConfigChangedEvent; +import cpw.mods.fml.client.registry.ClientRegistry; import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLLoadCompleteEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.InputEvent; import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent; import cpw.mods.fml.common.gameevent.TickEvent.Phase; import cpw.mods.fml.common.network.FMLNetworkEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; public class ClientProxy extends CommonProxy { @@ -259,6 +266,13 @@ public class ClientProxy extends CommonProxy { MinecraftForge.EVENT_BUS.register(new ForgeEventHandler()); } + @Override + public void init(FMLInitializationEvent e) { + super.init(e); + + MinecraftForge.EVENT_BUS.register(new KeybindHandler()); + } + static void markTextureUsed(IIcon icon) { if (StructureLib.COMPAT instanceof IStructureCompat) ((IStructureCompat) StructureLib.COMPAT).markTextureUsed(icon); @@ -654,4 +668,30 @@ public class ClientProxy extends CommonProxy { p.endSection(); } } + + public static class KeybindHandler { + + private static final KeyBinding CYCLE_PROJECTOR_MODE = new KeyBinding( + "item.structurelib.constructableTrigger.keys.cycleMode", + 0, + "item.structurelib.constructableTrigger.keyCategory"); + + public KeybindHandler() { + FMLCommonHandler.instance().bus().register(this); + // If somebody wants to make a UI element for this, be my guest + ClientRegistry.registerKeyBinding(CYCLE_PROJECTOR_MODE); + } + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public void key(InputEvent.KeyInputEvent event) { + if (CYCLE_PROJECTOR_MODE.isPressed()) { + cycleProjectorMode(); + } + } + + private static void cycleProjectorMode() { + StructureLib.net.sendToServer(new StructureProjectorCycleModeMessage()); + } + } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java b/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java index 72e7e372..8660c8fe 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java +++ b/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java @@ -17,6 +17,7 @@ import net.minecraftforge.common.MinecraftForge; import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage; import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage; +import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLLoadCompleteEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.eventhandler.SubscribeEvent; @@ -64,6 +65,8 @@ public class CommonProxy { public void preInit(FMLPreInitializationEvent e) {} + public void init(FMLInitializationEvent e) {} + public long getOverworldTime() { return MinecraftServer.getServer().getEntityWorld().getTotalWorldTime(); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java b/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java index 0d8504e0..3c36ba86 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java +++ b/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java @@ -20,6 +20,7 @@ import com.gtnewhorizon.structurelib.net.AlignmentMessage; import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage; import com.gtnewhorizon.structurelib.net.RegistryOrderSyncMessage; import com.gtnewhorizon.structurelib.net.SetChannelDataMessage; +import com.gtnewhorizon.structurelib.net.StructureProjectorCycleModeMessage; import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage; import com.gtnewhorizon.structurelib.util.InventoryUtility; import com.gtnewhorizon.structurelib.util.XSTR; @@ -27,6 +28,7 @@ import com.gtnewhorizon.structurelib.util.XSTR; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLLoadCompleteEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; @@ -70,6 +72,11 @@ public class StructureLib { net.registerMessage(SetChannelDataMessage.Handler.class, SetChannelDataMessage.class, 3, Side.SERVER); net.registerMessage(ErrorHintParticleMessage.Handler.class, ErrorHintParticleMessage.class, 4, Side.CLIENT); net.registerMessage(RegistryOrderSyncMessage.Handler.class, RegistryOrderSyncMessage.class, 5, Side.SERVER); + net.registerMessage( + StructureProjectorCycleModeMessage.Handler.class, + StructureProjectorCycleModeMessage.class, + 6, + Side.SERVER); try { DEBUG_MODE = Boolean.parseBoolean(System.getProperty("structurelib.debug")); @@ -124,6 +131,11 @@ public class StructureLib { isGTLoaded = Loader.isModLoaded("gregtech"); } + @Mod.EventHandler + public void init(FMLInitializationEvent e) { + proxy.init(e); + } + @Mod.EventHandler public void loadComplete(FMLLoadCompleteEvent e) { proxy.loadComplete(e); diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java index 92bd596f..4e588c31 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java @@ -57,12 +57,12 @@ public class ConstructableUtility { } IConstructable constructable = null; - if (tTileEntity instanceof IConstructableProvider) - constructable = ((IConstructableProvider) tTileEntity).getConstructable(); - else if (tTileEntity instanceof IConstructable) { - constructable = (IConstructable) tTileEntity; + if (tTileEntity instanceof IConstructableProvider aConstructableProvider) + constructable = aConstructableProvider.getConstructable(); + else if (tTileEntity instanceof IConstructable aConstructable) { + constructable = aConstructable; } else if (IMultiblockInfoContainer.contains(tTileEntity.getClass())) { - ExtendedFacing facing = tTileEntity instanceof IAlignment ? ((IAlignment) tTileEntity).getExtendedFacing() + ExtendedFacing facing = tTileEntity instanceof IAlignment alignment ? alignment.getExtendedFacing() : ExtendedFacing.of(ForgeDirection.getOrientation(aSide)); constructable = IMultiblockInfoContainer.get(tTileEntity.getClass()) .toConstructable(tTileEntity, facing); @@ -70,14 +70,13 @@ public class ConstructableUtility { if (constructable == null) return false; - if (aPlayer instanceof EntityPlayerMP) { - EntityPlayerMP playerMP = (EntityPlayerMP) aPlayer; + if (aPlayer instanceof EntityPlayerMP playerMP) { // server side and sneaking (already checked above) // do construct if (aPlayer.capabilities.isCreativeMode) { constructable.construct(aStack, false); - } else if (constructable instanceof ISurvivalConstructable) { - int built = ((ISurvivalConstructable) constructable).survivalConstruct( + } else if (constructable instanceof ISurvivalConstructable aConstructable) { + int built = aConstructable.survivalConstruct( aStack, ConfigurationHandler.INSTANCE.getAutoPlaceBudget(), ISurvivalBuildEnvironment.create(IItemSource.fromPlayer(playerMP), playerMP)); diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java index 118c954f..d2bebe78 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java @@ -7,9 +7,14 @@ import static net.minecraft.util.StatCollector.translateToLocalFormatted; import java.util.List; +import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.util.IIcon; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; import org.lwjgl.input.Keyboard; @@ -23,12 +28,73 @@ import cpw.mods.fml.common.FMLCommonHandler; public class ItemConstructableTrigger extends Item { + private static final String TAG_MODE = "mode"; + + private static final IIcon[] textures = new IIcon[3]; + public ItemConstructableTrigger() { setUnlocalizedName("structurelib.constructableTrigger"); - setTextureName(MOD_ID + ":itemConstructableTrigger"); setCreativeTab(StructureLib.creativeTab); } + public static void cycleMode(ItemStack held) { + if (held.getTagCompound() == null) held.setTagCompound(new NBTTagCompound()); + if (!held.getTagCompound().hasKey(TAG_MODE)) held.getTagCompound().setTag(TAG_MODE, new NBTTagInt(0)); + held.getTagCompound().setInteger(TAG_MODE, (held.getTagCompound().getInteger(TAG_MODE) + 1) % 3); + } + + @Override + public void registerIcons(IIconRegister register) { + textures[0] = register.registerIcon(MOD_ID + ":constructableTrigger/BUILDING"); + textures[1] = register.registerIcon(MOD_ID + ":constructableTrigger/UPDATING"); + textures[2] = register.registerIcon(MOD_ID + ":constructableTrigger/REMOVING"); + } + + @Override + public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { + return getIcon(stack, renderPass); + } + + @Override + public IIcon getIcon(ItemStack stack, int pass) { + if (!stack.hasTagCompound() || !stack.getTagCompound().hasKey(TAG_MODE)) { + return textures[0]; + } + return textures[stack.getTagCompound().getInteger(TAG_MODE)]; + } + + @Override + public String getItemStackDisplayName(ItemStack stack) { + if (!stack.hasTagCompound() || !stack.getTagCompound().hasKey(TAG_MODE)) { + return getDisplayName(0); + } + return getDisplayName(stack.getTagCompound().getInteger(TAG_MODE)); + } + + @Override + public IIcon getIconIndex(ItemStack stack) { + return getIcon(stack, 0); + } + + @Override + public IIcon getIconFromDamage(int damage) { + return textures[damage]; + } + + private String getDisplayName(int mode) { + return StatCollector.translateToLocal("item.structurelib.constructableTrigger.name") + " - " + + StatCollector.translateToLocal("item.structurelib.constructableTrigger.modes." + mode); + } + + public static int getMode(ItemStack held) { + if (held == null || !held.hasTagCompound() || !held.getTagCompound().hasKey(TAG_MODE)) { + // default behavior + return 0; + } + // get user-defined mode + return held.getTagCompound().getInteger(TAG_MODE); + } + @Override public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { if (world.isRemote && getMovingObjectPositionFromPlayer(world, player, true) == null) { diff --git a/src/main/java/com/gtnewhorizon/structurelib/net/StructureProjectorCycleModeMessage.java b/src/main/java/com/gtnewhorizon/structurelib/net/StructureProjectorCycleModeMessage.java new file mode 100644 index 00000000..80858eac --- /dev/null +++ b/src/main/java/com/gtnewhorizon/structurelib/net/StructureProjectorCycleModeMessage.java @@ -0,0 +1,37 @@ +package com.gtnewhorizon.structurelib.net; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; + +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; + +public class StructureProjectorCycleModeMessage implements IMessage { + + @Override + public void fromBytes(ByteBuf buf) { + // no op + } + + @Override + public void toBytes(ByteBuf buf) { + // no op + } + + public static class Handler implements IMessageHandler { + + @Override + public IMessage onMessage(StructureProjectorCycleModeMessage message, MessageContext ctx) { + EntityPlayerMP player = ctx.getServerHandler().playerEntity; + final ItemStack held = player.getHeldItem(); + if (held != null && held.getItem() instanceof ItemConstructableTrigger) { + ItemConstructableTrigger.cycleMode(held); + } + return null; + } + } +} diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java index 2b6b7732..1c949e17 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java @@ -348,77 +348,47 @@ public interface IStructureDefinition { } if (checkBlocksIfNotNullForceCheckAllIfTrue != null) { - boolean success; - if (checkBlocksIfNotNullForceCheckAllIfTrue) { - success = StructureUtility.iterateV2( - elements, - world, - extendedFacing, - basePositionX, - basePositionY, - basePositionZ, - basePositionA, - basePositionB, - basePositionC, - (e, w, x, y, z, a, b, c) -> e.check(object, w, x, y, z), - "check"); - } else { - success = StructureUtility.iterateV2( - elements, - world, - extendedFacing, - basePositionX, - basePositionY, - basePositionZ, - basePositionA, - basePositionB, - basePositionC, - skipBlockUnloaded((e, w, x, y, z, a, b, c) -> e.check(object, w, x, y, z)), - "check force"); - } + boolean success = StructureUtility.iterateV2( + elements, + world, + extendedFacing, + basePositionX, + basePositionY, + basePositionZ, + basePositionA, + basePositionB, + basePositionC, + checkBlocksIfNotNullForceCheckAllIfTrue ? (e, w, x, y, z, a, b, c) -> e.check(object, w, x, y, z) + : skipBlockUnloaded((e, w, x, y, z, a, b, c) -> e.check(object, w, x, y, z)), + checkBlocksIfNotNullForceCheckAllIfTrue ? "check" : "check force"); if (StructureLibAPI.isDebugEnabled() && success) { StructureLib.LOGGER .info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] pass"); } return success; } else { - if (hintsOnly) { - StructureUtility.iterateV2( - elements, - world, - extendedFacing, - basePositionX, - basePositionY, - basePositionZ, - basePositionA, - basePositionB, - basePositionC, - ignoreBlockUnloaded((e, w, x, y, z, a, b, c) -> { - e.spawnHint(object, world, x, y, z, trigger); - if (ChannelDataAccessor.hasSubChannel(trigger, "show_error") - && !e.couldBeValid(object, world, x, y, z, trigger)) { - StructureLibAPI.markHintParticleError(StructureLib.getCurrentPlayer(), world, x, y, z); - } - return true; - }), - "spawnHint"); - } else { - StructureUtility.iterateV2( - elements, - world, - extendedFacing, - basePositionX, - basePositionY, - basePositionZ, - basePositionA, - basePositionB, - basePositionC, - ignoreBlockUnloaded((e, w, x, y, z, a, b, c) -> { - e.placeBlock(object, world, x, y, z, trigger); - return true; - }), - "placeBlock"); - } + StructureUtility.iterateV2( + elements, + world, + extendedFacing, + basePositionX, + basePositionY, + basePositionZ, + basePositionA, + basePositionB, + basePositionC, + hintsOnly ? ignoreBlockUnloaded((e, w, x, y, z, a, b, c) -> { + e.spawnHint(object, world, x, y, z, trigger); + if (ChannelDataAccessor.hasSubChannel(trigger, "show_error") + && !e.couldBeValid(object, world, x, y, z, trigger)) { + StructureLibAPI.markHintParticleError(StructureLib.getCurrentPlayer(), world, x, y, z); + } + return true; + }) : ignoreBlockUnloaded((e, w, x, y, z, a, b, c) -> { + e.placeBlock(object, world, x, y, z, trigger); + return true; + }), + hintsOnly ? "spawnHint" : "placeBlock"); } return true; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java index 63d1b4b7..f7361eb1 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java @@ -21,6 +21,7 @@ import net.minecraft.util.IChatComponent; import net.minecraft.world.World; import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; import com.gtnewhorizon.structurelib.util.ItemStackPredicate; import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; @@ -137,12 +138,13 @@ public interface IStructureElement { */ default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + int mode = ItemConstructableTrigger.getMode(trigger); BlocksToPlace e = getBlocksToPlace(t, world, x, y, z, trigger, env); IItemSource source = env.getSource(); EntityPlayer actor = env.getActor(); Consumer chatter = env.getChatter(); if (e != null) { - if (check(t, world, x, y, z)) return PlaceResult.SKIP; + if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; if (e.getStacks() == null) { ItemStack taken = source.takeOne(e.getPredicate(), true); return StructureUtility.survivalPlaceBlock( @@ -159,7 +161,7 @@ public interface IStructureElement { chatter); } for (ItemStack stack : e.getStacks()) { - if (!source.takeOne(stack, true)) continue; + if (mode < 2 && !source.takeOne(stack, true)) continue; return StructureUtility.survivalPlaceBlock( stack, NBTMode.EXACT, diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 03bb9e6b..588eed58 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -28,6 +28,7 @@ import java.util.function.Supplier; import javax.annotation.Nullable; import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; @@ -51,6 +52,7 @@ import com.gtnewhorizon.structurelib.StructureLib; import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; @@ -206,7 +208,11 @@ public class StructureUtility { @Override public boolean placeBlock(Object o, World world, int x, int y, int z, ItemStack trigger) { - world.setBlock(x, y, z, StructureLibAPI.getBlockHint(), 14, 2); + placeRemoveOrUpdate( + trigger, + () -> world.setBlock(x, y, z, StructureLibAPI.getBlockHint(), 14, 2), + () -> world.setBlock(x, y, z, StructureLibAPI.getBlockHint(), 14, 2), + () -> world.setBlock(x, y, z, Blocks.air, 0, 2)); return true; } @@ -219,11 +225,16 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - if (check(o, world, x, y, z)) return PlaceResult.SKIP; + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode < 2 && check(o, world, x, y, z)) return PlaceResult.SKIP; // user should place anything here. // maybe make this configurable, but for now we try to take some cobble from user if (env.getSource().takeOne(new ItemStack(Blocks.cobblestone), false)) { - world.setBlock(x, y, z, Blocks.cobblestone, 0, 2); + placeRemoveOrUpdate( + trigger, + () -> world.setBlock(x, y, z, Blocks.cobblestone, 0, 2), + () -> world.setBlock(x, y, z, Blocks.cobblestone, 0, 2), + () -> world.setBlock(x, y, z, Blocks.air, 0, 2)); } return PlaceResult.REJECT; } @@ -329,30 +340,74 @@ public class StructureUtility { */ public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, EntityPlayer actor, Consumer chatter) { + if (x == -176 && y == 62 && z == -74) { + new Throwable().printStackTrace(); + } if (block == null) throw new NullPointerException(); - if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; + int mode = 0; + if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { + // best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the + // ...trigger instead of assuming default behavior + mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); + } + if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; Item itemBlock = Item.getItemFromBlock(block); int itemMeta = itemBlock instanceof ISpecialItemBlock ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) : meta; ItemStack stack = new ItemStack(itemBlock, 1, itemMeta); - if (!s.takeOne(stack, true)) { + if (mode == 1 && !world.isAirBlock(x, y, z)) { + Block blockInWorld = world.getBlock(x, y, z); + if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) { + // This is the block we are looking for, move along + return PlaceResult.SKIP; + } + } + if (mode < 2 && !s.takeOne(stack, true)) { if (chatter != null) chatter.accept( new ChatComponentTranslation( "structurelib.autoplace.error.no_simple_block", stack.func_151000_E())); return PlaceResult.REJECT; } - if (block instanceof ICustomBlockSetting) { - ICustomBlockSetting blockCustom = (ICustomBlockSetting) block; - blockCustom.setBlock(world, x, y, z, meta); - } else if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + if (mode < 2) { + if (block instanceof ICustomBlockSetting) { + ICustomBlockSetting blockCustom = (ICustomBlockSetting) block; + blockCustom.setBlock(world, x, y, z, meta); + } else { + if (mode == 1 && !world.isAirBlock(x, y, z)) { + // We're in updating mode and there's a block in our way (grr), so let's remove whatever is there + // ...and drop it to the player + ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); + toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); + if (!world.setBlock(x, y, z, Blocks.air, 0, 4) || !tryGiveOrDropItem(world, actor, toGive)) { + // We either weren't able to give the player the block that was there, or we weren't able to + // remove + // the block, either way, we need to reject the update. Also, since we hid the block update from + // the client in an effort to make the exchange as seamless as possible, we need to now notify + // the client if we did successfully remove the block. + if (world.isAirBlock(x, y, z)) world.notifyBlockChange(x, y, z, Blocks.air); + return PlaceResult.REJECT; + } + } + if (!stack.copy() + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } - if (!s.takeOne(stack, false)) { - // rollback + } + } + if (mode == 2 && world.isAirBlock(x, y, z)) { + return PlaceResult.SKIP; + } + if (mode == 2 || !s.takeOne(stack, false)) { + // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air + ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); + toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); world.setBlockToAir(x, y, z); + if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) { + // Something went wrong while trying to give the player the block we removed, let's just fail for now + return PlaceResult.REJECT; + } } return PlaceResult.ACCEPT; } @@ -441,27 +496,75 @@ public class StructureUtility { public static PlaceResult survivalPlaceBlock(ItemStack stack, NBTMode nbtMode, NBTTagCompound tag, boolean assumeStackPresent, World world, int x, int y, int z, IItemSource s, EntityPlayer actor, @Nullable Consumer chatter) { + if (x == -176 && y == 62 && z == -74) { + System.out.println("At this fucking coordinate"); + new Throwable().printStackTrace(); + } if (stack == null) throw new NullPointerException(); if (stack.stackSize != 1) throw new IllegalArgumentException(); if (!(stack.getItem() instanceof ItemBlock)) throw new IllegalArgumentException(); - if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; - if (!assumeStackPresent && !s.takeOne(stack, true)) { + int mode = 0; + if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { + // best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the + // ...trigger instead of assuming default behavior + mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); + } + if (mode == 1 && !world.isAirBlock(x, y, z)) { + Block blockInWorld = world.getBlock(x, y, z); + ItemStack blockInWorldItem = new ItemStack(blockInWorld); + blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z)); + if (blockInWorldItem.isItemEqual(stack)) { + // This is the block we are looking for, move along + return PlaceResult.SKIP; + } + } + if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; + if (mode < 2 && !assumeStackPresent && !s.takeOne(stack, true)) { if (chatter != null) chatter.accept( new ChatComponentTranslation("structurelib.autoplace.error.no_item_stack", stack.func_151000_E())); return PlaceResult.REJECT; } - if (!stack.copy().tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) - return PlaceResult.REJECT; - if (!s.takeOne(stack, false)) - // this is bad! probably an exploit somehow. Let's nullify the block we just placed instead + if (mode < 2) { + if (mode == 1 && !world.isAirBlock(x, y, z)) { + // We're in updating mode and there's a block in our way (grr), so let's remove whatever is there + // ...and drop it to the player + ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); + toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); + if (!world.setBlock(x, y, z, Blocks.air, 0, 4) || !tryGiveOrDropItem(world, actor, toGive)) { + // We either weren't able to give the player the block that was there, or we weren't able to remove + // the block, either way, we need to reject the update. Also, since we hid the block update from + // the client in an effort to make the exchange as seamless as possible, we need to now notify + // the client if we did successfully remove the block. + if (world.isAirBlock(x, y, z)) world.notifyBlockChange(x, y, z, Blocks.air); + return PlaceResult.REJECT; + } + } + if (!stack.copy() + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + return PlaceResult.REJECT; + } + } + if (mode == 2 && world.isAirBlock(x, y, z)) { + return PlaceResult.SKIP; + } + if (mode == 2 || !s.takeOne(stack, false)) { + // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air + ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); + toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); world.setBlockToAir(x, y, z); + if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) { + // We were in removing mode and something went wrong while trying to give the player the block we + // ...removed, let's just fail for now + return PlaceResult.REJECT; + } + } return PlaceResult.ACCEPT; } /** * Return a structure element that only allow air (or air equivalents, like Railcraft hidden blocks). You usually - * don't need to call this yourselves. Use {@code -} in shape to automatically use this. Provided nontheless in case - * you want this as a fallback to something else. + * don't need to call this yourselves. Use {@code -} in shape to automatically use this. Provided nonetheless in + * case you want this as a fallback to something else. */ @SuppressWarnings("unchecked") public static IStructureElement isAir() { @@ -470,8 +573,8 @@ public class StructureUtility { /** * Return a structure element that allow anything but air (or air equivalents, like Railcraft hidden blocks). You - * usually don't need to call this yourselves. Use {@code +} in shape to automatically use this. Provided nontheless - * in case you want this as a fallback to something else. + * usually don't need to call this yourselves. Use {@code +} in shape to automatically use this. Provided + * nonetheless in case you want this as a fallback to something else. */ @SuppressWarnings("unchecked") public static IStructureElement notAir() { @@ -697,7 +800,7 @@ public class StructureUtility { List> hints = allKnownTiers == null ? Collections.emptyList() : allKnownTiers; if (hints.stream().anyMatch(Objects::isNull)) throw new IllegalArgumentException(); IStructureElementCheckOnly check = ofBlocksTiered(tierExtractor, notSet, setter, getter); - return new StructureElement_Bridge() { + return new StructureElement_Bridge<>() { @Override public boolean check(T t, World world, int x, int y, int z) { @@ -754,12 +857,13 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + int mode = ItemConstructableTrigger.getMode(trigger); Pair hint = getHint(trigger); if (hint == null) return PlaceResult.REJECT; // TODO or SKIP? Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); TIER tier = tierExtractor.convert(block, meta); - if (Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) + if (mode < 2 && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( hint.getKey(), @@ -849,7 +953,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - if (check(t, world, x, y, z)) return PlaceResult.SKIP; + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; if (getBlock() == null) return PlaceResult.REJECT; return StructureUtility.survivalPlaceBlock( getBlock(), @@ -936,7 +1041,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { - if (check(t, world, x, y, z)) return PlaceResult.SKIP; + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; if (init()) return StructureUtility.survivalPlaceBlock(block, meta, world, x, y, z, s, actor, chatter); return fallback.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @@ -944,7 +1050,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - if (check(t, world, x, y, z)) return PlaceResult.SKIP; + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; if (init()) return StructureUtility.survivalPlaceBlock( block, meta, @@ -1572,7 +1679,9 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - if (world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta) + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode < 2 && world.getBlock(x, y, z) == defaultBlock + && world.getBlockMetadata(x, y, z) == defaultMeta) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( defaultBlock, @@ -1618,7 +1727,9 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - if (world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta) + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode < 2 && world.getBlock(x, y, z) == defaultBlock + && world.getBlockMetadata(x, y, z) == defaultMeta) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( defaultBlock, @@ -1878,7 +1989,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { - if (predicate.test(t)) + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode == 2 || predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); return placeResultWhenDisabled; } @@ -1886,7 +1998,9 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - if (predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); + int mode = ItemConstructableTrigger.getMode(trigger); + if (mode == 2 || predicate.test(t)) + return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); return placeResultWhenDisabled; } }; @@ -3253,4 +3367,35 @@ public class StructureUtility { } return shape; } + + /** + * Performs a creation, removal, or update operation at the given position + * + * @param trigger ItemStack for the trigger item + * @param onCreate Operation to be performed when the mode of the trigger is set to building mode + * @param onUpdate Operation to be performed when the mode of the trigger is set to updating mode + * @param onRemove Operation to be performed when the mode of the trigger is set to removing mode + */ + public static void placeRemoveOrUpdate(ItemStack trigger, Runnable onCreate, Runnable onUpdate, Runnable onRemove) { + int mode = ItemConstructableTrigger.getMode(trigger); + switch (mode) { + case 0: + onCreate.run(); + break; + case 1: + onUpdate.run(); + break; + case 2: + onRemove.run(); + break; + } + } + + public static boolean tryGiveOrDropItem(World world, EntityPlayer actor, ItemStack stack) { + if (actor.inventory.addItemStackToInventory(stack)) { + actor.inventoryContainer.detectAndSendChanges(); + return true; + } + return world.spawnEntityInWorld(new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack)); + } } diff --git a/src/main/resources/assets/structurelib/lang/en_US.lang b/src/main/resources/assets/structurelib/lang/en_US.lang index e188dac1..b741f628 100644 --- a/src/main/resources/assets/structurelib/lang/en_US.lang +++ b/src/main/resources/assets/structurelib/lang/en_US.lang @@ -22,6 +22,9 @@ item.structurelib.frontRotationTool.desc.1=Rotates only the front panel, item.structurelib.frontRotationTool.desc.2=which allows structure rotation. item.structurelib.constructableTrigger.name=Multiblock Structure Hologram Projector +item.structurelib.constructableTrigger.modes.0=Building Mode +item.structurelib.constructableTrigger.modes.1=Updating Mode +item.structurelib.constructableTrigger.modes.2=Removing Mode item.structurelib.constructableTrigger.desc.0=Triggers Constructable Interface item.structurelib.constructableTrigger.desc.1=Shows multiblock construction schematic, item.structurelib.constructableTrigger.desc.2=use on the multiblock controller. @@ -40,6 +43,8 @@ item.structurelib.constructableTrigger.gui.error.show=Show Errors item.structurelib.constructableTrigger.gui.error.hide=Hide Errors item.structurelib.constructableTrigger.gui.gt_no_hatch.enable=No Hatch item.structurelib.constructableTrigger.gui.gt_no_hatch.disable=Hatches +item.structurelib.constructableTrigger.keyCategory=Multiblock Structure Hologram Projector Keys +item.structurelib.constructableTrigger.keys.cycleMode=Cycle Projector Mode structurelib.autoplace.built_stat=Built %s blocks structurelib.autoplace.complete=§aThis multiblock has completed! diff --git a/src/main/resources/assets/structurelib/textures/items/itemConstructableTrigger.png b/src/main/resources/assets/structurelib/textures/items/constructableTrigger/BUILDING.png similarity index 100% rename from src/main/resources/assets/structurelib/textures/items/itemConstructableTrigger.png rename to src/main/resources/assets/structurelib/textures/items/constructableTrigger/BUILDING.png diff --git a/src/main/resources/assets/structurelib/textures/items/constructableTrigger/REMOVING.png b/src/main/resources/assets/structurelib/textures/items/constructableTrigger/REMOVING.png new file mode 100644 index 0000000000000000000000000000000000000000..adcb90dee9cbcc7cbfe53e8600c0b0f223e6a5fa GIT binary patch literal 821 zcmV-51Iqk~P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0?J85K~y+TZIe%E zTvZswfA>x1Ihq@*L(?RNl$02nI+)37M%#r7wm66=8fhqG7AAGm;-XaDL>=4WN{xyX zL^mn~1VIbZkrouJh#f=KP+DzmwM|Jw+DR5k=g)h2@3?rAF+$Jo!a3*r?%{lf28100 z9tK`Q%au}TfnxC=z>v#rCX?yF_d{Gawk83;($3C*L^|8s~q++v1zOX1zfd zaD3iv9Xi;*i>dq4NCFHxc_89QIJ+jJu_q52);5sD;NTRi?kRnH_82`jj`{o}oVR|6 zD9teu!c!kOKqs&p&kHzwxP&o>aMF2&$G%pW>`{16xAu4MPZ0r&p(WY-NEx`fm~4djD&lC@mm9k0a?A7Fh~2@Fjsd2UJ=B~SMo}(p zfls!w#EHv4eg!-M2+s=;_7P!!U2^VK@a!}4&VMhH&dW*XRj*x8z4oV)soe@5+OE23 zldvnoo)LDOD0N#9_OJb&8M)hrRj-~?t$I#QYFJKcSmuG}R4Y&GlMP!n(LN+$2ZgmX zn}|)c_wA^bTU?NujWY<**uU{kB_203GY2q@D~S5sw^Na@!ECnSKQjb}#$GoQ6OT5< ztiQ%JcwRs}?ocYtQ!HKt0&=;nWHMd1J?DP`HIPPtGyiB700000NkvXXu0mjf3A}i- literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/structurelib/textures/items/constructableTrigger/UPDATING.png b/src/main/resources/assets/structurelib/textures/items/constructableTrigger/UPDATING.png new file mode 100644 index 0000000000000000000000000000000000000000..c9ed6178e393652942d771591b1f1693bcbfd78d GIT binary patch literal 724 zcmV;_0xSKAP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0%=J^K~y+Tb(2p> zR8bVhf9E+f>Qyudo(NhNND$&w)EFU2&>w`BwJIj4MQ&Uaw2J^S*iSw0JX%xw8Who)aj@<{zIavj01q?>r z3Zw3*QFlNNo>$M#YsP+8i6_=hUd%X4G9V>IP!etprAZr9X)i z&1$nj+2mic{-rie^MzX19H z3w$dO0C+iiilgu5iFS@t{B)Sh?_(r}XNg|0TV!T82kF;>NKq&yEXu&sP#9_!8L->GQ2JqohgO@N+&+o1AV|w z;8I!^o^45a_?@>!t1E$C-~_M%%w^M74%7hmfSYMq@c#nEi4f{uJ?uOH0000kE! literal 0 HcmV?d00001 From d3e258dd30242bd699871c83727cfbc3d8f4796c Mon Sep 17 00:00:00 2001 From: reign Date: Tue, 8 Apr 2025 10:56:50 -0400 Subject: [PATCH 2/6] Remove logs and found workaround for updating mode bug --- .../structure/StructureUtility.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 588eed58..8b5c50a3 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -340,9 +340,6 @@ public class StructureUtility { */ public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, EntityPlayer actor, Consumer chatter) { - if (x == -176 && y == 62 && z == -74) { - new Throwable().printStackTrace(); - } if (block == null) throw new NullPointerException(); int mode = 0; if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { @@ -351,6 +348,11 @@ public class StructureUtility { mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; + if (mode == 1 && world.getTileEntity(x, y, z) instanceof TileEntity) { + // We're in updating mode and the block we're looking at might be important, so let's just leave it alone + // since it's probably not something we want to replace with something else + return PlaceResult.SKIP; + } Item itemBlock = Item.getItemFromBlock(block); int itemMeta = itemBlock instanceof ISpecialItemBlock ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) @@ -496,10 +498,6 @@ public class StructureUtility { public static PlaceResult survivalPlaceBlock(ItemStack stack, NBTMode nbtMode, NBTTagCompound tag, boolean assumeStackPresent, World world, int x, int y, int z, IItemSource s, EntityPlayer actor, @Nullable Consumer chatter) { - if (x == -176 && y == 62 && z == -74) { - System.out.println("At this fucking coordinate"); - new Throwable().printStackTrace(); - } if (stack == null) throw new NullPointerException(); if (stack.stackSize != 1) throw new IllegalArgumentException(); if (!(stack.getItem() instanceof ItemBlock)) throw new IllegalArgumentException(); @@ -510,6 +508,12 @@ public class StructureUtility { mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } if (mode == 1 && !world.isAirBlock(x, y, z)) { + if (world.getTileEntity(x, y, z) instanceof TileEntity) { + // We're in updating mode and the block we're looking at might be important, so let's just leave it + // alone + // since it's probably not something we want to replace with something else + return PlaceResult.SKIP; + } Block blockInWorld = world.getBlock(x, y, z); ItemStack blockInWorldItem = new ItemStack(blockInWorld); blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z)); From bd76be4f6fef24151702d03a0c29a4cc9e36f049 Mon Sep 17 00:00:00 2001 From: reign Date: Tue, 8 Apr 2025 10:58:39 -0400 Subject: [PATCH 3/6] Comment out GT5U Dependency --- dependencies.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 147e7467..559dd6e8 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,7 +7,7 @@ dependencies { testImplementation(platform('org.junit:junit-bom:5.9.2')) testImplementation('org.junit.jupiter:junit-jupiter') - runtimeOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.227:dev") { - exclude group: "com.github.GTNewHorizons", module: "StructureLib" - } +// runtimeOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.227:dev") { +// exclude group: "com.github.GTNewHorizons", module: "StructureLib" +// } } From 5b0b9ba3c5ebdd017e7a9d4fe3f9a721a1be519f Mon Sep 17 00:00:00 2001 From: reign Date: Wed, 9 Apr 2025 21:35:01 -0400 Subject: [PATCH 4/6] Streamline codepaths and add SU compat for permission checking --- dependencies.gradle | 2 + .../item/ItemConstructableTrigger.java | 35 +-- .../structure/IStructureElement.java | 35 ++- .../structure/StructureUtility.java | 269 ++++++++++-------- .../xmod/ServerUtilitiesCompat.java | 24 ++ 5 files changed, 211 insertions(+), 154 deletions(-) create mode 100644 src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java diff --git a/dependencies.gradle b/dependencies.gradle index 559dd6e8..085cf9e1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -4,6 +4,8 @@ dependencies { api("com.github.GTNewHorizons:GTNHLib:0.6.13:dev") runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.7.29-GTNH:dev") + compileOnly("com.github.GTNewHorizons:ServerUtilities:2.1.41-pre") + testImplementation(platform('org.junit:junit-bom:5.9.2')) testImplementation('org.junit.jupiter:junit-jupiter') diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java index d2bebe78..a93ac7c5 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java @@ -1,12 +1,10 @@ package com.gtnewhorizon.structurelib.item; -import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; -import static net.minecraft.util.EnumChatFormatting.BLUE; -import static net.minecraft.util.StatCollector.translateToLocal; -import static net.minecraft.util.StatCollector.translateToLocalFormatted; - -import java.util.List; - +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; +import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; +import cpw.mods.fml.common.FMLCommonHandler; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; @@ -16,15 +14,14 @@ import net.minecraft.nbt.NBTTagInt; import net.minecraft.util.IIcon; import net.minecraft.util.StatCollector; import net.minecraft.world.World; - import org.lwjgl.input.Keyboard; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; -import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; +import java.util.List; -import cpw.mods.fml.common.FMLCommonHandler; +import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; +import static net.minecraft.util.EnumChatFormatting.BLUE; +import static net.minecraft.util.StatCollector.translateToLocal; +import static net.minecraft.util.StatCollector.translateToLocalFormatted; public class ItemConstructableTrigger extends Item { @@ -32,6 +29,12 @@ public class ItemConstructableTrigger extends Item { private static final IIcon[] textures = new IIcon[3]; + public enum TriggerMode { + BUILDING, + UPDATING, + REMOVING + } + public ItemConstructableTrigger() { setUnlocalizedName("structurelib.constructableTrigger"); setCreativeTab(StructureLib.creativeTab); @@ -86,13 +89,13 @@ public class ItemConstructableTrigger extends Item { + StatCollector.translateToLocal("item.structurelib.constructableTrigger.modes." + mode); } - public static int getMode(ItemStack held) { + public static TriggerMode getMode(ItemStack held) { if (held == null || !held.hasTagCompound() || !held.getTagCompound().hasKey(TAG_MODE)) { // default behavior - return 0; + return TriggerMode.BUILDING; } // get user-defined mode - return held.getTagCompound().getInteger(TAG_MODE); + return TriggerMode.values()[held.getTagCompound().getInteger(TAG_MODE)]; } @Override diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java index f7361eb1..f95fa27e 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java @@ -1,16 +1,9 @@ package com.gtnewhorizon.structurelib.structure; -import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; -import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; - -import java.util.Arrays; -import java.util.Collections; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -20,10 +13,16 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Collections; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; +import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; /** * Use StructureUtility to instantiate. These are the building blocks for your {@link IStructureDefinition}. It @@ -138,13 +137,13 @@ public interface IStructureElement { */ default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); BlocksToPlace e = getBlocksToPlace(t, world, x, y, z, trigger, env); IItemSource source = env.getSource(); EntityPlayer actor = env.getActor(); Consumer chatter = env.getChatter(); if (e != null) { - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (e.getStacks() == null) { ItemStack taken = source.takeOne(e.getPredicate(), true); return StructureUtility.survivalPlaceBlock( @@ -161,7 +160,7 @@ public interface IStructureElement { chatter); } for (ItemStack stack : e.getStacks()) { - if (mode < 2 && !source.takeOne(stack, true)) continue; + if (mode != REMOVING && !source.takeOne(stack, true)) continue; return StructureUtility.survivalPlaceBlock( stack, NBTMode.EXACT, diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 8b5c50a3..56faaf22 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -1,9 +1,40 @@ package com.gtnewhorizon.structurelib.structure; -import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; -import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; -import static java.lang.Integer.MIN_VALUE; +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; +import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; +import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; +import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import com.gtnewhorizon.structurelib.util.Vec3Impl; +import com.gtnewhorizon.structurelib.xmod.ServerUtilitiesCompat; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.registry.GameRegistry; +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -25,42 +56,12 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; -import javax.annotation.Nullable; - -import net.minecraft.block.Block; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; - -import com.google.common.collect.ImmutableList; -import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; -import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; -import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; -import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; -import com.gtnewhorizon.structurelib.util.Vec3Impl; - -import cpw.mods.fml.common.registry.GameRegistry; +import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; +import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.BUILDING; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.UPDATING; +import static java.lang.Integer.MIN_VALUE; /** * A brief index of everything contained @@ -148,6 +149,8 @@ public class StructureUtility { private static final String NICE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=|!@#$%&()[]{};:<>/?_,.*^'`"; + private static final boolean isSULoaded = Loader.isModLoaded("serverutilities"); + @SuppressWarnings("rawtypes") private static final Map STEP = new HashMap<>(); @@ -225,8 +228,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(o, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(o, world, x, y, z)) return PlaceResult.SKIP; // user should place anything here. // maybe make this configurable, but for now we try to take some cobble from user if (env.getSource().takeOne(new ItemStack(Blocks.cobblestone), false)) { @@ -341,43 +344,45 @@ public class StructureUtility { public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, EntityPlayer actor, Consumer chatter) { if (block == null) throw new NullPointerException(); - int mode = 0; + ItemConstructableTrigger.TriggerMode mode = BUILDING; if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { // best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the // ...trigger instead of assuming default behavior mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } - if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; - if (mode == 1 && world.getTileEntity(x, y, z) instanceof TileEntity) { - // We're in updating mode and the block we're looking at might be important, so let's just leave it alone - // since it's probably not something we want to replace with something else - return PlaceResult.SKIP; + if (mode == BUILDING && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; + if (mode == UPDATING) { + if (!world.isAirBlock(x, y, z)) { + if (world.getTileEntity(x, y, z) instanceof TileEntity) { + // We're in updating mode and the block we're looking at might be important, so let's just leave it alone + // since it's probably not something we want to replace with something else + return PlaceResult.SKIP; + } + Block blockInWorld = world.getBlock(x, y, z); + if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) { + // This is the block we are looking for, move along + return PlaceResult.SKIP; + } + } } Item itemBlock = Item.getItemFromBlock(block); int itemMeta = itemBlock instanceof ISpecialItemBlock - ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) - : meta; + ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) + : meta; ItemStack stack = new ItemStack(itemBlock, 1, itemMeta); - if (mode == 1 && !world.isAirBlock(x, y, z)) { - Block blockInWorld = world.getBlock(x, y, z); - if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) { - // This is the block we are looking for, move along - return PlaceResult.SKIP; - } - } - if (mode < 2 && !s.takeOne(stack, true)) { - if (chatter != null) chatter.accept( + if (mode != REMOVING) { + if (!s.takeOne(stack, true)) { + if (chatter != null) chatter.accept( new ChatComponentTranslation( - "structurelib.autoplace.error.no_simple_block", - stack.func_151000_E())); - return PlaceResult.REJECT; - } - if (mode < 2) { + "structurelib.autoplace.error.no_simple_block", + stack.func_151000_E())); + return PlaceResult.REJECT; + } if (block instanceof ICustomBlockSetting) { ICustomBlockSetting blockCustom = (ICustomBlockSetting) block; blockCustom.setBlock(world, x, y, z, meta); } else { - if (mode == 1 && !world.isAirBlock(x, y, z)) { + if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) { // We're in updating mode and there's a block in our way (grr), so let's remove whatever is there // ...and drop it to the player ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); @@ -393,21 +398,24 @@ public class StructureUtility { } } if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } } } - if (mode == 2 && world.isAirBlock(x, y, z)) { - return PlaceResult.SKIP; - } - if (mode == 2 || !s.takeOne(stack, false)) { - // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air + if (mode == REMOVING || !s.takeOne(stack, true)) { + // If we're in removing mode, or if the user didn't have the block in their inventory, and we're in some other mode, let's check some stuff + if(world.isAirBlock(x, y, z)) { + return PlaceResult.SKIP; + } ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); + if(mode == REMOVING && !checkPermission(world, actor, x, y, z)) { + return PlaceResult.REJECT; + } world.setBlockToAir(x, y, z); - if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) { - // Something went wrong while trying to give the player the block we removed, let's just fail for now + if (mode == REMOVING && !tryGiveOrDropItem(world, actor, toGive)) { + // We're in removing mode and something went wrong while trying to give the player the block we removed, let's just fail for now return PlaceResult.REJECT; } } @@ -501,35 +509,38 @@ public class StructureUtility { if (stack == null) throw new NullPointerException(); if (stack.stackSize != 1) throw new IllegalArgumentException(); if (!(stack.getItem() instanceof ItemBlock)) throw new IllegalArgumentException(); - int mode = 0; + ItemConstructableTrigger.TriggerMode mode = BUILDING; if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) { // best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the // ...trigger instead of assuming default behavior mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } - if (mode == 1 && !world.isAirBlock(x, y, z)) { - if (world.getTileEntity(x, y, z) instanceof TileEntity) { - // We're in updating mode and the block we're looking at might be important, so let's just leave it - // alone - // since it's probably not something we want to replace with something else - return PlaceResult.SKIP; + if (mode != REMOVING) { + if (mode == BUILDING) { + if(!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) { + return PlaceResult.SKIP; + } } - Block blockInWorld = world.getBlock(x, y, z); - ItemStack blockInWorldItem = new ItemStack(blockInWorld); - blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z)); - if (blockInWorldItem.isItemEqual(stack)) { - // This is the block we are looking for, move along - return PlaceResult.SKIP; + if (mode == UPDATING) { + if (!world.isAirBlock(x, y, z)) { + if (world.getTileEntity(x, y, z) instanceof TileEntity) { + return PlaceResult.SKIP; + } + Block blockInWorld = world.getBlock(x, y, z); + ItemStack blockInWorldItem = new ItemStack(blockInWorld); + blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z)); + if (blockInWorldItem.isItemEqual(stack)) { + // This is the block we are looking for, move along + return PlaceResult.SKIP; + } + } } - } - if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; - if (mode < 2 && !assumeStackPresent && !s.takeOne(stack, true)) { - if (chatter != null) chatter.accept( + if (!assumeStackPresent && !s.takeOne(stack, true)) { + if (chatter != null) chatter.accept( new ChatComponentTranslation("structurelib.autoplace.error.no_item_stack", stack.func_151000_E())); - return PlaceResult.REJECT; - } - if (mode < 2) { - if (mode == 1 && !world.isAirBlock(x, y, z)) { + return PlaceResult.REJECT; + } + if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) { // We're in updating mode and there's a block in our way (grr), so let's remove whatever is there // ...and drop it to the player ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); @@ -544,19 +555,22 @@ public class StructureUtility { } } if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } } - if (mode == 2 && world.isAirBlock(x, y, z)) { - return PlaceResult.SKIP; - } - if (mode == 2 || !s.takeOne(stack, false)) { + if (mode == REMOVING || !s.takeOne(stack, false)) { + if (world.isAirBlock(x, y, z)) { + return PlaceResult.SKIP; + } // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); + if(mode == REMOVING && !checkPermission(world, actor, x, y, z)) { + return PlaceResult.REJECT; + } world.setBlockToAir(x, y, z); - if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) { + if (mode == REMOVING && !tryGiveOrDropItem(world, actor, toGive)) { // We were in removing mode and something went wrong while trying to give the player the block we // ...removed, let's just fail for now return PlaceResult.REJECT; @@ -861,13 +875,13 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); Pair hint = getHint(trigger); if (hint == null) return PlaceResult.REJECT; // TODO or SKIP? Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); TIER tier = tierExtractor.convert(block, meta); - if (mode < 2 && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) + if (mode != REMOVING && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( hint.getKey(), @@ -957,8 +971,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (getBlock() == null) return PlaceResult.REJECT; return StructureUtility.survivalPlaceBlock( getBlock(), @@ -1045,8 +1059,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (init()) return StructureUtility.survivalPlaceBlock(block, meta, world, x, y, z, s, actor, chatter); return fallback.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @@ -1054,8 +1068,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP; + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; if (init()) return StructureUtility.survivalPlaceBlock( block, meta, @@ -1683,8 +1697,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && world.getBlock(x, y, z) == defaultBlock + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( @@ -1731,8 +1745,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode < 2 && world.getBlock(x, y, z) == defaultBlock + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode != REMOVING && world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( @@ -1993,8 +2007,8 @@ public class StructureUtility { @Deprecated public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode == 2 || predicate.test(t)) + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode == REMOVING || predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); return placeResultWhenDisabled; } @@ -2002,8 +2016,8 @@ public class StructureUtility { @Override public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { - int mode = ItemConstructableTrigger.getMode(trigger); - if (mode == 2 || predicate.test(t)) + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); + if (mode == REMOVING || predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); return placeResultWhenDisabled; } @@ -3381,15 +3395,15 @@ public class StructureUtility { * @param onRemove Operation to be performed when the mode of the trigger is set to removing mode */ public static void placeRemoveOrUpdate(ItemStack trigger, Runnable onCreate, Runnable onUpdate, Runnable onRemove) { - int mode = ItemConstructableTrigger.getMode(trigger); + ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); switch (mode) { - case 0: + case BUILDING: onCreate.run(); break; - case 1: + case UPDATING: onUpdate.run(); break; - case 2: + case REMOVING: onRemove.run(); break; } @@ -3400,6 +3414,21 @@ public class StructureUtility { actor.inventoryContainer.detectAndSendChanges(); return true; } - return world.spawnEntityInWorld(new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack)); + EntityItem toSpawn = new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack); + // For some reason these things sometimes spawn with the velocity of an F1 car, so let's prevent that + toSpawn.motionX = 0; + toSpawn.motionY = 0; + toSpawn.motionZ = 0; + return world.spawnEntityInWorld(toSpawn); + } + + public static boolean checkPermission(World world, EntityPlayer actor, int x, int y, int z) { + boolean res = true; + if(isSULoaded) { + res = ServerUtilitiesCompat.checkPermission(world, actor, x, z); + } + res = res && !world.getBlock(x, y, z).isAssociatedBlock(Blocks.bedrock); + // maybe check mining level who knows :shrug: + return res; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java b/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java new file mode 100644 index 00000000..843c1764 --- /dev/null +++ b/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java @@ -0,0 +1,24 @@ +package com.gtnewhorizon.structurelib.xmod; + +import cpw.mods.fml.common.Optional; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.world.World; +import serverutils.data.ClaimedChunks; +import serverutils.lib.data.ForgePlayer; +import serverutils.lib.data.ForgeTeam; +import serverutils.lib.data.Universe; +import serverutils.lib.math.ChunkDimPos; + +public class ServerUtilitiesCompat { + + @Optional.Method(modid = "serverutilities") + public static boolean checkPermission(World world, EntityPlayer actor, int x, int z) { + final ForgeTeam owningTeam = ClaimedChunks.instance.getChunkTeam(new ChunkDimPos(x >> 4, z >> 4, world.provider.dimensionId)); + if (owningTeam == null) { + return true; + } + final ForgePlayer currentPlayer = new ForgePlayer(Universe.get(), actor.getUniqueID(), actor.getCommandSenderName()); + return owningTeam.isAlly(currentPlayer) || owningTeam.isMember(currentPlayer); + } + +} From dfe910ebd39f3d64ac44356d9e5f261587c3c79f Mon Sep 17 00:00:00 2001 From: reign Date: Fri, 11 Apr 2025 18:39:15 -0400 Subject: [PATCH 5/6] Fix a few bugs, add removal checking --- .../structure/IStructureElement.java | 4 +- .../structure/StructureUtility.java | 42 +++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java index f95fa27e..ea263a12 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java @@ -23,6 +23,7 @@ import java.util.function.Predicate; import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.checkForRemoving; /** * Use StructureUtility to instantiate. These are the building blocks for your {@link IStructureDefinition}. It @@ -143,7 +144,8 @@ public interface IStructureElement { EntityPlayer actor = env.getActor(); Consumer chatter = env.getChatter(); if (e != null) { - if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z); + if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; if (e.getStacks() == null) { ItemStack taken = source.takeOne(e.getPredicate(), true); return StructureUtility.survivalPlaceBlock( diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 56faaf22..49851881 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -403,7 +403,7 @@ public class StructureUtility { } } } - if (mode == REMOVING || !s.takeOne(stack, true)) { + if (mode == REMOVING || !s.takeOne(stack, false)) { // If we're in removing mode, or if the user didn't have the block in their inventory, and we're in some other mode, let's check some stuff if(world.isAirBlock(x, y, z)) { return PlaceResult.SKIP; @@ -843,6 +843,10 @@ public class StructureUtility { return Objects.equals(hintTier, worldTier); } + private boolean isInAllKnownTiers(Block b) { + return allKnownTiers != null && allKnownTiers.stream().anyMatch(pair -> pair.getLeft().isAssociatedBlock(b)); + } + @Override public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { Pair hint = getHint(trigger); @@ -881,8 +885,11 @@ public class StructureUtility { Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); TIER tier = tierExtractor.convert(block, meta); - if (mode != REMOVING && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue()))) + if (mode != REMOVING && (Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue())))) return PlaceResult.SKIP; + if (mode == REMOVING && (!isInAllKnownTiers(block) && !world.isAirBlock(x, y, z))) { + return PlaceResult.REJECT; + } return StructureUtility.survivalPlaceBlock( hint.getKey(), hint.getValue(), @@ -972,7 +979,8 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z); + if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; if (getBlock() == null) return PlaceResult.REJECT; return StructureUtility.survivalPlaceBlock( getBlock(), @@ -1060,7 +1068,8 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z); + if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; if (init()) return StructureUtility.survivalPlaceBlock(block, meta, world, x, y, z, s, actor, chatter); return fallback.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @@ -1069,7 +1078,8 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode != REMOVING && check(t, world, x, y, z)) return PlaceResult.SKIP; + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z); + if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; if (init()) return StructureUtility.survivalPlaceBlock( block, meta, @@ -1698,9 +1708,9 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode != REMOVING && world.getBlock(x, y, z) == defaultBlock - && world.getBlockMetadata(x, y, z) == defaultMeta) - return PlaceResult.SKIP; + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, world.getBlock(x, y, z) == defaultBlock + && world.getBlockMetadata(x, y, z) == defaultMeta, world, x, y, z); + if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; return StructureUtility.survivalPlaceBlock( defaultBlock, defaultMeta, @@ -1746,9 +1756,9 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode != REMOVING && world.getBlock(x, y, z) == defaultBlock - && world.getBlockMetadata(x, y, z) == defaultMeta) - return PlaceResult.SKIP; + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, world.getBlock(x, y, z) == defaultBlock + && world.getBlockMetadata(x, y, z) == defaultMeta, world, x, y, z); + if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; return StructureUtility.survivalPlaceBlock( defaultBlock, defaultMeta, @@ -2008,7 +2018,7 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode == REMOVING || predicate.test(t)) + if (predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); return placeResultWhenDisabled; } @@ -2017,7 +2027,7 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (mode == REMOVING || predicate.test(t)) + if (predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); return placeResultWhenDisabled; } @@ -3431,4 +3441,10 @@ public class StructureUtility { // maybe check mining level who knows :shrug: return res; } + + public static PlaceResult checkForRemoving(ItemConstructableTrigger.TriggerMode mode, boolean checkResult, World world, int x, int y, int z) { + if (mode != REMOVING && checkResult) return PlaceResult.SKIP; + else if (mode != BUILDING && !checkResult && !world.isAirBlock(x, y, z)) return PlaceResult.REJECT; + return PlaceResult.ACCEPT; + } } From b4b6f4e5eba65c1c340d36356e2547f4a0f62bf2 Mon Sep 17 00:00:00 2001 From: ReignOfFROZE Date: Fri, 11 Apr 2025 18:45:17 -0400 Subject: [PATCH 6/6] Spotless apply --- .../item/ItemConstructableTrigger.java | 23 +-- .../structure/IStructureElement.java | 32 ++-- .../structure/StructureUtility.java | 151 ++++++++++-------- .../xmod/ServerUtilitiesCompat.java | 11 +- 4 files changed, 124 insertions(+), 93 deletions(-) diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java index a93ac7c5..3d51c1de 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java @@ -1,10 +1,12 @@ package com.gtnewhorizon.structurelib.item; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; -import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; -import cpw.mods.fml.common.FMLCommonHandler; +import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; +import static net.minecraft.util.EnumChatFormatting.BLUE; +import static net.minecraft.util.StatCollector.translateToLocal; +import static net.minecraft.util.StatCollector.translateToLocalFormatted; + +import java.util.List; + import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; @@ -14,14 +16,15 @@ import net.minecraft.nbt.NBTTagInt; import net.minecraft.util.IIcon; import net.minecraft.util.StatCollector; import net.minecraft.world.World; + import org.lwjgl.input.Keyboard; -import java.util.List; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; +import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; -import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; -import static net.minecraft.util.EnumChatFormatting.BLUE; -import static net.minecraft.util.StatCollector.translateToLocal; -import static net.minecraft.util.StatCollector.translateToLocalFormatted; +import cpw.mods.fml.common.FMLCommonHandler; public class ItemConstructableTrigger extends Item { diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java index ea263a12..c307eaa0 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java @@ -1,9 +1,18 @@ package com.gtnewhorizon.structurelib.structure; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; +import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; +import static com.gtnewhorizon.structurelib.structure.StructureUtility.checkForRemoving; + +import java.util.Arrays; +import java.util.Collections; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -13,17 +22,10 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collections; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; -import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; -import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; -import static com.gtnewhorizon.structurelib.structure.StructureUtility.checkForRemoving; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; /** * Use StructureUtility to instantiate. These are the building blocks for your {@link IStructureDefinition}. It diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 49851881..f200dbc7 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -1,40 +1,12 @@ package com.gtnewhorizon.structurelib.structure; -import com.google.common.collect.ImmutableList; -import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; -import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; -import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; -import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; -import com.gtnewhorizon.structurelib.util.Vec3Impl; -import com.gtnewhorizon.structurelib.xmod.ServerUtilitiesCompat; -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.registry.GameRegistry; -import net.minecraft.block.Block; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.IChatComponent; -import net.minecraft.util.IIcon; -import net.minecraft.world.World; -import net.minecraftforge.common.util.ForgeDirection; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; +import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; +import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.BUILDING; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; +import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.UPDATING; +import static java.lang.Integer.MIN_VALUE; -import javax.annotation.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -56,12 +28,44 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; -import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; -import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; -import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.BUILDING; -import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.REMOVING; -import static com.gtnewhorizon.structurelib.item.ItemConstructableTrigger.TriggerMode.UPDATING; -import static java.lang.Integer.MIN_VALUE; +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; + +import com.google.common.collect.ImmutableList; +import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; +import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; +import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; +import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; +import com.gtnewhorizon.structurelib.util.Vec3Impl; +import com.gtnewhorizon.structurelib.xmod.ServerUtilitiesCompat; + +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.registry.GameRegistry; /** * A brief index of everything contained @@ -350,11 +354,13 @@ public class StructureUtility { // ...trigger instead of assuming default behavior mode = ItemConstructableTrigger.getMode(actor.getHeldItem()); } - if (mode == BUILDING && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; + if (mode == BUILDING && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) + return PlaceResult.REJECT; if (mode == UPDATING) { if (!world.isAirBlock(x, y, z)) { if (world.getTileEntity(x, y, z) instanceof TileEntity) { - // We're in updating mode and the block we're looking at might be important, so let's just leave it alone + // We're in updating mode and the block we're looking at might be important, so let's just leave it + // alone // since it's probably not something we want to replace with something else return PlaceResult.SKIP; } @@ -367,15 +373,15 @@ public class StructureUtility { } Item itemBlock = Item.getItemFromBlock(block); int itemMeta = itemBlock instanceof ISpecialItemBlock - ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) - : meta; + ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) + : meta; ItemStack stack = new ItemStack(itemBlock, 1, itemMeta); if (mode != REMOVING) { if (!s.takeOne(stack, true)) { if (chatter != null) chatter.accept( - new ChatComponentTranslation( - "structurelib.autoplace.error.no_simple_block", - stack.func_151000_E())); + new ChatComponentTranslation( + "structurelib.autoplace.error.no_simple_block", + stack.func_151000_E())); return PlaceResult.REJECT; } if (block instanceof ICustomBlockSetting) { @@ -398,24 +404,26 @@ public class StructureUtility { } } if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } } } if (mode == REMOVING || !s.takeOne(stack, false)) { - // If we're in removing mode, or if the user didn't have the block in their inventory, and we're in some other mode, let's check some stuff - if(world.isAirBlock(x, y, z)) { + // If we're in removing mode, or if the user didn't have the block in their inventory, and we're in some + // other mode, let's check some stuff + if (world.isAirBlock(x, y, z)) { return PlaceResult.SKIP; } ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); - if(mode == REMOVING && !checkPermission(world, actor, x, y, z)) { + if (mode == REMOVING && !checkPermission(world, actor, x, y, z)) { return PlaceResult.REJECT; } world.setBlockToAir(x, y, z); if (mode == REMOVING && !tryGiveOrDropItem(world, actor, toGive)) { - // We're in removing mode and something went wrong while trying to give the player the block we removed, let's just fail for now + // We're in removing mode and something went wrong while trying to give the player the block we removed, + // let's just fail for now return PlaceResult.REJECT; } } @@ -517,7 +525,7 @@ public class StructureUtility { } if (mode != REMOVING) { if (mode == BUILDING) { - if(!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) { + if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) { return PlaceResult.SKIP; } } @@ -537,7 +545,9 @@ public class StructureUtility { } if (!assumeStackPresent && !s.takeOne(stack, true)) { if (chatter != null) chatter.accept( - new ChatComponentTranslation("structurelib.autoplace.error.no_item_stack", stack.func_151000_E())); + new ChatComponentTranslation( + "structurelib.autoplace.error.no_item_stack", + stack.func_151000_E())); return PlaceResult.REJECT; } if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) { @@ -555,7 +565,7 @@ public class StructureUtility { } } if (!stack.copy() - .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { + .tryPlaceItemIntoWorld(actor, world, x, y, z, ForgeDirection.UP.ordinal(), 0.5f, 0.5f, 0.5f)) { return PlaceResult.REJECT; } } @@ -566,7 +576,7 @@ public class StructureUtility { // If the user didn't have the item in their inventory, or we're in removing mode, we set it to air ItemStack toGive = new ItemStack(world.getBlock(x, y, z)); toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z)); - if(mode == REMOVING && !checkPermission(world, actor, x, y, z)) { + if (mode == REMOVING && !checkPermission(world, actor, x, y, z)) { return PlaceResult.REJECT; } world.setBlockToAir(x, y, z); @@ -844,7 +854,8 @@ public class StructureUtility { } private boolean isInAllKnownTiers(Block b) { - return allKnownTiers != null && allKnownTiers.stream().anyMatch(pair -> pair.getLeft().isAssociatedBlock(b)); + return allKnownTiers != null + && allKnownTiers.stream().anyMatch(pair -> pair.getLeft().isAssociatedBlock(b)); } @Override @@ -1708,8 +1719,13 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, world.getBlock(x, y, z) == defaultBlock - && world.getBlockMetadata(x, y, z) == defaultMeta, world, x, y, z); + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving( + mode, + world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta, + world, + x, + y, + z); if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; return StructureUtility.survivalPlaceBlock( defaultBlock, @@ -1756,8 +1772,13 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, world.getBlock(x, y, z) == defaultBlock - && world.getBlockMetadata(x, y, z) == defaultMeta, world, x, y, z); + PlaceResult skipOrRejectBasedOnCheck = checkForRemoving( + mode, + world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta, + world, + x, + y, + z); if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck; return StructureUtility.survivalPlaceBlock( defaultBlock, @@ -2027,8 +2048,7 @@ public class StructureUtility { public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger); - if (predicate.test(t)) - return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); + if (predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env); return placeResultWhenDisabled; } }; @@ -3434,7 +3454,7 @@ public class StructureUtility { public static boolean checkPermission(World world, EntityPlayer actor, int x, int y, int z) { boolean res = true; - if(isSULoaded) { + if (isSULoaded) { res = ServerUtilitiesCompat.checkPermission(world, actor, x, z); } res = res && !world.getBlock(x, y, z).isAssociatedBlock(Blocks.bedrock); @@ -3442,7 +3462,8 @@ public class StructureUtility { return res; } - public static PlaceResult checkForRemoving(ItemConstructableTrigger.TriggerMode mode, boolean checkResult, World world, int x, int y, int z) { + public static PlaceResult checkForRemoving(ItemConstructableTrigger.TriggerMode mode, boolean checkResult, + World world, int x, int y, int z) { if (mode != REMOVING && checkResult) return PlaceResult.SKIP; else if (mode != BUILDING && !checkResult && !world.isAirBlock(x, y, z)) return PlaceResult.REJECT; return PlaceResult.ACCEPT; diff --git a/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java b/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java index 843c1764..4dace253 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java +++ b/src/main/java/com/gtnewhorizon/structurelib/xmod/ServerUtilitiesCompat.java @@ -1,8 +1,9 @@ package com.gtnewhorizon.structurelib.xmod; -import cpw.mods.fml.common.Optional; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; + +import cpw.mods.fml.common.Optional; import serverutils.data.ClaimedChunks; import serverutils.lib.data.ForgePlayer; import serverutils.lib.data.ForgeTeam; @@ -13,11 +14,15 @@ public class ServerUtilitiesCompat { @Optional.Method(modid = "serverutilities") public static boolean checkPermission(World world, EntityPlayer actor, int x, int z) { - final ForgeTeam owningTeam = ClaimedChunks.instance.getChunkTeam(new ChunkDimPos(x >> 4, z >> 4, world.provider.dimensionId)); + final ForgeTeam owningTeam = ClaimedChunks.instance + .getChunkTeam(new ChunkDimPos(x >> 4, z >> 4, world.provider.dimensionId)); if (owningTeam == null) { return true; } - final ForgePlayer currentPlayer = new ForgePlayer(Universe.get(), actor.getUniqueID(), actor.getCommandSenderName()); + final ForgePlayer currentPlayer = new ForgePlayer( + Universe.get(), + actor.getUniqueID(), + actor.getCommandSenderName()); return owningTeam.isAlly(currentPlayer) || owningTeam.isMember(currentPlayer); }