From 464e44de8541a46833f50c3bd363d50e1677a685 Mon Sep 17 00:00:00 2001 From: Raven Szewczyk Date: Mon, 30 Jan 2023 12:52:27 +0000 Subject: [PATCH] [ci skip] spotlessApply with the new settings --- dependencies.gradle | 2 +- .../structurelib/ClientProxy.java | 39 +- .../structurelib/CommonProxy.java | 24 +- .../structurelib/ConfigurationHandler.java | 13 +- .../structurelib/ConfigurationVersion.java | 10 +- .../gtnewhorizon/structurelib/GuiFactory.java | 5 +- .../gtnewhorizon/structurelib/GuiHandler.java | 6 +- .../structurelib/GuiModConfig.java | 16 +- .../structurelib/IStructureCompat.java | 1 + .../structurelib/StructureEvent.java | 47 +- .../structurelib/StructureLib.java | 34 +- .../structurelib/StructureLibAPI.java | 123 +- .../alignment/AlignmentLimits.java | 3 +- .../alignment/AlignmentUtility.java | 1 + .../structurelib/alignment/IAlignment.java | 25 +- .../alignment/IAlignmentLimits.java | 27 +- .../alignment/IAlignmentProvider.java | 1 + .../alignment/IntegerAxisSwap.java | 48 +- .../constructable/ChannelDataAccessor.java | 85 +- .../constructable/ConstructableUtility.java | 43 +- .../constructable/IConstructable.java | 5 +- .../constructable/IConstructableProvider.java | 1 + .../IMultiblockInfoContainer.java | 35 +- .../constructable/ISurvivalConstructable.java | 31 +- .../alignment/enumerable/Direction.java | 9 +- .../alignment/enumerable/ExtendedFacing.java | 55 +- .../alignment/enumerable/Flip.java | 2 + .../alignment/enumerable/Rotation.java | 6 +- .../structurelib/alignment/package-info.java | 4 +- .../structurelib/block/BlockHint.java | 12 +- .../command/CommandConfigureChannels.java | 32 +- .../entity/fx/WeightlessParticleFX.java | 16 +- .../gui/GuiScreenConfigureChannels.java | 92 +- .../structurelib/gui/GuiScrollableList.java | 34 +- .../structurelib/item/ItemBlockHint.java | 34 +- .../item/ItemConstructableTrigger.java | 59 +- .../item/ItemFrontRotationTool.java | 37 +- .../structurelib/net/AlignmentMessage.java | 28 +- .../net/ErrorHintParticleMessage.java | 22 +- .../net/SetChannelDataMessage.java | 20 +- .../net/UpdateHintParticleMessage.java | 20 +- .../structure/AutoPlaceEnvironment.java | 45 +- .../structure/ChatThrottleKey.java | 1 + .../DefaultSurvivalBuildEnvironment.java | 1 + .../structure/IBlockPosConsumer.java | 1 + .../structure/ICustomBlockSetting.java | 5 +- .../structurelib/structure/IItemSource.java | 33 +- .../structure/ISpecialItemBlock.java | 1 + .../structure/IStructureDefinition.java | 344 ++--- .../structure/IStructureElement.java | 145 +- .../structure/IStructureElementChain.java | 30 +- .../structure/IStructureElementCheckOnly.java | 18 +- .../structure/IStructureElementDeferred.java | 3 +- .../IStructureElementNoPlacement.java | 18 +- .../structure/IStructureNavigate.java | 18 +- .../structure/IStructureWalker.java | 15 +- .../structure/ISurvivalBuildEnvironment.java | 16 +- .../structure/ITierConverter.java | 1 + .../structure/IWithExtendedContext.java | 1 + .../structure/LazyStructureElement.java | 23 +- .../structure/StructureDefinition.java | 64 +- .../structure/StructureElement_Bridge.java | 18 +- .../structure/StructureUtility.java | 1324 ++++++++--------- .../SurvivalBuildStructureWalker.java | 19 +- .../structure/adders/IBlockAdder.java | 1 + .../structure/adders/ITileAdder.java | 1 + .../structurelib/structure/package-info.java | 4 +- .../structurelib/util/InventoryIterable.java | 3 + .../structurelib/util/InventoryUtility.java | 150 +- .../util/ItemStackArrayIterable.java | 3 + .../structurelib/util/ItemStackPredicate.java | 14 +- .../structurelib/util/MiscUtils.java | 2 + .../structurelib/util/SortedRegistry.java | 1 + .../structurelib/util/Vec3Impl.java | 5 +- .../gtnewhorizon/structurelib/util/XSTR.java | 144 +- .../enumerable/ExtendedFacingTest.java | 1 + 76 files changed, 1717 insertions(+), 1863 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 5c7b33e8..8a8419a6 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -2,7 +2,7 @@ dependencies { compile("com.github.GTNewHorizons:GTNHLib:0.0.1:dev") - runtime("com.github.GTNewHorizons:NotEnoughItems:2.2.20-GTNH:dev") + runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.2.20-GTNH:dev") testImplementation(platform('org.junit:junit-bom:5.8.2')) testImplementation('org.junit.jupiter:junit-jupiter') diff --git a/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java b/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java index d68aac0b..05362839 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java +++ b/src/main/java/com/gtnewhorizon/structurelib/ClientProxy.java @@ -2,14 +2,8 @@ package com.gtnewhorizon.structurelib; import static com.gtnewhorizon.structurelib.StructureLib.RANDOM; -import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX; -import com.gtnewhorizon.structurelib.net.SetChannelDataMessage; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent; -import cpw.mods.fml.common.gameevent.TickEvent.Phase; import java.util.*; + import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiNewChat; @@ -31,12 +25,22 @@ import net.minecraft.world.World; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.WorldEvent; + import org.lwjgl.opengl.GL11; +import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX; +import com.gtnewhorizon.structurelib.net.SetChannelDataMessage; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; + public class ClientProxy extends CommonProxy { - private static final short[] RGBA_NO_TINT = {255, 255, 255, 255}; - private static final short[] RGBA_RED_TINT = {255, 128, 128, 0}; + private static final short[] RGBA_NO_TINT = { 255, 255, 255, 255 }; + private static final short[] RGBA_RED_TINT = { 255, 128, 128, 0 }; private static final Map allHints = new HashMap<>(); /** * All batches of hints. @@ -55,11 +59,10 @@ public class ClientProxy extends CommonProxy { */ private static final List allHintsForRender = new ArrayList<>(10000); /** - * If the diff to current player position is too great sort the allHints. - * Initial value is very far off below y=0 but not huge enough to make a NaN. + * If the diff to current player position is too great sort the allHints. Initial value is very far off below y=0 + * but not huge enough to make a NaN. *

- * We are using this supposedly immutable object as a mutable object here. - * So be aware. + * We are using this supposedly immutable object as a mutable object here. So be aware. */ private static final Vec3 lastPlayerPos = Vec3.createVectorHelper(0, -1e30, 0); /** @@ -158,11 +161,7 @@ public class ClientProxy extends CommonProxy { } @Override - public void addThrottledChat( - Object throttleKey, - EntityPlayer player, - IChatComponent text, - short intervalRequired, + public void addThrottledChat(Object throttleKey, EntityPlayer player, IChatComponent text, short intervalRequired, boolean forceUpdateLastSend) { if (player instanceof EntityPlayerMP) super.addThrottledChat(throttleKey, player, text, intervalRequired, forceUpdateLastSend); @@ -250,6 +249,7 @@ public class ClientProxy extends CommonProxy { } private static class HintGroup { + private final List hints = new LinkedList<>(); private int creationTime = -1; @@ -267,6 +267,7 @@ public class ClientProxy extends CommonProxy { } private static class HintParticleInfo { + private final World w; // these are the block coordinate for e.g. w.getBlock() private final int x, y, z; @@ -418,6 +419,7 @@ public class ClientProxy extends CommonProxy { } public static class FMLEventHandler { + private void resetPlayerLocation() { lastPlayerPos.xCoord = Minecraft.getMinecraft().thePlayer.posX; lastPlayerPos.yCoord = Minecraft.getMinecraft().thePlayer.posY; @@ -466,6 +468,7 @@ public class ClientProxy extends CommonProxy { } public static class ForgeEventHandler { + @SubscribeEvent public void onWorldLoad(WorldEvent.Load e) { if (e.world.isRemote) { diff --git a/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java b/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java index 5ecc274a..61bb2d5c 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java +++ b/src/main/java/com/gtnewhorizon/structurelib/CommonProxy.java @@ -1,11 +1,9 @@ package com.gtnewhorizon.structurelib; -import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage; -import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage; -import cpw.mods.fml.common.event.FMLPreInitializationEvent; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; + import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -15,7 +13,12 @@ import net.minecraft.util.IChatComponent; import net.minecraft.util.IIcon; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage; +import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; + public class CommonProxy { + public void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) {} public void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) {} @@ -68,11 +71,7 @@ public class CommonProxy { private final Map> throttleMap = new WeakHashMap<>(); - public void addThrottledChat( - Object throttleKey, - EntityPlayer player, - IChatComponent text, - short intervalRequired, + public void addThrottledChat(Object throttleKey, EntityPlayer player, IChatComponent text, short intervalRequired, boolean forceUpdateLastSend) { if (player instanceof EntityPlayerMP) { Map submap = throttleMap.computeIfAbsent((EntityPlayerMP) player, p -> new HashMap<>()); @@ -80,13 +79,8 @@ public class CommonProxy { } } - protected static void addThrottledChat( - Object throttleKey, - EntityPlayer player, - IChatComponent text, - short intervalRequired, - boolean forceUpdateLastSend, - Map submap) { + protected static void addThrottledChat(Object throttleKey, EntityPlayer player, IChatComponent text, + short intervalRequired, boolean forceUpdateLastSend, Map submap) { long now = System.currentTimeMillis(); Long old; if (forceUpdateLastSend) { diff --git a/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java b/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java index a9868abc..e96b5aad 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java +++ b/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java @@ -1,15 +1,18 @@ package com.gtnewhorizon.structurelib; -import cpw.mods.fml.client.event.ConfigChangedEvent; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; import java.io.File; import java.util.Map; + import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; +import cpw.mods.fml.client.event.ConfigChangedEvent; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + public enum ConfigurationHandler { + INSTANCE; private Configuration config; @@ -54,8 +57,8 @@ public enum ConfigurationHandler { "client.hologram", true, "An attempt will be made to remove an existing hologram if it collides with a new hologram."); - hintLifespan = - config.getInt("hintLifespan", "client.hologram", 400, 1, 20000, "Ticks before a hologram disappears."); + hintLifespan = config + .getInt("hintLifespan", "client.hologram", 400, 1, 20000, "Ticks before a hologram disappears."); hintTransparency = config.getInt( "hintTransparency", "client.hologram", diff --git a/src/main/java/com/gtnewhorizon/structurelib/ConfigurationVersion.java b/src/main/java/com/gtnewhorizon/structurelib/ConfigurationVersion.java index 3c107bce..15c6ab9f 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/ConfigurationVersion.java +++ b/src/main/java/com/gtnewhorizon/structurelib/ConfigurationVersion.java @@ -2,11 +2,15 @@ package com.gtnewhorizon.structurelib; import java.util.Arrays; import java.util.Objects; + import javax.annotation.Nullable; + import net.minecraftforge.common.config.Configuration; enum ConfigurationVersion { + V1 { + @Override protected void step(Configuration c) {} }; @@ -30,10 +34,8 @@ enum ConfigurationVersion { } public static ConfigurationVersion identify(Configuration c) { - return Arrays.stream(VALUES) - .filter(v -> Objects.equals(c.getLoadedConfigVersion(), v.getVersionMarker())) - .findFirst() - .orElse(V1); + return Arrays.stream(VALUES).filter(v -> Objects.equals(c.getLoadedConfigVersion(), v.getVersionMarker())) + .findFirst().orElse(V1); } @Nullable diff --git a/src/main/java/com/gtnewhorizon/structurelib/GuiFactory.java b/src/main/java/com/gtnewhorizon/structurelib/GuiFactory.java index 22dba088..2133e9fa 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/GuiFactory.java +++ b/src/main/java/com/gtnewhorizon/structurelib/GuiFactory.java @@ -1,11 +1,14 @@ package com.gtnewhorizon.structurelib; -import cpw.mods.fml.client.IModGuiFactory; import java.util.Set; + import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; +import cpw.mods.fml.client.IModGuiFactory; + public class GuiFactory implements IModGuiFactory { + @Override public void initialize(Minecraft minecraftInstance) {} diff --git a/src/main/java/com/gtnewhorizon/structurelib/GuiHandler.java b/src/main/java/com/gtnewhorizon/structurelib/GuiHandler.java index ec13d349..bda4ded5 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/GuiHandler.java +++ b/src/main/java/com/gtnewhorizon/structurelib/GuiHandler.java @@ -1,11 +1,13 @@ package com.gtnewhorizon.structurelib; -import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; -import cpw.mods.fml.common.network.IGuiHandler; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels; +import cpw.mods.fml.common.network.IGuiHandler; + public class GuiHandler implements IGuiHandler { + @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { return null; diff --git a/src/main/java/com/gtnewhorizon/structurelib/GuiModConfig.java b/src/main/java/com/gtnewhorizon/structurelib/GuiModConfig.java index db725ff1..b1fcbdc0 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/GuiModConfig.java +++ b/src/main/java/com/gtnewhorizon/structurelib/GuiModConfig.java @@ -1,14 +1,17 @@ package com.gtnewhorizon.structurelib; -import cpw.mods.fml.client.config.GuiConfig; -import cpw.mods.fml.client.config.IConfigElement; import java.util.List; import java.util.stream.Collectors; + import net.minecraft.client.gui.GuiScreen; import net.minecraftforge.common.config.ConfigElement; import net.minecraftforge.common.config.Configuration; +import cpw.mods.fml.client.config.GuiConfig; +import cpw.mods.fml.client.config.IConfigElement; + public class GuiModConfig extends GuiConfig { + public GuiModConfig(GuiScreen guiScreen) { super( guiScreen, @@ -16,16 +19,13 @@ public class GuiModConfig extends GuiConfig { StructureLibAPI.MOD_ID, false, false, - GuiConfig.getAbridgedConfigPath( - ConfigurationHandler.INSTANCE.getConfig().toString())); + GuiConfig.getAbridgedConfigPath(ConfigurationHandler.INSTANCE.getConfig().toString())); } @SuppressWarnings("rawtypes") private static List getConfigElements() { final Configuration config = ConfigurationHandler.INSTANCE.getConfig(); - return config.getCategoryNames().stream() - .filter(name -> name.indexOf('.') == -1) - .map(name -> new ConfigElement(config.getCategory(name))) - .collect(Collectors.toList()); + return config.getCategoryNames().stream().filter(name -> name.indexOf('.') == -1) + .map(name -> new ConfigElement(config.getCategory(name))).collect(Collectors.toList()); } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/IStructureCompat.java b/src/main/java/com/gtnewhorizon/structurelib/IStructureCompat.java index 1ec15bbb..c1cb744d 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/IStructureCompat.java +++ b/src/main/java/com/gtnewhorizon/structurelib/IStructureCompat.java @@ -3,5 +3,6 @@ package com.gtnewhorizon.structurelib; import net.minecraft.util.IIcon; public interface IStructureCompat { + void markTextureUsed(IIcon o); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/StructureEvent.java b/src/main/java/com/gtnewhorizon/structurelib/StructureEvent.java index b555a69c..4c09825f 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/StructureEvent.java +++ b/src/main/java/com/gtnewhorizon/structurelib/StructureEvent.java @@ -1,9 +1,10 @@ package com.gtnewhorizon.structurelib; +import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; + import com.gtnewhorizon.structurelib.structure.IStructureElement; import cpw.mods.fml.common.eventhandler.Event; -import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; /** * Subscribers are required to not keep reference to these events, nor to depend on values of these events after @@ -12,10 +13,11 @@ import net.minecraftforge.common.MinecraftForge; * All of these events will be fired on the {@link net.minecraftforge.common.MinecraftForge#EVENT_BUS}, if they are * enabled by {@link StructureLibAPI#enableInstrument(Object)}. *

- * All public stuff in this class and its enclosed classes are considered part of the public API. - * Backwards compatibility is maintained to the maximum extend possible. + * All public stuff in this class and its enclosed classes are considered part of the public API. Backwards + * compatibility is maintained to the maximum extend possible. */ public abstract class StructureEvent extends Event { + /* * In case the event is passed to another thread for processing. */ @@ -35,20 +37,21 @@ public abstract class StructureEvent extends Event { * Fired just before any structure element is visited. */ public static final class StructureElementVisitedEvent extends StructureEvent { + private final World world; private final int x, y, z; private final int a, b, c; private final IStructureElement element; /** - * Fire this event on {@link MinecraftForge#EVENT_BUS} by populating it with given arguments. - * Do nothing if instrumenting isn't enabled for current thread. + * Fire this event on {@link MinecraftForge#EVENT_BUS} by populating it with given arguments. Do nothing if + * instrumenting isn't enabled for current thread. *

* Any {@link Exception} thrown by event listeners will be logged and ignored. {@link Error} will be propagated * as is. */ - public static void fireEvent( - World world, int x, int y, int z, int a, int b, int c, IStructureElement element) { + public static void fireEvent(World world, int x, int y, int z, int a, int b, int c, + IStructureElement element) { if (StructureLibAPI.isInstrumentEnabled()) { try { MinecraftForge.EVENT_BUS.post(new StructureElementVisitedEvent(world, x, y, z, a, b, c, element)); @@ -58,8 +61,8 @@ public abstract class StructureEvent extends Event { } } - StructureElementVisitedEvent( - World world, int x, int y, int z, int a, int b, int c, IStructureElement element) { + StructureElementVisitedEvent(World world, int x, int y, int z, int a, int b, int c, + IStructureElement element) { this.world = world; this.x = x; this.y = y; @@ -107,14 +110,22 @@ public abstract class StructureEvent extends Event { @Override public String toString() { return "StructureElementVisitedEvent{" + "a=" - + a + ", b=" - + b + ", c=" - + c + ", element=" - + element + ", world=" - + getWorld() + ", x=" - + getX() + ", y=" - + getY() + ", z=" - + getZ() + '}'; + + a + + ", b=" + + b + + ", c=" + + c + + ", element=" + + element + + ", world=" + + getWorld() + + ", x=" + + getX() + + ", y=" + + getY() + + ", z=" + + getZ() + + '}'; } /** diff --git a/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java b/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java index 20d9aac6..2269a7db 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java +++ b/src/main/java/com/gtnewhorizon/structurelib/StructureLib.java @@ -1,5 +1,15 @@ package com.gtnewhorizon.structurelib; +import net.minecraft.block.Block; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.launchwrapper.Launch; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import com.gtnewhorizon.structurelib.block.BlockHint; import com.gtnewhorizon.structurelib.command.CommandConfigureChannels; import com.gtnewhorizon.structurelib.item.ItemBlockHint; @@ -10,6 +20,7 @@ import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage; import com.gtnewhorizon.structurelib.net.SetChannelDataMessage; import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage; import com.gtnewhorizon.structurelib.util.XSTR; + import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; @@ -20,14 +31,6 @@ import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.block.Block; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; -import net.minecraft.launchwrapper.Launch; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; /** * This class does not contain a stable API. Refrain from using this class. @@ -39,6 +42,7 @@ import org.apache.logging.log4j.Logger; acceptableRemoteVersions = "*", guiFactory = "com.gtnewhorizon.structurelib.GuiFactory") public class StructureLib { + private static final String STRUCTURECOMPAT_MODID = "structurecompat"; public static boolean DEBUG_MODE; public static boolean PANIC_MODE = Boolean.getBoolean("structurelib.panic"); @@ -53,7 +57,10 @@ public class StructureLib { static { net.registerMessage( - AlignmentMessage.ServerHandler.class, AlignmentMessage.AlignmentQuery.class, 0, Side.SERVER); + AlignmentMessage.ServerHandler.class, + AlignmentMessage.AlignmentQuery.class, + 0, + Side.SERVER); net.registerMessage(AlignmentMessage.ClientHandler.class, AlignmentMessage.AlignmentData.class, 1, Side.CLIENT); net.registerMessage(UpdateHintParticleMessage.Handler.class, UpdateHintParticleMessage.class, 2, Side.CLIENT); net.registerMessage(SetChannelDataMessage.Handler.class, SetChannelDataMessage.class, 3, Side.SERVER); @@ -80,6 +87,7 @@ public class StructureLib { static Item itemFrontRotationTool; static Item itemConstructableTrigger; public static final CreativeTabs creativeTab = new CreativeTabs("structurelib") { + @Override @SideOnly(Side.CLIENT) public Item getTabIconItem() { @@ -93,7 +101,8 @@ public class StructureLib { GameRegistry.registerBlock(blockHint = new BlockHint(), ItemBlockHint.class, "blockhint"); itemBlockHint = ItemBlock.getItemFromBlock(StructureLibAPI.getBlockHint()); GameRegistry.registerItem( - itemFrontRotationTool = new ItemFrontRotationTool(), itemFrontRotationTool.getUnlocalizedName()); + itemFrontRotationTool = new ItemFrontRotationTool(), + itemFrontRotationTool.getUnlocalizedName()); GameRegistry.registerItem( itemConstructableTrigger = new ItemConstructableTrigger(), itemConstructableTrigger.getUnlocalizedName()); @@ -101,10 +110,7 @@ public class StructureLib { NetworkRegistry.INSTANCE.registerGuiHandler(instance(), new GuiHandler()); if (Loader.isModLoaded(STRUCTURECOMPAT_MODID)) { - COMPAT = Loader.instance() - .getIndexedModList() - .get(STRUCTURECOMPAT_MODID) - .getMod(); + COMPAT = Loader.instance().getIndexedModList().get(STRUCTURECOMPAT_MODID).getMod(); } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/StructureLibAPI.java b/src/main/java/com/gtnewhorizon/structurelib/StructureLibAPI.java index 0728af5b..aa1790ff 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/StructureLibAPI.java +++ b/src/main/java/com/gtnewhorizon/structurelib/StructureLibAPI.java @@ -2,13 +2,6 @@ package com.gtnewhorizon.structurelib; import static com.gtnewhorizon.structurelib.StructureLib.proxy; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.net.AlignmentMessage; -import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; -import com.gtnewhorizon.structurelib.structure.IStructureDefinition; -import cpw.mods.fml.common.network.NetworkRegistry; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -18,10 +11,20 @@ import net.minecraft.util.IChatComponent; import net.minecraft.util.IIcon; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.net.AlignmentMessage; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IStructureDefinition; +import cpw.mods.fml.common.network.NetworkRegistry; + /** - * A stable interface into the structure lib's internals. Backwards compatibility is maintained to the maximum extend possible. + * A stable interface into the structure lib's internals. Backwards compatibility is maintained to the maximum extend + * possible. */ public class StructureLibAPI { + public static final String MOD_ID = "structurelib"; public static final int HINT_BLOCK_META_GENERIC_0 = 0; public static final int HINT_BLOCK_META_GENERIC_1 = 1; @@ -47,12 +50,13 @@ public class StructureLibAPI { * appropriate. Otherwise, these events will not be sent at all, regardless of whether a listener for these events * are registered. *

- * Identifiers are required to be value-comparable, i.e. overrides {@link Object#equals(Object)}. - * Suggested identifier includes + * Identifiers are required to be value-comparable, i.e. overrides {@link Object#equals(Object)}. Suggested + * identifier includes *

    - *
  • Mod Instance or {@link cpw.mods.fml.common.ModContainer}
  • - *
  • {@link com.gtnewhorizon.structurelib.alignment.constructable.IConstructable} and its friends, if you are triggering structure check via this interface.
  • - *
  • {@link net.minecraft.util.ResourceLocation}
  • + *
  • Mod Instance or {@link cpw.mods.fml.common.ModContainer}
  • + *
  • {@link com.gtnewhorizon.structurelib.alignment.constructable.IConstructable} and its friends, if you are + * triggering structure check via this interface.
  • + *
  • {@link net.minecraft.util.ResourceLocation}
  • *
*

* It's an API abuse for normal {@link IStructureDefinition} users to depend on this feature. They have full control @@ -82,6 +86,7 @@ public class StructureLibAPI { /** * Check if instrumenting is enabled. + * * @return true if enabled, false otherwise */ public static boolean isInstrumentEnabled() { @@ -89,18 +94,22 @@ public class StructureLibAPI { } /** - * Start a batch of hinting. All hints particles generated during one batch will be considered to belong to one hologram. + * Start a batch of hinting. All hints particles generated during one batch will be considered to belong to one + * hologram. *

- * You don't need to call this unless your constructable tool didn't call {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)} + * You don't need to call this unless your constructable tool didn't call + * {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)} */ public static void startHinting(World w) { proxy.startHinting(w); } /** - * End current batch of hinting. All hints particles generated during one batch will be considered to belong to one hologram. + * End current batch of hinting. All hints particles generated during one batch will be considered to belong to one + * hologram. *

- * You don't need to call this unless your constructable tool didn't call {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)} + * You don't need to call this unless your constructable tool didn't call + * {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)} */ public static void endHinting(World w) { proxy.endHinting(w); @@ -114,7 +123,8 @@ public class StructureLibAPI { * @param y y coord * @param z z coord * @param icons 6 texture. in forge direction order. - * @param RGBa a 4 short array. tint in rgba form. currently alpha channel is ignored, but we might change this later on. + * @param RGBa a 4 short array. tint in rgba form. currently alpha channel is ignored, but we might change this + * later on. */ public static void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) { proxy.hintParticleTinted(w, x, y, z, icons, RGBa); @@ -129,7 +139,8 @@ public class StructureLibAPI { * @param z z coord * @param block block to take texture from * @param meta the meta of block to take texture from - * @param RGBa a 4 short array. tint in rgba form. currently alpha channel is ignored, but we might change this later on. + * @param RGBa a 4 short array. tint in rgba form. currently alpha channel is ignored, but we might change this + * later on. */ public static void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) { proxy.hintParticleTinted(w, x, y, z, block, meta, RGBa); @@ -165,9 +176,8 @@ public class StructureLibAPI { /** * Update the tint of given hint particle. Do nothing if particle not found. *

- * Can be called on either client side or server side. - * Server side will schedule a network message to update it for this player only. - * Will do nothing if no hint particle is found at given location. + * Can be called on either client side or server side. Server side will schedule a network message to update it for + * this player only. Will do nothing if no hint particle is found at given location. * * @return false if nothing updated. true if updated or update instruction sent. */ @@ -185,11 +195,13 @@ public class StructureLibAPI { } /** - * Query the ExtendedFacing of this tile entity from client side. Can be sent only on client side. - * The ExtendedFacing will later be set onto given tile entity via {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} - * upon arrival of server reply. + * Query the ExtendedFacing of this tile entity from client side. Can be sent only on client side. The + * ExtendedFacing will later be set onto given tile entity via + * {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} upon arrival of + * server reply. *

- * The server side will query the {@link ExtendedFacing} of this provider using {@link IAlignment#getExtendedFacing()} + * The server side will query the {@link ExtendedFacing} of this provider using + * {@link IAlignment#getExtendedFacing()} * * @throws IllegalArgumentException if is not tile entity or provided a null alignment */ @@ -200,7 +212,8 @@ public class StructureLibAPI { /** * Send the ExtendedFacing of this Tile Entity to all players. Can be called on server side only. *

- * The receiving tile entity will receive the {@link ExtendedFacing} via its {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. + * The receiving tile entity will receive the {@link ExtendedFacing} via its + * {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. * * @throws IllegalArgumentException if is not tile entity or provided a null alignment */ @@ -211,7 +224,8 @@ public class StructureLibAPI { /** * Send the ExtendedFacing of this Tile Entity to given player. Can be called on server side only. *

- * The receiving tile entity will receive the {@link ExtendedFacing} via its {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. + * The receiving tile entity will receive the {@link ExtendedFacing} via its + * {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. * * @throws IllegalArgumentException if is not tile entity or provided a null alignment */ @@ -220,9 +234,11 @@ public class StructureLibAPI { } /** - * Send the ExtendedFacing of this Tile Entity to all players around target point. Can be called on server side only. + * Send the ExtendedFacing of this Tile Entity to all players around target point. Can be called on server side + * only. *

- * The receiving tile entity will receive the {@link ExtendedFacing} via its {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. + * The receiving tile entity will receive the {@link ExtendedFacing} via its + * {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. * * @throws IllegalArgumentException if is not tile entity or provided a null alignment */ @@ -233,7 +249,8 @@ public class StructureLibAPI { /** * Send the ExtendedFacing of this Tile Entity to all players in that dimension. Can be called on server side only. *

- * The receiving tile entity will receive the {@link ExtendedFacing} via its {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. + * The receiving tile entity will receive the {@link ExtendedFacing} via its + * {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} method. * * @throws IllegalArgumentException if is not tile entity or provided a null alignment */ @@ -269,10 +286,11 @@ public class StructureLibAPI { } /** - * Determines if given block can be replaced without much effort. The exact predicate clauses is not stable and - * will be changed, but the general idea will always stay the same. + * Determines if given block can be replaced without much effort. The exact predicate clauses is not stable and will + * be changed, but the general idea will always stay the same. *

- * Use this in your {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} + * Use this in your + * {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} */ @Deprecated public static boolean isBlockTriviallyReplaceable(World w, int x, int y, int z, EntityPlayerMP actor) { @@ -280,10 +298,11 @@ public class StructureLibAPI { } /** - * Determines if given block can be replaced without much effort. The exact predicate clauses is not stable and - * will be changed, but the general idea will always stay the same. + * Determines if given block can be replaced without much effort. The exact predicate clauses is not stable and will + * be changed, but the general idea will always stay the same. *

- * Use this in your {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} + * Use this in your + * {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} */ public static boolean isBlockTriviallyReplaceable(World w, int x, int y, int z, EntityPlayer actor) { // TODO extend this function a bit @@ -294,35 +313,33 @@ public class StructureLibAPI { /** * Send chat to player, but throttled. * - * @param throttleKey throttle key. Must properly implement {@link Object#hashCode()} and {@link Object#equals(Object)} - * to handle value equality. + * @param throttleKey throttle key. Must properly implement {@link Object#hashCode()} and + * {@link Object#equals(Object)} to handle value equality. * @param player player to send chat to * @param text chat to send - * @param intervalRequired interval required before last recorded time to actually send the message. unit in millisecond. - * we purposefully chose to not use a bigger data type to limit how long this interval can be + * @param intervalRequired interval required before last recorded time to actually send the message. unit in + * millisecond. we purposefully chose to not use a bigger data type to limit how long this + * interval can be */ - public static void addThrottledChat( - Object throttleKey, EntityPlayer player, IChatComponent text, short intervalRequired) { + public static void addThrottledChat(Object throttleKey, EntityPlayer player, IChatComponent text, + short intervalRequired) { addThrottledChat(throttleKey, player, text, intervalRequired, false); } /** * Send chat to player, but throttled. * - * @param throttleKey throttle key. Must properly implement {@link Object#hashCode()} and {@link Object#equals(Object)} - * to handle value equality. + * @param throttleKey throttle key. Must properly implement {@link Object#hashCode()} and + * {@link Object#equals(Object)} to handle value equality. * @param player player to send chat to * @param text chat to send - * @param intervalRequired interval required before last recorded time to actually send the message. unit in millisecond. - * we purposefully chose to not use a bigger data type to limit how long this interval can be + * @param intervalRequired interval required before last recorded time to actually send the message. unit in + * millisecond. we purposefully chose to not use a bigger data type to limit how long + * this interval can be * @param forceUpdateLastSend if true, always update the last send time, even if the message isn't actually sent. */ - public static void addThrottledChat( - Object throttleKey, - EntityPlayer player, - IChatComponent text, - short intervalRequired, - boolean forceUpdateLastSend) { + public static void addThrottledChat(Object throttleKey, EntityPlayer player, IChatComponent text, + short intervalRequired, boolean forceUpdateLastSend) { proxy.addThrottledChat(throttleKey, player, text, intervalRequired, forceUpdateLastSend); } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java index 3ffbf05a..cf24d8c3 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java @@ -1,8 +1,9 @@ package com.gtnewhorizon.structurelib.alignment; +import net.minecraftforge.common.util.ForgeDirection; + import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; -import net.minecraftforge.common.util.ForgeDirection; class AlignmentLimits implements IAlignmentLimits { diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentUtility.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentUtility.java index 7a50c04c..cf11a3d2 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentUtility.java @@ -7,6 +7,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; public class AlignmentUtility { + private AlignmentUtility() {} public static boolean handle(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ) { diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignment.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignment.java index 1f9349b0..b7f13f58 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignment.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignment.java @@ -1,12 +1,14 @@ package com.gtnewhorizon.structurelib.alignment; +import net.minecraftforge.common.util.ForgeDirection; + import com.gtnewhorizon.structurelib.alignment.enumerable.Direction; import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; -import net.minecraftforge.common.util.ForgeDirection; public interface IAlignment extends IAlignmentLimits, IAlignmentProvider { + int DIRECTIONS_COUNT = Direction.VALUES.length; int ROTATIONS_COUNT = Rotation.VALUES.length; int FLIPS_COUNT = Flip.VALUES.length; @@ -15,8 +17,8 @@ public interface IAlignment extends IAlignmentLimits, IAlignmentProvider { ExtendedFacing getExtendedFacing(); /** - * Set the facing without additional checks. - * Tools altering facing should use {@link #toolSetExtendedFacing(ExtendedFacing)} instead. + * Set the facing without additional checks. Tools altering facing should use + * {@link #toolSetExtendedFacing(ExtendedFacing)} instead. */ void setExtendedFacing(ExtendedFacing alignment); @@ -57,9 +59,8 @@ public interface IAlignment extends IAlignmentLimits, IAlignmentProvider { default boolean toolSetDirection(ForgeDirection direction) { if (direction == null || direction == ForgeDirection.UNKNOWN) { - for (int i = 0, j = getDirection().ordinal() + 1, valuesLength = Direction.VALUES.length; - i < valuesLength; - i++) { + for (int i = 0, j = getDirection().ordinal() + 1, valuesLength = Direction.VALUES.length; i + < valuesLength; i++) { if (toolSetDirection(Direction.VALUES[(j + i) % valuesLength].getForgeDirection())) { return true; } @@ -97,8 +98,11 @@ public interface IAlignment extends IAlignmentLimits, IAlignmentProvider { int rotations = Rotation.VALUES.length; for (int ii = 0, jj = getFlip().ordinal(); ii < flips; ii++) { for (int i = 1, j = getRotation().ordinal(); i < rotations; i++) { - if (checkedSetExtendedFacing(ExtendedFacing.of( - getDirection(), Rotation.VALUES[(j + i) % rotations], Flip.VALUES[(jj + ii) % flips]))) { + if (checkedSetExtendedFacing( + ExtendedFacing.of( + getDirection(), + Rotation.VALUES[(j + i) % rotations], + Flip.VALUES[(jj + ii) % flips]))) { return true; } } @@ -140,9 +144,8 @@ public interface IAlignment extends IAlignmentLimits, IAlignmentProvider { default boolean toolSetExtendedFacing(ExtendedFacing extendedFacing) { if (extendedFacing == null) { - for (int i = 0, j = getExtendedFacing().ordinal() + 1, valuesLength = ExtendedFacing.VALUES.length; - i < valuesLength; - i++) { + for (int i = 0, j = getExtendedFacing().ordinal() + 1, valuesLength = ExtendedFacing.VALUES.length; i + < valuesLength; i++) { if (checkedSetExtendedFacing(ExtendedFacing.VALUES[(j + i) % valuesLength])) { return true; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java index b616eeb0..4cefb739 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java @@ -2,14 +2,16 @@ package com.gtnewhorizon.structurelib.alignment; import static com.gtnewhorizon.structurelib.alignment.IAlignment.STATES_COUNT; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; -import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import java.util.Arrays; import java.util.Optional; import java.util.function.Function; + import net.minecraftforge.common.util.ForgeDirection; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; +import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; + public interface IAlignmentLimits { IAlignmentLimits UNLIMITED = (direction, rotation, flip) -> true; @@ -37,6 +39,7 @@ public interface IAlignmentLimits { } class Builder { + protected final boolean[] validStates = new boolean[STATES_COUNT]; private Builder() {} @@ -54,15 +57,13 @@ public interface IAlignmentLimits { } public Builder deny(ForgeDirection fd) { - ExtendedFacing.getAllWith(fd).stream() - .mapToInt(ExtendedFacing::getIndex) + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex) .forEach(v -> validStates[v] = false); return this; } public Builder allow(ForgeDirection fd) { - ExtendedFacing.getAllWith(fd).stream() - .mapToInt(ExtendedFacing::getIndex) + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex) .forEach(v -> validStates[v] = true); return this; } @@ -78,29 +79,25 @@ public interface IAlignmentLimits { } public Builder deny(Rotation fd) { - ExtendedFacing.getAllWith(fd).stream() - .mapToInt(ExtendedFacing::getIndex) + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex) .forEach(v -> validStates[v] = false); return this; } public Builder allow(Rotation fd) { - ExtendedFacing.getAllWith(fd).stream() - .mapToInt(ExtendedFacing::getIndex) + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex) .forEach(v -> validStates[v] = true); return this; } public Builder deny(Flip fd) { - ExtendedFacing.getAllWith(fd).stream() - .mapToInt(ExtendedFacing::getIndex) + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex) .forEach(v -> validStates[v] = false); return this; } public Builder allow(Flip fd) { - ExtendedFacing.getAllWith(fd).stream() - .mapToInt(ExtendedFacing::getIndex) + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex) .forEach(v -> validStates[v] = true); return this; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentProvider.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentProvider.java index df3d355e..f7439c35 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentProvider.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentProvider.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.alignment; import javax.annotation.Nullable; public interface IAlignmentProvider { + @Nullable IAlignment getAlignment(); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/IntegerAxisSwap.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/IntegerAxisSwap.java index 2619c746..526ba1f1 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/IntegerAxisSwap.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/IntegerAxisSwap.java @@ -2,12 +2,14 @@ package com.gtnewhorizon.structurelib.alignment; import static java.lang.Math.abs; -import com.gtnewhorizon.structurelib.alignment.enumerable.Direction; -import com.gtnewhorizon.structurelib.util.Vec3Impl; import net.minecraft.util.Vec3; import net.minecraftforge.common.util.ForgeDirection; +import com.gtnewhorizon.structurelib.alignment.enumerable.Direction; +import com.gtnewhorizon.structurelib.util.Vec3Impl; + public class IntegerAxisSwap { + private final Vec3Impl forFirstAxis; private final Vec3Impl forSecondAxis; private final Vec3Impl forThirdAxis; @@ -20,61 +22,49 @@ public class IntegerAxisSwap { || abs(this.forFirstAxis.get1()) + abs(this.forSecondAxis.get1()) + abs(this.forThirdAxis.get1()) != 1 || abs(this.forFirstAxis.get2()) + abs(this.forSecondAxis.get2()) + abs(this.forThirdAxis.get2()) != 1) { - throw new IllegalArgumentException("Axis are overlapping/missing! " + forFirstAxis.name() - + " " + forSecondAxis.name() - + " " + forThirdAxis.name()); + throw new IllegalArgumentException( + "Axis are overlapping/missing! " + forFirstAxis + .name() + " " + forSecondAxis.name() + " " + forThirdAxis.name()); } } public Vec3Impl translate(Vec3Impl point) { return new Vec3Impl( - forFirstAxis.get0() * point.get0() - + forFirstAxis.get1() * point.get1() + forFirstAxis.get0() * point.get0() + forFirstAxis.get1() * point.get1() + forFirstAxis.get2() * point.get2(), - forSecondAxis.get0() * point.get0() - + forSecondAxis.get1() * point.get1() + forSecondAxis.get0() * point.get0() + forSecondAxis.get1() * point.get1() + forSecondAxis.get2() * point.get2(), - forThirdAxis.get0() * point.get0() - + forThirdAxis.get1() * point.get1() + forThirdAxis.get0() * point.get0() + forThirdAxis.get1() * point.get1() + forThirdAxis.get2() * point.get2()); } public Vec3Impl inverseTranslate(Vec3Impl point) { return new Vec3Impl( - forFirstAxis.get0() * point.get0() - + forSecondAxis.get0() * point.get1() + forFirstAxis.get0() * point.get0() + forSecondAxis.get0() * point.get1() + forThirdAxis.get0() * point.get2(), - forFirstAxis.get1() * point.get0() - + forSecondAxis.get1() * point.get1() + forFirstAxis.get1() * point.get0() + forSecondAxis.get1() * point.get1() + forThirdAxis.get1() * point.get2(), - forFirstAxis.get2() * point.get0() - + forSecondAxis.get2() * point.get1() + forFirstAxis.get2() * point.get0() + forSecondAxis.get2() * point.get1() + forThirdAxis.get2() * point.get2()); } public Vec3 translate(Vec3 point) { return Vec3.createVectorHelper( - forFirstAxis.get0() * point.xCoord - + forFirstAxis.get1() * point.yCoord + forFirstAxis.get0() * point.xCoord + forFirstAxis.get1() * point.yCoord + forFirstAxis.get2() * point.zCoord, - forSecondAxis.get0() * point.xCoord - + forSecondAxis.get1() * point.yCoord + forSecondAxis.get0() * point.xCoord + forSecondAxis.get1() * point.yCoord + forSecondAxis.get2() * point.zCoord, - forThirdAxis.get0() * point.xCoord - + forThirdAxis.get1() * point.yCoord + forThirdAxis.get0() * point.xCoord + forThirdAxis.get1() * point.yCoord + forThirdAxis.get2() * point.zCoord); } public Vec3 inverseTranslate(Vec3 point) { return Vec3.createVectorHelper( - forFirstAxis.get0() * point.xCoord - + forSecondAxis.get0() * point.yCoord + forFirstAxis.get0() * point.xCoord + forSecondAxis.get0() * point.yCoord + forThirdAxis.get0() * point.zCoord, - forFirstAxis.get1() * point.xCoord - + forSecondAxis.get1() * point.yCoord + forFirstAxis.get1() * point.xCoord + forSecondAxis.get1() * point.yCoord + forThirdAxis.get1() * point.zCoord, - forFirstAxis.get2() * point.xCoord - + forSecondAxis.get2() * point.yCoord + forFirstAxis.get2() * point.xCoord + forSecondAxis.get2() * point.yCoord + forThirdAxis.get2() * point.zCoord); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java index 9d1ea2d1..d7d34784 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java @@ -3,23 +3,27 @@ package com.gtnewhorizon.structurelib.alignment.constructable; import static com.gtnewhorizon.structurelib.util.MiscUtils.getTagKeys; import static net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND; -import com.gtnewhorizon.structurelib.StructureLibAPI; import java.util.Locale; import java.util.Map.Entry; import java.util.stream.Stream; + import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.Constants.NBT; + import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import com.gtnewhorizon.structurelib.StructureLibAPI; + /** * Provide accessor methods for channel data from trigger item. * * Channels section on overview */ public class ChannelDataAccessor { + private static final String SECONDARY_HINT_TAG = "channels"; private ChannelDataAccessor() {} @@ -27,29 +31,25 @@ public class ChannelDataAccessor { /** * Return a trigger item that *

    - *
  • Still carry all the subchannel in some unspecified ways
  • - *
  • Have its master channel data replaced with specified subchannel's data
  • + *
  • Still carry all the subchannel in some unspecified ways
  • + *
  • Have its master channel data replaced with specified subchannel's data
  • *
* - * If given subchannel does not exist, masterStack may or may not be returned to save performance. - * Code within StructureLib can depend on this behavior, you cannot. + * If given subchannel does not exist, masterStack may or may not be returned to save performance. Code within + * StructureLib can depend on this behavior, you cannot. * * @param masterStack trigger item. can be the return value of another {@link #withChannel(ItemStack, String)} call - * @param channel subchannel to use. will use current master channel data instead if this channel does not exist - * Note: all channel identifiers are supposed to be lower case and not empty. + * @param channel subchannel to use. will use current master channel data instead if this channel does not exist + * Note: all channel identifiers are supposed to be lower case and not empty. * @return a trigger item with new master channel */ public static ItemStack withChannel(ItemStack masterStack, String channel) { if (StringUtils.isEmpty(channel) || masterStack == null) throw new IllegalArgumentException(); - if (StructureLibAPI.isDebugEnabled() - && !channel.toLowerCase(Locale.ROOT).equals(channel)) + if (StructureLibAPI.isDebugEnabled() && !channel.toLowerCase(Locale.ROOT).equals(channel)) throw new IllegalArgumentException("Channel name can be lower case ONLY"); - if (!masterStack.hasTagCompound() - || !masterStack.stackTagCompound.hasKey(SECONDARY_HINT_TAG, TAG_COMPOUND) - || !masterStack - .stackTagCompound - .getCompoundTag(SECONDARY_HINT_TAG) - .hasKey(channel, NBT.TAG_INT)) return masterStack; + if (!masterStack.hasTagCompound() || !masterStack.stackTagCompound.hasKey(SECONDARY_HINT_TAG, TAG_COMPOUND) + || !masterStack.stackTagCompound.getCompoundTag(SECONDARY_HINT_TAG).hasKey(channel, NBT.TAG_INT)) + return masterStack; ItemStack ret = new ItemStack( masterStack.getItem(), masterStack.stackTagCompound.getCompoundTag(SECONDARY_HINT_TAG).getInteger(channel), @@ -60,6 +60,7 @@ public class ChannelDataAccessor { /** * Check if given trigger item contains any subchannel + * * @param masterStack trigger stack to check * @return true if contains any subchannel */ @@ -70,57 +71,47 @@ public class ChannelDataAccessor { /** * Check if given trigger item contains specified subchannel + * * @param masterStack trigger stack to check - * @param channel channel identifier. - * Note: all channel identifiers are supposed to be lower case and not empty. + * @param channel channel identifier. Note: all channel identifiers are supposed to be lower case and not empty. * @return true if contains specified subchannel */ public static boolean hasSubChannel(ItemStack masterStack, String channel) { if (StringUtils.isEmpty(channel) || masterStack == null) throw new IllegalArgumentException(); - if (StructureLibAPI.isDebugEnabled() - && !channel.toLowerCase(Locale.ROOT).equals(channel)) + if (StructureLibAPI.isDebugEnabled() && !channel.toLowerCase(Locale.ROOT).equals(channel)) throw new IllegalArgumentException("Channel name can be lower case ONLY"); - return !channel.isEmpty() - && masterStack.hasTagCompound() + return !channel.isEmpty() && masterStack.hasTagCompound() && masterStack.stackTagCompound.hasKey(SECONDARY_HINT_TAG, TAG_COMPOUND) - && masterStack - .stackTagCompound - .getCompoundTag(SECONDARY_HINT_TAG) - .hasKey(channel, NBT.TAG_INT); + && masterStack.stackTagCompound.getCompoundTag(SECONDARY_HINT_TAG).hasKey(channel, NBT.TAG_INT); } /** * Get the subchannel data from given trigger item. Will use master channel instead if not present. + * * @param masterStack trigger stack to query from - * @param channel channel identifier. - * Note: all channel identifiers are supposed to be lower case and not empty. + * @param channel channel identifier. Note: all channel identifiers are supposed to be lower case and not empty. * @return channel data */ public static int getChannelData(ItemStack masterStack, String channel) { if (StringUtils.isEmpty(channel) || masterStack == null) throw new IllegalArgumentException(); - if (StructureLibAPI.isDebugEnabled() - && !channel.toLowerCase(Locale.ROOT).equals(channel)) + if (StructureLibAPI.isDebugEnabled() && !channel.toLowerCase(Locale.ROOT).equals(channel)) throw new IllegalArgumentException("Channel name can be lower case ONLY"); - if (!masterStack.hasTagCompound() - || !masterStack.stackTagCompound.hasKey(SECONDARY_HINT_TAG, TAG_COMPOUND) - || !masterStack - .stackTagCompound - .getCompoundTag(SECONDARY_HINT_TAG) - .hasKey(channel, NBT.TAG_INT)) return masterStack.stackSize; + if (!masterStack.hasTagCompound() || !masterStack.stackTagCompound.hasKey(SECONDARY_HINT_TAG, TAG_COMPOUND) + || !masterStack.stackTagCompound.getCompoundTag(SECONDARY_HINT_TAG).hasKey(channel, NBT.TAG_INT)) + return masterStack.stackSize; return masterStack.stackTagCompound.getCompoundTag(SECONDARY_HINT_TAG).getInteger(channel); } /** * Set the subchannel data on given trigger item + * * @param masterStack trigger stack to check - * @param channel channel identifier. - * Note: all channel identifiers are supposed to be lower case and not empty. - * @param data subchannel data. should always be a positive value + * @param channel channel identifier. Note: all channel identifiers are supposed to be lower case and not empty. + * @param data subchannel data. should always be a positive value */ public static void setChannelData(ItemStack masterStack, String channel, int data) { if (StringUtils.isEmpty(channel) || masterStack == null) throw new IllegalArgumentException(); - if (StructureLibAPI.isDebugEnabled() - && !channel.toLowerCase(Locale.ROOT).equals(channel)) + if (StructureLibAPI.isDebugEnabled() && !channel.toLowerCase(Locale.ROOT).equals(channel)) throw new IllegalArgumentException("Channel name can be lower case ONLY"); if (data <= 0) throw new IllegalArgumentException(); if (masterStack.stackTagCompound == null) masterStack.stackTagCompound = new NBTTagCompound(); @@ -131,14 +122,13 @@ public class ChannelDataAccessor { /** * Clear the given subchannel from given trigger item, if it exists + * * @param masterStack trigger stack to unset - * @param channel channel identifier. - * Note: all channel identifiers are supposed to be lower case and not empty. + * @param channel channel identifier. Note: all channel identifiers are supposed to be lower case and not empty. */ public static void unsetChannelData(ItemStack masterStack, String channel) { if (StringUtils.isEmpty(channel) || masterStack == null) throw new IllegalArgumentException(); - if (StructureLibAPI.isDebugEnabled() - && !channel.toLowerCase(Locale.ROOT).equals(channel)) + if (StructureLibAPI.isDebugEnabled() && !channel.toLowerCase(Locale.ROOT).equals(channel)) throw new IllegalArgumentException("Channel name can be lower case ONLY"); if (masterStack.stackTagCompound == null) masterStack.stackTagCompound = new NBTTagCompound(); NBTTagCompound main = masterStack.stackTagCompound; @@ -151,6 +141,7 @@ public class ChannelDataAccessor { /** * Wipe all subchannel data on given trigger item + * * @param masterStack trigger stack to wipe */ public static void wipeChannelData(ItemStack masterStack) { @@ -160,10 +151,11 @@ public class ChannelDataAccessor { /** * Iterate over all subchannel data on trigger stack. Does not include master channel!! + * * @param masterStack trigger stack to check * @return A java8 stream of pairs. Key is channel identifier and value is channel data. Pairs do not support - * mutation nor removal. Can still cause {@link java.util.ConcurrentModificationException} if underlying channel - * data is modified while stream is working. + * mutation nor removal. Can still cause {@link java.util.ConcurrentModificationException} if underlying + * channel data is modified while stream is working. */ public static Stream> iterateChannelData(ItemStack masterStack) { if (!hasSubChannel(masterStack)) return Stream.empty(); @@ -173,6 +165,7 @@ public class ChannelDataAccessor { /** * Get the number of subchannels present on given trigger item. Does not include master channel. + * * @param masterStack trigger stack to query from * @return subchannel count */ 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 d4f9e0f7..92bd596f 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java @@ -1,13 +1,7 @@ package com.gtnewhorizon.structurelib.alignment.constructable; -import com.gtnewhorizon.structurelib.ConfigurationHandler; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.structure.IItemSource; -import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import java.util.WeakHashMap; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; @@ -17,6 +11,14 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.ForgeDirection; +import com.gtnewhorizon.structurelib.ConfigurationHandler; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; + public class ConstructableUtility { private static final WeakHashMap lastUse = new WeakHashMap<>(); @@ -24,16 +26,16 @@ public class ConstructableUtility { private ConstructableUtility() {} - public static boolean handle( - ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, int aSide) { + public static boolean handle(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + int aSide) { StructureLibAPI.startHinting(aWorld); boolean ret = handle0(aStack, aPlayer, aWorld, aX, aY, aZ, aSide); StructureLibAPI.endHinting(aWorld); return ret; } - private static boolean handle0( - ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, int aSide) { + private static boolean handle0(ItemStack aStack, EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ, + int aSide) { TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ); if (tTileEntity == null || aPlayer instanceof FakePlayer) { return aPlayer instanceof EntityPlayerMP; @@ -44,9 +46,10 @@ public class ConstructableUtility { long timePast = System.currentTimeMillis() - getLastUseMilis(aPlayer); if (timePast < ConfigurationHandler.INSTANCE.getAutoPlaceInterval()) { - aPlayer.addChatComponentMessage(new ChatComponentTranslation( - "item.structurelib.constructableTrigger.too_fast", - ConfigurationHandler.INSTANCE.getAutoPlaceInterval() - timePast)); + aPlayer.addChatComponentMessage( + new ChatComponentTranslation( + "item.structurelib.constructableTrigger.too_fast", + ConfigurationHandler.INSTANCE.getAutoPlaceInterval() - timePast)); return true; } } else if (!StructureLib.isCurrentPlayer(aPlayer)) { @@ -59,8 +62,7 @@ public class ConstructableUtility { else if (tTileEntity instanceof IConstructable) { constructable = (IConstructable) tTileEntity; } else if (IMultiblockInfoContainer.contains(tTileEntity.getClass())) { - ExtendedFacing facing = tTileEntity instanceof IAlignment - ? ((IAlignment) tTileEntity).getExtendedFacing() + ExtendedFacing facing = tTileEntity instanceof IAlignment ? ((IAlignment) tTileEntity).getExtendedFacing() : ExtendedFacing.of(ForgeDirection.getOrientation(aSide)); constructable = IMultiblockInfoContainer.get(tTileEntity.getClass()) .toConstructable(tTileEntity, facing); @@ -75,11 +77,10 @@ public class ConstructableUtility { if (aPlayer.capabilities.isCreativeMode) { constructable.construct(aStack, false); } else if (constructable instanceof ISurvivalConstructable) { - int built = ((ISurvivalConstructable) constructable) - .survivalConstruct( - aStack, - ConfigurationHandler.INSTANCE.getAutoPlaceBudget(), - ISurvivalBuildEnvironment.create(IItemSource.fromPlayer(playerMP), playerMP)); + int built = ((ISurvivalConstructable) constructable).survivalConstruct( + aStack, + ConfigurationHandler.INSTANCE.getAutoPlaceBudget(), + ISurvivalBuildEnvironment.create(IItemSource.fromPlayer(playerMP), playerMP)); if (built > 0) { playerMP.addChatMessage(new ChatComponentTranslation("structurelib.autoplace.built_stat", built)); } else if (built == -1) { diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructable.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructable.java index 37751d9b..29010704 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructable.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructable.java @@ -1,14 +1,17 @@ package com.gtnewhorizon.structurelib.alignment.constructable; +import net.minecraft.item.ItemStack; + import com.gtnewhorizon.structurelib.structure.IStructureDefinition; + import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import net.minecraft.item.ItemStack; /** * Created by Tec on 24.03.2017. */ public interface IConstructable { + void construct(ItemStack stackSize, boolean hintsOnly); /** diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructableProvider.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructableProvider.java index 5e58b11c..0f263608 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructableProvider.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IConstructableProvider.java @@ -6,6 +6,7 @@ import javax.annotation.Nullable; * Implement this interface if this tile entity MIGHT be constructable */ public interface IConstructableProvider { + /** * @return null if not constructable, an instance otherwise. */ diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IMultiblockInfoContainer.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IMultiblockInfoContainer.java index d93d2e2e..39ab7c08 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IMultiblockInfoContainer.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/IMultiblockInfoContainer.java @@ -1,19 +1,23 @@ package com.gtnewhorizon.structurelib.alignment.constructable; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.structure.IItemSource; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import java.util.HashMap; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.structure.IItemSource; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + /** * To implement IConstructable on not own TileEntities */ public interface IMultiblockInfoContainer { + HashMap> MULTIBLOCK_MAP = new HashMap<>(); /** @@ -36,16 +40,13 @@ public interface IMultiblockInfoContainer { void construct(ItemStack stackSize, boolean hintsOnly, T tileEntity, ExtendedFacing aSide); /** - * Construct the structure using {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, java.util.function.Consumer)} + * Construct the structure using + * {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, java.util.function.Consumer)} + * * @return -1 if done, a helping pointer */ - default int survivalConstruct( - ItemStack stackSize, - int elementBudge, - IItemSource source, - EntityPlayerMP actorProfile, - T tileEntity, - ExtendedFacing aSide) { + default int survivalConstruct(ItemStack stackSize, int elementBudge, IItemSource source, + EntityPlayerMP actorProfile, T tileEntity, ExtendedFacing aSide) { return -1; } @@ -58,6 +59,7 @@ public interface IMultiblockInfoContainer { */ default IConstructable toConstructable(T tileEntity, ExtendedFacing aSide) { return new IConstructable() { + @Override public void construct(ItemStack stackSize, boolean hintsOnly) { IMultiblockInfoContainer.this.construct(stackSize, hintsOnly, tileEntity, aSide); @@ -70,12 +72,13 @@ public interface IMultiblockInfoContainer { }; } - static ISurvivalConstructable toConstructable( - IMultiblockInfoContainer thiz, T tileEntity, ExtendedFacing aSide) { + static ISurvivalConstructable toConstructable(IMultiblockInfoContainer thiz, T tileEntity, + ExtendedFacing aSide) { return new ISurvivalConstructable() { + @Override - public int survivalConstruct( - ItemStack stackSize, int elementBudget, IItemSource source, EntityPlayerMP actor) { + public int survivalConstruct(ItemStack stackSize, int elementBudget, IItemSource source, + EntityPlayerMP actor) { return thiz.survivalConstruct(stackSize, elementBudget, source, actor, tileEntity, aSide); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ISurvivalConstructable.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ISurvivalConstructable.java index 3ad6ca7b..c2556874 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ISurvivalConstructable.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ISurvivalConstructable.java @@ -1,31 +1,35 @@ package com.gtnewhorizon.structurelib.alignment.constructable; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; -import com.gtnewhorizon.structurelib.structure.IItemSource; -import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; +import com.gtnewhorizon.structurelib.structure.AutoPlaceEnvironment; +import com.gtnewhorizon.structurelib.structure.IItemSource; +import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; + /** - * An extension to {@link IConstructable}. Tile Entities (or delegates returned by {@link IConstructableProvider#getConstructable()} - * should implement this interface to allow third party tools and StructureLib builtin constructable tools to trigger - * autoplace in survival mode. + * An extension to {@link IConstructable}. Tile Entities (or delegates returned by + * {@link IConstructableProvider#getConstructable()} should implement this interface to allow third party tools and + * StructureLib builtin constructable tools to trigger autoplace in survival mode. *

* While not originally planned, a creative player can also use this interface to trigger autoplace by using an * {@link IItemSource} with every possible items in the game. */ public interface ISurvivalConstructable extends IConstructable { + /** * End player might want to disable this hack if it turns out to be too crashy */ boolean DISABLE_HACKY_MIGRATION_CODE = Boolean.getBoolean("structurelib.disable_isc_migration_hack"); /** - * Construct the structure using {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, java.util.function.Consumer)} - * or {@link com.gtnewhorizon.structurelib.structure.IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, IItemSource, EntityPlayerMP, boolean)} + * Construct the structure using + * {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, java.util.function.Consumer)} + * or + * {@link com.gtnewhorizon.structurelib.structure.IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, IItemSource, EntityPlayerMP, boolean)} * * @param elementBudget The server configured element budget. The implementor can choose to tune this up a bit if * the structure is too big, but generally should not be a 4 digits number to not overwhelm the @@ -38,14 +42,16 @@ public interface ISurvivalConstructable extends IConstructable { } /** - * Construct the structure using {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} - * or {@link com.gtnewhorizon.structurelib.structure.IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, ISurvivalBuildEnvironment, boolean)} + * Construct the structure using + * {@link com.gtnewhorizon.structurelib.structure.IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} + * or + * {@link com.gtnewhorizon.structurelib.structure.IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, ISurvivalBuildEnvironment, boolean)} * * @param elementBudget The server configured element budget. The implementor can choose to tune this up a bit if * the structure is too big, but generally should not be a 4 digits number to not overwhelm the * server * @return -1 if done, -2 if not supported (e.g. due to an incompatible change in the API of env, otherwise number - * of elements placed this round + * of elements placed this round */ default int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { EntityPlayer actor = env.getActor(); @@ -74,5 +80,6 @@ public interface ISurvivalConstructable extends IConstructable { } class GlobalStates { + public static final ThreadLocal entityPlayer = new ThreadLocal<>(); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Direction.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Direction.java index eaae4067..acc81ce0 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Direction.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Direction.java @@ -1,13 +1,16 @@ package com.gtnewhorizon.structurelib.alignment.enumerable; -import com.gtnewhorizon.structurelib.util.Vec3Impl; import java.util.Arrays; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; + import net.minecraftforge.common.util.ForgeDirection; +import com.gtnewhorizon.structurelib.util.Vec3Impl; + public enum Direction { + DOWN(ForgeDirection.DOWN), UP(ForgeDirection.UP), NORTH(ForgeDirection.NORTH), @@ -18,8 +21,8 @@ public enum Direction { private final ForgeDirection forgeDirection; private final Vec3Impl axisVector; public static final Direction[] VALUES = values(); - private static final Map reverseMap = - Arrays.stream(VALUES).collect(Collectors.toMap(d -> d.axisVector, Function.identity())); + private static final Map reverseMap = Arrays.stream(VALUES) + .collect(Collectors.toMap(d -> d.axisVector, Function.identity())); Direction(ForgeDirection forgeDirection) { this.forgeDirection = forgeDirection; diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java index ec76db85..eb08049c 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java @@ -6,16 +6,19 @@ import static java.lang.Math.abs; import static java.util.Arrays.stream; import static java.util.stream.Collectors.*; -import com.google.common.collect.ImmutableSet; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.IntegerAxisSwap; -import com.gtnewhorizon.structurelib.util.Vec3Impl; import java.util.*; + import net.minecraft.util.StatCollector; import net.minecraft.util.Vec3; import net.minecraftforge.common.util.ForgeDirection; +import com.google.common.collect.ImmutableSet; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.IntegerAxisSwap; +import com.gtnewhorizon.structurelib.util.Vec3Impl; + public enum ExtendedFacing { + DOWN_NORMAL_NONE("down normal none"), DOWN_NORMAL_HORIZONTAL("down normal horizontal"), DOWN_NORMAL_VERTICAL("down normal vertical"), @@ -119,31 +122,31 @@ public enum ExtendedFacing { public static final int STATES_COUNT = VALUES.length; static { - stream(values()) - .forEach(extendedFacing -> - FOR_FACING.compute(extendedFacing.direction, ((forgeDirection, extendedFacings) -> { - if (extendedFacings == null) { - extendedFacings = new ArrayList<>(); - } - extendedFacings.add(extendedFacing); - return extendedFacings; - }))); + stream(values()).forEach( + extendedFacing -> FOR_FACING.compute(extendedFacing.direction, ((forgeDirection, extendedFacings) -> { + if (extendedFacings == null) { + extendedFacings = new ArrayList<>(); + } + extendedFacings.add(extendedFacing); + return extendedFacings; + }))); } - private static final Map NAME_LOOKUP = - stream(VALUES).collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing)); + private static final Map NAME_LOOKUP = stream(VALUES) + .collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing)); private static final EnumMap> LOOKUP_BY_DIRECTION = stream(VALUES) - .collect(groupingBy( - ExtendedFacing::getDirection, - () -> new EnumMap<>(ForgeDirection.class), - collectingAndThen(toSet(), ImmutableSet::copyOf))); - private static final EnumMap> LOOKUP_BY_ROTATION = stream(VALUES) - .collect(groupingBy( + .collect( + groupingBy( + ExtendedFacing::getDirection, + () -> new EnumMap<>(ForgeDirection.class), + collectingAndThen(toSet(), ImmutableSet::copyOf))); + private static final EnumMap> LOOKUP_BY_ROTATION = stream(VALUES).collect( + groupingBy( ExtendedFacing::getRotation, () -> new EnumMap<>(Rotation.class), collectingAndThen(toSet(), ImmutableSet::copyOf))); - private static final EnumMap> LOOKUP_BY_FLIP = stream(VALUES) - .collect(groupingBy( + private static final EnumMap> LOOKUP_BY_FLIP = stream(VALUES).collect( + groupingBy( ExtendedFacing::getFlip, () -> new EnumMap<>(Flip.class), collectingAndThen(toSet(), ImmutableSet::copyOf))); @@ -333,7 +336,7 @@ public enum ExtendedFacing { } /** - * Translates relative to front facing offset to world offset + * Translates relative to front facing offset to world offset * * @param abcOffset A,B,C offset (facing relative {@code L-->R,U-->D,F-->B}) * @return X, Y, Z offset in world @@ -377,10 +380,10 @@ public enum ExtendedFacing { } /** - * Translates world offset to relative front facing offset + * Translates world offset to relative front facing offset * * @param xyzOffset X,Y,Z offset in world - * @return A, B, C offset (facing relative {@code L-->R,U-->D,F-->B}) + * @return A, B, C offset (facing relative {@code L-->R,U-->D,F-->B}) */ public Vec3 getOffsetABC(Vec3 xyzOffset) { return integerAxisSwap.translate(xyzOffset); diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Flip.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Flip.java index dade8c75..f43a7ba6 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Flip.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Flip.java @@ -7,9 +7,11 @@ import static java.util.stream.Collectors.toMap; import java.util.Locale; import java.util.Map; import java.util.Random; + import javax.annotation.Nonnull; public enum Flip { + NONE(3, "none"), HORIZONTAL(2, "horizontal"), VERTICAL(1, "vertical"), diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Rotation.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Rotation.java index a555f00b..de9201bc 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Rotation.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/Rotation.java @@ -7,9 +7,11 @@ import static java.util.stream.Collectors.toMap; import java.util.Locale; import java.util.Map; import java.util.Random; + import javax.annotation.Nonnull; public enum Rotation { + NORMAL(2, "normal"), CLOCKWISE(3, "clockwise"), UPSIDE_DOWN(0, "upside down"), @@ -19,8 +21,8 @@ public enum Rotation { private final String name; public static final Rotation[] VALUES = values(); - private static final Map NAME_LOOKUP = - stream(VALUES).collect(toMap(Rotation::getName2, (rotation) -> rotation)); + private static final Map NAME_LOOKUP = stream(VALUES) + .collect(toMap(Rotation::getName2, (rotation) -> rotation)); Rotation(int oppositeIn, String nameIn) { this.opposite = oppositeIn; diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/package-info.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/package-info.java index af026250..cbad28cb 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/package-info.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/package-info.java @@ -1,7 +1,7 @@ /** * This package provide a framework for rotating a given block, or a multiblock structure. *

- * All public stuff in this package and its subpackages are considered part of the public API. - * Backwards compatibility is maintained to the maximum extend possible. + * All public stuff in this package and its subpackages are considered part of the public API. Backwards compatibility + * is maintained to the maximum extend possible. */ package com.gtnewhorizon.structurelib.alignment; diff --git a/src/main/java/com/gtnewhorizon/structurelib/block/BlockHint.java b/src/main/java/com/gtnewhorizon/structurelib/block/BlockHint.java index de6bfbc7..6c66c491 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/block/BlockHint.java +++ b/src/main/java/com/gtnewhorizon/structurelib/block/BlockHint.java @@ -1,10 +1,7 @@ package com.gtnewhorizon.structurelib.block; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import java.util.List; + import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; @@ -14,7 +11,14 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.StructureLibAPI; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + public class BlockHint extends Block { + private static final IIcon[] hint = new IIcon[16]; public BlockHint() { diff --git a/src/main/java/com/gtnewhorizon/structurelib/command/CommandConfigureChannels.java b/src/main/java/com/gtnewhorizon/structurelib/command/CommandConfigureChannels.java index c066ee6e..ceb3ab98 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/command/CommandConfigureChannels.java +++ b/src/main/java/com/gtnewhorizon/structurelib/command/CommandConfigureChannels.java @@ -1,10 +1,9 @@ package com.gtnewhorizon.structurelib.command; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; + import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; @@ -13,7 +12,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ChatComponentTranslation; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; + public class CommandConfigureChannels extends CommandBase { + @Override public String getCommandName() { return "sl_channel"; @@ -58,13 +61,12 @@ public class CommandConfigureChannels extends CommandBase { if (!ChannelDataAccessor.hasSubChannel(heldItem)) { sender.addChatMessage(new ChatComponentText("No subchannel")); } else { - sender.addChatMessage(new ChatComponentTranslation( - "item.structurelib.constructableTrigger.desc.lshift.0", - ChannelDataAccessor.countChannelData(heldItem))); - ChannelDataAccessor.iterateChannelData(heldItem) - .map(e -> e.getKey() + ": " + e.getValue()) - .map(ChatComponentText::new) - .forEach(player::addChatMessage); + sender.addChatMessage( + new ChatComponentTranslation( + "item.structurelib.constructableTrigger.desc.lshift.0", + ChannelDataAccessor.countChannelData(heldItem))); + ChannelDataAccessor.iterateChannelData(heldItem).map(e -> e.getKey() + ": " + e.getValue()) + .map(ChatComponentText::new).forEach(player::addChatMessage); } return; case "wipe": @@ -73,13 +75,11 @@ public class CommandConfigureChannels extends CommandBase { case "get": case "unset": if (args.length < 2) throw new WrongUsageException(getCommandUsage(sender)); - channel = - args.length == 2 ? args[1] : Arrays.stream(args).skip(1).collect(Collectors.joining()); + channel = args.length == 2 ? args[1] : Arrays.stream(args).skip(1).collect(Collectors.joining()); break; case "set": if (args.length < 3) throw new WrongUsageException(getCommandUsage(sender)); - channel = args.length == 3 - ? args[1] + channel = args.length == 3 ? args[1] : Arrays.stream(args).skip(1).limit(args.length - 2).collect(Collectors.joining()); break; default: @@ -88,9 +88,9 @@ public class CommandConfigureChannels extends CommandBase { switch (args[0]) { case "get": - if (ChannelDataAccessor.hasSubChannel(heldItem, channel)) - sender.addChatMessage(new ChatComponentText( - channel + " value: " + ChannelDataAccessor.getChannelData(heldItem, channel))); + if (ChannelDataAccessor.hasSubChannel(heldItem, channel)) sender.addChatMessage( + new ChatComponentText( + channel + " value: " + ChannelDataAccessor.getChannelData(heldItem, channel))); else sender.addChatMessage(new ChatComponentText(channel + " value: N/A")); break; case "clear": diff --git a/src/main/java/com/gtnewhorizon/structurelib/entity/fx/WeightlessParticleFX.java b/src/main/java/com/gtnewhorizon/structurelib/entity/fx/WeightlessParticleFX.java index 5f4a7c12..2980a37a 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/entity/fx/WeightlessParticleFX.java +++ b/src/main/java/com/gtnewhorizon/structurelib/entity/fx/WeightlessParticleFX.java @@ -1,20 +1,16 @@ package com.gtnewhorizon.structurelib.entity.fx; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.particle.EntityFX; import net.minecraft.world.World; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + @SideOnly(Side.CLIENT) public class WeightlessParticleFX extends EntityFX { - public WeightlessParticleFX( - World p_i1205_1_, - double p_i1205_2_, - double p_i1205_4_, - double p_i1205_6_, - double p_i1205_8_, - double p_i1205_10_, - double p_i1205_12_) { + + public WeightlessParticleFX(World p_i1205_1_, double p_i1205_2_, double p_i1205_4_, double p_i1205_6_, + double p_i1205_8_, double p_i1205_10_, double p_i1205_12_) { super(p_i1205_1_, p_i1205_2_, p_i1205_4_, p_i1205_6_, p_i1205_8_, p_i1205_10_, p_i1205_12_); this.motionX = p_i1205_8_ + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F); this.motionY = p_i1205_10_ + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F); diff --git a/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScreenConfigureChannels.java b/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScreenConfigureChannels.java index fed006d0..314c2519 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScreenConfigureChannels.java +++ b/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScreenConfigureChannels.java @@ -1,12 +1,10 @@ package com.gtnewhorizon.structurelib.gui; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.gui.GuiScrollableList.IGuiScreen; import java.util.List; import java.util.Locale; import java.util.Map.Entry; import java.util.stream.Collectors; + import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; @@ -15,12 +13,18 @@ import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; + import org.apache.commons.lang3.StringUtils; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; +import com.gtnewhorizon.structurelib.gui.GuiScrollableList.IGuiScreen; + public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen { + private static final int KEY_MAX_WIDTH = 50; private final ItemStack trigger; private final GuiChannelsList list; @@ -48,6 +52,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen guiTop = (this.height - this.getYSize()) / 2; key = new GuiTextField(fontRendererObj, guiLeft + 45, guiTop + 119, 151 + 12 - 45, 12) { + @Override public void writeText(String text) { // force lower case @@ -58,8 +63,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen @Override public void mouseClicked(int p_146192_1_, int p_146192_2_, int p_146192_3_) { super.mouseClicked(p_146192_1_, p_146192_2_, p_146192_3_); - boolean flag = p_146192_1_ >= this.xPosition - && p_146192_1_ < this.xPosition + this.width + boolean flag = p_146192_1_ >= this.xPosition && p_146192_1_ < this.xPosition + this.width && p_146192_2_ >= this.yPosition && p_146192_2_ < this.yPosition + this.height; if (flag && p_146192_3_ == 1) { @@ -75,6 +79,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen } }; value = new GuiTextField(fontRendererObj, guiLeft + 45, guiTop + 139, 151 + 12 - 45, 12) { + @Override public void writeText(String text) { // ignore write requests containing non digit characters. @@ -104,8 +109,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen @Override public void mouseClicked(int p_146192_1_, int p_146192_2_, int p_146192_3_) { super.mouseClicked(p_146192_1_, p_146192_2_, p_146192_3_); - boolean flag = p_146192_1_ >= this.xPosition - && p_146192_1_ < this.xPosition + this.width + boolean flag = p_146192_1_ >= this.xPosition && p_146192_1_ < this.xPosition + this.width && p_146192_2_ >= this.yPosition && p_146192_2_ < this.yPosition + this.height; if (flag && p_146192_3_ == 1) { @@ -122,22 +126,30 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen list.onGuiInit(this); - addButton(new GuiButton( - 0, guiLeft + 12, guiTop + 157, 47, 20, I18n.format("item.structurelib.constructableTrigger.gui.add"))); - addButton(new GuiButton( - 1, - guiLeft + 65, - guiTop + 157, - 47, - 20, - I18n.format("item.structurelib.constructableTrigger.gui.unset"))); - addButton(new GuiButton( - 2, - guiLeft + 118, - guiTop + 157, - 47, - 20, - I18n.format("item.structurelib.constructableTrigger.gui.wipe"))); + addButton( + new GuiButton( + 0, + guiLeft + 12, + guiTop + 157, + 47, + 20, + I18n.format("item.structurelib.constructableTrigger.gui.add"))); + addButton( + new GuiButton( + 1, + guiLeft + 65, + guiTop + 157, + 47, + 20, + I18n.format("item.structurelib.constructableTrigger.gui.unset"))); + addButton( + new GuiButton( + 2, + guiLeft + 118, + guiTop + 157, + 47, + 20, + I18n.format("item.structurelib.constructableTrigger.gui.wipe"))); updateButtons(); } @@ -238,8 +250,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen // STACKOVERFLOW! String keyText = key.getText(); boolean existing = !StringUtils.isEmpty(keyText) && ChannelDataAccessor.hasSubChannel(trigger, keyText); - getButtonList().get(0).displayString = existing - ? I18n.format("item.structurelib.constructableTrigger.gui.set") + getButtonList().get(0).displayString = existing ? I18n.format("item.structurelib.constructableTrigger.gui.set") : I18n.format("item.structurelib.constructableTrigger.gui.add"); getButtonList().get(0).enabled = !StringUtils.isBlank(value.getText()); getButtonList().get(1).enabled = existing && !StringUtils.isBlank(value.getText()); @@ -300,14 +311,21 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen super.drawScreen(mX, mY, partialTick); list.drawScreen(mX, mY, partialTick); fontRendererObj.drawString( - I18n.format("item.structurelib.constructableTrigger.gui.key"), guiLeft + 12, guiTop + 122, 0); + I18n.format("item.structurelib.constructableTrigger.gui.key"), + guiLeft + 12, + guiTop + 122, + 0); key.drawTextBox(); fontRendererObj.drawString( - I18n.format("item.structurelib.constructableTrigger.gui.value"), guiLeft + 12, guiTop + 142, 0); + I18n.format("item.structurelib.constructableTrigger.gui.value"), + guiLeft + 12, + guiTop + 142, + 0); value.drawTextBox(); } private class GuiChannelsList extends GuiScrollableList> { + private List> cache; public GuiChannelsList(int width, int height, int originX, int originY, int slotHeight) { @@ -316,11 +334,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen @Override public Entry getElementAt(int index) { - return ChannelDataAccessor.iterateChannelData(trigger) - .sorted() - .skip(index) - .findFirst() - .orElse(null); + return ChannelDataAccessor.iterateChannelData(trigger).sorted().skip(index).findFirst().orElse(null); } @Override @@ -330,8 +344,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen @Override protected boolean elementClicked(int elementIndex, boolean doubleClick, int mXRelative, int mYRelative) { - if (mXRelative >= margin + 1 - && mXRelative <= margin + 5 + if (mXRelative >= margin + 1 && mXRelative <= margin + 5 && mYRelative >= margin / 2 + 1 && mYRelative <= margin / 2 + 5) { Entry e = getElementAt(elementIndex); @@ -349,8 +362,8 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen } @Override - protected void drawElement( - int elementIndex, int x, int y, int height, Tessellator tessellator, boolean isHovering) { + protected void drawElement(int elementIndex, int x, int y, int height, Tessellator tessellator, + boolean isHovering) { if (elementIndex < 0 || elementIndex >= cache.size()) { return; } @@ -382,8 +395,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen // TODO optimize this to not create a billion string, or maybe cache this String s = fontRendererObj.trimStringToWidth(e, keyMaxWidth); if (s.length() != e.length()) { - StringBuilder buffer = - new StringBuilder(s).deleteCharAt(s.length() - 1).append("..."); + StringBuilder buffer = new StringBuilder(s).deleteCharAt(s.length() - 1).append("..."); while ((s = fontRendererObj.trimStringToWidth(buffer.toString(), keyMaxWidth)).length() != buffer.length()) // drop last original char @@ -391,9 +403,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen do { buffer.append('.'); } while (fontRendererObj.getStringWidth(buffer.toString()) <= keyMaxWidth); - s = buffer.deleteCharAt(s.length() - 1) - .insert(s.length() - 3, EnumChatFormatting.GRAY) - .toString(); + s = buffer.deleteCharAt(s.length() - 1).insert(s.length() - 3, EnumChatFormatting.GRAY).toString(); } return s; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScrollableList.java b/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScrollableList.java index a316a077..ae6aa50b 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScrollableList.java +++ b/src/main/java/com/gtnewhorizon/structurelib/gui/GuiScrollableList.java @@ -2,31 +2,34 @@ package com.gtnewhorizon.structurelib.gui; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; + import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.Tessellator; + import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; /** * Shamelessly stolen from EnderCore, with some amount of edit to fit in one file. Original code from CrazyPants. *

- * As the code has been released into public domain, it is now LGPL as part of this library as a whole. - * You can go to EnderCore's repository to obtain a public domain copy though + * As the code has been released into public domain, it is now LGPL as part of this library as a whole. You can go to + * EnderCore's repository to obtain a public domain copy though * * Major edits *

    - *
  • Separate dwheel handling to handleDWheel. The next event calls often cause the mouse click event to - * not fire on other widgets
  • - *
  • scrollbar are now rendered within width
  • - *
  • added prepareDrawElements
  • + *
  • Separate dwheel handling to handleDWheel. The next event calls often cause the mouse click event to not fire on + * other widgets
  • + *
  • scrollbar are now rendered within width
  • + *
  • added prepareDrawElements
  • *
* * @author CrazyPants * @author glee8e */ public abstract class GuiScrollableList { + protected final int slotHeight; private final Minecraft mc = Minecraft.getMinecraft(); protected final int originX; @@ -113,8 +116,8 @@ public abstract class GuiScrollableList { public abstract int getNumElements(); - protected abstract void drawElement( - int elementIndex, int x, int y, int height, Tessellator tessellator, boolean isHovering); + protected abstract void drawElement(int elementIndex, int x, int y, int height, Tessellator tessellator, + boolean isHovering); protected boolean elementClicked(int elementIndex, boolean doubleClick, int mXRelative, int mYRelative) { return true; @@ -165,8 +168,7 @@ public abstract class GuiScrollableList { } /** - * draws the slot to the screen, pass in mouse's current x and y and partial - * ticks + * draws the slot to the screen, pass in mouse's current x and y and partial ticks */ public void drawScreen(int mX, int mY, float partialTick) { this.mouseX = mX; @@ -343,15 +345,17 @@ public abstract class GuiScrollableList { int y = mouseY - minY + (int) amountScrolled - margin; int mouseOverElement = y / slotHeight; - if (mouseX >= minX - && mouseX <= maxX + if (mouseX >= minX && mouseX <= maxX && mouseOverElement >= 0 && y >= 0 && mouseOverElement < getNumElements()) { - boolean doubleClick = - mouseOverElement == selectedIndex && Minecraft.getSystemTime() - lastClickedTime < 250L; + boolean doubleClick = mouseOverElement == selectedIndex + && Minecraft.getSystemTime() - lastClickedTime < 250L; if (elementClicked( - mouseOverElement, doubleClick, mouseX - minX, y - slotHeight * mouseOverElement)) { + mouseOverElement, + doubleClick, + mouseX - minX, + y - slotHeight * mouseOverElement)) { setSelection(mouseOverElement); lastClickedTime = Minecraft.getSystemTime(); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemBlockHint.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemBlockHint.java index 7dfe21f6..c9869a5a 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemBlockHint.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemBlockHint.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.item; import static net.minecraft.util.StatCollector.translateToLocal; import java.util.List; + import net.minecraft.block.Block; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; @@ -11,6 +12,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; public class ItemBlockHint extends ItemBlock { + public ItemBlockHint(Block p_i45328_1_) { super(p_i45328_1_); setMaxDamage(0); @@ -35,29 +37,31 @@ public class ItemBlockHint extends ItemBlock { case 9: case 10: case 11: - aList.add(EnumChatFormatting.AQUA.toString() - + EnumChatFormatting.BOLD - + translateToLocal("structurelib.blockhint.desc.1")); // Placeholder for a certain group. + aList.add( + EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + + translateToLocal("structurelib.blockhint.desc.1")); // Placeholder for a certain + // group. break; case 12: - aList.add(EnumChatFormatting.AQUA.toString() - + EnumChatFormatting.BOLD - + translateToLocal("structurelib.blockhint.desc.2")); // General placeholder. + aList.add( + EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + + translateToLocal("structurelib.blockhint.desc.2")); // General placeholder. break; case 13: - aList.add(EnumChatFormatting.AQUA.toString() - + EnumChatFormatting.BOLD - + translateToLocal("structurelib.blockhint.desc.3")); // Make sure it contains Air material. + aList.add( + EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + + translateToLocal("structurelib.blockhint.desc.3")); // Make sure it contains Air + // material. break; case 14: - aList.add(EnumChatFormatting.AQUA.toString() - + EnumChatFormatting.BOLD - + translateToLocal( - "structurelib.blockhint.desc.4")); // Make sure it does not contain Air material. + aList.add( + EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + + translateToLocal("structurelib.blockhint.desc.4")); // Make sure it does not contain + // Air material. break; case 15: - aList.add(EnumChatFormatting.BLUE - + translateToLocal("structurelib.blockhint.desc.5")); // ERROR, what did u expect? + aList.add(EnumChatFormatting.BLUE + translateToLocal("structurelib.blockhint.desc.5")); // ERROR, what + // did u expect? break; default: // WTF? aList.add("Damn son where did you get that!?"); diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java index 6cd14704..3656df34 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java @@ -5,17 +5,21 @@ import static net.minecraft.util.EnumChatFormatting.BLUE; import static net.minecraft.util.StatCollector.translateToLocal; import static net.minecraft.util.StatCollector.translateToLocalFormatted; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; -import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; import java.util.List; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; 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; + public class ItemConstructableTrigger extends Item { + public ItemConstructableTrigger() { setUnlocalizedName("structurelib.constructableTrigger"); setTextureName(MOD_ID + ":itemConstructableTrigger"); @@ -30,17 +34,8 @@ public class ItemConstructableTrigger extends Item { } @Override - public boolean onItemUseFirst( - ItemStack stack, - EntityPlayer player, - World world, - int x, - int y, - int z, - int side, - float hitX, - float hitY, - float hitZ) { + public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, + float hitX, float hitY, float hitZ) { return ConstructableUtility.handle(stack, player, world, x, y, z, side); } @@ -48,27 +43,25 @@ public class ItemConstructableTrigger extends Item { @Override public void addInformation(ItemStack aStack, EntityPlayer ep, List aList, boolean boo) { if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { - aList.add(translateToLocalFormatted( - "item.structurelib.constructableTrigger.desc.lshift.0", - ChannelDataAccessor.countChannelData(aStack))); - ChannelDataAccessor.iterateChannelData(aStack) - .map(e -> e.getKey() + ": " + e.getValue()) + aList.add( + translateToLocalFormatted( + "item.structurelib.constructableTrigger.desc.lshift.0", + ChannelDataAccessor.countChannelData(aStack))); + ChannelDataAccessor.iterateChannelData(aStack).map(e -> e.getKey() + ": " + e.getValue()) .forEach(aList::add); } else { - aList.add(translateToLocal( - "item.structurelib.constructableTrigger.desc.0")); // Triggers Constructable Interface - aList.add(BLUE - + translateToLocal( - "item.structurelib.constructableTrigger.desc.1")); // Shows multiblock construction details, - aList.add(BLUE - + translateToLocal( - "item.structurelib.constructableTrigger.desc.2")); // just Use on a multiblock controller. - aList.add(BLUE - + translateToLocal( - "item.structurelib.constructableTrigger.desc.3")); // (Sneak Use in creative to build) - aList.add(BLUE - + translateToLocal( - "item.structurelib.constructableTrigger.desc.4")); // Quantity affects tier/mode/type + aList.add(translateToLocal("item.structurelib.constructableTrigger.desc.0")); // Triggers Constructable + // Interface + aList.add(BLUE + translateToLocal("item.structurelib.constructableTrigger.desc.1")); // Shows multiblock + // construction + // details, + aList.add(BLUE + translateToLocal("item.structurelib.constructableTrigger.desc.2")); // just Use on a + // multiblock + // controller. + aList.add(BLUE + translateToLocal("item.structurelib.constructableTrigger.desc.3")); // (Sneak Use in + // creative to build) + aList.add(BLUE + translateToLocal("item.structurelib.constructableTrigger.desc.4")); // Quantity affects + // tier/mode/type if (ChannelDataAccessor.hasSubChannel(aStack)) aList.add(translateToLocal("item.structurelib.constructableTrigger.desc.5")); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemFrontRotationTool.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemFrontRotationTool.java index 88538047..012b8e6c 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemFrontRotationTool.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemFrontRotationTool.java @@ -3,18 +3,22 @@ package com.gtnewhorizon.structurelib.item; import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID; import static net.minecraft.util.StatCollector.translateToLocal; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.AlignmentUtility; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import java.util.List; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.alignment.AlignmentUtility; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + public class ItemFrontRotationTool extends Item { + public ItemFrontRotationTool() { setMaxStackSize(1); setUnlocalizedName("structurelib.frontRotationTool"); @@ -23,17 +27,8 @@ public class ItemFrontRotationTool extends Item { } @Override - public boolean onItemUseFirst( - ItemStack stack, - EntityPlayer player, - World world, - int x, - int y, - int z, - int side, - float hitX, - float hitY, - float hitZ) { + public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, + float hitX, float hitY, float hitZ) { return AlignmentUtility.handle(player, world, x, y, z); } @@ -41,9 +36,13 @@ public class ItemFrontRotationTool extends Item { @SideOnly(Side.CLIENT) public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List aList, boolean p_77624_4_) { aList.add(translateToLocal("item.structurelib.frontRotationTool.desc.0")); // Triggers Front Rotation Interface - aList.add(EnumChatFormatting.BLUE - + translateToLocal("item.structurelib.frontRotationTool.desc.1")); // Rotates only the front panel, - aList.add(EnumChatFormatting.BLUE - + translateToLocal("item.structurelib.frontRotationTool.desc.2")); // which allows structure rotation. + aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.1")); // Rotates + // only the + // front + // panel, + aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.2")); // which + // allows + // structure + // rotation. } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/net/AlignmentMessage.java b/src/main/java/com/gtnewhorizon/structurelib/net/AlignmentMessage.java index 16e7248d..339b9ff0 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/net/AlignmentMessage.java +++ b/src/main/java/com/gtnewhorizon/structurelib/net/AlignmentMessage.java @@ -1,20 +1,23 @@ package com.gtnewhorizon.structurelib.net; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.alignment.IAlignment; -import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; -import cpw.mods.fml.common.network.ByteBufUtils; -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; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.alignment.IAlignment; +import com.gtnewhorizon.structurelib.alignment.IAlignmentProvider; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; + +import cpw.mods.fml.common.network.ByteBufUtils; +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 abstract class AlignmentMessage implements IMessage { + int mPosX; int mPosY; int mPosZ; @@ -66,6 +69,7 @@ public abstract class AlignmentMessage implements IMessage { } public static class AlignmentQuery extends AlignmentMessage { + public AlignmentQuery() {} public AlignmentQuery(IAlignmentProvider provider) { @@ -78,6 +82,7 @@ public abstract class AlignmentMessage implements IMessage { } public static class AlignmentData extends AlignmentMessage { + public AlignmentData() {} private AlignmentData(AlignmentQuery query) { @@ -98,11 +103,11 @@ public abstract class AlignmentMessage implements IMessage { } public static class ClientHandler implements IMessageHandler { + @Override public IMessage onMessage(AlignmentData pMessage, MessageContext pCtx) { if (StructureLib.getCurrentPlayer().worldObj.provider.dimensionId == pMessage.mPosD) { - TileEntity te = StructureLib.getCurrentPlayer() - .worldObj + TileEntity te = StructureLib.getCurrentPlayer().worldObj .getTileEntity(pMessage.mPosX, pMessage.mPosY, pMessage.mPosZ); if (te instanceof IAlignmentProvider) { IAlignment alignment = ((IAlignmentProvider) te).getAlignment(); @@ -116,6 +121,7 @@ public abstract class AlignmentMessage implements IMessage { } public static class ServerHandler implements IMessageHandler { + @Override public AlignmentData onMessage(AlignmentQuery pMessage, MessageContext pCtx) { World world = DimensionManager.getWorld(pMessage.mPosD); diff --git a/src/main/java/com/gtnewhorizon/structurelib/net/ErrorHintParticleMessage.java b/src/main/java/com/gtnewhorizon/structurelib/net/ErrorHintParticleMessage.java index 79f4cea6..db89228d 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/net/ErrorHintParticleMessage.java +++ b/src/main/java/com/gtnewhorizon/structurelib/net/ErrorHintParticleMessage.java @@ -4,12 +4,14 @@ import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; import com.gtnewhorizon.structurelib.StructureLib; import com.gtnewhorizon.structurelib.StructureLibAPI; + 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 ErrorHintParticleMessage implements IMessage { + private int x; private short y; private int z; @@ -37,17 +39,21 @@ public class ErrorHintParticleMessage implements IMessage { } public static class Handler implements IMessageHandler { + @Override public IMessage onMessage(ErrorHintParticleMessage msg, MessageContext ctx) { boolean updateResult = StructureLibAPI.markHintParticleError( - StructureLib.getCurrentPlayer(), StructureLib.getCurrentPlayer().worldObj, msg.x, msg.y, msg.z); - if (StructureLibAPI.isDebugEnabled()) - LOGGER.debug( - "Server instructed to mark hint particle at ({}, {}, {}) error, result {}!", - msg.x, - msg.y, - msg.z, - updateResult); + StructureLib.getCurrentPlayer(), + StructureLib.getCurrentPlayer().worldObj, + msg.x, + msg.y, + msg.z); + if (StructureLibAPI.isDebugEnabled()) LOGGER.debug( + "Server instructed to mark hint particle at ({}, {}, {}) error, result {}!", + msg.x, + msg.y, + msg.z, + updateResult); return null; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/net/SetChannelDataMessage.java b/src/main/java/com/gtnewhorizon/structurelib/net/SetChannelDataMessage.java index efe11a5e..5e5d3d53 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/net/SetChannelDataMessage.java +++ b/src/main/java/com/gtnewhorizon/structurelib/net/SetChannelDataMessage.java @@ -1,22 +1,27 @@ package com.gtnewhorizon.structurelib.net; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; + +import org.apache.commons.lang3.tuple.Pair; + import com.gtnewhorizon.structurelib.StructureLib; import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger; + import cpw.mods.fml.common.network.ByteBufUtils; 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; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.ItemStack; -import org.apache.commons.lang3.tuple.Pair; public class SetChannelDataMessage implements IMessage { + private final List> data = new ArrayList<>(); public SetChannelDataMessage() {} @@ -44,6 +49,7 @@ public class SetChannelDataMessage implements IMessage { } public static class Handler implements IMessageHandler { + @Override public IMessage onMessage(SetChannelDataMessage message, MessageContext ctx) { EntityPlayerMP player = ctx.getServerHandler().playerEntity; diff --git a/src/main/java/com/gtnewhorizon/structurelib/net/UpdateHintParticleMessage.java b/src/main/java/com/gtnewhorizon/structurelib/net/UpdateHintParticleMessage.java index 8aa7acd3..701b482c 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/net/UpdateHintParticleMessage.java +++ b/src/main/java/com/gtnewhorizon/structurelib/net/UpdateHintParticleMessage.java @@ -4,12 +4,14 @@ import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; import com.gtnewhorizon.structurelib.StructureLib; import com.gtnewhorizon.structurelib.StructureLibAPI; + 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 UpdateHintParticleMessage implements IMessage { + private int x; private short y; private int z; @@ -53,6 +55,7 @@ public class UpdateHintParticleMessage implements IMessage { } public static class Handler implements IMessageHandler { + @Override public IMessage onMessage(UpdateHintParticleMessage msg, MessageContext ctx) { boolean updateResult = StructureLibAPI.updateHintParticleTint( @@ -61,16 +64,13 @@ public class UpdateHintParticleMessage implements IMessage { msg.x, msg.y, msg.z, - new short[] { - msg.r, msg.g, msg.b, msg.a, - }); - if (StructureLibAPI.isDebugEnabled()) - LOGGER.debug( - "Server instructed to update hint particle at ({}, {}, {}), result {}!", - msg.x, - msg.y, - msg.z, - updateResult); + new short[] { msg.r, msg.g, msg.b, msg.a, }); + if (StructureLibAPI.isDebugEnabled()) LOGGER.debug( + "Server instructed to update hint particle at ({}, {}, {}), result {}!", + msg.x, + msg.y, + msg.z, + updateResult); return null; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/AutoPlaceEnvironment.java b/src/main/java/com/gtnewhorizon/structurelib/structure/AutoPlaceEnvironment.java index f6902628..b063169c 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/AutoPlaceEnvironment.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/AutoPlaceEnvironment.java @@ -1,19 +1,23 @@ package com.gtnewhorizon.structurelib.structure; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; + import javax.annotation.Nonnull; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; + /** * Represent the environment in which autoplace of a single element took place. */ public class AutoPlaceEnvironment { + private IItemSource source; private final EntityPlayer actor; private final Consumer chatter; @@ -23,8 +27,8 @@ public class AutoPlaceEnvironment { final int[] offsetABC; private final int[] baseOffsetABC; - public static AutoPlaceEnvironment fromLegacy( - IItemSource source, EntityPlayer actor, Consumer chatter) { + public static AutoPlaceEnvironment fromLegacy(IItemSource source, EntityPlayer actor, + Consumer chatter) { if (source instanceof WrappedIItemSource) { AutoPlaceEnvironment original = ((WrappedIItemSource) source).container; // feels like this is extremely likely to cause issues, but this does allow us to recover lost info. @@ -40,13 +44,8 @@ public class AutoPlaceEnvironment { return new AutoPlaceEnvironment(source, actor, chatter, null, null, null, null, null); } - AutoPlaceEnvironment( - EntityPlayer actor, - Consumer chatter, - IStructureDefinition definition, - String piece, - ExtendedFacing facing, - int[] baseOffsetABC) { + AutoPlaceEnvironment(EntityPlayer actor, Consumer chatter, IStructureDefinition definition, + String piece, ExtendedFacing facing, int[] baseOffsetABC) { this.source = null; this.actor = actor; this.chatter = chatter; @@ -57,14 +56,8 @@ public class AutoPlaceEnvironment { this.baseOffsetABC = baseOffsetABC; } - AutoPlaceEnvironment( - IItemSource source, - EntityPlayer actor, - Consumer chatter, - IStructureDefinition definition, - String piece, - ExtendedFacing facing, - int[] offsetABC, + AutoPlaceEnvironment(IItemSource source, EntityPlayer actor, Consumer chatter, + IStructureDefinition definition, String piece, ExtendedFacing facing, int[] offsetABC, int[] baseOffsetABC) { this.source = definition != null && !(source instanceof WrappedIItemSource) ? new WrappedIItemSource(this, source) @@ -97,8 +90,7 @@ public class AutoPlaceEnvironment { } public APILevel getAPILevel() { - return definition == null - ? actor instanceof EntityPlayerMP ? APILevel.Legacy : APILevel.LegacyRelaxed + return definition == null ? actor instanceof EntityPlayerMP ? APILevel.Legacy : APILevel.LegacyRelaxed : APILevel.V2; } @@ -110,8 +102,8 @@ public class AutoPlaceEnvironment { } /** - * The initiator of actions. for very critical errors you can also just send the error messages here, bypassing - * any filter that {@link #getChatter()} might have. You might want to use + * The initiator of actions. for very critical errors you can also just send the error messages here, bypassing any + * filter that {@link #getChatter()} might have. You might want to use * {@link com.gtnewhorizon.structurelib.StructureLibAPI#addThrottledChat(Object, EntityPlayer, IChatComponent, short)} * to help reduce spam. */ @@ -179,6 +171,7 @@ public class AutoPlaceEnvironment { } private static class WrappedIItemSource implements IItemSource { + final AutoPlaceEnvironment container; final IItemSource delegate; @@ -221,13 +214,13 @@ public class AutoPlaceEnvironment { */ public enum APILevel { /** - * Implements {@link #getChatter()}, {@link #getActor()} and {@link #getSource()}. - * {@link #getActor()} is guaranteed to be an {@link net.minecraft.entity.player.EntityPlayerMP} + * Implements {@link #getChatter()}, {@link #getActor()} and {@link #getSource()}. {@link #getActor()} is + * guaranteed to be an {@link net.minecraft.entity.player.EntityPlayerMP} */ Legacy, /** - * Implements {@link #getChatter()}, {@link #getActor()} and {@link #getSource()}. - * {@link #getActor()} is NOT guaranteed to be an {@link net.minecraft.entity.player.EntityPlayerMP} + * Implements {@link #getChatter()}, {@link #getActor()} and {@link #getSource()}. {@link #getActor()} is + * NOT guaranteed to be an {@link net.minecraft.entity.player.EntityPlayerMP} */ LegacyRelaxed, /** diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/ChatThrottleKey.java b/src/main/java/com/gtnewhorizon/structurelib/structure/ChatThrottleKey.java index 751d7e7e..1dacccbc 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/ChatThrottleKey.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/ChatThrottleKey.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.structure; class ChatThrottleKey { static class NoExplicitChannel { + private static final int hashOffset = NoExplicitChannel.class.hashCode(); private final String subchannel; diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/DefaultSurvivalBuildEnvironment.java b/src/main/java/com/gtnewhorizon/structurelib/structure/DefaultSurvivalBuildEnvironment.java index 77f571f5..6ec16360 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/DefaultSurvivalBuildEnvironment.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/DefaultSurvivalBuildEnvironment.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.structure; import net.minecraft.entity.player.EntityPlayer; class DefaultSurvivalBuildEnvironment implements ISurvivalBuildEnvironment { + private final IItemSource source; private final EntityPlayer actor; diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IBlockPosConsumer.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IBlockPosConsumer.java index 568e1924..a14a7678 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IBlockPosConsumer.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IBlockPosConsumer.java @@ -3,5 +3,6 @@ package com.gtnewhorizon.structurelib.structure; import net.minecraft.world.World; public interface IBlockPosConsumer { + void consume(World world, int x, int y, int z); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/ICustomBlockSetting.java b/src/main/java/com/gtnewhorizon/structurelib/structure/ICustomBlockSetting.java index db52edd5..31dc726f 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/ICustomBlockSetting.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/ICustomBlockSetting.java @@ -4,9 +4,10 @@ import net.minecraft.block.Block; import net.minecraft.world.World; public interface ICustomBlockSetting { + /** - * Default block setting calls {@link World#setBlock(int x, int y, int z, Block block, int meta, int updateType)} like: - * {@code world.setBlock(x,y,z,this/block,meta,2)} where updateType 2 means to update lighting and stuff + * Default block setting calls {@link World#setBlock(int x, int y, int z, Block block, int meta, int updateType)} + * like: {@code world.setBlock(x,y,z,this/block,meta,2)} where updateType 2 means to update lighting and stuff * * @param world world that should be affected * @param x x position to set diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IItemSource.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IItemSource.java index 3f057a6f..e482850a 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IItemSource.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IItemSource.java @@ -1,25 +1,29 @@ package com.gtnewhorizon.structurelib.structure; +import java.util.Map; +import java.util.function.Predicate; + +import javax.annotation.Nonnull; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + import com.gtnewhorizon.structurelib.util.InventoryIterable; import com.gtnewhorizon.structurelib.util.InventoryUtility; import com.gtnewhorizon.structurelib.util.ItemStackPredicate; import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; -import java.util.Map; -import java.util.function.Predicate; -import javax.annotation.Nonnull; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemStack; /** * Represent an item source. Take only, cannot be placed back. */ public interface IItemSource { + /** * Retrieve some amount of items from this item source matching given filter. *

- * We probably don't need to get a lot of items from this method, - * so I don't care about the overhead of storing all fetched items even if downstream code doesn't need it + * We probably don't need to get a lot of items from this method, so I don't care about the overhead of storing all + * fetched items even if downstream code doesn't need it * * @param predicate filtering predicate. should return true for ItemStacks that should be added to result collection * @param simulate whether to actually commit the modification. true for dry run, false otherwise. @@ -64,11 +68,11 @@ public interface IItemSource { /** * Take exactly one item. ItemStack given must have a stack size of 1. *

- * This is meant to be an optimized version of {@link #takeOne(Predicate, boolean)}. - * Implementations that support item storage indexed by ItemStack can use this to speed up calculation. + * This is meant to be an optimized version of {@link #takeOne(Predicate, boolean)}. Implementations that support + * item storage indexed by ItemStack can use this to speed up calculation. * - * @param stack what item to extract. The NBT tag of this ItemStack is siginifcant and will be - * considered during matching. must have a stack size of 1. + * @param stack what item to extract. The NBT tag of this ItemStack is siginifcant and will be considered during + * matching. must have a stack size of 1. * @param simulate whether to actually commit the modification. true for dry run, false otherwise. * @return true if found. false otherwise * @throws IllegalArgumentException if given stack is invalid, or has a stack size other than 1. @@ -82,8 +86,8 @@ public interface IItemSource { /** * Take some item. Will not take item if it cannot find enough items to take. *

- * This is meant to be an optimized version of {@link #takeOne(Predicate, boolean)}. - * Implementations that support indexing off ItemStack can use this to speed up calculation. + * This is meant to be an optimized version of {@link #takeOne(Predicate, boolean)}. Implementations that support + * indexing off ItemStack can use this to speed up calculation. * * @param stack what item and how many to extract. The NBT tag of this ItemStack is siginifcant and will be * considered during matching @@ -110,6 +114,7 @@ public interface IItemSource { */ static IItemSource fromPlayer(EntityPlayerMP player) { return new IItemSource() { + @Nonnull @Override public Map take(Predicate p, boolean s, int c) { diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/ISpecialItemBlock.java b/src/main/java/com/gtnewhorizon/structurelib/structure/ISpecialItemBlock.java index d7ca064f..cb247902 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/ISpecialItemBlock.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/ISpecialItemBlock.java @@ -3,5 +3,6 @@ package com.gtnewhorizon.structurelib.structure; import net.minecraft.block.Block; public interface ISpecialItemBlock { + int getItemMetaFromBlockMeta(Block block, int blockMeta); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java index 56a7b6b7..8c152071 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureDefinition.java @@ -3,26 +3,28 @@ package com.gtnewhorizon.structurelib.structure; import static com.gtnewhorizon.structurelib.structure.IStructureWalker.ignoreBlockUnloaded; import static com.gtnewhorizon.structurelib.structure.IStructureWalker.skipBlockUnloaded; -import com.gtnewhorizon.structurelib.StructureLib; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import java.util.function.Function; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.StructureLib; +import com.gtnewhorizon.structurelib.StructureLibAPI; +import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; + /** * This is the structure definition of your multi. You will have one of these for each multi. * *

Cache the instances of this class

*

- * You will construct this definition once per multi, either at class load or at first call to your variant of {@code getStructureDefinition()}. - * You can use a {@link ClassValue ClassValue<IStructureDefinition<?>>} if you have a template for subclass. - * You can also use {@link StructureUtility#defer(Function) defer()} or its overloads for simpler cases, but it is - * slightly less performant as it will allocate new objects on each structure check, whereas {@link ClassValue} will - * allocate once and cache it onwards. + * You will construct this definition once per multi, either at class load or at first call to your variant of + * {@code getStructureDefinition()}. You can use a {@link ClassValue ClassValue<IStructureDefinition<?>>} if you + * have a template for subclass. You can also use {@link StructureUtility#defer(Function) defer()} or its overloads for + * simpler cases, but it is slightly less performant as it will allocate new objects on each structure check, whereas + * {@link ClassValue} will allocate once and cache it onwards. *

*

Constructing

*

@@ -30,30 +32,39 @@ import net.minecraft.world.World; *

* Builder has two main methods: *

    - *
  • {@link com.gtnewhorizon.structurelib.structure.StructureDefinition.Builder#addShape(String, String[][]) addShape()} - * is a 2d string array describing the layout of structure. You can optionally use `StructureUtility#transpose()` - * to transpose the array to make the structure look nicer in source code. - *
  • {@link com.gtnewhorizon.structurelib.structure.StructureDefinition.Builder#addElement(Character, IStructureElement) addElement()}. It takes a char identifier (mapped to a char in any of {@link com.gtnewhorizon.structurelib.structure.StructureDefinition.Builder#addShape(String, String[][]) addShape()} calls) and a {@link IStructureElement}. + *
  • {@link com.gtnewhorizon.structurelib.structure.StructureDefinition.Builder#addShape(String, String[][]) + * addShape()} is a 2d string array describing the layout of structure. You can optionally use + * `StructureUtility#transpose()` to transpose the array to make the structure look nicer in source code. + *
  • {@link com.gtnewhorizon.structurelib.structure.StructureDefinition.Builder#addElement(Character, IStructureElement) + * addElement()}. It takes a char identifier (mapped to a char in any of + * {@link com.gtnewhorizon.structurelib.structure.StructureDefinition.Builder#addShape(String, String[][]) addShape()} + * calls) and a {@link IStructureElement}. *
*

Position A, B and C

* * Imagine you stand in front of the controller, with controller facing towards you not rotated or flipped. *
    - *
  • The "A" position would be the number of blocks on the left side of the controller, not counting controller itself.
  • - *
  • The "B" position would be the number of blocks on the top side of the controller, not counting controller itself.
  • + *
  • The "A" position would be the number of blocks on the left side of the controller, not counting controller + * itself.
  • + *
  • The "B" position would be the number of blocks on the top side of the controller, not counting controller + * itself.
  • *
  • The "C" position would be the number of blocks between you and controller, not counting controller itself.
  • *
+ * * @param Type of the context object. Usually this will be the multiblock controller. */ public interface IStructureDefinition { + /** * Used internally *

- * Might, but is not required, to throw {@link java.util.NoSuchElementException} if the given structure piece is not found. + * Might, but is not required, to throw {@link java.util.NoSuchElementException} if the given structure piece is not + * found. * * @param name same name as for other methods here * @return the array of elements to process - * @throws java.util.NoSuchElementException if the given structure piece is not found and the moon phase perfectly matches + * @throws java.util.NoSuchElementException if the given structure piece is not found and the moon phase perfectly + * matches */ IStructureElement[] getStructureFor(String name); @@ -61,30 +72,22 @@ public interface IStructureDefinition { /** * Run a structure check. - * @param object context object. usually multiblock controller. - * @param piece the structure piece's string identifier. - * @param world the world object this check takes place in. - * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc + * + * @param object context object. usually multiblock controller. + * @param piece the structure piece's string identifier. + * @param world the world object this check takes place in. + * @param extendedFacing the current structure's orientation. + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc * @param forceCheckAllBlocks check all location even if chunk not currently loaded. * @return true if successful, false otherwise */ - default boolean check( - T object, - String piece, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, + default boolean check(T object, String piece, World world, ExtendedFacing extendedFacing, int basePositionX, + int basePositionY, int basePositionZ, int basePositionA, int basePositionB, int basePositionC, boolean forceCheckAllBlocks) { return iterate( object, @@ -104,29 +107,21 @@ public interface IStructureDefinition { /** * Spawn hint particles. Should not be called on server side. - * @param object context object. usually multiblock controller. - * @param piece the structure piece's string identifier. - * @param world the world object this check takes place in. + * + * @param object context object. usually multiblock controller. + * @param piece the structure piece's string identifier. + * @param world the world object this check takes place in. * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc * @return true if successful, false otherwise */ - default boolean hints( - T object, - ItemStack trigger, - String piece, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, + default boolean hints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, + int basePositionX, int basePositionY, int basePositionZ, int basePositionA, int basePositionB, int basePositionC) { return iterate( object, @@ -148,30 +143,21 @@ public interface IStructureDefinition { * Build the multi in creative mode on a best-effort basis. Does not guarantee the structure is correct after a * successful call. * - * @param object context object. usually multiblock controller. - * @param trigger The trigger item that contains channel data. - * @param piece the structure piece's string identifier. - * @param world the world object this check takes place in. + * @param object context object. usually multiblock controller. + * @param trigger The trigger item that contains channel data. + * @param piece the structure piece's string identifier. + * @param world the world object this check takes place in. * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc * @return true if sucessful, false otherwise */ - default boolean build( - T object, - ItemStack trigger, - String piece, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, + default boolean build(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, + int basePositionX, int basePositionY, int basePositionZ, int basePositionA, int basePositionB, int basePositionC) { return iterate( object, @@ -190,38 +176,29 @@ public interface IStructureDefinition { } /** - * Call {@link #build(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int)} if {@code hintsOnly}, - * call {@link #hints(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int)} otherwise. + * Call {@link #build(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int)} if + * {@code hintsOnly}, call + * {@link #hints(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int)} otherwise. * - * @param object context object. usually multiblock controller. - * @param trigger The trigger item that contains channel data. - * @param piece the structure piece's string identifier. - * @param world the world object this check takes place in. + * @param object context object. usually multiblock controller. + * @param trigger The trigger item that contains channel data. + * @param piece the structure piece's string identifier. + * @param world the world object this check takes place in. * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc - * @param hintsOnly whether to spawn hints or do creative build. + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc + * @param hintsOnly whether to spawn hints or do creative build. * @return true if sucessful, false otherwise * @see #hints(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int) * @see #build(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int) */ - default boolean buildOrHints( - T object, - ItemStack trigger, - String piece, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - boolean hintsOnly) { + default boolean buildOrHints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, + int basePositionX, int basePositionY, int basePositionZ, int basePositionA, int basePositionB, + int basePositionC, boolean hintsOnly) { return iterate( object, trigger, @@ -241,44 +218,31 @@ public interface IStructureDefinition { /** * Cause a survival build. * - * @param object context object. usually multiblock controller. - * @param trigger The trigger item that contains channel data. - * @param piece the structure piece's string identifier. - * @param world the world object this check takes place in. + * @param object context object. usually multiblock controller. + * @param trigger The trigger item that contains channel data. + * @param piece the structure piece's string identifier. + * @param world the world object this check takes place in. * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc - * @param elementBudget build up to this many elements - * @param source from where to drain resource - * @param actor source of action - * @param check whether {@link IStructureElement#check(Object, World, int, int, int)} should be called if anything - * would be placed. use with caution. - * if in doubt, call {@link #check(Object, String, World, ExtendedFacing, int, int, int, int, int, int, boolean)} - * after this call and set this parameter to false + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc + * @param elementBudget build up to this many elements + * @param source from where to drain resource + * @param actor source of action + * @param check whether {@link IStructureElement#check(Object, World, int, int, int)} should be called if + * anything would be placed. use with caution. if in doubt, call + * {@link #check(Object, String, World, ExtendedFacing, int, int, int, int, int, int, boolean)} + * after this call and set this parameter to false * @return number of elements built, or -1 if structure done * @see #build(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int) */ @Deprecated - default int survivalBuild( - T object, - ItemStack trigger, - String piece, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - int elementBudget, - IItemSource source, - EntityPlayerMP actor, - boolean check) { + default int survivalBuild(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, + int basePositionX, int basePositionY, int basePositionZ, int basePositionA, int basePositionB, + int basePositionC, int elementBudget, IItemSource source, EntityPlayerMP actor, boolean check) { EntityPlayer realActor; if (actor == null) { realActor = ISurvivalConstructable.__get_player(); @@ -306,41 +270,29 @@ public interface IStructureDefinition { /** * Cause a survival build. * - * @param object context object. usually multiblock controller. - * @param trigger The trigger item that contains channel data. - * @param piece the structure piece's string identifier. - * @param world the world object this check takes place in. + * @param object context object. usually multiblock controller. + * @param trigger The trigger item that contains channel data. + * @param piece the structure piece's string identifier. + * @param world the world object this check takes place in. * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc - * @param elementBudget build up to this many elements - * @param env build environment. - * @param check whether {@link IStructureElement#check(Object, World, int, int, int)} should be called if anything - * would be placed. use with caution. - * if in doubt, call {@link IStructureDefinition#check(Object, String, World, ExtendedFacing, int, int, int, int, int, int, boolean)} - * after this call and set this parameter to false + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc + * @param elementBudget build up to this many elements + * @param env build environment. + * @param check whether {@link IStructureElement#check(Object, World, int, int, int)} should be called if + * anything would be placed. use with caution. if in doubt, call + * {@link IStructureDefinition#check(Object, String, World, ExtendedFacing, int, int, int, int, int, int, boolean)} + * after this call and set this parameter to false * @return number of elements built, or -1 if structure done * @see #build(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int) */ - default int survivalBuild( - T object, - ItemStack trigger, - String piece, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - int elementBudget, - ISurvivalBuildEnvironment env, - boolean check) { + default int survivalBuild(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, + int basePositionX, int basePositionY, int basePositionZ, int basePositionA, int basePositionB, + int basePositionC, int elementBudget, ISurvivalBuildEnvironment env, boolean check) { SurvivalBuildStructureWalker walker = new SurvivalBuildStructureWalker<>( object, trigger, @@ -349,7 +301,7 @@ public interface IStructureDefinition { this, piece, extendedFacing, - new int[] {basePositionA, basePositionB, basePositionC}, + new int[] { basePositionA, basePositionB, basePositionC }, check); StructureUtility.iterateV2( getStructureFor(piece), @@ -368,37 +320,28 @@ public interface IStructureDefinition { /** * Low level utility. - * @param object context object. usually multiblock controller. - * @param trigger The trigger item that contains channel data. - * @param elements the structure piece - * @param world the world object this check takes place in. - * @param extendedFacing the current structure's orientation. - * @param basePositionX X location of the structure - * @param basePositionY Y location of the structure - * @param basePositionZ Z location of the structure - * @param basePositionA see class javadoc - * @param basePositionB see class javadoc - * @param basePositionC see class javadoc - * @param hintsOnly whether to spawn hints or do creative build. no effect if {@code checkBlocksIfNotNullForceCheckAllIfTrue} is not null. - * @param checkBlocksIfNotNullForceCheckAllIfTrue creative build or spawn hints if null. Force check not loaded chunk - * if true. Check only loaded chunk is false. + * + * @param object context object. usually multiblock controller. + * @param trigger The trigger item that contains channel data. + * @param elements the structure piece + * @param world the world object this check takes place in. + * @param extendedFacing the current structure's orientation. + * @param basePositionX X location of the structure + * @param basePositionY Y location of the structure + * @param basePositionZ Z location of the structure + * @param basePositionA see class javadoc + * @param basePositionB see class javadoc + * @param basePositionC see class javadoc + * @param hintsOnly whether to spawn hints or do creative build. no effect if + * {@code checkBlocksIfNotNullForceCheckAllIfTrue} is not null. + * @param checkBlocksIfNotNullForceCheckAllIfTrue creative build or spawn hints if null. Force check not loaded + * chunk if true. Check only loaded chunk is false. * @return true if iteration completed successfully. * @param type of context object. */ - static boolean iterate( - T object, - ItemStack trigger, - IStructureElement[] elements, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - boolean hintsOnly, - Boolean checkBlocksIfNotNullForceCheckAllIfTrue) { + static boolean iterate(T object, ItemStack trigger, IStructureElement[] elements, World world, + ExtendedFacing extendedFacing, int basePositionX, int basePositionY, int basePositionZ, int basePositionA, + int basePositionB, int basePositionC, boolean hintsOnly, Boolean checkBlocksIfNotNullForceCheckAllIfTrue) { if (!world.isRemote && hintsOnly) { return false; } @@ -433,8 +376,8 @@ public interface IStructureDefinition { "check force"); } if (StructureLibAPI.isDebugEnabled() && success) { - StructureLib.LOGGER.info( - "Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] pass"); + StructureLib.LOGGER + .info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] pass"); } return success; } else { @@ -477,6 +420,7 @@ public interface IStructureDefinition { /** * Create a new instance of builder. + * * @param type of context object */ static StructureDefinition.Builder builder() { diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java index 3769b537..eb16fcc5 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElement.java @@ -3,15 +3,14 @@ package com.gtnewhorizon.structurelib.structure; import static com.gtnewhorizon.structurelib.StructureLib.LOGGER; import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE; -import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; 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; @@ -21,11 +20,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.util.ItemStackPredicate; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; + /** - * Use StructureUtility to instantiate. These are the building blocks for your {@link IStructureDefinition}. It represents - * what a particular element can be and how this particular element should be autoplaced. + * Use StructureUtility to instantiate. These are the building blocks for your {@link IStructureDefinition}. It + * represents what a particular element can be and how this particular element should be autoplaced. */ public interface IStructureElement { + boolean check(T t, World world, int x, int y, int z); boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger); @@ -35,35 +39,27 @@ public interface IStructureElement { /** * Try place the block by taking resource from given IItemSource. *

- * You might want to use {@link StructureUtility#survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, net.minecraft.entity.player.EntityPlayer)} + * You might want to use + * {@link StructureUtility#survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, net.minecraft.entity.player.EntityPlayer)} * or its overloads to implement this. * * @param trigger trigger item * @param s drain resources from this place - * @param actor source of action. for very critical errors you can also just send the error messages here, bypassing - * any filter that chatter might have. + * @param actor source of action. for very critical errors you can also just send the error messages here, + * bypassing any filter that chatter might have. * @param chatter send error messages here. Caller will choose an appropriate way to forward it to player if the * other fallbacks also fails. * @deprecated caller should call the non deprecated overload. implementor for reusable {@link IStructureElement} - * should still implement this. implementor for private implementations can freely ignore this as long as you know - * the caller will not call this overload. + * should still implement this. implementor for private implementations can freely ignore this as long + * as you know the caller will not call this overload. */ @Deprecated - default PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { if (PANIC_MODE) throw new RuntimeException("Panic Tripwire hit"); - if (StructureLibAPI.isDebugEnabled()) - LOGGER.error( - "Default implementation of survivalPlaceBlock hit! Things aren't going to work well! IStructureElement class: {}", - getClass().getName()); + if (StructureLibAPI.isDebugEnabled()) LOGGER.error( + "Default implementation of survivalPlaceBlock hit! Things aren't going to work well! IStructureElement class: {}", + getClass().getName()); if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; return PlaceResult.SKIP; } @@ -73,54 +69,64 @@ public interface IStructureElement { *

* BY OVERRIDING THIS TO NULL, YOU ACKNOWLEDGE THAT THE {@link #check(Object, World, int, int, int)} OF THIS * CLASS IS SIDE EFFECT FREE AND CAN HAVE ITS CHECK CALLED WITHOUT BREAKING ANYTHING. OTHERWISE OVERRIDE THE - * {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} TO PROVIDE A SIDEEFFECT - * FREE {@link PlaceResult#SKIP}. + * {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} TO PROVIDE A + * SIDEEFFECT FREE {@link PlaceResult#SKIP}. *

- * It should be noticed that this filter is only advisory and the actual {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} - * or {@link #check(Object, World, int, int, int)} are free to reject/accept/place blocks not contained in this list, + * It should be noticed that this filter is only advisory and the actual + * {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} or + * {@link #check(Object, World, int, int, int)} are free to reject/accept/place blocks not contained in this list, * e.g. when the element can be placed anywhere in the structure, but no more than 3 overall; when the structure * element cannot know all blocks it will accept at the time of calling; when this is backed by a legacy * {@link IStructureElement} that just didn't implement this API. * * @param trigger trigger item * @param env autoplacing environment - * @return null if not implemented, otherwise an instance describing what kind of blocks will be placed by {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} + * @return null if not implemented, otherwise an instance describing what kind of blocks will be placed by + * {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)} */ @Nullable - default BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return null; } /** * Try place the block by taking resource from given {@link IItemSource}. *

- * You might want to use {@link StructureUtility#survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, net.minecraft.entity.player.EntityPlayer)} + * You might want to use + * {@link StructureUtility#survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, net.minecraft.entity.player.EntityPlayer)} * or its overloads to implement this. *

* The default implementation provided will *

    - *
  1. Get {@link BlocksToPlace} via {@link #getBlocksToPlace(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)}. If not null - *
      - *
    1. call {@link #check(Object, World, int, int, int)}. If this returns {@code true}, {@link PlaceResult#SKIP} will be returned without further action.
    2. - *
    3. Use the {@link BlocksToPlace} retrieved earlier and passed in {@link IItemSource} to determine an item to place
    4. - *
    5. Hand over control to {@link StructureUtility#survivalPlaceBlock(ItemStack, NBTMode, NBTTagCompound, boolean, World, int, int, int, IItemSource, EntityPlayer, Consumer)}
    6. - *
    - *
  2. - *
  3. Call legacy {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} if {@code env.getActor()} contains an {@link EntityPlayerMP}
  4. - *
  5. Emit warning under debug mode (or throw exception under panic mode), then return {@link PlaceResult#SKIP}
  6. + *
  7. Get {@link BlocksToPlace} via + * {@link #getBlocksToPlace(Object, World, int, int, int, ItemStack, AutoPlaceEnvironment)}. If not null + *
      + *
    1. call {@link #check(Object, World, int, int, int)}. If this returns {@code true}, {@link PlaceResult#SKIP} + * will be returned without further action.
    2. + *
    3. Use the {@link BlocksToPlace} retrieved earlier and passed in {@link IItemSource} to determine an item to + * place
    4. + *
    5. Hand over control to + * {@link StructureUtility#survivalPlaceBlock(ItemStack, NBTMode, NBTTagCompound, boolean, World, int, int, int, IItemSource, EntityPlayer, Consumer)}
    6. + *
    + *
  8. + *
  9. Call legacy + * {@link #survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} if + * {@code env.getActor()} contains an {@link EntityPlayerMP}
  10. + *
  11. Emit warning under debug mode (or throw exception under panic mode), then return + * {@link PlaceResult#SKIP}
  12. *
* It should be noticed that the default implementation is likely to cause unexpected issues if the - * {@link #check(Object, World, int, int, int)} is not side effect free, or is not idempotent. - * E.g. the {@link #check(Object, World, int, int, int)} will add current coord to a {@link java.util.List}. As - * this method might be invoked at a location that is already accepted, this will cause the machine to have multiple - * of this coord in its list. + * {@link #check(Object, World, int, int, int)} is not side effect free, or is not idempotent. E.g. the + * {@link #check(Object, World, int, int, int)} will add current coord to a {@link java.util.List}. As this method + * might be invoked at a location that is already accepted, this will cause the machine to have multiple of this + * coord in its list. * * @param trigger trigger item * @param env autoplacing environment */ - default PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { BlocksToPlace e = getBlocksToPlace(t, world, x, y, z, trigger, env); IItemSource source = env.getSource(); EntityPlayer actor = env.getActor(); @@ -130,22 +136,41 @@ public interface IStructureElement { if (e.getStacks() == null) { ItemStack taken = source.takeOne(e.getPredicate(), true); return StructureUtility.survivalPlaceBlock( - taken, NBTMode.EXACT, taken.stackTagCompound, true, world, x, y, z, source, actor, chatter); + taken, + NBTMode.EXACT, + taken.stackTagCompound, + true, + world, + x, + y, + z, + source, + actor, + chatter); } for (ItemStack stack : e.getStacks()) { if (!source.takeOne(stack, true)) continue; return StructureUtility.survivalPlaceBlock( - stack, NBTMode.EXACT, stack.stackTagCompound, true, world, x, y, z, source, actor, chatter); + stack, + NBTMode.EXACT, + stack.stackTagCompound, + true, + world, + x, + y, + z, + source, + actor, + chatter); } return PlaceResult.REJECT; } if (actor instanceof EntityPlayerMP) return survivalPlaceBlock(t, world, x, y, z, trigger, source, (EntityPlayerMP) actor, chatter); if (PANIC_MODE) throw new RuntimeException("Panic Tripwire hit"); - if (StructureLibAPI.isDebugEnabled()) - LOGGER.info( - "Fallback shim code of survivalPlaceBlock hit! Things aren't going to work well! IStructureElement class: {}", - getClass().getName()); + if (StructureLibAPI.isDebugEnabled()) LOGGER.info( + "Fallback shim code of survivalPlaceBlock hit! Things aren't going to work well! IStructureElement class: {}", + getClass().getName()); return PlaceResult.SKIP; } @@ -197,18 +222,19 @@ public interface IStructureElement { enum PlaceResult { /** - * This element either exists already, or does not yet have an implementation for survivalPlaceBlock, or - * some other unforeseen situations. - * TODO this definition doesn't seem right. Should we separate SKIP from EXISTS, or SKIP from ERROR? + * This element either exists already, or does not yet have an implementation for survivalPlaceBlock, or some + * other unforeseen situations. TODO this definition doesn't seem right. Should we separate SKIP from EXISTS, or + * SKIP from ERROR? */ SKIP, /** - * This element's space is occupied by other stuff and require player attention, or player missing required resource, - * or the block cannot be placed due to obscure mechanisms, or some other unforeseen situations. + * This element's space is occupied by other stuff and require player attention, or player missing required + * resource, or the block cannot be placed due to obscure mechanisms, or some other unforeseen situations. */ REJECT, /** - * Autoplace cannot proceed within this tick. To proceed further would require stopping the placement and wait for next round. + * Autoplace cannot proceed within this tick. To proceed further would require stopping the placement and wait + * for next round. */ STOP, /** @@ -224,6 +250,7 @@ public interface IStructureElement { } final class BlocksToPlace { + public static final BlocksToPlace errored = createEmpty(); private final Predicate predicate; private final Iterable stacks; diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementChain.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementChain.java index fe58b7e4..5bc55cd8 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementChain.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementChain.java @@ -1,20 +1,24 @@ package com.gtnewhorizon.structurelib.structure; -import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; + import javax.annotation.Nullable; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; +import com.google.common.collect.Iterables; + /** * Use StructureUtility to instantiate */ public interface IStructureElementChain extends IStructureElement { + IStructureElement[] fallbacks(); @Override @@ -49,8 +53,8 @@ public interface IStructureElementChain extends IStructureElement { @Nullable @Override - default BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { Predicate predicate = null; List> is = new ArrayList<>(); for (IStructureElement fallback : fallbacks()) { @@ -65,16 +69,8 @@ public interface IStructureElementChain extends IStructureElement { } @Override - default PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { boolean haveSkip = false; List bufferedNoise = new ArrayList<>(); for (IStructureElement fallback : fallbacks()) { @@ -96,13 +92,13 @@ public interface IStructureElementChain extends IStructureElement { } @Override - default PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { boolean haveSkip = false; List bufferedNoise = new ArrayList<>(); for (IStructureElement fallback : fallbacks()) { - PlaceResult result = - fallback.survivalPlaceBlock(t, world, x, y, z, trigger, env.withChatter(bufferedNoise::add)); + PlaceResult result = fallback + .survivalPlaceBlock(t, world, x, y, z, trigger, env.withChatter(bufferedNoise::add)); switch (result) { case REJECT: break; diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementCheckOnly.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementCheckOnly.java index e874389d..03f2b859 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementCheckOnly.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementCheckOnly.java @@ -1,12 +1,14 @@ package com.gtnewhorizon.structurelib.structure; import java.util.function.Consumer; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; public interface IStructureElementCheckOnly extends IStructureElement { + @Override default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { return false; @@ -18,22 +20,14 @@ public interface IStructureElementCheckOnly extends IStructureElement { } @Override - default PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { return PlaceResult.SKIP; } @Override - default PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return PlaceResult.SKIP; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementDeferred.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementDeferred.java index 44d02988..cf5ab2d9 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementDeferred.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementDeferred.java @@ -3,4 +3,5 @@ package com.gtnewhorizon.structurelib.structure; /** * Use StructureUtility to instantiate */ -public interface IStructureElementDeferred extends IStructureElement {} +public interface IStructureElementDeferred extends IStructureElement { +} diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementNoPlacement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementNoPlacement.java index 0570e862..9a8ee12e 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementNoPlacement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureElementNoPlacement.java @@ -1,34 +1,28 @@ package com.gtnewhorizon.structurelib.structure; import java.util.function.Consumer; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; public interface IStructureElementNoPlacement extends IStructureElement { + @Override default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { return false; } @Override - default PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { return PlaceResult.REJECT; } @Override - default PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return PlaceResult.REJECT; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureNavigate.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureNavigate.java index a464b317..6ce52c52 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureNavigate.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureNavigate.java @@ -1,6 +1,7 @@ package com.gtnewhorizon.structurelib.structure; import java.util.function.Consumer; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; @@ -10,6 +11,7 @@ import net.minecraft.world.World; * Use StructureUtility to instantiate */ interface IStructureNavigate extends IStructureElement { + @Override default boolean check(T t, World world, int x, int y, int z) { return true; @@ -26,22 +28,14 @@ interface IStructureNavigate extends IStructureElement { } @Override - default PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { return PlaceResult.SKIP; } @Override - default PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return PlaceResult.SKIP; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureWalker.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureWalker.java index 9284f3a9..2f3111df 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureWalker.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IStructureWalker.java @@ -3,23 +3,25 @@ package com.gtnewhorizon.structurelib.structure; import net.minecraft.world.World; interface IStructureWalker { + boolean visit(IStructureElement element, World world, int x, int y, int z, int a, int b, int c); - default boolean blockNotLoaded( - IStructureElement element, World world, int x, int y, int z, int a, int b, int c) { + default boolean blockNotLoaded(IStructureElement element, World world, int x, int y, int z, int a, int b, + int c) { return false; } static IStructureWalker ignoreBlockUnloaded(IStructureWalker walker) { return new IStructureWalker() { + @Override public boolean visit(IStructureElement element, World world, int x, int y, int z, int a, int b, int c) { return walker.visit(element, world, x, y, z, a, b, c); } @Override - public boolean blockNotLoaded( - IStructureElement element, World world, int x, int y, int z, int a, int b, int c) { + public boolean blockNotLoaded(IStructureElement element, World world, int x, int y, int z, int a, int b, + int c) { return walker.visit(element, world, x, y, z, a, b, c); } }; @@ -27,14 +29,15 @@ interface IStructureWalker { static IStructureWalker skipBlockUnloaded(IStructureWalker walker) { return new IStructureWalker() { + @Override public boolean visit(IStructureElement element, World world, int x, int y, int z, int a, int b, int c) { return walker.visit(element, world, x, y, z, a, b, c); } @Override - public boolean blockNotLoaded( - IStructureElement element, World world, int x, int y, int z, int a, int b, int c) { + public boolean blockNotLoaded(IStructureElement element, World world, int x, int y, int z, int a, int b, + int c) { return true; } }; diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/ISurvivalBuildEnvironment.java b/src/main/java/com/gtnewhorizon/structurelib/structure/ISurvivalBuildEnvironment.java index bda10471..cbfb296a 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/ISurvivalBuildEnvironment.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/ISurvivalBuildEnvironment.java @@ -1,25 +1,31 @@ package com.gtnewhorizon.structurelib.structure; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.world.World; +import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; + /* * Architecture notes: this should never get any callback from survival build. All structure significant code belongs - * within the IStructureElement. This will make the user easier to maintain the IStructureDefinition. - * Structure Element knows the most about what this structure element should do, not the caller. + * within the IStructureElement. This will make the user easier to maintain the IStructureDefinition. Structure Element + * knows the most about what this structure element should do, not the caller. */ public interface ISurvivalBuildEnvironment { + /** * Get the source of the items. This will be invoked exactly once per structure element build. *

- * If the call chain ever got into the old API, this will be called at least once per {@link IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, ISurvivalBuildEnvironment, boolean)} call. + * If the call chain ever got into the old API, this will be called at least once per + * {@link IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, ISurvivalBuildEnvironment, boolean)} + * call. */ IItemSource getSource(); /** - * Get the origin of action. This will be invoked at least once per {@link IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, ISurvivalBuildEnvironment, boolean)} call. + * Get the origin of action. This will be invoked at least once per + * {@link IStructureDefinition#survivalBuild(Object, ItemStack, String, World, ExtendedFacing, int, int, int, int, int, int, int, ISurvivalBuildEnvironment, boolean)} + * call. */ EntityPlayer getActor(); diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/ITierConverter.java b/src/main/java/com/gtnewhorizon/structurelib/structure/ITierConverter.java index 6eee2357..5943b4e2 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/ITierConverter.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/ITierConverter.java @@ -9,5 +9,6 @@ import net.minecraft.block.Block; */ @FunctionalInterface public interface ITierConverter { + TIER convert(Block block, int meta); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/IWithExtendedContext.java b/src/main/java/com/gtnewhorizon/structurelib/structure/IWithExtendedContext.java index 740933fc..8f182d3e 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/IWithExtendedContext.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/IWithExtendedContext.java @@ -11,5 +11,6 @@ package com.gtnewhorizon.structurelib.structure; * @param the temporary state context */ public interface IWithExtendedContext { + CTX getCurrentContext(); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/LazyStructureElement.java b/src/main/java/com/gtnewhorizon/structurelib/structure/LazyStructureElement.java index 8cb1bacc..3f8cfda3 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/LazyStructureElement.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/LazyStructureElement.java @@ -2,13 +2,16 @@ package com.gtnewhorizon.structurelib.structure; import java.util.function.Consumer; import java.util.function.Function; + import javax.annotation.Nullable; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; import net.minecraft.world.World; class LazyStructureElement implements IStructureElementDeferred { + private Function> to; private IStructureElement elem; @@ -41,28 +44,20 @@ class LazyStructureElement implements IStructureElementDeferred { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return get(t).getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { return get(t).survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return get(t).survivalPlaceBlock(t, world, x, y, z, trigger, env); } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureDefinition.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureDefinition.java index 71715d13..5e085c7f 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureDefinition.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureDefinition.java @@ -2,11 +2,13 @@ package com.gtnewhorizon.structurelib.structure; import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; -import com.gtnewhorizon.structurelib.util.Vec3Impl; import java.util.*; import java.util.stream.Collectors; +import com.gtnewhorizon.structurelib.util.Vec3Impl; + public class StructureDefinition implements IStructureDefinition { + private final Map> elements; private final Map shapes; private final Map[]> structures; @@ -16,11 +18,8 @@ public class StructureDefinition implements IStructureDefinition { return new Builder<>(); } - private StructureDefinition( - Map> elements, - Map shapes, - Map[]> structures, - Map> occupiedSpaces) { + private StructureDefinition(Map> elements, Map shapes, + Map[]> structures, Map> occupiedSpaces) { this.elements = elements; this.shapes = shapes; this.structures = structures; @@ -28,6 +27,7 @@ public class StructureDefinition implements IStructureDefinition { } public static class Builder { + private static final char A = '\uA000'; private static final char B = '\uB000'; private static final char C = '\uC000'; @@ -54,11 +54,10 @@ public class StructureDefinition implements IStructureDefinition { /** * Adds shape. Shape is a two-dimensional string array. Each character inside any of these strings will - * be later mapped to a particular type of {@link IStructureElement} as indicated by {@link #addElement(Character, IStructureElement)}. + * be later mapped to a particular type of {@link IStructureElement} as indicated by + * {@link #addElement(Character, IStructureElement)}. *

- * next char is next block(a) - * next string is next line(b) - * next string[] is next slice(c) + * next char is next block(a) next string is next line(b) next string[] is next slice(c) *

* There are a few special reserved characters that are pre-mapped to some common structure elements *

    @@ -71,7 +70,8 @@ public class StructureDefinition implements IStructureDefinition { *

    * * @param name unlocalized/code name - * @param structurePiece generated or written struct - DO NOT STORE IT ANYWHERE, or at least set them to null afterwards + * @param structurePiece generated or written struct - DO NOT STORE IT ANYWHERE, or at least set them to null + * afterwards * @return this builder */ public Builder addShape(String name, String[][] structurePiece) { @@ -170,22 +170,25 @@ public class StructureDefinition implements IStructureDefinition { public IStructureDefinition build() { Map[]> structures = compileStructureMap(); return new StructureDefinition<>( - new HashMap<>(elements), new HashMap<>(shapes), structures, occupiedSpaces); + new HashMap<>(elements), + new HashMap<>(shapes), + structures, + occupiedSpaces); } @SuppressWarnings("unchecked") private Map[]> compileElementSetMap() { Set missing = findMissing(); if (missing.isEmpty()) { - return shapes.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - .chars() - .mapToObj(c -> (char) c) - .distinct() - .map(elements::get) - .toArray(IStructureElement[]::new))); + return shapes.entrySet().stream().collect( + Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().chars().mapToObj(c -> (char) c).distinct().map(elements::get) + .toArray(IStructureElement[]::new))); } else { - throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " - + Arrays.toString(missing.toArray())); + throw new RuntimeException( + "Missing Structure Element bindings for (chars as integers): " + + Arrays.toString(missing.toArray())); } } @@ -193,22 +196,21 @@ public class StructureDefinition implements IStructureDefinition { private Map[]> compileStructureMap() { Set missing = findMissing(); if (missing.isEmpty()) { - return shapes.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue() - .chars() - .mapToObj(c -> elements.get((char) c)) - .toArray(IStructureElement[]::new))); + return shapes.entrySet().stream().collect( + Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().chars().mapToObj(c -> elements.get((char) c)) + .toArray(IStructureElement[]::new))); } else { - throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " - + Arrays.toString(missing.toArray())); + throw new RuntimeException( + "Missing Structure Element bindings for (chars as integers): " + + Arrays.toString(missing.toArray())); } } private Set findMissing() { - return shapes.values().stream() - .flatMapToInt(CharSequence::chars) - .filter(i -> !elements.containsKey((char) i)) - .boxed() - .collect(Collectors.toSet()); + return shapes.values().stream().flatMapToInt(CharSequence::chars) + .filter(i -> !elements.containsKey((char) i)).boxed().collect(Collectors.toSet()); } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureElement_Bridge.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureElement_Bridge.java index afbf58bf..5496d7c3 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureElement_Bridge.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureElement_Bridge.java @@ -1,6 +1,7 @@ package com.gtnewhorizon.structurelib.structure; import java.util.function.Consumer; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.IChatComponent; @@ -10,23 +11,16 @@ import net.minecraft.world.World; * Internal bridge class for easing implementation */ abstract class StructureElement_Bridge implements IStructureElement { + // seal the deprecated method to prevent accidental overrides @Deprecated @Override - public final PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public final PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { return survivalPlaceBlock(t, world, x, y, z, trigger, AutoPlaceEnvironment.fromLegacy(s, actor, chatter)); } // clear the default implementation. we don't need that. - public abstract PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env); + public abstract PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index b27769c6..460a2849 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -2,23 +2,12 @@ package com.gtnewhorizon.structurelib.structure; 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.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 java.util.*; import java.util.Map.Entry; import java.util.function.*; + import javax.annotation.Nullable; + import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -33,106 +22,116 @@ 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.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; + /** * A brief index of everything contained - *

    Control blocks

    - * A lot of these might seem to make more sense as a default function on {@link IStructureElement}. However, in that - * case javac generic will often fail to infer the type for you, so we have to define them as static methods - *

    If block

    - * Provide if block, allowing downstream call only if user specified conditions are meet (i.e. predicate returns true) + *

    Control blocks

    A lot of these might seem to make more sense as a default function on + * {@link IStructureElement}. However, in that case javac generic will often fail to infer the type for you, so we have + * to define them as static methods + *

    If block

    Provide if block, allowing downstream call only if user specified conditions are meet (i.e. + * predicate returns true) *
      - *
    • {@link #onlyIf(Predicate, IStructureElement)} and its overloads
    • + *
    • {@link #onlyIf(Predicate, IStructureElement)} and its overloads
    • *
    - *

    Switch block

    - * Provide switch block, allowing to select a downstream element by using a key or index computed from trigger item - * and/or context object. + *

    Switch block

    Provide switch block, allowing to select a downstream element by using a key or index computed + * from trigger item and/or context object. *
      - *
    • {@link #partitionBy(Function, IStructureElement[])} and its overloads
    • + *
    • {@link #partitionBy(Function, IStructureElement[])} and its overloads
    • *
    - *

    Or Chain

    - * Provide a short-circuiting OR chain. + *

    Or Chain

    Provide a short-circuiting OR chain. *
      - *
    • {@link #ofChain(IStructureElement[])} and its overloads
    • + *
    • {@link #ofChain(IStructureElement[])} and its overloads
    • *
    - *

    Side effect

    - * Provide callbacks on various occasion + *

    Side effect

    Provide callbacks on various occasion *
      - *
    • {@link #onElementPass(Consumer, IStructureElement)}: Call an callback upon element check success
    • - *
    • {@link #onElementFail(Consumer, IStructureElement)}: Call an callback upon element check failure
    • + *
    • {@link #onElementPass(Consumer, IStructureElement)}: Call an callback upon element check success
    • + *
    • {@link #onElementFail(Consumer, IStructureElement)}: Call an callback upon element check failure
    • *
    * *

    Other Primitives

    - *

    Error statement

    - * Unconditionally return false. + *

    Error statement

    Unconditionally return false. *
      - *
    • {@link #error()}
    • + *
    • {@link #error()}
    • *
    - *

    Context Object Change

    - * Switch the context object. + *

    Context Object Change

    Switch the context object. *
      - *
    • {@link #withContext(IStructureElement)}: switch context to the extended context
    • + *
    • {@link #withContext(IStructureElement)}: switch context to the extended context
    • *
    - *

    Channel Change

    - * Change the channel. See Channels section on overview for more information. + *

    Channel Change

    Change the channel. See Channels section + * on overview for more information. *
      - *
    • {@link #withChannel(String, IStructureElement)}: switch channel using {@link ChannelDataAccessor#withChannel(ItemStack, String)} when a trigger item is present.
    • + *
    • {@link #withChannel(String, IStructureElement)}: switch channel using + * {@link ChannelDataAccessor#withChannel(ItemStack, String)} when a trigger item is present.
    • *
    - *

    Spawn hint particle

    - * Just spawn a hint. Do nothing otherwise. Useful when you want to override the hint provided by another structure element, - * or as a fallback to a structure element that is check only. + *

    Spawn hint particle

    Just spawn a hint. Do nothing otherwise. Useful when you want to override the hint + * provided by another structure element, or as a fallback to a structure element that is check only. *
      - *
    • {@link #ofHint(int)}, {@link #ofHintDeferred(Supplier)} and its overloads
    • + *
    • {@link #ofHint(int)}, {@link #ofHintDeferred(Supplier)} and its overloads
    • *
    * - *

    Actual Element

    - * These elements are elements that can actually do structure check, spawn hint and do auto place. - * Elements listed in above 2 sections are not going to be helpful without elements like these. - * They also serve as a reference implementation for your own custom {@link IStructureElement} implementations. - *

    Simple Block Element

    - * These accept one or more different block types in one location. + *

    Actual Element

    These elements are elements that can actually do structure check, spawn hint and do auto + * place. Elements listed in above 2 sections are not going to be helpful without elements like these. They also serve + * as a reference implementation for your own custom {@link IStructureElement} implementations. + *

    Simple Block Element

    These accept one or more different block types in one location. *
      - *
    • {@link #ofBlock(Block, int, Block, int)}, {@link #ofBlocksFlat(Map, Block, int)}, {@link #ofBlocksMap(Map, Block, int)} - * and their overloads: the most basic form
    • - *
    • {@link #ofBlockHint(Block, int, Block, int)}, {@link #ofBlocksFlatHint(Map, Block, int)}, {@link #ofBlocksMapHint(Map, Block, int)}: - * these are the same as above, but will not do autoplace
    • - *
    • {@link #isAir()}, {@link #notAir()}: They are supplied by default under the identifier {@code '-'} and {@code '+'} - * respectively, but are provided here regardless in case you want to use them as a fallback.
    • + *
    • {@link #ofBlock(Block, int, Block, int)}, {@link #ofBlocksFlat(Map, Block, int)}, + * {@link #ofBlocksMap(Map, Block, int)} and their overloads: the most basic form
    • + *
    • {@link #ofBlockHint(Block, int, Block, int)}, {@link #ofBlocksFlatHint(Map, Block, int)}, + * {@link #ofBlocksMapHint(Map, Block, int)}: these are the same as above, but will not do autoplace
    • + *
    • {@link #isAir()}, {@link #notAir()}: They are supplied by default under the identifier {@code '-'} and + * {@code '+'} respectively, but are provided here regardless in case you want to use them as a fallback.
    • *
    - *

    Complex Block Element

    - * In case your logic on determining which block is accepted is complex, use these. + *

    Complex Block Element

    In case your logic on determining which block is accepted is complex, use these. *
      - *
    • {@link #ofBlockAdder(IBlockAdder, Block, int)}, {@link #ofBlockAdderHint(IBlockAdder, Block, int)} and their - * overloads: hands off actual adder logic to an {@link IBlockAdder} you supplied. Save you the boilerplate of querying - * block type and block meta from {@link World}
    • - *
    • {@link #ofBlocksTiered(ITierConverter, Object, BiConsumer, Function)} and its overloads: accept a series of - * blocks that each may have different tier, but only allow one single tier for anywhere this element is used (e.g. coils).
    • - *
    • {@link #ofTileAdder(ITileAdder, Block, int)}, {@link #ofSpecificTileAdder(BiPredicate, Class, Block, int)}: - * Similar to block adder, but for tile entities.
    • + *
    • {@link #ofBlockAdder(IBlockAdder, Block, int)}, {@link #ofBlockAdderHint(IBlockAdder, Block, int)} and their + * overloads: hands off actual adder logic to an {@link IBlockAdder} you supplied. Save you the boilerplate of querying + * block type and block meta from {@link World}
    • + *
    • {@link #ofBlocksTiered(ITierConverter, Object, BiConsumer, Function)} and its overloads: accept a series of + * blocks that each may have different tier, but only allow one single tier for anywhere this element is used (e.g. + * coils).
    • + *
    • {@link #ofTileAdder(ITileAdder, Block, int)}, {@link #ofSpecificTileAdder(BiPredicate, Class, Block, int)}: + * Similar to block adder, but for tile entities.
    • *
    * - *

    Helper Methods

    - * These don't construct a {@link IStructureElement}, but is helpful to the instantiation or implementation of these. + *

    Helper Methods

    These don't construct a {@link IStructureElement}, but is helpful to the instantiation or + * implementation of these. *
      - *
    • {@link #survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, EntityPlayer, Consumer)} and its overloads: - * Helper method to cut common boilerplate for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)}
    • - *
    • {@link #getPseudoJavaCode(World, ExtendedFacing, int, int, int, int, int, int, Function, int, int, int, boolean)}: - * Generate a structure code template from existing structure.
    • - *
    • {@link #iterate(World, ExtendedFacing, int, int, int, int, int, int, boolean, int, int, int, IBlockPosConsumer, Runnable, Runnable)} - * and its overloads: help iterate over a coordinate space.
    • + *
    • {@link #survivalPlaceBlock(Block, int, World, int, int, int, IItemSource, EntityPlayer, Consumer)} and its + * overloads: Helper method to cut common boilerplate for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)}
    • + *
    • {@link #getPseudoJavaCode(World, ExtendedFacing, int, int, int, int, int, int, Function, int, int, int, boolean)}: + * Generate a structure code template from existing structure.
    • + *
    • {@link #iterate(World, ExtendedFacing, int, int, int, int, int, int, boolean, int, int, int, IBlockPosConsumer, Runnable, Runnable)} + * and its overloads: help iterate over a coordinate space.
    • *
    */ public class StructureUtility { - private static final String NICE_CHARS = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=|!@#$%&()[]{};:<>/?_,.*^'`"; + + private static final String NICE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=|!@#$%&()[]{};:<>/?_,.*^'`"; @SuppressWarnings("rawtypes") private static final Map STEP = new HashMap<>(); @SuppressWarnings("rawtypes") private static final IStructureElement AIR = new StructureElement_Bridge() { + @Override public boolean check(Object t, World world, int x, int y, int z) { return world.isAirBlock(x, y, z); @@ -152,8 +151,8 @@ public class StructureUtility { @Override @Deprecated - public PlaceResult survivalPlaceBlock( - Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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; if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return PlaceResult.REJECT; world.setBlock(x, y, z, Blocks.air, 0, 2); @@ -163,6 +162,7 @@ public class StructureUtility { @SuppressWarnings("rawtypes") private static final IStructureElement NOT_AIR = new StructureElement_Bridge() { + @Override public boolean check(Object t, World world, int x, int y, int z) { return !world.isAirBlock(x, y, z); @@ -181,14 +181,14 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(Object o, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return BlocksToPlace.create(Objects::nonNull); } @Override - public PlaceResult survivalPlaceBlock( - Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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; // user should place anything here. // maybe make this configurable, but for now we try to take some cobble from user @@ -201,6 +201,7 @@ public class StructureUtility { @SuppressWarnings("rawtypes") private static final IStructureElement ERROR = new StructureElement_Bridge() { + @Override public boolean check(Object t, World world, int x, int y, int z) { return false; @@ -218,8 +219,8 @@ public class StructureUtility { } @Override - public PlaceResult survivalPlaceBlock( - Object o, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(Object o, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return PlaceResult.REJECT; } }; @@ -227,86 +228,72 @@ public class StructureUtility { private StructureUtility() {} /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. * * @param s drain resources from this place * @param actor source of action. cannot be null. */ - public static PlaceResult survivalPlaceBlock( - Block block, int meta, World world, int x, int y, int z, IItemSource s, EntityPlayerMP actor) { + public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, + EntityPlayerMP actor) { return survivalPlaceBlock(block, meta, world, x, y, z, s, (EntityPlayer) actor); } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. * * @param s drain resources from this place * @param actor source of action. cannot be null. */ - public static PlaceResult survivalPlaceBlock( - Block block, int meta, World world, int x, int y, int z, IItemSource s, EntityPlayer actor) { + public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, + EntityPlayer actor) { return survivalPlaceBlock(block, meta, world, x, y, z, s, actor, null); } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. - * This method might yield error messages to the chatter. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. This method might yield error messages to the chatter. * * @param s drain resources from this place * @param actor source of action. cannot be null. * @param chatter normal error destination. can be null to suppress them. */ - public static PlaceResult survivalPlaceBlock( - Block block, - int meta, - World world, - int x, - int y, - int z, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s, + EntityPlayerMP actor, Consumer chatter) { return survivalPlaceBlock(block, meta, world, x, y, z, s, (EntityPlayer) actor, chatter); } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. - * This method might yield error messages to the chatter. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. This method might yield error messages to the chatter. * * @param s drain resources from this place * @param actor source of action. cannot be null. * @param chatter normal error destination. can be null to suppress them. */ - public static PlaceResult survivalPlaceBlock( - Block block, - int meta, - World world, - int x, - int y, - int z, - IItemSource s, - EntityPlayer actor, - Consumer chatter) { + 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(); if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; Item itemBlock = Item.getItemFromBlock(block); @@ -314,10 +301,10 @@ public class StructureUtility { ? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta) : meta; if (!s.takeOne(new ItemStack(itemBlock, 1, itemMeta), false)) { - if (chatter != null) - chatter.accept(new ChatComponentTranslation( - "structurelib.autoplace.error.no_simple_block", - new ItemStack(itemBlock, 1, itemMeta).func_151000_E())); + if (chatter != null) chatter.accept( + new ChatComponentTranslation( + "structurelib.autoplace.error.no_simple_block", + new ItemStack(itemBlock, 1, itemMeta).func_151000_E())); return PlaceResult.REJECT; } if (block instanceof ICustomBlockSetting) { @@ -330,121 +317,96 @@ public class StructureUtility { } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. * * @param stack a valid stack with stack size of exactly 1. Must be of an ItemBlock! * @param s drain resources from this place * @param actor source of action. cannot be null. */ - public static PlaceResult survivalPlaceBlock( - ItemStack stack, - NBTMode nbtMode, - NBTTagCompound tag, - boolean assumeStackPresent, - World world, - int x, - int y, - int z, - IItemSource s, - EntityPlayerMP actor) { + public static PlaceResult survivalPlaceBlock(ItemStack stack, NBTMode nbtMode, NBTTagCompound tag, + boolean assumeStackPresent, World world, int x, int y, int z, IItemSource s, EntityPlayerMP actor) { return survivalPlaceBlock(stack, nbtMode, tag, assumeStackPresent, world, x, y, z, s, (EntityPlayer) actor); } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. * * @param stack a valid stack with stack size of exactly 1. Must be of an ItemBlock! * @param s drain resources from this place * @param actor source of action. cannot be null. */ - public static PlaceResult survivalPlaceBlock( - ItemStack stack, - NBTMode nbtMode, - NBTTagCompound tag, - boolean assumeStackPresent, - World world, - int x, - int y, - int z, - IItemSource s, - EntityPlayer actor) { + public static PlaceResult survivalPlaceBlock(ItemStack stack, NBTMode nbtMode, NBTTagCompound tag, + boolean assumeStackPresent, World world, int x, int y, int z, IItemSource s, EntityPlayer actor) { return survivalPlaceBlock(stack, nbtMode, tag, assumeStackPresent, world, x, y, z, s, actor, null); } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. - * This method might yield error messages to the chatter. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. This method might yield error messages to the chatter. * * @param stack a valid stack with stack size of exactly 1. Must be of an ItemBlock! * @param s drain resources from this place * @param actor source of action. cannot be null. * @param chatter normal error destination. can be null to suppress them. */ - public static PlaceResult survivalPlaceBlock( - ItemStack stack, - NBTMode nbtMode, - NBTTagCompound tag, - boolean assumeStackPresent, - World world, - int x, - int y, - int z, - IItemSource s, - EntityPlayerMP actor, + public static PlaceResult survivalPlaceBlock(ItemStack stack, NBTMode nbtMode, NBTTagCompound tag, + boolean assumeStackPresent, World world, int x, int y, int z, IItemSource s, EntityPlayerMP actor, @Nullable Consumer chatter) { return survivalPlaceBlock( - stack, nbtMode, tag, assumeStackPresent, world, x, y, z, s, (EntityPlayer) actor, chatter); + stack, + nbtMode, + tag, + assumeStackPresent, + world, + x, + y, + z, + s, + (EntityPlayer) actor, + chatter); } /** - * This is a helper method for implementing {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} + * This is a helper method for implementing + * {@link IStructureElement#survivalPlaceBlock(Object, World, int, int, int, ItemStack, IItemSource, EntityPlayerMP, Consumer)} *

    - * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at given - * location. - * This method assume block at given coord is NOT acceptable, but may or may not be trivially replaceable - * This method might yield error messages to the player only if there is likely a programming error or exploit. - * This method might yield error messages to the chatter. + * This method will try to look up an {@link ItemBlock} for given block and meta from {@code s} and place it at + * given location. This method assume block at given coord is NOT acceptable, but may or may not be trivially + * replaceable This method might yield error messages to the player only if there is likely a programming error or + * exploit. This method might yield error messages to the chatter. * * @param stack a valid stack with stack size of exactly 1. Must be of an ItemBlock! * @param s drain resources from this place * @param actor source of action. cannot be null. * @param chatter normal error destination. can be null to suppress them. */ - public static PlaceResult survivalPlaceBlock( - ItemStack stack, - NBTMode nbtMode, - NBTTagCompound tag, - boolean assumeStackPresent, - World world, - int x, - int y, - int z, - IItemSource s, - EntityPlayer actor, + 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 (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)) { - if (chatter != null) - chatter.accept(new ChatComponentTranslation( - "structurelib.autoplace.error.no_item_stack", stack.func_151000_E())); + 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)) @@ -456,9 +418,9 @@ public class StructureUtility { } /** - * 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. + * 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. */ @SuppressWarnings("unchecked") public static IStructureElement isAir() { @@ -466,9 +428,9 @@ 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. + * 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. */ @SuppressWarnings("unchecked") public static IStructureElement notAir() { @@ -476,9 +438,8 @@ public class StructureUtility { } /** - * Check returns false. - * Placement is always handled by this and does nothing. - * Makes little to no use it in fallback chain. + * Check returns false. Placement is always handled by this and does nothing. Makes little to no use it in fallback + * chain. */ @SuppressWarnings("unchecked") public static IStructureElement error() { @@ -488,13 +449,13 @@ public class StructureUtility { // region hint only /** - * Spawn a hint with given amount of dots. - * Check always returns: true. - * Only useful as a fallback, e.g. {@link #ofBlockUnlocalizedName(String, String, int, IStructureElement)} + * Spawn a hint with given amount of dots. Check always returns: true. Only useful as a fallback, e.g. + * {@link #ofBlockUnlocalizedName(String, String, int, IStructureElement)} */ public static IStructureElementNoPlacement ofHint(int dots) { int meta = dots - 1; return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return true; @@ -509,12 +470,12 @@ public class StructureUtility { } /** - * Spawn a hint with given textures. - * Check always returns: true. - * Only useful as a fallback, e.g. {@link #ofBlockUnlocalizedName(String, String, int, IStructureElement)} + * Spawn a hint with given textures. Check always returns: true. Only useful as a fallback, e.g. + * {@link #ofBlockUnlocalizedName(String, String, int, IStructureElement)} */ public static IStructureElementNoPlacement ofHintDeferred(Supplier icons) { return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return true; @@ -529,12 +490,12 @@ public class StructureUtility { } /** - * Spawn a hint with given amount of textures and tint. - * Check always returns: true. - * Only useful as a fallback, e.g. {@link #ofBlockUnlocalizedName(String, String, int, IStructureElement)} + * Spawn a hint with given amount of textures and tint. Check always returns: true. Only useful as a fallback, e.g. + * {@link #ofBlockUnlocalizedName(String, String, int, IStructureElement)} */ public static IStructureElementNoPlacement ofHintDeferred(Supplier icons, short[] RGBa) { return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return true; @@ -553,8 +514,8 @@ public class StructureUtility { // region block /** - * A more primitive variant of {@link #ofBlocksTiered(ITierConverter, List, Object, BiConsumer, Function)} - * Main difference is this one is check only. + * A more primitive variant of {@link #ofBlocksTiered(ITierConverter, List, Object, BiConsumer, Function)} Main + * difference is this one is check only. *

    * Note that if tierExtractor returns a null, this block will be rejected immediately. This makes null a potent * candidate for notSet. @@ -563,11 +524,8 @@ public class StructureUtility { * * @see #ofBlocksTiered(ITierConverter, Object, BiConsumer, Function) */ - public static IStructureElementCheckOnly ofBlocksTiered( - ITierConverter tierExtractor, - @Nullable TIER notSet, - BiConsumer setter, - Function getter) { + public static IStructureElementCheckOnly ofBlocksTiered(ITierConverter tierExtractor, + @Nullable TIER notSet, BiConsumer setter, Function getter) { if (tierExtractor == null) throw new IllegalArgumentException(); if (setter == null) throw new IllegalArgumentException(); if (getter == null) throw new IllegalArgumentException(); @@ -585,8 +543,8 @@ public class StructureUtility { } else { StructureLib.LOGGER.error("#########################################"); StructureLib.LOGGER.error("#########################################"); - StructureLib.LOGGER.error( - "tierExtractor should never return notSet: {}", notSet, new Throwable()); + StructureLib.LOGGER + .error("tierExtractor should never return notSet: {}", notSet, new Throwable()); StructureLib.LOGGER.error("#########################################"); StructureLib.LOGGER.error("#########################################"); } @@ -599,21 +557,21 @@ public class StructureUtility { } /** - * Element representing a component with different tiers. Your multi will accept any of them (as long as - * player does not mix them (*)), but would like to know which is used. Player can use more blueprint to get - * hints denoting more advanced components. + * Element representing a component with different tiers. Your multi will accept any of them (as long as player does + * not mix them (*)), but would like to know which is used. Player can use more blueprint to get hints denoting more + * advanced components. *

    - * (*): Implementation wise, this structure element will only accept a block if its tier is the same as existing tier or - * if existing tier is unset (i.e. value of third argument) + * (*): Implementation wise, this structure element will only accept a block if its tier is the same as existing + * tier or if existing tier is unset (i.e. value of third argument) *

    * Above all else, you need to decide what tier you are going to use. For simpler cases, Integer is a good choice. - * You can also use an existing Enum. Tier can never be null though. - * It can also be a String or a {@link net.minecraft.util.ResourceLocation}, or basically anything. - * It doesn't even have to implement {@link Comparable}. + * You can also use an existing Enum. Tier can never be null though. It can also be a String or a + * {@link net.minecraft.util.ResourceLocation}, or basically anything. It doesn't even have to implement + * {@link Comparable}. *

    - * This assumes you will reset the backing storage, and on the first occurrence getter would return notSet. - * You can also make getter to return other value to forcefully select a certain tier, but you're probably better - * off using block adders or {@link #ofBlock(Block, int, Block, int)} and its overloads + * This assumes you will reset the backing storage, and on the first occurrence getter would return notSet. You can + * also make getter to return other value to forcefully select a certain tier, but you're probably better off using + * block adders or {@link #ofBlock(Block, int, Block, int)} and its overloads *

    * Implementation wise, this allows a block only when we don't yet have a tier, or the block at that location has * the same tier as we already have. @@ -624,17 +582,20 @@ public class StructureUtility { * have this kind of chain of events: *

      *
    • at check start, tier is reset to notSet - *
    • at first occurrence, ofBlocksTiered finds your current tier is notSet, and the block's tier is notSet, so it's accepted + *
    • at first occurrence, ofBlocksTiered finds your current tier is notSet, and the block's tier is notSet, so + * it's accepted *
    • at 2nd, 3rd..., same thing in 2 happens *
    • at last occurrence, player placed a valid block with a tier not notSet. ofBlocksTiered now sets your current * tier to this tier, and accept the block - *
    • check got notified structure is sound, and tier is not notSet. it marks the structure as complete and start doing its business + *
    • check got notified structure is sound, and tier is not notSet. it marks the structure as complete and start + * doing its business *
    • Player enjoy a (probably) hilariously shaped multi and (probably) reduced build cost. *
    *

    * Example: *

    * Assume you have 16 tier, each map to one block's 16 different meta. You will usually want something like this + * *

          * public class Tile extends TileEntity {
          *     private static final Block B = getTargetBlock();
    @@ -657,28 +618,27 @@ public class StructureUtility {
          * }
          * 
    * - * @param tierExtractor a function to extract tier info from a block. - * This function can return null and will never be passed a null block or an invalid block meta. - * @param allKnownTiers A list of all known tiers as of calling. Can be empty or null. No hint will be spawned if empty or null. Cannot have null elements. - * First element denotes the most primitive tier. Last element denotes the most advanced tier. - * If not all tiers are available at definition construction time, use {@link #lazy(Supplier)} or its overloads to delay a bit. - * This list is only for hint particle spawning and survival build. - * The hint/autoplace code will choose 1st pair to spawn/place if trigger item has master channel data of 1, - * 2nd pair if 2, and so on. - * @param notSet The value returned from {@code getter} when there were no tier info found in T yet. Can be null. + * @param tierExtractor a function to extract tier info from a block. This function can return null and will never + * be passed a null block or an invalid block meta. + * @param allKnownTiers A list of all known tiers as of calling. Can be empty or null. No hint will be spawned if + * empty or null. Cannot have null elements. First element denotes the most primitive tier. + * Last element denotes the most advanced tier. If not all tiers are available at definition + * construction time, use {@link #lazy(Supplier)} or its overloads to delay a bit. This list is + * only for hint particle spawning and survival build. The hint/autoplace code will choose 1st + * pair to spawn/place if trigger item has master channel data of 1, 2nd pair if 2, and so on. + * @param notSet The value returned from {@code getter} when there were no tier info found in T yet. Can be + * null. * @param getter a function to retrieve the current tier from context object * @param setter a function to set the current tier into context object */ - public static IStructureElement ofBlocksTiered( - ITierConverter tierExtractor, - @Nullable List> allKnownTiers, - @Nullable TIER notSet, - BiConsumer setter, + public static IStructureElement ofBlocksTiered(ITierConverter tierExtractor, + @Nullable List> allKnownTiers, @Nullable TIER notSet, BiConsumer setter, Function getter) { 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() { + @Override public boolean check(T t, World world, int x, int y, int z) { return check.check(t, world, x, y, z); @@ -711,15 +671,15 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { Pair hint = getHint(trigger); return BlocksToPlace.create(hint.getKey(), hint.getValue()); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { Pair hint = getHint(trigger); if (hint == null) return PlaceResult.REJECT; // TODO or SKIP? Block block = world.getBlock(x, y, z); @@ -744,10 +704,11 @@ public class StructureUtility { /** * Denote a block using unlocalized names. This can be useful to get around mod loading order issues. *

    - * DUE TO HISTORICAL REASONS, THIS WAS CALLED ofBlockUnlocalizedName, BUT IT ACTUALLY USES REGISTRY NAME INSTEAD. + * DUE TO HISTORICAL REASONS, THIS WAS CALLED ofBlockUnlocalizedName, BUT IT ACTUALLY USES REGISTRY NAME + * INSTEAD. *

    - * While no immediate error will be thrown, client code should ensure said mod is loaded and - * said mod is present, otherwise bad things will happen later! + * While no immediate error will be thrown, client code should ensure said mod is loaded and said mod is present, + * otherwise bad things will happen later! */ public static IStructureElement ofBlockUnlocalizedName(String modid, String unlocalizedName, int meta) { return ofBlockUnlocalizedName(modid, unlocalizedName, meta, false); @@ -756,20 +717,22 @@ public class StructureUtility { /** * Denote a block using unlocalized names. This can be useful to get around mod loading order issues. *

    - * DUE TO HISTORICAL REASONS, THIS WAS CALLED ofBlockUnlocalizedName, BUT IT ACTUALLY USES REGISTRY NAME INSTEAD. + * DUE TO HISTORICAL REASONS, THIS WAS CALLED ofBlockUnlocalizedName, BUT IT ACTUALLY USES REGISTRY NAME + * INSTEAD. *

    - * While no immediate error will be thrown, client code should ensure said mod is loaded and - * said mod is present, otherwise the element will effectively become an {@link #error()}. + * While no immediate error will be thrown, client code should ensure said mod is loaded and said mod is present, + * otherwise the element will effectively become an {@link #error()}. *

    * Will place block or hint using the given meta if wildcard is true. */ - public static IStructureElement ofBlockUnlocalizedName( - String modid, String registryName, int meta, boolean wildcard) { + public static IStructureElement ofBlockUnlocalizedName(String modid, String registryName, int meta, + boolean wildcard) { if (StringUtils.isBlank(registryName)) throw new IllegalArgumentException(); if (meta < 0) throw new IllegalArgumentException(); if (meta > 15) throw new IllegalArgumentException(); if (StringUtils.isBlank(modid)) throw new IllegalArgumentException(); return new StructureElement_Bridge() { + private Block block; private Block getBlock() { @@ -798,41 +761,51 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (getBlock() == null) return error().getBlocksToPlace(t, world, x, y, z, trigger, env); return BlocksToPlace.create(getBlock(), meta); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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; if (getBlock() == null) return PlaceResult.REJECT; return StructureUtility.survivalPlaceBlock( - getBlock(), meta, world, x, y, z, env.getSource(), env.getActor(), env.getChatter()); + getBlock(), + meta, + world, + x, + y, + z, + env.getSource(), + env.getActor(), + env.getChatter()); } }; } /** - * Similiar to the other overload, but allows client code to specify a fallback in case said block was not found later - * when the element got called. + * Similiar to the other overload, but allows client code to specify a fallback in case said block was not found + * later when the element got called. *

    - * DUE TO HISTORICAL REASONS, THIS WAS CALLED ofBlockUnlocalizedName, BUT IT ACTUALLY USES REGISTRY NAME INSTEAD. + * DUE TO HISTORICAL REASONS, THIS WAS CALLED ofBlockUnlocalizedName, BUT IT ACTUALLY USES REGISTRY NAME + * INSTEAD. *

    - * This is slightly different to using the other overload and another element in a {@link #ofChain(IStructureElement[])}. - * Here fallback will only ever be used if this fails, where ofChain would form an OR relationship even if the mod - * is loaded and the block exists in registry. + * This is slightly different to using the other overload and another element in a + * {@link #ofChain(IStructureElement[])}. Here fallback will only ever be used if this fails, where ofChain would + * form an OR relationship even if the mod is loaded and the block exists in registry. */ - public static IStructureElement ofBlockUnlocalizedName( - String modid, String unlocalizedName, int meta, IStructureElement fallback) { + public static IStructureElement ofBlockUnlocalizedName(String modid, String unlocalizedName, int meta, + IStructureElement fallback) { if (StringUtils.isBlank(unlocalizedName)) throw new IllegalArgumentException(); if (meta < 0) throw new IllegalArgumentException(); if (meta > 15) throw new IllegalArgumentException(); if (StringUtils.isBlank(modid)) throw new IllegalArgumentException(); if (fallback == null) throw new IllegalArgumentException(); return new IStructureElement() { + private Block block; private boolean initialized; @@ -868,44 +841,43 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (init()) return BlocksToPlace.create(block, meta); return fallback.getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + 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; 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); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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; - if (init()) - return StructureUtility.survivalPlaceBlock( - block, meta, world, x, y, z, env.getSource(), env.getActor(), env.getChatter()); + if (init()) return StructureUtility.survivalPlaceBlock( + block, + meta, + world, + x, + y, + z, + env.getSource(), + env.getActor(), + env.getChatter()); return fallback.survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; } /** - * Accept a set of blocks. Less cumbersome to use than {@link #ofBlocksMapHint(Map, Block, int)} when for any accepted - * block type we accept only one meta for each. + * Accept a set of blocks. Less cumbersome to use than {@link #ofBlocksMapHint(Map, Block, int)} when for any + * accepted block type we accept only one meta for each. *

    * Does not have autoplace. * @@ -914,12 +886,13 @@ public class StructureUtility { * @param hintMeta hint meta to use * @see #ofBlocksMapHint(Map, Block, int) */ - public static IStructureElementNoPlacement ofBlocksFlatHint( - Map blocsMap, Block hintBlock, int hintMeta) { + public static IStructureElementNoPlacement ofBlocksFlatHint(Map blocsMap, Block hintBlock, + int hintMeta) { if (blocsMap == null || blocsMap.isEmpty() || hintBlock == null) { throw new IllegalArgumentException(); } return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -944,8 +917,8 @@ public class StructureUtility { * @param hintMeta hint meta to use * @see #ofBlocksFlatHint(Map, Block, int) */ - public static IStructureElementNoPlacement ofBlocksMapHint( - Map> blocsMap, Block hintBlock, int hintMeta) { + public static IStructureElementNoPlacement ofBlocksMapHint(Map> blocsMap, + Block hintBlock, int hintMeta) { if (blocsMap == null || blocsMap.isEmpty() || hintBlock == null) { throw new IllegalArgumentException(); } @@ -955,6 +928,7 @@ public class StructureUtility { } } return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -973,12 +947,13 @@ public class StructureUtility { /** * Accept one (block, meta). Spawn hint particles using an alternative block and meta. Not very useful... */ - public static IStructureElementNoPlacement ofBlockHint( - Block block, int meta, Block hintBlock, int hintMeta) { + public static IStructureElementNoPlacement ofBlockHint(Block block, int meta, Block hintBlock, + int hintMeta) { if (block == null || hintBlock == null) { throw new IllegalArgumentException(); } return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -1006,12 +981,13 @@ public class StructureUtility { *

    * Useful when your logic is very complex. Does not support autoplace. */ - public static IStructureElementNoPlacement ofBlockAdderHint( - IBlockAdder iBlockAdder, Block hintBlock, int hintMeta) { + public static IStructureElementNoPlacement ofBlockAdderHint(IBlockAdder iBlockAdder, Block hintBlock, + int hintMeta) { if (iBlockAdder == null || hintBlock == null) { throw new IllegalArgumentException(); } return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -1035,13 +1011,14 @@ public class StructureUtility { * @param defaultMeta default meta to place/spawn hint * @see #ofBlocksMapHint(Map, Block, int) */ - public static IStructureElement ofBlocksFlat( - Map blocsMap, Block defaultBlock, int defaultMeta) { + public static IStructureElement ofBlocksFlat(Map blocsMap, Block defaultBlock, + int defaultMeta) { if (blocsMap == null || blocsMap.isEmpty() || defaultBlock == null) { throw new IllegalArgumentException(); } if (defaultBlock instanceof ICustomBlockSetting) { return new IStructureElement() { + private BlocksToPlace blocksToPlace; @Override @@ -1064,8 +1041,8 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (blocksToPlace == null) { ImmutableList.Builder blocks = ImmutableList.builder(); Predicate predicate = s -> true; @@ -1085,6 +1062,7 @@ public class StructureUtility { }; } else { return new IStructureElement() { + private BlocksToPlace blocksToPlace; @Override @@ -1106,8 +1084,8 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (blocksToPlace == null) { ImmutableList.Builder blocks = ImmutableList.builder(); Predicate predicate = s -> true; @@ -1136,8 +1114,8 @@ public class StructureUtility { * @param defaultMeta default meta to place/spawn hint * @see #ofBlocksMapHint(Map, Block, int) */ - public static IStructureElement ofBlocksMap( - Map> blocsMap, Block defaultBlock, int defaultMeta) { + public static IStructureElement ofBlocksMap(Map> blocsMap, Block defaultBlock, + int defaultMeta) { if (blocsMap == null || blocsMap.isEmpty() || defaultBlock == null) { throw new IllegalArgumentException(); } @@ -1148,6 +1126,7 @@ public class StructureUtility { } if (defaultBlock instanceof ICustomBlockSetting) { return new IStructureElement() { + private BlocksToPlace blocksToPlace; @Override @@ -1170,8 +1149,8 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (blocksToPlace == null) { ImmutableList.Builder blocks = ImmutableList.builder(); Predicate predicate = s -> true; @@ -1192,6 +1171,7 @@ public class StructureUtility { }; } else { return new IStructureElement() { + private BlocksToPlace blocksToPlace; @Override @@ -1214,8 +1194,8 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (blocksToPlace == null) { ImmutableList.Builder blocks = ImmutableList.builder(); Predicate predicate = s -> true; @@ -1251,6 +1231,7 @@ public class StructureUtility { } if (block instanceof ICustomBlockSetting) { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -1270,13 +1251,14 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return BlocksToPlace.create(block, meta); } }; } else { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -1296,8 +1278,8 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return BlocksToPlace.create(block, meta); } }; @@ -1313,6 +1295,7 @@ public class StructureUtility { } if (block instanceof ICustomBlockSetting) { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return block == world.getBlock(x, y, z); @@ -1331,14 +1314,15 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { // there is getSubItems on ItemBlock, but it's client only return BlocksToPlace.create(defaultBlock, defaultMeta); } }; } else { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return block == world.getBlock(x, y, z); @@ -1357,8 +1341,8 @@ public class StructureUtility { } @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { // there is getSubItems on ItemBlock, but it's client only return BlocksToPlace.create(defaultBlock, defaultMeta); } @@ -1396,13 +1380,14 @@ public class StructureUtility { *

    * Useful when your logic is very complex. */ - public static IStructureElement ofBlockAdder( - IBlockAdder iBlockAdder, Block defaultBlock, int defaultMeta) { + public static IStructureElement ofBlockAdder(IBlockAdder iBlockAdder, Block defaultBlock, + int defaultMeta) { if (iBlockAdder == null || defaultBlock == null) { throw new IllegalArgumentException(); } if (defaultBlock instanceof ICustomBlockSetting) { return new StructureElement_Bridge() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -1423,8 +1408,8 @@ public class StructureUtility { @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( @@ -1441,6 +1426,7 @@ public class StructureUtility { }; } else { return new StructureElement_Bridge() { + @Override public boolean check(T t, World world, int x, int y, int z) { Block worldBlock = world.getBlock(x, y, z); @@ -1461,8 +1447,8 @@ public class StructureUtility { @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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) return PlaceResult.SKIP; return StructureUtility.survivalPlaceBlock( @@ -1488,12 +1474,13 @@ public class StructureUtility { * Try to add a structure element with a tile entity. Note that tile adder will be called with a null argument at * locations without tile entity. */ - public static IStructureElementNoPlacement ofTileAdder( - ITileAdder iTileAdder, Block hintBlock, int hintMeta) { + public static IStructureElementNoPlacement ofTileAdder(ITileAdder iTileAdder, Block hintBlock, + int hintMeta) { if (iTileAdder == null || hintBlock == null) { throw new IllegalArgumentException(); } return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { TileEntity tileEntity = world.getTileEntity(x, y, z); @@ -1513,12 +1500,13 @@ public class StructureUtility { * Try to add a structure element with a particular type of tile entity. Note that tile adder will not be called at * locations without a tile entity. */ - public static IStructureElementNoPlacement ofSpecificTileAdder( - BiPredicate iTileAdder, Class tileClass, Block hintBlock, int hintMeta) { + public static IStructureElementNoPlacement ofSpecificTileAdder(BiPredicate iTileAdder, + Class tileClass, Block hintBlock, int hintMeta) { if (iTileAdder == null || hintBlock == null || tileClass == null) { throw new IllegalArgumentException(); } return new IStructureElementNoPlacement() { + @Override public boolean check(T t, World world, int x, int y, int z) { TileEntity tileEntity = world.getTileEntity(x, y, z); @@ -1546,9 +1534,10 @@ public class StructureUtility { * @param onCheckPass side effect * @param element downstream */ - public static , T> IStructureElement onElementPass( - Consumer onCheckPass, B element) { + public static , T> IStructureElement onElementPass(Consumer onCheckPass, + B element) { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { boolean check = element.check(t, world, x, y, z); @@ -1570,29 +1559,21 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return element.getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return element.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return element.survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; @@ -1604,9 +1585,10 @@ public class StructureUtility { * @param onFail side effect * @param element downstream */ - public static , T> IStructureElement onElementFail( - Consumer onFail, B element) { + public static , T> IStructureElement onElementFail(Consumer onFail, + B element) { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { boolean check = element.check(t, world, x, y, z); @@ -1628,29 +1610,21 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return element.getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return element.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return element.survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; @@ -1663,8 +1637,8 @@ public class StructureUtility { *

    * Return SKIP when survival auto place if given predicate returns false. */ - public static IStructureElement onlyIf( - Predicate predicate, IStructureElement downstream) { + public static IStructureElement onlyIf(Predicate predicate, + IStructureElement downstream) { return onlyIf(predicate, downstream, PlaceResult.SKIP); } @@ -1673,11 +1647,10 @@ public class StructureUtility { * * @param placeResultWhenDisabled value to return for survival auto place when predicate returns false */ - public static IStructureElement onlyIf( - Predicate predicate, - IStructureElement downstream, - PlaceResult placeResultWhenDisabled) { + public static IStructureElement onlyIf(Predicate predicate, + IStructureElement downstream, PlaceResult placeResultWhenDisabled) { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return predicate.test(t) && downstream.check(t, world, x, y, z); @@ -1695,32 +1668,24 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { if (predicate.test(t)) return downstream.getBlocksToPlace(t, world, x, y, z, trigger, env); return BlocksToPlace.createEmpty(); } @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + 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)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); return placeResultWhenDisabled; } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + 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); return placeResultWhenDisabled; } @@ -1728,22 +1693,21 @@ public class StructureUtility { } /** - * This allows you to compose different {@link IStructureElement} to form a OR chain. - * As with any other OR operator, this one exhibits short-circuiting behavior, i.e. it will not call next structure element - * if previous one succeeded. (*) + * This allows you to compose different {@link IStructureElement} to form a OR chain. As with any other OR + * operator, this one exhibits short-circuiting behavior, i.e. it will not call next structure element if previous + * one succeeded. (*) *

    * This allows you e.g. accept both a glass block using {@link #ofBlock(Block, int, Block, int)} and a piece of air - * using {@link #isAir()}. - * It will not attempt to capture any errors though, so next one will not be tried if previous one would crash. + * using {@link #isAir()}. It will not attempt to capture any errors though, so next one will not be tried if + * previous one would crash. *

    - * (*): For survival auto place, it will - * * REJECT, if all structure element REJECT - * * SKIP, if 1 or more structure element SKIP and the rest structure element (0 or more) REJECT - * * any other result, **immediately** upon any structure element returns these other results. - * This behavior is not 100% fixed and might change later on, but we will send the notice on a best effort basis. + * (*): For survival auto place, it will * REJECT, if all structure element REJECT * SKIP, if 1 or more structure + * element SKIP and the rest structure element (0 or more) REJECT * any other result, **immediately** upon any + * structure element returns these other results. This behavior is not 100% fixed and might change later on, but we + * will send the notice on a best effort basis. *

    - * Take care while chaining, as it will try to call every structure element until it returns true. - * If none does it will finally return false. + * Take care while chaining, as it will try to call every structure element until it returns true. If none does it + * will finally return false. */ @SafeVarargs public static IStructureElementChain ofChain(IStructureElement... elementChain) { @@ -1782,6 +1746,7 @@ public class StructureUtility { public static > IStructureElement withContext( IStructureElement elem) { return new IStructureElement() { + @Override public boolean check(T t, World world, int x, int y, int z) { return elem.check(t.getCurrentContext(), world, x, y, z); @@ -1799,29 +1764,21 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return elem.getBlocksToPlace(t.getCurrentContext(), world, x, y, z, trigger, env); } @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return elem.survivalPlaceBlock(t.getCurrentContext(), world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return elem.survivalPlaceBlock(t.getCurrentContext(), world, x, y, z, trigger, env); } }; @@ -1831,11 +1788,10 @@ public class StructureUtility { // region defer /** - * Similar to defer, but caches the first returned element returned and won't call it again. - * Initialization is not thread safe. - * These both allow the structure element **constructor** to access properties only present on the context object - * (e.g. GT5 multiblock controller), e.g. hatch texture index to use. - * Use `lazy` if the data you access will remain constant across different context object. + * Similar to defer, but caches the first returned element returned and won't call it again. Initialization is not + * thread safe. These both allow the structure element **constructor** to access properties only present on the + * context object (e.g. GT5 multiblock controller), e.g. hatch texture index to use. Use `lazy` if the data you + * access will remain constant across different context object. */ public static IStructureElementDeferred lazy(Supplier> to) { if (to == null) { @@ -1845,13 +1801,13 @@ public class StructureUtility { } /** - * This will defer the actual instantiation of structure element until the first time structure code is actually called. + * This will defer the actual instantiation of structure element until the first time structure code is + * actually called. *

    - * Similar to defer, but caches the first returned element returned and won't call it again. - * Initialization is not thread safe. - * This will allow the structure element constructor to access properties only present on the context object - * (e.g. GT5 multiblock controller), e.g. hatch texture index to use. - * Use this if the data you access will remain constant. + * Similar to defer, but caches the first returned element returned and won't call it again. Initialization is not + * thread safe. This will allow the structure element constructor to access properties only present on the + * context object (e.g. GT5 multiblock controller), e.g. hatch texture index to use. Use this if the data you access + * will remain constant. * * @param to create structure element from the first context object passed in */ @@ -1863,12 +1819,11 @@ public class StructureUtility { } /** - * This will defer the actual instantiation of structure element until the structure code is actually called. - * This will allow the structure element constructor to access properties only present on the context object - * (e.g. GT5 multiblock controller), e.g. hatch texture index to use. - * Use this if it might change for the same structure definition, e.g. if your structure might switch mode and - * change some parameter, while basically remain the same shape. - * Using this while {@link #lazy(Supplier)} is enough will not break anything, but would incur unnecessary + * This will defer the actual instantiation of structure element until the structure code is actually called. This + * will allow the structure element constructor to access properties only present on the context object (e.g. + * GT5 multiblock controller), e.g. hatch texture index to use. Use this if it might change for the same structure + * definition, e.g. if your structure might switch mode and change some parameter, while basically remain the same + * shape. Using this while {@link #lazy(Supplier)} is enough will not break anything, but would incur unnecessary * performance overhead. * * @param to downstream element supplier @@ -1878,6 +1833,7 @@ public class StructureUtility { throw new IllegalArgumentException(); } return new IStructureElementDeferred() { + @Override public boolean check(T t, World world, int x, int y, int z) { return to.get().check(t, world, x, y, z); @@ -1895,41 +1851,32 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.get().getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return to.get().survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.get().survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; } /** - * This will defer the actual instantiation of structure element until the structure code is actually called. - * This will allow the structure element constructor to access properties only present on the context object - * (e.g. GT5 multiblock controller), e.g. hatch texture index to use. - * Use this if it might change for the same structure definition, e.g. if your structure might switch mode and - * change some parameter, while basically remain the same shape. - * Using this while {@link #lazy(Supplier)} is enough will not break anything, but would incur unnecessary + * This will defer the actual instantiation of structure element until the structure code is actually called. This + * will allow the structure element constructor to access properties only present on the context object (e.g. + * GT5 multiblock controller), e.g. hatch texture index to use. Use this if it might change for the same structure + * definition, e.g. if your structure might switch mode and change some parameter, while basically remain the same + * shape. Using this while {@link #lazy(Supplier)} is enough will not break anything, but would incur unnecessary * performance overhead. * * @param to downstream element supplier @@ -1939,6 +1886,7 @@ public class StructureUtility { throw new IllegalArgumentException(); } return new IStructureElementDeferred() { + @Override public boolean check(T t, World world, int x, int y, int z) { return to.apply(t).check(t, world, x, y, z); @@ -1956,28 +1904,20 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.apply(t).getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return to.apply(t).survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.apply(t).survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; @@ -1986,25 +1926,25 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. * * @param keyExtractor extract a key from the context object * @param map all possible structure element * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractor, Map> map) { + public static IStructureElementDeferred defer(Function keyExtractor, + Map> map) { return partitionBy(keyExtractor, map); } /** * This is the switch block for structure code. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key - * not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key not + * found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2012,8 +1952,8 @@ public class StructureUtility { * @param keyExtractor extract a key from the context object * @param map all possible structure element */ - public static IStructureElementDeferred partitionBy( - Function keyExtractor, Map> map) { + public static IStructureElementDeferred partitionBy(Function keyExtractor, + Map> map) { if (keyExtractor == null || map == null) { throw new IllegalArgumentException(); } @@ -2023,8 +1963,8 @@ public class StructureUtility { /** * This is the switch block for structure code, with default case support. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play * nicely in combination with {@link #error()} *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality @@ -2036,16 +1976,16 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractor, Map> map, IStructureElement defaultElem) { + public static IStructureElementDeferred defer(Function keyExtractor, + Map> map, IStructureElement defaultElem) { return partitionBy(keyExtractor, map, defaultElem); } /** * This is the switch block for structure code, with default case support. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play * nicely in combination with {@link #error()} *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality @@ -2055,8 +1995,8 @@ public class StructureUtility { * @param map all possible structure element * @param defaultElem element to use when keyExtractor returns a value not found in given map */ - public static IStructureElementDeferred partitionBy( - Function keyExtractor, Map> map, IStructureElement defaultElem) { + public static IStructureElementDeferred partitionBy(Function keyExtractor, + Map> map, IStructureElement defaultElem) { if (keyExtractor == null || map == null) { throw new IllegalArgumentException(); } @@ -2066,9 +2006,9 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. * @@ -2078,17 +2018,17 @@ public class StructureUtility { */ @SafeVarargs @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractor, IStructureElement... array) { + public static IStructureElementDeferred defer(Function keyExtractor, + IStructureElement... array) { return partitionBy(keyExtractor, array); } /** * This is the switch block for structure code. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. * @@ -2096,8 +2036,8 @@ public class StructureUtility { * @param array all possible structure element */ @SafeVarargs - public static IStructureElementDeferred partitionBy( - Function keyExtractor, IStructureElement... array) { + public static IStructureElementDeferred partitionBy(Function keyExtractor, + IStructureElement... array) { if (keyExtractor == null || array == null) { throw new IllegalArgumentException(); } @@ -2107,9 +2047,9 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. * @@ -2118,17 +2058,17 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractor, List> array) { + public static IStructureElementDeferred defer(Function keyExtractor, + List> array) { return partitionBy(keyExtractor, array); } /** * This is the switch block for structure code. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. * @@ -2136,18 +2076,17 @@ public class StructureUtility { * @param array all possible structure element */ @SuppressWarnings("unchecked") - public static IStructureElementDeferred partitionBy( - Function keyExtractor, List> array) { + public static IStructureElementDeferred partitionBy(Function keyExtractor, + List> array) { return partitionBy(keyExtractor, array.toArray(new IStructureElement[0])); } /** - * This will defer the actual instantiation of structure element until the structure code is actually called. - * This will allow the structure element constructor to access properties only present on the context object - * (e.g. GT5 multiblock controller), e.g. hatch texture index to use. - * Use this if it might change for the same structure definition, e.g. if your structure might switch mode and - * change some parameter, while basically remain the same shape. - * Using this while {@link #lazy(Supplier)} is enough will not break anything, but would incur unnecessary + * This will defer the actual instantiation of structure element until the structure code is actually called. This + * will allow the structure element constructor to access properties only present on the context object (e.g. + * GT5 multiblock controller), e.g. hatch texture index to use. Use this if it might change for the same structure + * definition, e.g. if your structure might switch mode and change some parameter, while basically remain the same + * shape. Using this while {@link #lazy(Supplier)} is enough will not break anything, but would incur unnecessary * performance overhead. *

    * This variant also passes the trigger item to the function, allowing it to get more info. @@ -2159,6 +2098,7 @@ public class StructureUtility { throw new IllegalArgumentException(); } return new IStructureElementDeferred() { + @Override public boolean check(T t, World world, int x, int y, int z) { return to.apply(t, null).check(t, world, x, y, z); @@ -2176,28 +2116,20 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.apply(t, trigger).getBlocksToPlace(t, world, x, y, z, trigger, env); } @Override - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return to.apply(t, trigger).survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.apply(t, trigger).survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; @@ -2206,9 +2138,9 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key - * not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key not + * found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2220,17 +2152,17 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - BiFunction keyExtractor, Map> map) { + public static IStructureElementDeferred defer(BiFunction keyExtractor, + Map> map) { return partitionBy(keyExtractor, map); } /** * This is the switch block for structure code. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key - * not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key not + * found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2240,8 +2172,8 @@ public class StructureUtility { * @param keyExtractor extract a key from the context object and trigger item * @param map all possible structure element */ - public static IStructureElementDeferred partitionBy( - BiFunction keyExtractor, Map> map) { + public static IStructureElementDeferred partitionBy(BiFunction keyExtractor, + Map> map) { if (keyExtractor == null || map == null) { throw new IllegalArgumentException(); } @@ -2251,8 +2183,8 @@ public class StructureUtility { /** * This is the switch block for structure code, with default case support. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play * nicely in combination with {@link #error()} *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality @@ -2266,18 +2198,16 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - BiFunction keyExtractor, - Map> map, - IStructureElement defaultElem) { + public static IStructureElementDeferred defer(BiFunction keyExtractor, + Map> map, IStructureElement defaultElem) { return partitionBy(keyExtractor, map, defaultElem); } /** * This is the switch block for structure code, with default case support. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. The fallback will only be used when keyExtractor returns a value not found in given map. This will play * nicely in combination with {@link #error()} *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality @@ -2289,10 +2219,8 @@ public class StructureUtility { * @param map all possible structure element * @param defaultElem element to use when keyExtractor returns a value not found in given map */ - public static IStructureElementDeferred partitionBy( - BiFunction keyExtractor, - Map> map, - IStructureElement defaultElem) { + public static IStructureElementDeferred partitionBy(BiFunction keyExtractor, + Map> map, IStructureElement defaultElem) { if (keyExtractor == null || map == null) { throw new IllegalArgumentException(); } @@ -2302,9 +2230,9 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. *

    @@ -2314,8 +2242,8 @@ public class StructureUtility { * @param array all possible structure element */ @SafeVarargs - public static IStructureElementDeferred defer( - BiFunction keyExtractor, IStructureElement... array) { + public static IStructureElementDeferred defer(BiFunction keyExtractor, + IStructureElement... array) { if (keyExtractor == null || array == null) { throw new IllegalArgumentException(); } @@ -2325,9 +2253,9 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. *

    @@ -2336,19 +2264,19 @@ public class StructureUtility { * @param keyExtractor extract a key from the context object and trigger item * @param array all possible structure element */ - public static IStructureElementDeferred defer( - BiFunction keyExtractor, List> array) { + public static IStructureElementDeferred defer(BiFunction keyExtractor, + List> array) { return defer(keyExtractor.andThen(array::get)); } /** - * This will defer the actual instantiation of structure element until the first time structure code is actually called. + * This will defer the actual instantiation of structure element until the first time structure code is + * actually called. *

    - * Similar to defer, but caches the first returned element returned and won't call it again. - * Initialization is not thread safe. - * This will allow the structure element constructor to access properties only present on the context object - * (e.g. GT5 multiblock controller), e.g. hatch texture index to use. - * Use this if the data you access will remain constant. + * Similar to defer, but caches the first returned element returned and won't call it again. Initialization is not + * thread safe. This will allow the structure element constructor to access properties only present on the + * context object (e.g. GT5 multiblock controller), e.g. hatch texture index to use. Use this if the data you access + * will remain constant. *

    * This variant will override the check function of the structure element from second function with the one returned * from the structure element from first function. @@ -2356,12 +2284,13 @@ public class StructureUtility { * @param toCheck override the check function with the returned element * @param to create structure element from the context object passed in */ - public static IStructureElementDeferred defer( - Function> toCheck, BiFunction> to) { + public static IStructureElementDeferred defer(Function> toCheck, + BiFunction> to) { if (to == null) { throw new IllegalArgumentException(); } return new IStructureElementDeferred() { + @Override public boolean check(T t, World world, int x, int y, int z) { return toCheck.apply(t).check(t, world, x, y, z); @@ -2378,22 +2307,14 @@ public class StructureUtility { } @Override - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { return to.apply(t, trigger).survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter); } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return to.apply(t, trigger).survivalPlaceBlock(t, world, x, y, z, trigger, env); } }; @@ -2402,9 +2323,9 @@ public class StructureUtility { /** * This is the switch block for structure code. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key - * not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key not + * found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2420,19 +2341,17 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractorCheck, - BiFunction keyExtractor, - Map> map) { + public static IStructureElementDeferred defer(Function keyExtractorCheck, + BiFunction keyExtractor, Map> map) { return partitionBy(keyExtractorCheck, keyExtractor, map); } /** * This is the switch block for structure code. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key - * not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns a key not + * found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2446,10 +2365,8 @@ public class StructureUtility { * @param keyExtractor extract a key from the context object and trigger item * @param map all possible structure element */ - public static IStructureElementDeferred partitionBy( - Function keyExtractorCheck, - BiFunction keyExtractor, - Map> map) { + public static IStructureElementDeferred partitionBy(Function keyExtractorCheck, + BiFunction keyExtractor, Map> map) { if (keyExtractor == null || map == null) { throw new IllegalArgumentException(); } @@ -2459,8 +2376,8 @@ public class StructureUtility { /** * This is the switch block for structure code, with default case. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. defaultElem will be used if either extractor returned a key not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. defaultElem will be used if either extractor returned a key not found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2476,10 +2393,8 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractorCheck, - BiFunction keyExtractor, - Map> map, + public static IStructureElementDeferred defer(Function keyExtractorCheck, + BiFunction keyExtractor, Map> map, IStructureElement defaultElem) { return partitionBy(keyExtractorCheck, keyExtractor, map, defaultElem); } @@ -2487,8 +2402,8 @@ public class StructureUtility { /** * This is the switch block for structure code, with default case. *

    - * This allows you to extract or compute a key from context object, and lookup a map for actual structure element - * to use. defaultElem will be used if either extractor returned a key not found in map. + * This allows you to extract or compute a key from context object, and lookup a map for actual structure element to + * use. defaultElem will be used if either extractor returned a key not found in map. *

    * Do pay attention to what properties your map has though. You need to pay attention to how they consider equality * and how they consider null key/values. Guava ImmutableMap is usually a good enough choice. @@ -2502,10 +2417,8 @@ public class StructureUtility { * @param keyExtractor extract a key from the context object and trigger item * @param map all possible structure element */ - public static IStructureElementDeferred partitionBy( - Function keyExtractorCheck, - BiFunction keyExtractor, - Map> map, + public static IStructureElementDeferred partitionBy(Function keyExtractorCheck, + BiFunction keyExtractor, Map> map, IStructureElement defaultElem) { if (keyExtractor == null || map == null) { throw new IllegalArgumentException(); @@ -2518,9 +2431,9 @@ public class StructureUtility { /** * This is the switch block for structure code, with default case. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. *

    @@ -2536,19 +2449,17 @@ public class StructureUtility { */ @SafeVarargs @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractorCheck, - BiFunction keyExtractor, - IStructureElement... array) { + public static IStructureElementDeferred defer(Function keyExtractorCheck, + BiFunction keyExtractor, IStructureElement... array) { return partitionBy(keyExtractorCheck, keyExtractor, array); } /** * This is the switch block for structure code, with default case. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * Do pay place null values in the array. *

    @@ -2562,10 +2473,8 @@ public class StructureUtility { * @param array all possible structure element */ @SafeVarargs - public static IStructureElementDeferred partitionBy( - Function keyExtractorCheck, - BiFunction keyExtractor, - IStructureElement... array) { + public static IStructureElementDeferred partitionBy(Function keyExtractorCheck, + BiFunction keyExtractor, IStructureElement... array) { if (keyExtractor == null || array == null) { throw new IllegalArgumentException(); } @@ -2575,9 +2484,9 @@ public class StructureUtility { /** * This is the switch block for structure code, with default case. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * This variant also passes the trigger item to the function, allowing it to get more info. *

    @@ -2590,19 +2499,17 @@ public class StructureUtility { * @deprecated renamed to partitionBy */ @Deprecated - public static IStructureElementDeferred defer( - Function keyExtractorCheck, - BiFunction keyExtractor, - List> array) { + public static IStructureElementDeferred defer(Function keyExtractorCheck, + BiFunction keyExtractor, List> array) { return partitionBy(keyExtractorCheck, keyExtractor, array); } /** * This is the switch block for structure code, with default case. *

    - * This allows you to extract or compute an index from context object, and lookup an array for actual structure element - * to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns an index - * not within the array bound + * This allows you to extract or compute an index from context object, and lookup an array for actual structure + * element to use. This will usually, but not guaranteed, to throw an exception at runtime if keyExtractor returns + * an index not within the array bound *

    * This variant also passes the trigger item to the function, allowing it to get more info. *

    @@ -2614,10 +2521,8 @@ public class StructureUtility { * @param array all possible structure element */ @SuppressWarnings("unchecked") - public static IStructureElementDeferred partitionBy( - Function keyExtractorCheck, - BiFunction keyExtractor, - List> array) { + public static IStructureElementDeferred partitionBy(Function keyExtractorCheck, + BiFunction keyExtractor, List> array) { return partitionBy(keyExtractorCheck, keyExtractor, array.toArray(new IStructureElement[0])); } @@ -2630,6 +2535,7 @@ public class StructureUtility { */ public static IStructureElement withChannel(String channel, IStructureElement backing) { return new IStructureElement() { + public boolean check(T t, World world, int x, int y, int z) { return backing.check(t, world, x, y, z); } @@ -2661,22 +2567,14 @@ public class StructureUtility { @Nullable @Override - public BlocksToPlace getBlocksToPlace( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public BlocksToPlace getBlocksToPlace(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { return backing.getBlocksToPlace(t, world, x, y, z, trigger, env); } @Deprecated - public PlaceResult survivalPlaceBlock( - T t, - World world, - int x, - int y, - int z, - ItemStack trigger, - IItemSource s, - EntityPlayerMP actor, - Consumer chatter) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + IItemSource s, EntityPlayerMP actor, Consumer chatter) { ItemStack newTrigger = ChannelDataAccessor.withChannel(trigger, channel); if (newTrigger == trigger) // we will bypass the chatter filter here, as this is a warning that player definitively want to see @@ -2686,8 +2584,8 @@ public class StructureUtility { } @Override - public PlaceResult survivalPlaceBlock( - T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) { + public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger, + AutoPlaceEnvironment env) { ItemStack newTrigger = ChannelDataAccessor.withChannel(trigger, channel); if (newTrigger == trigger) // we will bypass the chatter filter here, as this is a warning that player definitively want to see @@ -2727,6 +2625,7 @@ public class StructureUtility { private static IStructureNavigate stepA(int a, int b, int c) { return new IStructureNavigate() { + @Override public int getStepA() { return a; @@ -2746,6 +2645,7 @@ public class StructureUtility { private static IStructureNavigate stepB(int a, int b, int c) { return new IStructureNavigate() { + @Override public int getStepA() { return a; @@ -2770,6 +2670,7 @@ public class StructureUtility { private static IStructureNavigate stepC(int a, int b, int c) { return new IStructureNavigate() { + @Override public int getStepA() { return a; @@ -2802,21 +2703,12 @@ public class StructureUtility { *

    * NOTE: GT specific code got removed. TODO add a mean * - * @param tileEntityClassifier return a string that denote the type of a tile entity, or null if it's nothing special. useful if the tile entity cannot be simply distinguished via getClass. + * @param tileEntityClassifier return a string that denote the type of a tile entity, or null if it's nothing + * special. useful if the tile entity cannot be simply distinguished via getClass. */ - public static String getPseudoJavaCode( - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - Function tileEntityClassifier, - int sizeA, - int sizeB, - int sizeC, + public static String getPseudoJavaCode(World world, ExtendedFacing extendedFacing, int basePositionX, + int basePositionY, int basePositionZ, int basePositionA, int basePositionB, int basePositionC, + Function tileEntityClassifier, int sizeA, int sizeB, int sizeC, boolean transpose) { Map> blocks = new TreeMap<>(Comparator.comparing(Block::getUnlocalizedName)); Set> tiles = new HashSet<>(); @@ -2868,12 +2760,8 @@ public class StructureUtility { return "Too complicated for nice chars"; } map.put(block.getUnlocalizedName() + '\0' + meta, c); - builder.append(c) - .append(" -> ofBlock...(") - .append(block.getUnlocalizedName()) - .append(", ") - .append(meta) - .append(", ...);\n"); + builder.append(c).append(" -> ofBlock...(").append(block.getUnlocalizedName()).append(", ") + .append(meta).append(", ...);\n"); } } builder.append("\nTiles:\n"); @@ -2892,19 +2780,12 @@ public class StructureUtility { return "Too complicated for nice chars"; } map.put(tile, c); - builder.append(c) - .append(" -> ofSpecialTileAdder(") - .append(tile) + builder.append(c).append(" -> ofSpecialTileAdder(").append(tile) .append(", ...); // You will probably want to change it to something else\n"); } } - builder.append("\nOffsets:\n") - .append(basePositionA) - .append(' ') - .append(basePositionB) - .append(' ') - .append(basePositionC) - .append('\n'); + builder.append("\nOffsets:\n").append(basePositionA).append(' ').append(basePositionB).append(' ') + .append(basePositionC).append('\n'); if (transpose) { builder.append("\nTransposed Scan:\n").append("new String[][]{\n").append(" {\""); iterate( @@ -2925,8 +2806,10 @@ public class StructureUtility { if (tileEntity == null) { Block block = w.getBlock(x, y, z); if (block != null && block != Blocks.air) { - builder.append(map.get( - block.getUnlocalizedName() + '\0' + block.getDamageValue(world, x, y, z))); + builder.append( + map.get( + block.getUnlocalizedName() + '\0' + + block.getDamageValue(world, x, y, z))); } else { builder.append(' '); } @@ -2965,8 +2848,10 @@ public class StructureUtility { if (tileEntity == null) { Block block = w.getBlock(x, y, z); if (block != null && block != Blocks.air) { - builder.append(map.get( - block.getUnlocalizedName() + '\0' + block.getDamageValue(world, x, y, z))); + builder.append( + map.get( + block.getUnlocalizedName() + '\0' + + block.getDamageValue(world, x, y, z))); } else { builder.append(' '); } @@ -2989,24 +2874,15 @@ public class StructureUtility { return (builder.toString().replaceAll("\"\"", "E")); } - static boolean iterateV2( - IStructureElement[] elements, - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - IStructureWalker predicate, - String iterateType) { + static boolean iterateV2(IStructureElement[] elements, World world, ExtendedFacing extendedFacing, + int basePositionX, int basePositionY, int basePositionZ, int basePositionA, int basePositionB, + int basePositionC, IStructureWalker predicate, String iterateType) { // change base position to base offset basePositionA = -basePositionA; basePositionB = -basePositionB; basePositionC = -basePositionC; - int[] abc = new int[] {basePositionA, basePositionB, basePositionC}; + int[] abc = new int[] { basePositionA, basePositionB, basePositionC }; int[] xyz = new int[3]; for (IStructureElement element : elements) { @@ -3020,15 +2896,14 @@ public class StructureUtility { xyz[1] += basePositionY; xyz[2] += basePositionZ; - if (StructureLibAPI.isDebugEnabled()) - StructureLib.LOGGER.info( - "Multi [{}, {}, {}] {} step @ {} {}", - basePositionX, - basePositionY, - basePositionZ, - iterateType, - Arrays.toString(xyz), - Arrays.toString(abc)); + if (StructureLibAPI.isDebugEnabled()) StructureLib.LOGGER.info( + "Multi [{}, {}, {}] {} step @ {} {}", + basePositionX, + basePositionY, + basePositionZ, + iterateType, + Arrays.toString(xyz), + Arrays.toString(abc)); if (world.blockExists(xyz[0], xyz[1], xyz[2])) { if (StructureLibAPI.isInstrumentEnabled()) { @@ -3075,18 +2950,8 @@ public class StructureUtility { return true; } - public static void iterate( - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - int sizeA, - int sizeB, - int sizeC, + public static void iterate(World world, ExtendedFacing extendedFacing, int basePositionX, int basePositionY, + int basePositionZ, int basePositionA, int basePositionB, int basePositionC, int sizeA, int sizeB, int sizeC, IBlockPosConsumer iBlockPosConsumer) { sizeA -= basePositionA; sizeB -= basePositionB; @@ -3099,29 +2964,16 @@ public class StructureUtility { for (abc[1] = -basePositionB; abc[1] < sizeB; abc[1]++) { for (abc[0] = -basePositionA; abc[0] < sizeA; abc[0]++) { extendedFacing.getWorldOffset(abc, xyz); - iBlockPosConsumer.consume( - world, xyz[0] + basePositionX, xyz[1] + basePositionY, xyz[2] + basePositionZ); + iBlockPosConsumer + .consume(world, xyz[0] + basePositionX, xyz[1] + basePositionY, xyz[2] + basePositionZ); } } } } - public static void iterate( - World world, - ExtendedFacing extendedFacing, - int basePositionX, - int basePositionY, - int basePositionZ, - int basePositionA, - int basePositionB, - int basePositionC, - boolean transpose, - int sizeA, - int sizeB, - int sizeC, - IBlockPosConsumer iBlockPosConsumer, - Runnable nextB, - Runnable nextC) { + public static void iterate(World world, ExtendedFacing extendedFacing, int basePositionX, int basePositionY, + int basePositionZ, int basePositionA, int basePositionB, int basePositionC, boolean transpose, int sizeA, + int sizeB, int sizeC, IBlockPosConsumer iBlockPosConsumer, Runnable nextB, Runnable nextC) { sizeA -= basePositionA; sizeB -= basePositionB; sizeC -= basePositionC; @@ -3133,8 +2985,8 @@ public class StructureUtility { for (abc[2] = -basePositionC; abc[2] < sizeC; abc[2]++) { for (abc[0] = -basePositionA; abc[0] < sizeA; abc[0]++) { extendedFacing.getWorldOffset(abc, xyz); - iBlockPosConsumer.consume( - world, xyz[0] + basePositionX, xyz[1] + basePositionY, xyz[2] + basePositionZ); + iBlockPosConsumer + .consume(world, xyz[0] + basePositionX, xyz[1] + basePositionY, xyz[2] + basePositionZ); } nextB.run(); } @@ -3145,8 +2997,8 @@ public class StructureUtility { for (abc[1] = -basePositionB; abc[1] < sizeB; abc[1]++) { for (abc[0] = -basePositionA; abc[0] < sizeA; abc[0]++) { extendedFacing.getWorldOffset(abc, xyz); - iBlockPosConsumer.consume( - world, xyz[0] + basePositionX, xyz[1] + basePositionY, xyz[2] + basePositionZ); + iBlockPosConsumer + .consume(world, xyz[0] + basePositionX, xyz[1] + basePositionY, xyz[2] + basePositionZ); } nextB.run(); } @@ -3156,8 +3008,8 @@ public class StructureUtility { } /** - * Transposes shape (swaps B and C axis, can be used to un-transpose transposed shape) - * WARNING! Do not use on old api... + * Transposes shape (swaps B and C axis, can be used to un-transpose transposed shape) WARNING! Do not use on old + * api... * * @param structurePiece shape (transposed shape) * @return transposed shape (untransposed shape) diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java b/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java index f7835f59..02b61922 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java @@ -1,12 +1,14 @@ package com.gtnewhorizon.structurelib.structure; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; class SurvivalBuildStructureWalker implements IStructureWalker { + final T object; final ItemStack trigger; private final int elementBudget; @@ -16,16 +18,9 @@ class SurvivalBuildStructureWalker implements IStructureWalker { private final AutoPlaceEnvironment env; - public SurvivalBuildStructureWalker( - T object, - ItemStack trigger, - int elementBudget, - ISurvivalBuildEnvironment params, - IStructureDefinition definition, - String piece, - ExtendedFacing facing, - int[] baseOffsetABC, - boolean check) { + public SurvivalBuildStructureWalker(T object, ItemStack trigger, int elementBudget, + ISurvivalBuildEnvironment params, IStructureDefinition definition, String piece, ExtendedFacing facing, + int[] baseOffsetABC, boolean check) { this.object = object; this.trigger = trigger; this.elementBudget = elementBudget; diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/adders/IBlockAdder.java b/src/main/java/com/gtnewhorizon/structurelib/structure/adders/IBlockAdder.java index 1fa0840f..240b646a 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/adders/IBlockAdder.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/adders/IBlockAdder.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.structure.adders; import net.minecraft.block.Block; public interface IBlockAdder { + /** * Callback on block added, needs to check if block is valid (and add it) * diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/adders/ITileAdder.java b/src/main/java/com/gtnewhorizon/structurelib/structure/adders/ITileAdder.java index 14e3b358..1e2fceb1 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/adders/ITileAdder.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/adders/ITileAdder.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.structure.adders; import net.minecraft.tileentity.TileEntity; public interface ITileAdder { + /** * Callback to add hatch, needs to check if tile is valid (and add it) * diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/package-info.java b/src/main/java/com/gtnewhorizon/structurelib/structure/package-info.java index aaee3a22..5bfe9a66 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/package-info.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/package-info.java @@ -1,7 +1,7 @@ /** * This package provide support for multiblock structure checking. *

    - * All public stuff in this package and its subpackages are considered part of the public API. - * Backwards compatibility is maintained to the maximum extend possible. + * All public stuff in this package and its subpackages are considered part of the public API. Backwards compatibility + * is maintained to the maximum extend possible. */ package com.gtnewhorizon.structurelib.structure; diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/InventoryIterable.java b/src/main/java/com/gtnewhorizon/structurelib/util/InventoryIterable.java index 1b27dc18..9b5a1041 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/InventoryIterable.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/InventoryIterable.java @@ -2,10 +2,12 @@ package com.gtnewhorizon.structurelib.util; import java.util.Iterator; import java.util.NoSuchElementException; + import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; public class InventoryIterable implements Iterable { + private final Inv inv; private final int maxSlot; @@ -25,6 +27,7 @@ public class InventoryIterable implements Iterable iterator() { return new Iterator() { + private int ptr = 0; @Override diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/InventoryUtility.java b/src/main/java/com/gtnewhorizon/structurelib/util/InventoryUtility.java index a8d0c0e7..4536d1fd 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/InventoryUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/InventoryUtility.java @@ -1,32 +1,27 @@ /** - * Copyright (c) 2022, glee8e - * This file is part of StructureLib. + * Copyright (c) 2022, glee8e This file is part of StructureLib. *

    - * StructureLib is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * StructureLib is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General + * Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any + * later version. *

    - * StructureLib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. + * StructureLib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. *

    - * You should have received a copy of the GNU Lesser General Public License - * along with Foobar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public License along with Foobar; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.gtnewhorizon.structurelib.util; -import com.gtnewhorizon.gtnhlib.util.map.ItemStackMap; -import com.gtnewhorizon.structurelib.util.InventoryUtility.ItemStackExtractor.APIType; -import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Function; import java.util.function.Predicate; + import javax.annotation.Nonnull; import javax.annotation.Nullable; + import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; @@ -34,10 +29,15 @@ import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryEnderChest; import net.minecraft.item.ItemStack; +import com.gtnewhorizon.gtnhlib.util.map.ItemStackMap; +import com.gtnewhorizon.structurelib.util.InventoryUtility.ItemStackExtractor.APIType; +import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode; + /** * This class is part of API, but is not stable. Use at your own risk. */ public class InventoryUtility { + private static final SortedRegistry stackExtractors = new SortedRegistry<>(); private static final List> enableEnder = new CopyOnWriteArrayList<>(); /** @@ -47,6 +47,7 @@ public class InventoryUtility { static { inventoryProviders.register("5000-main-inventory", new InventoryProvider>() { + @Override public InventoryIterable getInventory(EntityPlayerMP player) { return new InventoryIterable<>(player.inventory, player.inventory.mainInventory.length); @@ -59,8 +60,9 @@ public class InventoryUtility { inv.getInventory().player.inventoryContainer.detectAndSendChanges(); } }); - inventoryProviders.register( - "7000-ender-inventory", new InventoryProvider>() { + inventoryProviders + .register("7000-ender-inventory", new InventoryProvider>() { + @Override public InventoryIterable getInventory(EntityPlayerMP player) { if (enableEnder.stream().anyMatch(p -> p.test(player))) @@ -86,8 +88,8 @@ public class InventoryUtility { stackExtractors.register(key, val); } - public static void registerStackExtractor( - String key, Function extractor) { + public static void registerStackExtractor(String key, + Function extractor) { registerStackExtractor(key, newItemStackProvider(extractor)); } @@ -95,8 +97,8 @@ public class InventoryUtility { inventoryProviders.register(key, val); } - public static void registerInventoryProvider( - String key, Function extractor) { + public static void registerInventoryProvider(String key, + Function extractor) { registerInventoryProvider(key, newInventoryProvider(extractor)); } @@ -107,6 +109,7 @@ public class InventoryUtility { public static InventoryProvider> newInventoryProvider( Function extractor) { return new InventoryProvider>() { + @Override public InventoryIterable getInventory(EntityPlayerMP player) { Inv inv = extractor.apply(player); @@ -122,24 +125,26 @@ public class InventoryUtility { public static ItemStackExtractor newItemStackProvider(Function extractor) { return new ItemStackExtractor() { + @Override public boolean isAPIImplemented(APIType type) { return type == APIType.MAIN; } @Override - public int takeFromStack( - Predicate predicate, - boolean simulate, - int count, - ItemStackCounter store, - ItemStack stack, - ItemStack filter, - EntityPlayerMP player) { + public int takeFromStack(Predicate predicate, boolean simulate, int count, + ItemStackCounter store, ItemStack stack, ItemStack filter, EntityPlayerMP player) { IInventory inv = extractor.apply(stack); if (inv == null) return 0; int found = takeFromInventory( - new InventoryIterable<>(inv), predicate, simulate, count, store, filter, player, false); + new InventoryIterable<>(inv), + predicate, + simulate, + count, + store, + filter, + player, + false); if (found > 0) inv.markDirty(); return found; } @@ -147,8 +152,8 @@ public class InventoryUtility { } /** - * take count amount of stacks that matches given filter. might take partial amount of stuff, so simulation is suggested - * if you ever need to take more than one. + * take count amount of stacks that matches given filter. might take partial amount of stuff, so simulation is + * suggested if you ever need to take more than one. * * @param player source of stacks * @param predicate item stack filter @@ -156,8 +161,8 @@ public class InventoryUtility { * @param count let's hope int size is enough... * @return amount taken. never negative nor bigger than count... */ - public static Map takeFromInventory( - EntityPlayerMP player, Predicate predicate, boolean simulate, int count) { + public static Map takeFromInventory(EntityPlayerMP player, Predicate predicate, + boolean simulate, int count) { ItemStackCounterImpl store = new ItemStackCounterImpl(); int sum = 0; for (InventoryProvider provider : inventoryProviders) { @@ -168,8 +173,8 @@ public class InventoryUtility { } /** - * take count amount of stacks that matches given filter. might take partial amount of stuff, so simulation is suggested - * if you ever need to take more than one. + * take count amount of stacks that matches given filter. might take partial amount of stuff, so simulation is + * suggested if you ever need to take more than one. * * @param player source of stacks * @param filter the precise type of item to extract. stackSize matters @@ -189,14 +194,9 @@ public class InventoryUtility { } // workaround java generics issue - private static > int takeFromPlayer( - EntityPlayerMP player, - Predicate predicate, - boolean simulate, - int count, - ItemStackCounterImpl store, - InventoryProvider provider, - ItemStack filter) { + private static > int takeFromPlayer(EntityPlayerMP player, + Predicate predicate, boolean simulate, int count, ItemStackCounterImpl store, + InventoryProvider provider, ItemStack filter) { R inv = provider.getInventory(player); if (inv == null) return 0; int taken = takeFromInventory(inv, predicate, simulate, count, store, filter, player, true); @@ -215,29 +215,23 @@ public class InventoryUtility { * @param recursive do recursive lookup using {@link #getStackExtractors() stack extractors} * @return amount taken. never negative nor bigger than count... */ - public static Map takeFromInventory( - Iterable inv, Predicate predicate, boolean simulate, int count, boolean recursive) { + public static Map takeFromInventory(Iterable inv, Predicate predicate, + boolean simulate, int count, boolean recursive) { ItemStackCounterImpl store = new ItemStackCounterImpl(); takeFromInventory(inv, predicate, simulate, count, store, null, null, recursive); return store.getStore(); } - private static int takeFromInventory( - @Nonnull Iterable inv, - @Nonnull Predicate predicate, - boolean simulate, - int count, - @Nonnull ItemStackCounter store, - @Nullable ItemStack filter, - @Nullable EntityPlayerMP player, - boolean recursive) { + private static int takeFromInventory(@Nonnull Iterable inv, @Nonnull Predicate predicate, + boolean simulate, int count, @Nonnull ItemStackCounter store, @Nullable ItemStack filter, + @Nullable EntityPlayerMP player, boolean recursive) { int found = 0; ItemStack copiedFilter = null; if (filter != null) { copiedFilter = new ItemStack(filter.getItem(), filter.stackSize, Items.feather.getDamage(filter)); copiedFilter.setTagCompound(filter.stackTagCompound); } - for (Iterator iterator = inv.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = inv.iterator(); iterator.hasNext();) { ItemStack stack = iterator.next(); // invalid stack if (stack == null || stack.getItem() == null || stack.stackSize <= 0) continue; @@ -272,9 +266,10 @@ public class InventoryUtility { } public interface OptimizedExtractor { + /** - * Extract a particular type of item. The extractor can choose to not return all items contained within this item - * as long as it makes sense, but the author should inform the player of this. + * Extract a particular type of item. The extractor can choose to not return all items contained within this + * item as long as it makes sense, but the author should inform the player of this. *

    * Whether optimized extractor do recursive extraction is at the discretion of implementor. * @@ -288,12 +283,14 @@ public class InventoryUtility { } public interface InventoryProvider> { + R getInventory(EntityPlayerMP player); void markDirty(R inv); } public interface ItemStackExtractor { + enum APIType { MAIN, EXTRACT_ONE_STACK, @@ -302,13 +299,13 @@ public class InventoryUtility { boolean isAPIImplemented(APIType type); /** - * Extract a particular type of item. The extractor can choose to not return all items contained within this item - * as long as it makes sense, but the author should inform the player of this. + * Extract a particular type of item. The extractor can choose to not return all items contained within this + * item as long as it makes sense, but the author should inform the player of this. *

    * Whether this method does recursive extraction is at the discretion of implementor. * - * @param predicate the main filtering predicate. never null. It's assumed predicate always returns true on filter, - * if that is not null + * @param predicate the main filtering predicate. never null. It's assumed predicate always returns true on + * filter, if that is not null * @param store where to store extracted items. Should increment the * @param source from where an extraction should be attempted * @param filter stack to extract. should not be mutated! match the NBT tag using EXACT mode. might be null. @@ -316,18 +313,12 @@ public class InventoryUtility { * @param player executor of extraction, or null if from a machine * @return amount extracted, or -1 if this is not implemented */ - int takeFromStack( - Predicate predicate, - boolean simulate, - int count, - ItemStackCounter store, - ItemStack source, - ItemStack filter, - EntityPlayerMP player); + int takeFromStack(Predicate predicate, boolean simulate, int count, ItemStackCounter store, + ItemStack source, ItemStack filter, EntityPlayerMP player); /** - * Extract a particular type of item. The extractor can choose to not return all items contained within this item - * as long as it makes sense, but the author should inform the player of this. + * Extract a particular type of item. The extractor can choose to not return all items contained within this + * item as long as it makes sense, but the author should inform the player of this. *

    * Whether this method does recursive extraction is at the discretion of implementor. * @@ -343,20 +334,15 @@ public class InventoryUtility { static ItemStackExtractor createOnlyOptimized(@Nonnull OptimizedExtractor optimizedExtractor) { return new ItemStackExtractor() { + @Override public boolean isAPIImplemented(APIType type) { return type == APIType.EXTRACT_ONE_STACK; } @Override - public int takeFromStack( - Predicate predicate, - boolean simulate, - int count, - ItemStackCounter store, - ItemStack stack, - ItemStack filter, - EntityPlayerMP player) { + public int takeFromStack(Predicate predicate, boolean simulate, int count, + ItemStackCounter store, ItemStack stack, ItemStack filter, EntityPlayerMP player) { return 0; } @@ -369,6 +355,7 @@ public class InventoryUtility { } public interface ItemStackCounter { + /** * Add some amount of stack. Note stackSize is used instead of stack.stackSize. */ @@ -376,6 +363,7 @@ public class InventoryUtility { } private static class ItemStackCounterImpl implements ItemStackCounter { + private final Map store = new ItemStackMap<>(true); @Override diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackArrayIterable.java b/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackArrayIterable.java index ae49f49c..fb30a1cc 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackArrayIterable.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackArrayIterable.java @@ -1,9 +1,11 @@ package com.gtnewhorizon.structurelib.util; import java.util.Iterator; + import net.minecraft.item.ItemStack; public class ItemStackArrayIterable implements Iterable { + private final ItemStack[] stacks; public ItemStackArrayIterable(ItemStack[] stacks) { @@ -17,6 +19,7 @@ public class ItemStackArrayIterable implements Iterable { @Override public Iterator iterator() { return new Iterator() { + private int ptr = 0; @Override diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackPredicate.java b/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackPredicate.java index a366681c..1685f016 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackPredicate.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/ItemStackPredicate.java @@ -3,6 +3,7 @@ package com.gtnewhorizon.structurelib.util; import java.util.Objects; import java.util.function.BiPredicate; import java.util.function.Predicate; + import net.minecraft.block.Block; import net.minecraft.init.Items; import net.minecraft.item.Item; @@ -11,6 +12,7 @@ import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; public final class ItemStackPredicate implements Predicate { + public static ItemStackPredicate from(Item item) { return new ItemStackPredicate(item); } @@ -20,8 +22,7 @@ public final class ItemStackPredicate implements Predicate { } public static ItemStackPredicate from(ItemStack itemStack, NBTMode mode) { - return new ItemStackPredicate(itemStack.getItem()) - .setMeta(Items.feather.getDamage(itemStack)) + return new ItemStackPredicate(itemStack.getItem()).setMeta(Items.feather.getDamage(itemStack)) .setTag(mode, itemStack.stackTagCompound); } @@ -63,13 +64,16 @@ public final class ItemStackPredicate implements Predicate { } public enum NBTMode implements BiPredicate { + IGNORE { + @Override public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) { return true; } }, IN { + @Override public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) { if (lhs == null || lhs.hasNoTags()) return true; @@ -87,6 +91,7 @@ public final class ItemStackPredicate implements Predicate { } }, EXACT { + @Override public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) { if (lhs != null && lhs.hasNoTags()) lhs = null; @@ -95,6 +100,7 @@ public final class ItemStackPredicate implements Predicate { } }, IGNORE_KNOWN_INSIGNIFICANT_TAGS { + @Override public boolean test(NBTTagCompound lhs, NBTTagCompound rhs) { // fast path for empty tags @@ -105,8 +111,8 @@ public final class ItemStackPredicate implements Predicate { return EXACT.test(lhs, rhs); } }; - private static final String[] KNOWN_INSIGNIFICANT_TAGS = { - "display", // TODO expand/refine this + + private static final String[] KNOWN_INSIGNIFICANT_TAGS = { "display", // TODO expand/refine this }; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/MiscUtils.java b/src/main/java/com/gtnewhorizon/structurelib/util/MiscUtils.java index a794f031..6740e8e0 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/MiscUtils.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/MiscUtils.java @@ -1,12 +1,14 @@ package com.gtnewhorizon.structurelib.util; import java.util.Set; + import net.minecraft.nbt.NBTTagCompound; /** * not related to a certain mod! */ public class MiscUtils { + private MiscUtils() {} @SuppressWarnings("unchecked") diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/SortedRegistry.java b/src/main/java/com/gtnewhorizon/structurelib/util/SortedRegistry.java index d9bb5cb7..90253c70 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/SortedRegistry.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/SortedRegistry.java @@ -4,6 +4,7 @@ import java.util.*; import java.util.function.Consumer; public class SortedRegistry implements Iterable { + private final NavigableMap store = new TreeMap<>(); /** * Store stuff in an array for faster iteration access than a red black tree diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/Vec3Impl.java b/src/main/java/com/gtnewhorizon/structurelib/util/Vec3Impl.java index c3be106b..a7edf155 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/Vec3Impl.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/Vec3Impl.java @@ -3,10 +3,12 @@ package com.gtnewhorizon.structurelib.util; import java.util.HashMap; import java.util.Map; import java.util.function.Function; + import net.minecraft.dispenser.IPosition; import net.minecraftforge.common.util.ForgeDirection; public class Vec3Impl implements Comparable { + public static final Vec3Impl NULL_VECTOR = new Vec3Impl(0, 0, 0); private static final Map pool = new HashMap<>(); private final int val0; @@ -69,8 +71,7 @@ public class Vec3Impl implements Comparable { } public Vec3Impl offset(ForgeDirection facing, int n) { - return n == 0 - ? this + return n == 0 ? this : new Vec3Impl(val0 + facing.offsetX * n, val1 + facing.offsetY * n, val2 + facing.offsetZ * n); } diff --git a/src/main/java/com/gtnewhorizon/structurelib/util/XSTR.java b/src/main/java/com/gtnewhorizon/structurelib/util/XSTR.java index a079097c..075e93a9 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/util/XSTR.java +++ b/src/main/java/com/gtnewhorizon/structurelib/util/XSTR.java @@ -1,37 +1,20 @@ package com.gtnewhorizon.structurelib.util; /* - A subclass of java.util.random that implements the Xorshift random number - generator -

    - - it is 30% faster than the generator from Java's library - it produces - random sequences of higher quality than java.util.Random - this class also - provides a clone() function -

    - Usage: XSRandom rand = new XSRandom(); //Instantiation x = rand.nextInt(); - //pull a random number -

    - To use the class in legacy code, you may also instantiate an XSRandom object - and assign it to a java.util.Random object: java.util.Random rand = new - XSRandom(); -

    - for an explanation of the algorithm, see - http://demesos.blogspot.com/2011/09/pseudo-random-number-generators.html - - @author Wilfried Elmenreich University of Klagenfurt/Lakeside Labs -* http://www.elmenreich.tk -*

    -* This code is released under the GNU Lesser General Public License Version 3 -* http://www.gnu.org/licenses/lgpl-3.0.txt -*/ + * A subclass of java.util.random that implements the Xorshift random number generator

    - it is 30% faster than the + * generator from Java's library - it produces random sequences of higher quality than java.util.Random - this class + * also provides a clone() function

    Usage: XSRandom rand = new XSRandom(); //Instantiation x = rand.nextInt(); + * //pull a random number

    To use the class in legacy code, you may also instantiate an XSRandom object and assign it + * to a java.util.Random object: java.util.Random rand = new XSRandom();

    for an explanation of the algorithm, see + * http://demesos.blogspot.com/2011/09/pseudo-random-number-generators.html + * @author Wilfried Elmenreich University of Klagenfurt/Lakeside Labs http://www.elmenreich.tk

    This code is released + * under the GNU Lesser General Public License Version 3 http://www.gnu.org/licenses/lgpl-3.0.txt + */ import java.util.Random; import java.util.concurrent.atomic.AtomicLong; /** - * XSTR - Xorshift ThermiteRandom - * Modified by Bogdan-G - * 03.06.2016 - * version 0.0.4 + * XSTR - Xorshift ThermiteRandom Modified by Bogdan-G 03.06.2016 version 0.0.4 */ public class XSTR extends Random { @@ -40,10 +23,11 @@ public class XSTR extends Random { private static final long GAMMA = 0x9e3779b97f4a7c15L; private static final int PROBE_INCREMENT = 0x9e3779b9; private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL; - private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) + private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24) private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L); public static final XSTR XSTR_INSTANCE = new XSTR() { + @Override public synchronized void setSeed(long seed) { if (!Thread.currentThread().getStackTrace()[2].getClassName().equals(Random.class.getName())) { @@ -53,13 +37,11 @@ public class XSTR extends Random { }; /* - MODIFIED BY: Robotia - Modification: Implemented Random class seed generator - */ + * MODIFIED BY: Robotia Modification: Implemented Random class seed generator + */ /** - * Creates a new pseudo random number generator. The seed is initialized to - * the current time, as if by + * Creates a new pseudo random number generator. The seed is initialized to the current time, as if by * setSeed(System.currentTimeMillis());. */ public XSTR() { @@ -79,8 +61,8 @@ public class XSTR extends Random { } /** - * Creates a new pseudo random number generator, starting with the specified - * seed, using setSeed(seed);. + * Creates a new pseudo random number generator, starting with the specified seed, using + * setSeed(seed);. * * @param seed the initial seed */ @@ -108,9 +90,8 @@ public class XSTR extends Random { } /** - * Sets the seed for this pseudo random number generator. As described - * above, two instances of the same random class, starting with the same - * seed, produce the same results, if the same methods are called. + * Sets the seed for this pseudo random number generator. As described above, two instances of the same random + * class, starting with the same seed, produce the same results, if the same methods are called. * * @param seed the new seed */ @@ -128,9 +109,8 @@ public class XSTR extends Random { } /** - * Implementation of George Marsaglia's elegant Xorshift random generator - * 30% faster and better quality than the built-in java.util.random see also - * see http://www.javamex.com/tutorials/random_numbers/xorshift.shtml + * Implementation of George Marsaglia's elegant Xorshift random generator 30% faster and better quality than the + * built-in java.util.random see also see http://www.javamex.com/tutorials/random_numbers/xorshift.shtml * * @param nbits will shift nbits bits * @return next seed @@ -170,15 +150,14 @@ public class XSTR extends Random { } /** - * Returns a pseudorandom, uniformly distributed {@code int} value between 0 - * (inclusive) and the specified value (exclusive), drawn from this random - * number generator's sequence. The general contract of {@code nextInt} is - * that one {@code int} value in the specified range is pseudorandomly - * generated and returned. All {@code bound} possible {@code int} values are - * produced with (approximately) equal probability. The method - * {@code nextInt(int bound)} is implemented by class {@code Random} as if - * by: - *

     {@code
    +     * Returns a pseudorandom, uniformly distributed {@code int} value between 0 (inclusive) and the specified value
    +     * (exclusive), drawn from this random number generator's sequence. The general contract of {@code nextInt} is that
    +     * one {@code int} value in the specified range is pseudorandomly generated and returned. All {@code bound} possible
    +     * {@code int} values are produced with (approximately) equal probability. The method {@code nextInt(int bound)} is
    +     * implemented by class {@code Random} as if by:
    +     * 
    +     * 
    +     *  {@code
          * public int nextInt(int bound) {
          *   if (bound <= 0)
          *     throw new IllegalArgumentException("bound must be positive");
    @@ -192,35 +171,29 @@ public class XSTR extends Random {
          *       val = bits % bound;
          *   } while (bits - val + (bound-1) < 0);
          *   return val;
    -     * }}
    + * }} + *
    * - *

    The hedge "approx - * imately" is used in the foregoing description only because the next - * method is only approximately an unbiased source of independently chosen - * bits. If it were a perfect source of randomly chosen bits, then the - * algorithm shown would choose {@code int} values from the stated range - * with perfect uniformity. *

    - * The algorithm is slightly tricky. It rejects values that would result in - * an uneven distribution (due to the fact that 2^31 is not divisible by n). - * The probability of a value being rejected depends on n. The worst case is - * n=2^30+1, for which the probability of a reject is 1/2, and the expected - * number of iterations before the loop terminates is 2. + * The hedge "approx imately" is used in the foregoing description only because the next method is only + * approximately an unbiased source of independently chosen bits. If it were a perfect source of randomly chosen + * bits, then the algorithm shown would choose {@code int} values from the stated range with perfect uniformity. *

    - * The algorithm treats the case where n is a power of two specially: it - * returns the correct number of high-order bits from the underlying - * pseudo-random number generator. In the absence of special treatment, the - * correct number of low-order bits would be returned. Linear - * congruential pseudo-random number generators such as the one implemented - * by this class are known to have short periods in the sequence of values - * of their low-order bits. Thus, this special case greatly increases the - * length of the sequence of values returned by successive calls to this - * method if n is a small power of two. + * The algorithm is slightly tricky. It rejects values that would result in an uneven distribution (due to the fact + * that 2^31 is not divisible by n). The probability of a value being rejected depends on n. The worst case is + * n=2^30+1, for which the probability of a reject is 1/2, and the expected number of iterations before the loop + * terminates is 2. + *

    + * The algorithm treats the case where n is a power of two specially: it returns the correct number of high-order + * bits from the underlying pseudo-random number generator. In the absence of special treatment, the correct number + * of low-order bits would be returned. Linear congruential pseudo-random number generators such as the one + * implemented by this class are known to have short periods in the sequence of values of their low-order bits. + * Thus, this special case greatly increases the length of the sequence of values returned by successive calls to + * this method if n is a small power of two. * * @param bound the upper bound (exclusive). Must be positive. - * @return the next pseudorandom, uniformly distributed {@code int} value - * between zero (inclusive) and {@code bound} (exclusive) from this random - * number generator's sequence + * @return the next pseudorandom, uniformly distributed {@code int} value between zero (inclusive) and {@code bound} + * (exclusive) from this random number generator's sequence * @throws IllegalArgumentException if bound is not positive * @since 1.2 */ @@ -230,18 +203,10 @@ public class XSTR extends Random { // throw new RuntimeException("BadBound"); // } - /*int r = next(31); - int m = bound - 1; - if ((bound & m) == 0) // i.e., bound is a power of 2 - { - r = (int) ((bound * (long) r) >> 31); - } else { - for (int u = r; - u - (r = u % bound) + m < 0; - u = next(31)) - ; - } - return r;*/ + /* + * int r = next(31); int m = bound - 1; if ((bound & m) == 0) // i.e., bound is a power of 2 { r = (int) ((bound + * * (long) r) >> 31); } else { for (int u = r; u - (r = u % bound) + m < 0; u = next(31)) ; } return r; + */ // speedup, new nextInt ~+40% long last = seed ^ seed << 21; last ^= last >>> 35; @@ -269,10 +234,9 @@ public class XSTR extends Random { @Override public void nextBytes(byte[] bytes_arr) { - for (int iba = 0, lenba = bytes_arr.length; iba < lenba; ) { - for (int rndba = nextInt(), nba = Math.min(lenba - iba, Integer.SIZE / Byte.SIZE); - nba-- > 0; - rndba >>= Byte.SIZE) { + for (int iba = 0, lenba = bytes_arr.length; iba < lenba;) { + for (int rndba = nextInt(), nba = Math.min(lenba - iba, Integer.SIZE / Byte.SIZE); nba-- + > 0; rndba >>= Byte.SIZE) { bytes_arr[iba++] = (byte) rndba; } } diff --git a/src/test/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacingTest.java b/src/test/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacingTest.java index 333f6ce8..b1825bdd 100644 --- a/src/test/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacingTest.java +++ b/src/test/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacingTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import net.minecraftforge.common.util.ForgeDirection; + import org.junit.jupiter.api.Test; class ExtendedFacingTest {