Compare commits

..
21 Commits
Author SHA1 Message Date
Martin Robertz 8ab8532915 Merge remote-tracking branch 'ReignOfFROZE/master' into dev 2025-06-19 21:10:42 +02:00
Martin Robertz 67242aa138 Merge branch 'master' into dev 2025-06-19 21:10:38 +02:00
Martin Robertz 4a06c8f95b update 2025-06-19 21:09:58 +02:00
ReignOfFROZE 963975864c Comments 2 2025-06-19 14:53:43 -04:00
koolkrafter5 241bed1989 Update dev username (#41) 2025-06-16 10:53:32 +08:00
ReignOfFROZE 658c4231c4 Comments 2025-06-03 15:36:13 -04:00
Martin Robertz 8b9b4fe25a more h4 2025-04-30 18:04:34 +02:00
Martin Robertz ffd5570bcf update and fix 2025-04-30 17:48:52 +02:00
Martin Robertz 2c50a0ff16 Merge branch 'master' into master 2025-04-30 16:16:16 +02:00
Martin Robertz 54abc5edc1 sa+update deps 2025-04-30 16:15:39 +02:00
Martin Robertz f5594c25db update 2025-04-30 16:05:28 +02:00
Martin Robertz 997da93033 Merge branch 'master' into master 2025-04-30 16:00:31 +02:00
Glease 7cda901ae5 add channel desc and channel indicator item (#39)
Add channel desc and channel indicator item. Its meaning and development
examples has been added to overview page in javadoc.
Also removes gt_no_hatch and show_error special button from GUI as they
are now a candidate in the dropdown menu.

one day we will move this to MUI2, but for now let's stick to existing
infra that is known to work



https://github.com/user-attachments/assets/814edbb6-c4b4-4309-8798-787d9ed1aeef

Note: channels in demo video are from GT5. if you boot the pack without
the modified gt5 you won't see most of the channels.

---------

Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
2025-04-30 15:55:19 +02:00
ReignOfFROZE bbcf3a8669 Moved keybind to CommonProxy 2025-04-20 11:52:25 -04:00
ReignOfFROZE f1473bbb3a Bapy-ized textures 2025-04-20 11:49:45 -04:00
ReignOfFROZE 086b0a00ff Spotless 2025-04-20 11:48:23 -04:00
ReignOfFROZE 6a4886796a Switched to using SyncedKeybind instead of vanilla keybind implementation 2025-04-20 11:46:35 -04:00
ReignOfFROZE e6c82d422d Revert file mode changes 2025-04-20 11:24:25 -04:00
ReignOfFROZE b4b6f4e5eb Spotless apply 2025-04-11 18:45:17 -04:00
reign dfe910ebd3 Fix a few bugs, add removal checking 2025-04-11 18:39:15 -04:00
reign 5b0b9ba3c5 Streamline codepaths and add SU compat for permission checking 2025-04-09 21:35:01 -04:00
24 changed files with 313 additions and 376 deletions

No files matched your search

View File
File mode changed.
+3 -3
View File
@@ -1,13 +1,13 @@
// Add your dependencies here
dependencies {
api("com.github.GTNewHorizons:GTNHLib:0.6.19:dev")
implementation("com.github.GTNewHorizons:NotEnoughItems:2.7.38-GTNH:dev")
api("com.github.GTNewHorizons:GTNHLib:0.6.31:dev")
implementation("com.github.GTNewHorizons:NotEnoughItems:2.7.56-GTNH:dev")
testImplementation(platform('org.junit:junit-bom:5.9.2'))
testImplementation('org.junit.jupiter:junit-jupiter')
// runtimeOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.227:dev") {
// runtimeOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.51.261:dev") {
// exclude group: "com.github.GTNewHorizons", module: "StructureLib"
// }
}
+1 -1
View File
@@ -37,7 +37,7 @@ remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/co
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
developmentEnvironmentUserName = "Developer"
developmentEnvironmentUserName = Developer
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
Vendored Regular → Executable
View File
File mode changed.
+1
View File
@@ -1,4 +1,5 @@
// Add any additional repositiroes for your dependencies here
repositories {
mavenLocal()
}
@@ -20,7 +20,6 @@ import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -43,23 +42,18 @@ import org.lwjgl.opengl.GL11;
import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX;
import com.gtnewhorizon.structurelib.net.RegistryOrderSyncMessage;
import com.gtnewhorizon.structurelib.net.SetChannelDataMessage;
import com.gtnewhorizon.structurelib.net.StructureProjectorCycleModeMessage;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.client.event.ConfigChangedEvent;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;
import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent;
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
import cpw.mods.fml.common.network.FMLNetworkEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class ClientProxy extends CommonProxy {
@@ -266,13 +260,6 @@ public class ClientProxy extends CommonProxy {
MinecraftForge.EVENT_BUS.register(new ForgeEventHandler());
}
@Override
public void init(FMLInitializationEvent e) {
super.init(e);
MinecraftForge.EVENT_BUS.register(new KeybindHandler());
}
static void markTextureUsed(IIcon icon) {
if (StructureLib.COMPAT instanceof IStructureCompat)
((IStructureCompat) StructureLib.COMPAT).markTextureUsed(icon);
@@ -668,30 +655,4 @@ public class ClientProxy extends CommonProxy {
p.endSection();
}
}
public static class KeybindHandler {
private static final KeyBinding CYCLE_PROJECTOR_MODE = new KeyBinding(
"item.structurelib.constructableTrigger.keys.cycleMode",
0,
"item.structurelib.constructableTrigger.keyCategory");
public KeybindHandler() {
FMLCommonHandler.instance().bus().register(this);
// If somebody wants to make a UI element for this, be my guest
ClientRegistry.registerKeyBinding(CYCLE_PROJECTOR_MODE);
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void key(InputEvent.KeyInputEvent event) {
if (CYCLE_PROJECTOR_MODE.isPressed()) {
cycleProjectorMode();
}
}
private static void cycleProjectorMode() {
StructureLib.net.sendToServer(new StructureProjectorCycleModeMessage());
}
}
}
@@ -14,6 +14,8 @@ import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import com.gtnewhorizon.gtnhlib.keybind.SyncedKeybind;
import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger;
import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage;
import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage;
@@ -65,8 +67,6 @@ public class CommonProxy {
public void preInit(FMLPreInitializationEvent e) {}
public void init(FMLInitializationEvent e) {}
public long getOverworldTime() {
return MinecraftServer.getServer().getEntityWorld().getTotalWorldTime();
}
@@ -111,6 +111,16 @@ public class CommonProxy {
}
}
private static final SyncedKeybind MODE_SWAP_KEY = SyncedKeybind.createConfigurable(
"item.structurelib.constructableTrigger.keys.cycleMode",
"item.structurelib.constructableTrigger.keyCategory",
0).registerGlobalListener((entityPlayerMP, syncedKeybind) -> {
final ItemStack held = entityPlayerMP.getHeldItem();
if (held != null && held.getItem() instanceof ItemConstructableTrigger) {
ItemConstructableTrigger.cycleMode(held);
}
});
public void displayConfigGUI(String category) {}
public static class ForgeEventHandler {
@@ -1,8 +1,11 @@
package com.gtnewhorizon.structurelib;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
public interface IStructureCompat {
void markTextureUsed(IIcon o);
boolean checkServerUtilitiesPermission(World world, EntityPlayer actor, int x, int z);
}
@@ -27,7 +27,6 @@ import com.gtnewhorizon.structurelib.net.AlignmentMessage;
import com.gtnewhorizon.structurelib.net.ErrorHintParticleMessage;
import com.gtnewhorizon.structurelib.net.RegistryOrderSyncMessage;
import com.gtnewhorizon.structurelib.net.SetChannelDataMessage;
import com.gtnewhorizon.structurelib.net.StructureProjectorCycleModeMessage;
import com.gtnewhorizon.structurelib.net.UpdateHintParticleMessage;
import com.gtnewhorizon.structurelib.util.InventoryUtility;
import com.gtnewhorizon.structurelib.util.XSTR;
@@ -79,11 +78,6 @@ public class StructureLib {
net.registerMessage(SetChannelDataMessage.Handler.class, SetChannelDataMessage.class, 3, Side.SERVER);
net.registerMessage(ErrorHintParticleMessage.Handler.class, ErrorHintParticleMessage.class, 4, Side.CLIENT);
net.registerMessage(RegistryOrderSyncMessage.Handler.class, RegistryOrderSyncMessage.class, 5, Side.SERVER);
net.registerMessage(
StructureProjectorCycleModeMessage.Handler.class,
StructureProjectorCycleModeMessage.class,
6,
Side.SERVER);
try {
DEBUG_MODE = Boolean.parseBoolean(System.getProperty("structurelib.debug"));
@@ -99,7 +93,7 @@ public class StructureLib {
@Mod.Instance
static StructureLib INSTANCE;
@Mod.Instance(STRUCTURECOMPAT_MODID)
static Object COMPAT;
public static Object COMPAT;
static Block blockHint;
static Item itemBlockHint;
@@ -135,11 +129,6 @@ public class StructureLib {
DevelopHelper.onPreInit();
}
@Mod.EventHandler
public void init(FMLInitializationEvent e) {
proxy.init(e);
}
@Mod.EventHandler
public void loadComplete(FMLLoadCompleteEvent e) {
proxy.loadComplete(e);
@@ -9,7 +9,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.IIcon;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import com.gtnewhorizon.gtnhlib.util.AnimatedTooltipHandler;
@@ -381,7 +380,9 @@ public class StructureLibAPI {
ChannelDescription.item(channel, channelValue, stack);
AnimatedTooltipHandler.addItemTooltip(
stack,
() -> StatCollector
.translateToLocalFormatted("structurelib.tooltip.channelvalue", channelValue, channel));
AnimatedTooltipHandler.translatedText("structurelib.tooltip.channelvalue", channelValue, channel));
AnimatedTooltipHandler.addItemTooltip(
stack,
AnimatedTooltipHandler.translatedText("structurelib.tooltip.indicator_dnd", channelValue, channel));
}
}
@@ -1,17 +1,5 @@
package com.gtnewhorizon.structurelib.gui;
import static org.lwjgl.opengl.ARBImaging.*;
import static org.lwjgl.opengl.ARBImaging.GL_SEPARABLE_2D;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST_FUNC;
import static org.lwjgl.opengl.GL12.GL_RESCALE_NORMAL;
import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL14.GL_BLEND_SRC_RGB;
import static org.lwjgl.opengl.GL15.GL_FOG_COORD_ARRAY;
import static org.lwjgl.opengl.GL20.*;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
@@ -25,6 +13,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
@@ -42,7 +31,7 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import com.google.common.collect.ImmutableMap;
import com.google.common.base.Splitter;
import com.gtnewhorizon.structurelib.ChannelDescription;
import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor;
@@ -66,6 +55,7 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
private static final int WIPE_BTN = 2;
private static final int KEY_MAX_WIDTH = 50;
private static final int INFO_BOX_SIZE = 11;
private final ItemStack trigger;
private final GuiChannelsList list;
private final GuiAutoCompleteList autoCompleteList;
@@ -73,12 +63,13 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
private final TIntObjectMap<Map<String, String>> trimCache = new TIntObjectHashMap<>();
private GuiTextField key, value;
protected int guiTop, guiLeft;
private List<String> info;
public GuiScreenConfigureChannels(Container container, ItemStack trigger) {
super(container);
this.trigger = trigger;
list = new GuiChannelsList(152, 100, 12, 12, 14);
list = new GuiChannelsList(152, 91, 12, 21, 14);
list.addSelectionListener((list, selectedIndex) -> {
Entry<String, Integer> e = list.getElementAt(selectedIndex);
key.setText(e.getKey());
@@ -200,6 +191,14 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
updateButtons();
tooltipSplitCache.clear();
info = StreamSupport
.stream(
Splitter.on("\\n").split(
StatCollector.translateToLocal("item.structurelib.constructableTrigger.gui.info"))
.spliterator(),
false)
.flatMap(line -> fontRendererObj.listFormattedStringToWidth(line, width * 3 / 5).stream())
.collect(Collectors.toList());
}
@Override
@@ -299,6 +298,8 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
key.setText(autoCompleteList.getSelectedElement());
key.setFocused(false);
value.setFocused(true);
value.setText("1");
value.setSelectionPos(0);
return;
}
GuiButton add = getButtonList().get(ADD_BTN);
@@ -396,6 +397,11 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
int topLeftY = (this.height - this.getYSize()) / 2;
drawTexturedModalRect(topLeftX, topLeftY, 0, 0, getXSize(), getYSize());
list.drawScreen(mX, mY, partialTick);
fontRendererObj.drawString(
I18n.format("item.structurelib.constructableTrigger.gui.title"),
guiLeft + 12,
guiTop + 9,
0);
fontRendererObj.drawString(
I18n.format("item.structurelib.constructableTrigger.gui.key"),
guiLeft + 12,
@@ -430,6 +436,11 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
if (highlight != null) {
drawChannelDescriptionTooltip(highlight);
}
if (mouseX > xSize + guiLeft - INFO_BOX_SIZE - 12 && mouseX < xSize + guiLeft - 12
&& mouseY > guiTop + 7
&& mouseY < guiTop + INFO_BOX_SIZE + 7) {
drawHoveringText(info, mouseX, mouseY, fontRendererObj);
}
}
private void drawChannelDescriptionTooltip(String candidate) {
@@ -437,105 +448,6 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
drawHoveringText(tooltip, guiLeft + 151 + 12, guiTop + 122, fontRendererObj);
}
public static void debugPrintGLEnable() {
Map<Integer, String> functions = ImmutableMap.<Integer, String>builder().put(GL11.GL_NEVER, "GL_NEVER")
.put(GL11.GL_LESS, "GL_LESS").put(GL11.GL_EQUAL, "GL_EQUAL").put(GL11.GL_LEQUAL, "GL_LEQUAL")
.put(GL11.GL_GREATER, "GL_GREATER").put(GL11.GL_NOTEQUAL, "GL_NOTEQUAL")
.put(GL11.GL_GEQUAL, "GL_GEQUAL").put(GL11.GL_ALWAYS, "GL_ALWAYS").put(GL11.GL_ZERO, "GL_ZERO")
.put(GL11.GL_ONE, "GL_ONE").put(GL11.GL_SRC_COLOR, "GL_SRC_COLOR")
.put(GL11.GL_ONE_MINUS_SRC_COLOR, "GL_ONE_MINUS_SRC_COLOR").put(GL11.GL_DST_COLOR, "GL_DST_COLOR")
.put(GL11.GL_ONE_MINUS_DST_COLOR, "GL_ONE_MINUS_DST_COLOR").put(GL11.GL_SRC_ALPHA, "GL_SRC_ALPHA")
.put(GL11.GL_ONE_MINUS_SRC_ALPHA, "GL_ONE_MINUS_SRC_ALPHA").put(GL11.GL_DST_ALPHA, "GL_DST_ALPHA")
.put(GL11.GL_ONE_MINUS_DST_ALPHA, "GL_ONE_MINUS_DST_ALPHA")
.put(GL11.GL_CONSTANT_COLOR, "GL_CONSTANT_COLOR")
.put(GL11.GL_ONE_MINUS_CONSTANT_COLOR, "GL_ONE_MINUS_CONSTANT_COLOR")
.put(GL11.GL_CONSTANT_ALPHA, "GL_CONSTANT_ALPHA")
.put(GL11.GL_ONE_MINUS_CONSTANT_ALPHA, "GL_ONE_MINUS_CONSTANT_ALPHA")
.put(GL11.GL_SRC_ALPHA_SATURATE, "GL_SRC_ALPHA_SATURATE").build();
System.out.println("GL_ALPHA_TEST: " + GL11.glIsEnabled(GL_ALPHA_TEST));
System.out.println("GL_AUTO_NORMAL: " + GL11.glIsEnabled(GL_AUTO_NORMAL));
System.out.println("GL_BLEND: " + GL11.glIsEnabled(GL_BLEND));
System.out.println("GL_COLOR_ARRAY: " + GL11.glIsEnabled(GL_COLOR_ARRAY));
System.out.println("GL_COLOR_LOGIC_OP: " + GL11.glIsEnabled(GL_COLOR_LOGIC_OP));
System.out.println("GL_COLOR_MATERIAL: " + GL11.glIsEnabled(GL_COLOR_MATERIAL));
System.out.println("GL_COLOR_SUM: " + GL11.glIsEnabled(GL_COLOR_SUM));
System.out.println("GL_COLOR_TABLE: " + GL11.glIsEnabled(GL_COLOR_TABLE));
System.out.println("GL_CONVOLUTION_1D: " + GL11.glIsEnabled(GL_CONVOLUTION_1D));
System.out.println("GL_CONVOLUTION_2D: " + GL11.glIsEnabled(GL_CONVOLUTION_2D));
System.out.println("GL_CULL_FACE: " + GL11.glIsEnabled(GL_CULL_FACE));
System.out.println("GL_DEPTH_TEST: " + GL11.glIsEnabled(GL_DEPTH_TEST));
System.out.println("GL_DITHER: " + GL11.glIsEnabled(GL_DITHER));
System.out.println("GL_EDGE_FLAG_ARRAY: " + GL11.glIsEnabled(GL_EDGE_FLAG_ARRAY));
System.out.println("GL_FOG: " + GL11.glIsEnabled(GL_FOG));
System.out.println("GL_FOG_COORD_ARRAY: " + GL11.glIsEnabled(GL_FOG_COORD_ARRAY));
System.out.println("GL_HISTOGRAM: " + GL11.glIsEnabled(GL_HISTOGRAM));
System.out.println("GL_INDEX_ARRAY: " + GL11.glIsEnabled(GL_INDEX_ARRAY));
System.out.println("GL_INDEX_LOGIC_OP: " + GL11.glIsEnabled(GL_INDEX_LOGIC_OP));
System.out.println("GL_LIGHTING: " + GL11.glIsEnabled(GL_LIGHTING));
System.out.println("GL_LINE_SMOOTH: " + GL11.glIsEnabled(GL_LINE_SMOOTH));
System.out.println("GL_LINE_STIPPLE: " + GL11.glIsEnabled(GL_LINE_STIPPLE));
System.out.println("GL_MAP1_COLOR_4: " + GL11.glIsEnabled(GL_MAP1_COLOR_4));
System.out.println("GL_MAP1_INDEX: " + GL11.glIsEnabled(GL_MAP1_INDEX));
System.out.println("GL_MAP1_NORMAL: " + GL11.glIsEnabled(GL_MAP1_NORMAL));
System.out.println("GL_MAP1_TEXTURE_COORD_1: " + GL11.glIsEnabled(GL_MAP1_TEXTURE_COORD_1));
System.out.println("GL_MAP1_TEXTURE_COORD_2: " + GL11.glIsEnabled(GL_MAP1_TEXTURE_COORD_2));
System.out.println("GL_MAP1_TEXTURE_COORD_3: " + GL11.glIsEnabled(GL_MAP1_TEXTURE_COORD_3));
System.out.println("GL_MAP1_TEXTURE_COORD_4: " + GL11.glIsEnabled(GL_MAP1_TEXTURE_COORD_4));
System.out.println("GL_MAP2_COLOR_4: " + GL11.glIsEnabled(GL_MAP2_COLOR_4));
System.out.println("GL_MAP2_INDEX: " + GL11.glIsEnabled(GL_MAP2_INDEX));
System.out.println("GL_MAP2_NORMAL: " + GL11.glIsEnabled(GL_MAP2_NORMAL));
System.out.println("GL_MAP2_TEXTURE_COORD_1: " + GL11.glIsEnabled(GL_MAP2_TEXTURE_COORD_1));
System.out.println("GL_MAP2_TEXTURE_COORD_2: " + GL11.glIsEnabled(GL_MAP2_TEXTURE_COORD_2));
System.out.println("GL_MAP2_TEXTURE_COORD_3: " + GL11.glIsEnabled(GL_MAP2_TEXTURE_COORD_3));
System.out.println("GL_MAP2_TEXTURE_COORD_4: " + GL11.glIsEnabled(GL_MAP2_TEXTURE_COORD_4));
System.out.println("GL_MAP2_VERTEX_3: " + GL11.glIsEnabled(GL_MAP2_VERTEX_3));
System.out.println("GL_MAP2_VERTEX_4: " + GL11.glIsEnabled(GL_MAP2_VERTEX_4));
System.out.println("GL_MINMAX: " + GL11.glIsEnabled(GL_MINMAX));
System.out.println("GL_MULTISAMPLE: " + GL11.glIsEnabled(GL_MULTISAMPLE));
System.out.println("GL_NORMAL_ARRAY: " + GL11.glIsEnabled(GL_NORMAL_ARRAY));
System.out.println("GL_NORMALIZE: " + GL11.glIsEnabled(GL_NORMALIZE));
System.out.println("GL_POINT_SMOOTH: " + GL11.glIsEnabled(GL_POINT_SMOOTH));
System.out.println("GL_POINT_SPRITE: " + GL11.glIsEnabled(GL_POINT_SPRITE));
System.out.println("GL_POLYGON_SMOOTH: " + GL11.glIsEnabled(GL_POLYGON_SMOOTH));
System.out.println("GL_POLYGON_OFFSET_FILL: " + GL11.glIsEnabled(GL_POLYGON_OFFSET_FILL));
System.out.println("GL_POLYGON_OFFSET_LINE: " + GL11.glIsEnabled(GL_POLYGON_OFFSET_LINE));
System.out.println("GL_POLYGON_OFFSET_POINT: " + GL11.glIsEnabled(GL_POLYGON_OFFSET_POINT));
System.out.println("GL_POLYGON_STIPPLE: " + GL11.glIsEnabled(GL_POLYGON_STIPPLE));
System.out.println("GL_POST_COLOR_MATRIX_COLOR_TABLE: " + GL11.glIsEnabled(GL_POST_COLOR_MATRIX_COLOR_TABLE));
System.out.println("GL_POST_CONVOLUTION_COLOR_TABLE: " + GL11.glIsEnabled(GL_POST_CONVOLUTION_COLOR_TABLE));
System.out.println("GL_RESCALE_NORMAL: " + GL11.glIsEnabled(GL_RESCALE_NORMAL));
System.out.println("GL_SAMPLE_ALPHA_TO_COVERAGE: " + GL11.glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE));
System.out.println("GL_SAMPLE_ALPHA_TO_ONE: " + GL11.glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE));
System.out.println("GL_SAMPLE_COVERAGE: " + GL11.glIsEnabled(GL_SAMPLE_COVERAGE));
System.out.println("GL_SCISSOR_TEST: " + GL11.glIsEnabled(GL_SCISSOR_TEST));
System.out.println("GL_SECONDARY_COLOR_ARRAY: " + GL11.glIsEnabled(GL_SECONDARY_COLOR_ARRAY));
System.out.println("GL_SEPARABLE_2D: " + GL11.glIsEnabled(GL_SEPARABLE_2D));
System.out.println("GL_STENCIL_TEST: " + GL11.glIsEnabled(GL_STENCIL_TEST));
System.out.println("GL_TEXTURE_1D: " + GL11.glIsEnabled(GL_TEXTURE_1D));
System.out.println("GL_TEXTURE_2D: " + GL11.glIsEnabled(GL_TEXTURE_2D));
System.out.println("GL_TEXTURE_3D: " + GL11.glIsEnabled(GL_TEXTURE_3D));
System.out.println("GL_TEXTURE_COORD_ARRAY: " + GL11.glIsEnabled(GL_TEXTURE_COORD_ARRAY));
System.out.println("GL_TEXTURE_CUBE_MAP: " + GL11.glIsEnabled(GL_TEXTURE_CUBE_MAP));
System.out.println("GL_TEXTURE_GEN_Q: " + GL11.glIsEnabled(GL_TEXTURE_GEN_Q));
System.out.println("GL_TEXTURE_GEN_R: " + GL11.glIsEnabled(GL_TEXTURE_GEN_R));
System.out.println("GL_TEXTURE_GEN_S: " + GL11.glIsEnabled(GL_TEXTURE_GEN_S));
System.out.println("GL_TEXTURE_GEN_T: " + GL11.glIsEnabled(GL_TEXTURE_GEN_T));
System.out.println("GL_VERTEX_ARRAY: " + GL11.glIsEnabled(GL_VERTEX_ARRAY));
System.out.println("GL_VERTEX_PROGRAM_POINT_SIZE: " + GL11.glIsEnabled(GL_VERTEX_PROGRAM_POINT_SIZE));
System.out.println("GL_VERTEX_PROGRAM_TWO_SIDE: " + GL11.glIsEnabled(GL_VERTEX_PROGRAM_TWO_SIDE));
System.out.println("Depth Function: " + functions.get(GL11.glGetInteger(GL_DEPTH_FUNC)));
System.out.printf(
"Blend Function: DST: Alpha %s RGB %s, SRC: Alpha %s RGB %s\n",
functions.get(GL11.glGetInteger(GL_BLEND_DST_ALPHA)),
functions.get(GL11.glGetInteger(GL_BLEND_DST_RGB)),
functions.get(GL11.glGetInteger(GL_BLEND_SRC_ALPHA)),
functions.get(GL11.glGetInteger(GL_BLEND_SRC_RGB)));
System.out.println(
"Alpha Test Function: " + functions.get(GL11.glGetInteger(GL_ALPHA_TEST_FUNC))
+ ", Reference: "
+ GL11.glGetDouble(GL11.GL_ALPHA_TEST_REF));
}
private List<String> getChannelDescriptionTooltip(String candidate) {
List<String> tooltip = new ArrayList<>();
int maxLine = width - (guiLeft + 151 + 12) - 12;
@@ -23,9 +23,7 @@ import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor;
import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility;
public class ItemConstructableTrigger extends Item {
private static final String TAG_MODE = "mode";
public class ItemConstructableTrigger extends ModeToggleableItem {
private static final IIcon[] textures = new IIcon[3];
@@ -34,12 +32,6 @@ public class ItemConstructableTrigger extends Item {
setCreativeTab(StructureLib.creativeTab);
}
public static void cycleMode(ItemStack held) {
if (held.getTagCompound() == null) held.setTagCompound(new NBTTagCompound());
if (!held.getTagCompound().hasKey(TAG_MODE)) held.getTagCompound().setTag(TAG_MODE, new NBTTagInt(0));
held.getTagCompound().setInteger(TAG_MODE, (held.getTagCompound().getInteger(TAG_MODE) + 1) % 3);
}
@Override
public void registerIcons(IIconRegister register) {
textures[0] = register.registerIcon(MOD_ID + ":constructableTrigger/BUILDING");
@@ -83,15 +75,6 @@ public class ItemConstructableTrigger extends Item {
+ StatCollector.translateToLocal("item.structurelib.constructableTrigger.modes." + mode);
}
public static int getMode(ItemStack held) {
if (held == null || !held.hasTagCompound() || !held.getTagCompound().hasKey(TAG_MODE)) {
// default behavior
return 0;
}
// get user-defined mode
return held.getTagCompound().getInteger(TAG_MODE);
}
@Override
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) {
if (!world.isRemote && getMovingObjectPositionFromPlayer(world, player, true) == null) {
@@ -0,0 +1,32 @@
package com.gtnewhorizon.structurelib.item;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
public class ModeToggleableItem extends Item {
public enum TriggerMode {
BUILDING,
UPDATING,
REMOVING
}
public static TriggerMode getMode(ItemStack held) {
if (held == null || !held.hasTagCompound() || !held.getTagCompound().hasKey(TAG_MODE)) {
// default behavior
return TriggerMode.BUILDING;
}
// get user-defined mode
return TriggerMode.values()[held.getTagCompound().getInteger(TAG_MODE)];
}
public static void cycleMode(ItemStack held) {
if (held.getTagCompound() == null) held.setTagCompound(new NBTTagCompound());
if (!held.getTagCompound().hasKey(TAG_MODE)) held.getTagCompound().setTag(TAG_MODE, new NBTTagInt(0));
held.getTagCompound().setInteger(TAG_MODE, (held.getTagCompound().getInteger(TAG_MODE) + 1) % 3);
}
protected static final String TAG_MODE = "mode";
}
@@ -1,37 +0,0 @@
package com.gtnewhorizon.structurelib.net;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
public class StructureProjectorCycleModeMessage implements IMessage {
@Override
public void fromBytes(ByteBuf buf) {
// no op
}
@Override
public void toBytes(ByteBuf buf) {
// no op
}
public static class Handler implements IMessageHandler<StructureProjectorCycleModeMessage, IMessage> {
@Override
public IMessage onMessage(StructureProjectorCycleModeMessage message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
final ItemStack held = player.getHeldItem();
if (held != null && held.getItem() instanceof ItemConstructableTrigger) {
ItemConstructableTrigger.cycleMode(held);
}
return null;
}
}
}
@@ -379,7 +379,7 @@ public interface IStructureDefinition<T> {
basePositionC,
hintsOnly ? ignoreBlockUnloaded((e, w, x, y, z, a, b, c) -> {
e.spawnHint(object, world, x, y, z, trigger);
if (ChannelDataAccessor.hasSubChannel(trigger, StructureLibAPI.CHANNEL_SHOW_ERROR)
if (ChannelDataAccessor.hasSubChannel(trigger, "show_error")
&& !e.couldBeValid(object, world, x, y, z, trigger)) {
StructureLibAPI.markHintParticleError(StructureLib.getCurrentPlayer(), world, x, y, z);
}
@@ -2,6 +2,8 @@ package com.gtnewhorizon.structurelib.structure;
import static com.gtnewhorizon.structurelib.StructureLib.LOGGER;
import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE;
import static com.gtnewhorizon.structurelib.item.ModeToggleableItem.TriggerMode.REMOVING;
import static com.gtnewhorizon.structurelib.structure.StructureUtility.checkForRemoving;
import java.util.Arrays;
import java.util.Collections;
@@ -138,13 +140,14 @@ public interface IStructureElement<T> {
*/
default PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
BlocksToPlace e = getBlocksToPlace(t, world, x, y, z, trigger, env);
IItemSource source = env.getSource();
EntityPlayer actor = env.getActor();
Consumer<IChatComponent> chatter = env.getChatter();
if (e != null) {
if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP;
PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z);
if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck;
if (e.getStacks() == null) {
ItemStack taken = source.takeOne(e.getPredicate(), true);
return StructureUtility.survivalPlaceBlock(
@@ -161,7 +164,7 @@ public interface IStructureElement<T> {
chatter);
}
for (ItemStack stack : e.getStacks()) {
if (mode < 2 && !source.takeOne(stack, true)) continue;
if (mode != REMOVING && !source.takeOne(stack, true)) continue;
return StructureUtility.survivalPlaceBlock(
stack,
NBTMode.EXACT,
@@ -1,32 +1,21 @@
package com.gtnewhorizon.structurelib.structure;
import static com.gtnewhorizon.structurelib.StructureLib.LOGGER;
import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE;
import static java.lang.Integer.MIN_VALUE;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizon.structurelib.IStructureCompat;
import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent;
import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.StructureLibAPI;
import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor;
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger;
import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult;
import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder;
import com.gtnewhorizon.structurelib.structure.adders.ITileAdder;
import com.gtnewhorizon.structurelib.util.ItemStackPredicate;
import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode;
import com.gtnewhorizon.structurelib.util.Vec3Impl;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.Block;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
@@ -42,25 +31,18 @@ import net.minecraft.util.IChatComponent;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizon.structurelib.StructureEvent.StructureElementVisitedEvent;
import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.StructureLibAPI;
import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor;
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
import com.gtnewhorizon.structurelib.item.ItemConstructableTrigger;
import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult;
import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder;
import com.gtnewhorizon.structurelib.structure.adders.ITileAdder;
import com.gtnewhorizon.structurelib.util.ItemStackPredicate;
import com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode;
import com.gtnewhorizon.structurelib.util.Vec3Impl;
import javax.annotation.Nullable;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.*;
import cpw.mods.fml.common.registry.GameRegistry;
import static com.gtnewhorizon.structurelib.StructureLib.LOGGER;
import static com.gtnewhorizon.structurelib.StructureLib.PANIC_MODE;
import static com.gtnewhorizon.structurelib.item.ModeToggleableItem.TriggerMode.*;
import static java.lang.Integer.MIN_VALUE;
/**
* A brief index of everything contained
@@ -148,6 +130,8 @@ public class StructureUtility {
private static final String NICE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz=|!@#$%&()[]{};:<>/?_,.*^'`";
private static final boolean isSULoaded = Loader.isModLoaded("serverutilities");
@SuppressWarnings("rawtypes")
private static final Map<Vec3Impl, IStructureNavigate> STEP = new HashMap<>();
@@ -225,8 +209,8 @@ public class StructureUtility {
@Override
public PlaceResult survivalPlaceBlock(Object o, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode < 2 && check(o, world, x, y, z)) return PlaceResult.SKIP;
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
if (mode != REMOVING && check(o, world, x, y, z)) return PlaceResult.SKIP;
// user should place anything here.
// maybe make this configurable, but for now we try to take some cobble from user
if (env.getSource().takeOne(new ItemStack(Blocks.cobblestone), false)) {
@@ -341,43 +325,47 @@ public class StructureUtility {
public static PlaceResult survivalPlaceBlock(Block block, int meta, World world, int x, int y, int z, IItemSource s,
EntityPlayer actor, Consumer<IChatComponent> chatter) {
if (block == null) throw new NullPointerException();
int mode = 0;
ItemConstructableTrigger.TriggerMode mode = BUILDING;
if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) {
// best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the
// ...trigger instead of assuming default behavior
mode = ItemConstructableTrigger.getMode(actor.getHeldItem());
}
if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT;
if (mode == 1 && world.getTileEntity(x, y, z) instanceof TileEntity) {
// We're in updating mode and the block we're looking at might be important, so let's just leave it alone
// since it's probably not something we want to replace with something else
return PlaceResult.SKIP;
if (mode == BUILDING && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor))
return PlaceResult.REJECT;
if (mode == UPDATING) {
if (!world.isAirBlock(x, y, z)) {
if (world.getTileEntity(x, y, z) instanceof TileEntity) {
// We're in updating mode and the block we're looking at might be important, so let's just leave it
// alone
// since it's probably not something we want to replace with something else
return PlaceResult.SKIP;
}
Block blockInWorld = world.getBlock(x, y, z);
if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) {
// This is the block we are looking for, move along
return PlaceResult.SKIP;
}
}
}
Item itemBlock = Item.getItemFromBlock(block);
int itemMeta = itemBlock instanceof ISpecialItemBlock
? ((ISpecialItemBlock) itemBlock).getItemMetaFromBlockMeta(block, meta)
: meta;
ItemStack stack = new ItemStack(itemBlock, 1, itemMeta);
if (mode == 1 && !world.isAirBlock(x, y, z)) {
Block blockInWorld = world.getBlock(x, y, z);
if (blockInWorld.isAssociatedBlock(block) && blockInWorld.getDamageValue(world, x, y, z) == meta) {
// This is the block we are looking for, move along
return PlaceResult.SKIP;
if (mode != REMOVING) {
if (!s.takeOne(stack, true)) {
if (chatter != null) chatter.accept(
new ChatComponentTranslation(
"structurelib.autoplace.error.no_simple_block",
stack.func_151000_E()));
return PlaceResult.REJECT;
}
}
if (mode < 2 && !s.takeOne(stack, true)) {
if (chatter != null) chatter.accept(
new ChatComponentTranslation(
"structurelib.autoplace.error.no_simple_block",
stack.func_151000_E()));
return PlaceResult.REJECT;
}
if (mode < 2) {
if (block instanceof ICustomBlockSetting) {
ICustomBlockSetting blockCustom = (ICustomBlockSetting) block;
blockCustom.setBlock(world, x, y, z, meta);
} else {
if (mode == 1 && !world.isAirBlock(x, y, z)) {
if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) {
// We're in updating mode and there's a block in our way (grr), so let's remove whatever is there
// ...and drop it to the player
ItemStack toGive = new ItemStack(world.getBlock(x, y, z));
@@ -398,18 +386,31 @@ public class StructureUtility {
}
}
}
if (mode == 2 && world.isAirBlock(x, y, z)) {
return PlaceResult.SKIP;
}
if (mode == 2 || !s.takeOne(stack, false)) {
// If the user didn't have the item in their inventory, or we're in removing mode, we set it to air
if (mode == REMOVING) {
// We're in removing mode, so let's check some stuff
if (world.isAirBlock(x, y, z)) {
return PlaceResult.SKIP;
}
ItemStack toGive = new ItemStack(world.getBlock(x, y, z));
toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z));
if (!checkPermission(world, actor, x, y, z)) {
return PlaceResult.REJECT;
}
world.setBlockToAir(x, y, z);
if (!tryGiveOrDropItem(world, actor, toGive)) {
// We're in removing mode and something went wrong while trying to give the player the block we removed,
// let's just fail for now
return PlaceResult.REJECT;
}
} else if (!s.takeOne(stack, false)) {
// If the user didn't have the block in their inventory, and we're in some
// other mode, let's check some stuff
if (world.isAirBlock(x, y, z)) {
return PlaceResult.SKIP;
}
ItemStack toGive = new ItemStack(world.getBlock(x, y, z));
toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z));
world.setBlockToAir(x, y, z);
if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) {
// Something went wrong while trying to give the player the block we removed, let's just fail for now
return PlaceResult.REJECT;
}
}
return PlaceResult.ACCEPT;
}
@@ -501,35 +502,40 @@ public class StructureUtility {
if (stack == null) throw new NullPointerException();
if (stack.stackSize != 1) throw new IllegalArgumentException();
if (!(stack.getItem() instanceof ItemBlock)) throw new IllegalArgumentException();
int mode = 0;
ItemConstructableTrigger.TriggerMode mode = BUILDING;
if (actor.getHeldItem() != null && actor.getHeldItem().getItem() instanceof ItemConstructableTrigger) {
// best effort lookup if the item in the player's hand is a trigger, and if it is, get the mode from the
// ...trigger instead of assuming default behavior
mode = ItemConstructableTrigger.getMode(actor.getHeldItem());
}
if (mode == 1 && !world.isAirBlock(x, y, z)) {
if (world.getTileEntity(x, y, z) instanceof TileEntity) {
// We're in updating mode and the block we're looking at might be important, so let's just leave it
// alone
// since it's probably not something we want to replace with something else
return PlaceResult.SKIP;
if (mode != REMOVING) {
if (mode == BUILDING) {
if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) {
return PlaceResult.SKIP;
}
}
Block blockInWorld = world.getBlock(x, y, z);
ItemStack blockInWorldItem = new ItemStack(blockInWorld);
blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z));
if (blockInWorldItem.isItemEqual(stack)) {
// This is the block we are looking for, move along
return PlaceResult.SKIP;
if (mode == UPDATING) {
if (!world.isAirBlock(x, y, z)) {
if (world.getTileEntity(x, y, z) instanceof TileEntity) {
return PlaceResult.SKIP;
}
Block blockInWorld = world.getBlock(x, y, z);
ItemStack blockInWorldItem = new ItemStack(blockInWorld);
blockInWorldItem.setItemDamage(blockInWorld.getDamageValue(world, x, y, z));
if (blockInWorldItem.isItemEqual(stack)) {
// This is the block we are looking for, move along
return PlaceResult.SKIP;
}
}
}
}
if (mode == 0 && !StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT;
if (mode < 2 && !assumeStackPresent && !s.takeOne(stack, true)) {
if (chatter != null) chatter.accept(
new ChatComponentTranslation("structurelib.autoplace.error.no_item_stack", stack.func_151000_E()));
return PlaceResult.REJECT;
}
if (mode < 2) {
if (mode == 1 && !world.isAirBlock(x, y, z)) {
if (!assumeStackPresent && !s.takeOne(stack, true)) {
if (chatter != null) chatter.accept(
new ChatComponentTranslation(
"structurelib.autoplace.error.no_item_stack",
stack.func_151000_E()));
return PlaceResult.REJECT;
}
if (mode == UPDATING && !world.isAirBlock(x, y, z) && checkPermission(world, actor, x, y, z)) {
// We're in updating mode and there's a block in our way (grr), so let's remove whatever is there
// ...and drop it to the player
ItemStack toGive = new ItemStack(world.getBlock(x, y, z));
@@ -548,19 +554,30 @@ public class StructureUtility {
return PlaceResult.REJECT;
}
}
if (mode == 2 && world.isAirBlock(x, y, z)) {
return PlaceResult.SKIP;
}
if (mode == 2 || !s.takeOne(stack, false)) {
// If the user didn't have the item in their inventory, or we're in removing mode, we set it to air
if (mode == REMOVING) {
if (world.isAirBlock(x, y, z)) {
return PlaceResult.SKIP;
}
// If we're in removing mode, we set it to air
ItemStack toGive = new ItemStack(world.getBlock(x, y, z));
toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z));
if (!checkPermission(world, actor, x, y, z)) {
return PlaceResult.REJECT;
}
world.setBlockToAir(x, y, z);
if (mode == 2 && !tryGiveOrDropItem(world, actor, toGive)) {
if (!tryGiveOrDropItem(world, actor, toGive)) {
// We were in removing mode and something went wrong while trying to give the player the block we
// ...removed, let's just fail for now
return PlaceResult.REJECT;
}
} else if (!s.takeOne(stack, false)) {
if (world.isAirBlock(x, y, z)) {
return PlaceResult.SKIP;
}
// If the user didn't have the item in their inventory, we set it to air
ItemStack toGive = new ItemStack(world.getBlock(x, y, z));
toGive.setItemDamage(world.getBlock(x, y, z).getDamageValue(world, x, y, z));
world.setBlockToAir(x, y, z);
}
return PlaceResult.ACCEPT;
}
@@ -744,7 +761,20 @@ public class StructureUtility {
* given tier, then player will be allowed to use multiple kinds of blocks, but their tier is guaranteed to be the
* same.
* <p>
* <b>Example Implementation:</b>
* <h4>WARNING</h4> <b>You SHOULD NOT return notSet from your tierExtractor.</b> If you do so, we will have this
* chain of events:
* <ul>
* <li>at check start, tier is reset to notSet
* <li>the tier extractor returns notSet for first block, so since ofBlocksTiered finds your current tier is notSet,
* and the new block's tier is the same as that, so it's accepted
* <li>at 2nd, 3rd..., same thing in 2 happens
* <li>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
* <li>check got notified structure is sound, and tier is not notSet. it marks the structure as complete and start
* doing its business
* <li>Player enjoy a (probably) hilariously shaped multi and (probably) reduced build cost.
* </ul>
* <h4>Example Implementation</h4>
* <p>
* Assume you have 16 tier, each map to one particular block's 16 different meta. You will usually want something
* like this
@@ -771,7 +801,7 @@ public class StructureUtility {
* }
* </pre>
*
* Important bits:
* Important bits of this example implementation:
* <ul>
* <li>The supplied ITierConverter returns null for an invalid block</li>
* <li>Possible tier returned by ITierConverter is Integer object 0 to 15.</li>
@@ -780,19 +810,8 @@ public class StructureUtility {
* <li>notSet is never a tier returned by ITierConverter.</li>
* </ul>
* <p>
* <p>
* <b>You SHOULD NOT return notSet from your tierExtractor.</b> If you do so, we will have this chain of events:
* <ul>
* <li>at check start, tier is reset to notSet
* <li>the tier extractor returns notSet for first block, so since ofBlocksTiered finds your current tier is notSet,
* and the new block's tier is the same as that, so it's accepted
* <li>at 2nd, 3rd..., same thing in 2 happens
* <li>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
* <li>check got notified structure is sound, and tier is not notSet. it marks the structure as complete and start
* doing its business
* <li>Player enjoy a (probably) hilariously shaped multi and (probably) reduced build cost.
* </ul>
* As a friendly reminder, the above characteristics are only for this simply demo, not as a general restriction
* imposed by ofBlocksTiered.
*
* @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. If this function returns null, then the
@@ -839,6 +858,11 @@ public class StructureUtility {
return Objects.equals(hintTier, worldTier);
}
private boolean isInAllKnownTiers(Block b) {
return allKnownTiers != null
&& allKnownTiers.stream().anyMatch(pair -> pair.getLeft().isAssociatedBlock(b));
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
Pair<Block, Integer> hint = getHint(trigger);
@@ -871,14 +895,21 @@ public class StructureUtility {
@Override
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
Pair<Block, Integer> hint = getHint(trigger);
if (hint == null) return PlaceResult.REJECT; // TODO or SKIP?
Block block = world.getBlock(x, y, z);
int meta = world.getBlockMetadata(x, y, z);
TIER tier = tierExtractor.convert(block, meta);
if (mode < 2 && Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue())))
return PlaceResult.SKIP;
if (mode == REMOVING) {
if (!isInAllKnownTiers(block) && !world.isAirBlock(x, y, z)) {
return PlaceResult.REJECT;
}
} else {
if ((Objects.equals(tier, tierExtractor.convert(hint.getKey(), hint.getValue())))) {
return PlaceResult.SKIP;
}
}
return StructureUtility.survivalPlaceBlock(
hint.getKey(),
hint.getValue(),
@@ -967,8 +998,9 @@ public class StructureUtility {
@Override
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP;
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z);
if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck;
if (getBlock() == null) return PlaceResult.REJECT;
return StructureUtility.survivalPlaceBlock(
getBlock(),
@@ -1055,8 +1087,9 @@ public class StructureUtility {
@Deprecated
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
IItemSource s, EntityPlayerMP actor, Consumer<IChatComponent> chatter) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP;
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z);
if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck;
if (init()) return StructureUtility.survivalPlaceBlock(block, meta, world, x, y, z, s, actor, chatter);
return fallback.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter);
}
@@ -1064,8 +1097,9 @@ public class StructureUtility {
@Override
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode < 2 && check(t, world, x, y, z)) return PlaceResult.SKIP;
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(mode, check(t, world, x, y, z), world, x, y, z);
if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck;
if (init()) return StructureUtility.survivalPlaceBlock(
block,
meta,
@@ -1693,10 +1727,15 @@ public class StructureUtility {
@Deprecated
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode < 2 && world.getBlock(x, y, z) == defaultBlock
&& world.getBlockMetadata(x, y, z) == defaultMeta)
return PlaceResult.SKIP;
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(
mode,
world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta,
world,
x,
y,
z);
if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck;
return StructureUtility.survivalPlaceBlock(
defaultBlock,
defaultMeta,
@@ -1741,10 +1780,15 @@ public class StructureUtility {
@Deprecated
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode < 2 && world.getBlock(x, y, z) == defaultBlock
&& world.getBlockMetadata(x, y, z) == defaultMeta)
return PlaceResult.SKIP;
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
PlaceResult skipOrRejectBasedOnCheck = checkForRemoving(
mode,
world.getBlock(x, y, z) == defaultBlock && world.getBlockMetadata(x, y, z) == defaultMeta,
world,
x,
y,
z);
if (skipOrRejectBasedOnCheck != PlaceResult.ACCEPT) return skipOrRejectBasedOnCheck;
return StructureUtility.survivalPlaceBlock(
defaultBlock,
defaultMeta,
@@ -2003,8 +2047,7 @@ public class StructureUtility {
@Deprecated
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
IItemSource s, EntityPlayerMP actor, Consumer<IChatComponent> chatter) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode == 2 || predicate.test(t))
if (predicate.test(t))
return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, s, actor, chatter);
return placeResultWhenDisabled;
}
@@ -2012,9 +2055,7 @@ public class StructureUtility {
@Override
public PlaceResult survivalPlaceBlock(T t, World world, int x, int y, int z, ItemStack trigger,
AutoPlaceEnvironment env) {
int mode = ItemConstructableTrigger.getMode(trigger);
if (mode == 2 || predicate.test(t))
return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env);
if (predicate.test(t)) return downstream.survivalPlaceBlock(t, world, x, y, z, trigger, env);
return placeResultWhenDisabled;
}
};
@@ -3391,15 +3432,15 @@ public class StructureUtility {
* @param onRemove Operation to be performed when the mode of the trigger is set to removing mode
*/
public static void placeRemoveOrUpdate(ItemStack trigger, Runnable onCreate, Runnable onUpdate, Runnable onRemove) {
int mode = ItemConstructableTrigger.getMode(trigger);
ItemConstructableTrigger.TriggerMode mode = ItemConstructableTrigger.getMode(trigger);
switch (mode) {
case 0:
case BUILDING:
onCreate.run();
break;
case 1:
case UPDATING:
onUpdate.run();
break;
case 2:
case REMOVING:
onRemove.run();
break;
}
@@ -3410,6 +3451,28 @@ public class StructureUtility {
actor.inventoryContainer.detectAndSendChanges();
return true;
}
return world.spawnEntityInWorld(new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack));
EntityItem toSpawn = new EntityItem(world, actor.posX, actor.posY, actor.posZ, stack);
// For some reason these things sometimes spawn with the velocity of an F1 car, so let's prevent that
toSpawn.motionX = 0;
toSpawn.motionY = 0;
toSpawn.motionZ = 0;
return world.spawnEntityInWorld(toSpawn);
}
public static boolean checkPermission(World world, EntityPlayer actor, int x, int y, int z) {
boolean res = true;
if (isSULoaded && StructureLib.COMPAT instanceof IStructureCompat isc) {
res = isc.checkServerUtilitiesPermission(world, actor, x, z);
}
res = res && !world.getBlock(x, y, z).isAssociatedBlock(Blocks.bedrock);
// maybe check mining level who knows :shrug:
return res;
}
public static PlaceResult checkForRemoving(ItemConstructableTrigger.TriggerMode mode, boolean checkResult,
World world, int x, int y, int z) {
if (mode != REMOVING && checkResult) return PlaceResult.SKIP;
else if (mode != BUILDING && !checkResult && !world.isAirBlock(x, y, z)) return PlaceResult.REJECT;
return PlaceResult.ACCEPT;
}
}
+10
View File
@@ -133,6 +133,16 @@ StructureLib API documentation.
Usually there is no reason to reimplement this on your own.
</p>
<h2>{@link com.gtnewhorizon.structurelib.item.ModeToggleableItem}</h2>
<p>
This class is the base class for {@link com.gtnewhorizon.structurelib.item.ItemConstructableTrigger} that defines
the <code>TriggerMode</code>s for the {@link com.gtnewhorizon.structurelib.item.ItemConstructableTrigger}. There are
3 modes, <code>BUILDING</code>, <code>UPDATING</code>, and <code>REMOVING</code>. Each of these modes does as they
say, where building will build a new multi from scratch, updating will remove existing an existing structure and
replace it with new components (think upgrading glass on a multi, changing from a tier 1 to tier 2 of a multi, etc),
and removing will just straight up remove the multi.
</p>
<h2><a href="#channels" id="channels">Channels</a></h2>
<p>
@@ -33,6 +33,7 @@ item.structurelib.constructableTrigger.desc.4=Quantity of schematics in item sta
item.structurelib.constructableTrigger.desc.5=Hold §l[LSHIFT]§r to display channel data
item.structurelib.constructableTrigger.desc.lshift.0=Contain %d sub channel.
item.structurelib.constructableTrigger.too_fast=Please wait %d milliseconds before another autoplace...
item.structurelib.constructableTrigger.gui.title=Sub Channels
item.structurelib.constructableTrigger.gui.key=Key:
item.structurelib.constructableTrigger.gui.value=Value:
item.structurelib.constructableTrigger.gui.add=Add
@@ -46,10 +47,12 @@ item.structurelib.constructableTrigger.gui.gt_no_hatch.disable=Hatches
item.structurelib.constructableTrigger.keyCategory=Multiblock Structure Hologram Projector Keys
item.structurelib.constructableTrigger.keys.cycleMode=Cycle Projector Mode
item.structurelib.constructableTrigger.gui.channels.from=§rMod: §9§o%s
item.structurelib.constructableTrigger.gui.info=Many multiblocks support some degree of variation in its structure and use sub channels to indicate which variant to use.\n Sub channels are has a sequence of lower case characters as key and a positive integer as value. Most known sub channels should be available as typeahead completions.\nYou can also drag and drop items from NEI to set the corresponding sub channel value. These items all have a tooltip of §oIndicates value X for sub channel Y§r.
channels.structurelib.show_errors=When set, will highlight parts of the multiblock that is definitely wrong
structurelib.tooltip.channelvalue=§7Indicates value §6%d§r§7 for sub channel §6%s
structurelib.tooltip.indicator_dnd=Drop into GUI to select this value for this channel
structurelib.autoplace.built_stat=Built %s blocks
structurelib.autoplace.complete=§aThis multiblock has completed!
@@ -30,6 +30,7 @@ item.structurelib.constructableTrigger.desc.4=此物品堆叠数量会影响显
item.structurelib.constructableTrigger.desc.5=按下 §l[左SHIFT]§r 以显示子信道
item.structurelib.constructableTrigger.desc.lshift.0=包含 %d 个子信道
item.structurelib.constructableTrigger.too_fast=请在下一次自动搭建前等待 %d 毫秒...
item.structurelib.constructableTrigger.gui.title=子信道
item.structurelib.constructableTrigger.gui.key=信道名:
item.structurelib.constructableTrigger.gui.value=值:
item.structurelib.constructableTrigger.gui.add=添加
@@ -37,10 +38,12 @@ item.structurelib.constructableTrigger.gui.set=替换
item.structurelib.constructableTrigger.gui.unset=删除
item.structurelib.constructableTrigger.gui.wipe=§4全部清空
item.structurelib.constructableTrigger.gui.channels.from=§r模组: §9§o%s
item.structurelib.constructableTrigger.gui.info=许多多方块的结构都是可变的,在自动放置时,可以使用子信道来向多方块指明该使用哪一个变体。\n子信道由一个字符串标识、并拥有一个正整数作为值。这个GUI中的信道名支持自动补全到绝大多数已知的子信道。\n你也可以将部分物品从NEI中拖拽至GUI内来设置子信道值为该物品表示的值。这些物品的物品说明中都带有§o表示子信道 X 为 Y§r。
channels.structurelib.show_errors=添加后,在投影时会高亮标出必然错误的部分
structurelib.tooltip.channelvalue=§7表示子信道 §6%2$s§r§7 为 §6%d§r
structurelib.tooltip.indicator_dnd=拖入GUI中来选择该值
structurelib.autoplace.built_stat=已放置 %s 个方块
structurelib.autoplace.complete=§a这个多方块结构已经完成自动搭建!
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 667 B

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

After

Width:  |  Height:  |  Size: 365 B