Compare commits

...
10 Commits
Author SHA1 Message Date
Martin Robertz a00d1a6cf5 Merge branch 'dev' 2025-01-03 23:56:10 +01:00
glowredmanandGlease bf5dd5566b Add Localization (#36)
This adds some missing localizations for unlocalized names returned by
the ItemStack-insensitive version of `Item.getUnlocalizedName()`.
Relevant for the Item/Block stats introduced in
https://github.com/GTNewHorizons/Hodgepodge/pull/398.

---------

Co-authored-by: Glease <4586901+Glease@users.noreply.github.com>
2025-01-02 11:40:59 +08:00
Martin Robertz ece891f797 Merge remote-tracking branch 'origin/feature/channel-configure' into dev 2024-12-14 20:13:05 +01:00
Martin Robertz b9d0143245 update 2024-12-14 20:12:25 +01:00
Glease 2bde67bc20 localize hologram trigger item GUI
Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
2024-12-15 02:48:06 +08:00
Glease 361d2932f6 add mouse wheel scrolling for channel data
Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
2024-12-15 02:41:39 +08:00
Glease 27be10dfbf try to improve robustness of channels gui
Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
2024-12-15 02:41:26 +08:00
43fc39c99b Add error hint when block is invalid (#31)
Co-authored-by: kstvr32 <kstvr32@gmail.com>
Co-authored-by: Martin Robertz <dream-master@gmx.net>
2024-12-14 19:13:34 +01:00
Lyft 6337536dc3 Send correct identifier when instrumenting (#34) 2024-11-19 10:20:47 +08:00
Lyft 9b96560119 Fix IStructureElementChain returning an invalid Iterable (#33) 2024-11-09 15:46:49 +01:00
19 changed files with 373 additions and 30 deletions

No files matched your search

+2 -2
View File
@@ -1,8 +1,8 @@
// Add your dependencies here
dependencies {
api("com.github.GTNewHorizons:GTNHLib:0.4.2:dev")
runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.6.19-GTNH:dev")
api("com.github.GTNewHorizons:GTNHLib:0.5.22:dev")
runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.6.51-GTNH:dev")
testImplementation(platform('org.junit:junit-bom:5.9.2'))
testImplementation('org.junit.jupiter:junit-jupiter')
+3 -3
View File
@@ -50,10 +50,10 @@ enableGenericInjection = true
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
generateGradleTokenClass =
generateGradleTokenClass = com.gtnewhorizon.structurelib.Tags
# Name of the token containing the project's current version to generate/replace.
gradleTokenVersion = GRADLETOKEN_VERSION
gradleTokenVersion = VERSION
# [DEPRECATED] Mod ID replacement token.
gradleTokenModId =
@@ -70,7 +70,7 @@ gradleTokenGroupName =
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...]).
# Leave these properties empty to skip individual token replacements.
replaceGradleTokenInFile = StructureLib.java
replaceGradleTokenInFile =
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.26'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.30'
}
@@ -42,7 +42,7 @@ import cpw.mods.fml.relauncher.SideOnly;
@Mod(
modid = StructureLibAPI.MOD_ID,
name = "StructureLib",
version = "GRADLETOKEN_VERSION",
version = Tags.VERSION,
acceptableRemoteVersions = "*",
guiFactory = "com.gtnewhorizon.structurelib.GuiFactory")
public class StructureLib {
@@ -100,6 +100,8 @@ public class StructureLib {
}
};
public static boolean isGTLoaded;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent e) {
ConfigurationHandler.INSTANCE.init(e.getSuggestedConfigurationFile());
@@ -118,6 +120,8 @@ public class StructureLib {
if (Loader.isModLoaded(STRUCTURECOMPAT_MODID)) {
COMPAT = Loader.instance().getIndexedModList().get(STRUCTURECOMPAT_MODID).getMod();
}
isGTLoaded = Loader.isModLoaded("gregtech");
}
@Mod.EventHandler
@@ -72,7 +72,7 @@ public class StructureLibAPI {
*/
public static void enableInstrument(Object identifier) {
if (isInstrumentEnabled()) throw new IllegalStateException();
instrument.set(instrument);
instrument.set(identifier);
}
/**
@@ -25,6 +25,17 @@ import com.gtnewhorizon.structurelib.gui.GuiScrollableList.IGuiScreen;
public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen {
private static final String I18N_PREFIX = "item.structurelib.constructableTrigger.gui.";
private static final int ADD_BTN = 0;
private static final int UNSET_BTN = 1;
private static final int WIPE_BTN = 2;
private static final int SHOW_ERROR_BTN = 3;
private static final int GT_NO_HATCH_BTN = 4;
private static final String SHOW_ERROR_CHANNEL = "show_error";
private static final String GT_NO_HATCH_CHANNEL = "gt_no_hatch";
private static final int KEY_MAX_WIDTH = 50;
private final ItemStack trigger;
private final GuiChannelsList list;
@@ -128,7 +139,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
addButton(
new GuiButton(
0,
ADD_BTN,
guiLeft + 12,
guiTop + 157,
47,
@@ -136,7 +147,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
I18n.format("item.structurelib.constructableTrigger.gui.add")));
addButton(
new GuiButton(
1,
UNSET_BTN,
guiLeft + 65,
guiTop + 157,
47,
@@ -144,13 +155,27 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
I18n.format("item.structurelib.constructableTrigger.gui.unset")));
addButton(
new GuiButton(
2,
WIPE_BTN,
guiLeft + 118,
guiTop + 157,
47,
20,
I18n.format("item.structurelib.constructableTrigger.gui.wipe")));
addButton(
new GuiButton(
SHOW_ERROR_BTN,
StructureLib.isGTLoaded ? guiLeft + 12 : guiLeft + 52,
guiTop + 180,
73,
20,
""));
// only show GT hatch button if GT is loaded
if (StructureLib.isGTLoaded) {
addButton(new GuiButton(GT_NO_HATCH_BTN, guiLeft + 92, guiTop + 180, 73, 20, ""));
}
updateButtons();
}
@@ -171,7 +196,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
@Override
public int getYSize() {
return 188;
return 211;
}
@Override
@@ -199,10 +224,29 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
return buttonList;
}
private boolean isMouseOverValue() {
int mx = Mouse.getEventX() * this.width / this.mc.displayWidth;
int my = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
return mx >= value.xPosition && mx < value.xPosition + value.width
&& my >= value.yPosition
&& my < value.yPosition + value.height;
}
@Override
public void handleMouseInput() {
int delta = Mouse.getEventDWheel();
if (delta != 0) list.handleDWheel(delta);
if (delta != 0) {
if (isMouseOverValue()) {
if (delta > 0) {
value.setText(String.valueOf(getValue() + 1));
} else {
value.setText(String.valueOf(Math.max(getValue() - 1, 1)));
}
} else {
list.handleDWheel(delta);
}
}
super.handleMouseInput();
}
@@ -250,10 +294,26 @@ 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")
: I18n.format("item.structurelib.constructableTrigger.gui.add");
getButtonList().get(0).enabled = !StringUtils.isBlank(value.getText());
getButtonList().get(1).enabled = existing && !StringUtils.isBlank(value.getText());
getButtonList().get(ADD_BTN).displayString = existing ? I18n.format(I18N_PREFIX + "set")
: I18n.format(I18N_PREFIX + "add");
getButtonList().get(ADD_BTN).enabled = !StringUtils.isBlank(value.getText())
&& Integer.parseInt(value.getText()) > 0;
getButtonList().get(UNSET_BTN).enabled = existing && !StringUtils.isBlank(value.getText());
if (ChannelDataAccessor.hasSubChannel(trigger, SHOW_ERROR_CHANNEL)) {
getButtonList().get(SHOW_ERROR_BTN).displayString = I18n.format(I18N_PREFIX + "error.hide");
} else {
getButtonList().get(SHOW_ERROR_BTN).displayString = I18n.format(I18N_PREFIX + "error.show");
}
// this button only exists if GT is loaded.
if (StructureLib.isGTLoaded) {
if (ChannelDataAccessor.hasSubChannel(trigger, GT_NO_HATCH_CHANNEL)) {
getButtonList().get(GT_NO_HATCH_BTN).displayString = I18n.format(I18N_PREFIX + "gt_no_hatch.disable");
} else {
getButtonList().get(GT_NO_HATCH_BTN).displayString = I18n.format(I18N_PREFIX + "gt_no_hatch.enable");
}
}
}
private int getValue() {
@@ -268,18 +328,35 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
protected void actionPerformed(GuiButton btn) {
if (btn == null) return;
switch (btn.id) {
case 0:
case ADD_BTN:
int value = getValue();
if (value <= 0) return;
ChannelDataAccessor.setChannelData(trigger, key.getText(), value);
break;
case 1:
case UNSET_BTN:
ChannelDataAccessor.unsetChannelData(trigger, key.getText());
break;
case 2:
case WIPE_BTN:
ChannelDataAccessor.wipeChannelData(trigger);
break;
case SHOW_ERROR_BTN:
if (ChannelDataAccessor.hasSubChannel(trigger, SHOW_ERROR_CHANNEL)) {
ChannelDataAccessor.unsetChannelData(trigger, SHOW_ERROR_CHANNEL);
} else {
ChannelDataAccessor.setChannelData(trigger, SHOW_ERROR_CHANNEL, 1);
}
break;
case GT_NO_HATCH_BTN:
if (ChannelDataAccessor.hasSubChannel(trigger, GT_NO_HATCH_CHANNEL)) {
ChannelDataAccessor.unsetChannelData(trigger, GT_NO_HATCH_CHANNEL);
} else {
ChannelDataAccessor.setChannelData(trigger, GT_NO_HATCH_CHANNEL, 1);
}
break;
}
updateButtons();
super.actionPerformed(btn);
}
@@ -350,6 +427,7 @@ public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen
Entry<String, Integer> e = getElementAt(elementIndex);
if (e != null) {
ChannelDataAccessor.unsetChannelData(trigger, e.getKey());
updateButtons();
return false;
}
}
@@ -17,6 +17,9 @@ import org.lwjgl.input.Keyboard;
import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor;
import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility;
import com.gtnewhorizon.structurelib.gui.GuiScreenConfigureChannels;
import cpw.mods.fml.common.FMLCommonHandler;
public class ItemConstructableTrigger extends Item {
@@ -32,7 +35,7 @@ public class ItemConstructableTrigger extends Item {
if (player.isSneaking()) {
StructureLib.instance().proxy().displayConfigGUI("registries");
} else {
player.openGui(StructureLib.instance(), 0, world, player.inventory.currentItem, 0, 0);
FMLCommonHandler.instance().showGuiScreen(new GuiScreenConfigureChannels(stack));
}
}
return super.onItemRightClick(stack, world, player);
@@ -12,6 +12,7 @@ import net.minecraft.world.World;
import com.gtnewhorizon.structurelib.StructureLib;
import com.gtnewhorizon.structurelib.StructureLibAPI;
import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor;
import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable;
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
@@ -50,7 +51,7 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
* itself.</li>
* <li>The "C" position would be the number of blocks between you and controller, not counting controller itself.</li>
* </ul>
*
*
* @param <T> Type of the context object. Usually this will be the multiblock controller.
*/
public interface IStructureDefinition<T> {
@@ -72,7 +73,7 @@ public interface IStructureDefinition<T> {
/**
* 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.
@@ -107,7 +108,7 @@ public interface IStructureDefinition<T> {
/**
* 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.
@@ -320,7 +321,7 @@ public interface IStructureDefinition<T> {
/**
* Low level utility.
*
*
* @param object context object. usually multiblock controller.
* @param trigger The trigger item that contains channel data.
* @param elements the structure piece
@@ -394,6 +395,10 @@ public interface IStructureDefinition<T> {
basePositionC,
ignoreBlockUnloaded((e, w, x, y, z, a, b, c) -> {
e.spawnHint(object, world, x, y, z, trigger);
if (ChannelDataAccessor.hasSubChannel(trigger, "show_error")
&& !e.couldBeValid(object, world, x, y, z, trigger)) {
StructureLibAPI.markHintParticleError(StructureLib.getCurrentPlayer(), world, x, y, z);
}
return true;
}),
"spawnHint");
@@ -420,7 +425,7 @@ public interface IStructureDefinition<T> {
/**
* Create a new instance of builder.
*
*
* @param <T> type of context object
*/
static <T> StructureDefinition.Builder<T> builder() {
@@ -32,6 +32,16 @@ public interface IStructureElement<T> {
boolean check(T t, World world, int x, int y, int z);
/**
* Pure (stateless and side effect free) function to test if current block could be valid. Used to give user hints
* about incorrectly placed blocks given a controller and trigger item. If couldBeValid(...) == false for a set of
* channels, with those same tiers, check(...) == false. Not required, defaults to true which is always safe but
* won't give the user error hints.
*/
default boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return true;
}
boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger);
boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger);
@@ -185,6 +195,11 @@ public interface IStructureElement<T> {
return IStructureElement.this.check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return IStructureElement.this.couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return IStructureElement.this.spawnHint(t, world, x, y, z, trigger);
@@ -31,6 +31,16 @@ public interface IStructureElementChain<T> extends IStructureElement<T> {
return false;
}
@Override
default boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
for (IStructureElement<T> fallback : fallbacks()) {
if (fallback.couldBeValid(t, world, x, y, z, trigger)) {
return true;
}
}
return false;
}
@Override
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
for (IStructureElement<T> fallback : fallbacks()) {
@@ -62,7 +72,8 @@ public interface IStructureElementChain<T> extends IStructureElement<T> {
if (e == null) continue;
if (predicate == null) predicate = e.getPredicate();
else predicate = predicate.or(e.getPredicate());
is.add(e.getStacks());
Iterable<ItemStack> stacks = e.getStacks();
if (stacks != null) is.add(stacks);
}
if (predicate == null) return null;
return new BlocksToPlace(predicate, Iterables.concat(is));
@@ -14,6 +14,11 @@ public interface IStructureElementCheckOnly<T> extends IStructureElement<T> {
return false;
}
@Override
default boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return true;
}
@Override
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return false;
@@ -17,6 +17,11 @@ interface IStructureNavigate<T> extends IStructureElement<T> {
return true;
}
@Override
default boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return true;
}
@Override
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return true;
@@ -32,6 +32,11 @@ class LazyStructureElement<T> implements IStructureElementDeferred<T> {
return get(t).check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return get(t).couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return get(t).placeBlock(t, world, x, y, z, trigger);
@@ -1,5 +1,7 @@
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;
@@ -155,6 +157,11 @@ public class StructureUtility {
return world.isAirBlock(x, y, z);
}
@Override
public boolean couldBeValid(Object t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(Object o, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 13);
@@ -186,6 +193,11 @@ public class StructureUtility {
return !world.isAirBlock(x, y, z);
}
@Override
public boolean couldBeValid(Object t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(Object o, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 14);
@@ -225,6 +237,11 @@ public class StructureUtility {
return false;
}
@Override
public boolean couldBeValid(Object t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(Object o, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), 15);
@@ -479,6 +496,11 @@ public class StructureUtility {
return true;
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, StructureLibAPI.getBlockHint(), meta);
@@ -499,6 +521,11 @@ public class StructureUtility {
return true;
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, icons.get());
@@ -519,6 +546,11 @@ public class StructureUtility {
return true;
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticleTinted(world, x, y, z, icons.get(), RGBa);
@@ -556,7 +588,7 @@ public class StructureUtility {
TIER current = getter.apply(t);
if (Objects.equals(notSet, current)) {
if (Objects.equals(notSet, tier)) {
if (StructureLib.PANIC_MODE) {
if (PANIC_MODE) {
throw new AssertionError("tierExtractor should never return notSet: " + notSet);
} else {
StructureLib.LOGGER.error("#########################################");
@@ -667,9 +699,23 @@ public class StructureUtility {
}
private Pair<Block, Integer> getHint(ItemStack trigger) {
if (hints.isEmpty()) return null;
return hints.get(Math.min(Math.max(trigger.stackSize, 1), hints.size()) - 1);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
Pair<Block, Integer> hint = getHint(trigger);
if (hint == null) return true;
TIER hintTier = tierExtractor.convert(hint.getKey(), hint.getValue());
Block block = world.getBlock(x, y, z);
int meta = world.getBlockMetadata(x, y, z);
TIER worldTier = tierExtractor.convert(block, meta);
// if the block is in the same tier as the hint block, this could be valid
return Objects.equals(hintTier, worldTier);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
Pair<Block, Integer> hint = getHint(trigger);
@@ -767,6 +813,11 @@ public class StructureUtility {
return world.getBlock(x, y, z) == getBlock() && (wildcard || world.getBlockMetadata(x, y, z) == meta);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
if (getBlock() == null) return error().spawnHint(t, world, x, y, z, trigger);
@@ -841,10 +892,16 @@ public class StructureUtility {
@Override
public boolean check(T t, World world, int x, int y, int z) {
if (init()) return world.getBlock(x, y, z) != block && world.getBlockMetadata(x, y, z) == meta;
if (init()) return world.getBlock(x, y, z) == block && world.getBlockMetadata(x, y, z) == meta;
else return fallback.check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
if (init()) return world.getBlock(x, y, z) == block && world.getBlockMetadata(x, y, z) == meta;
else return fallback.couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
if (init()) {
@@ -921,6 +978,11 @@ public class StructureUtility {
return blocsMap.getOrDefault(worldBlock, MIN_VALUE) == worldBlock.getDamageValue(world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta);
@@ -958,6 +1020,11 @@ public class StructureUtility {
.contains(worldBlock.getDamageValue(world, x, y, z));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta);
@@ -982,6 +1049,11 @@ public class StructureUtility {
return block == worldBlock && meta == worldBlock.getDamageValue(world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta);
@@ -1016,6 +1088,13 @@ public class StructureUtility {
return iBlockAdder.apply(t, worldBlock, worldBlock.getDamageValue(world, x, y, z));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
// calling iBlockAdder can potentially modify external state
// therefore we assume this can always be valid.
return true;
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta);
@@ -1049,6 +1128,11 @@ public class StructureUtility {
return blocsMap.getOrDefault(worldBlock, MIN_VALUE) == worldBlock.getDamageValue(world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
((ICustomBlockSetting) defaultBlock).setBlock(world, x, y, z, defaultMeta);
@@ -1093,6 +1177,11 @@ public class StructureUtility {
return blocsMap.getOrDefault(worldBlock, MIN_VALUE) == worldBlock.getDamageValue(world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
world.setBlock(x, y, z, defaultBlock, defaultMeta, 2);
@@ -1158,6 +1247,11 @@ public class StructureUtility {
.contains(worldBlock.getDamageValue(world, x, y, z));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
((ICustomBlockSetting) defaultBlock).setBlock(world, x, y, z, defaultMeta);
@@ -1203,6 +1297,11 @@ public class StructureUtility {
.contains(worldBlock.getDamageValue(world, x, y, z));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
world.setBlock(x, y, z, defaultBlock, defaultMeta, 2);
@@ -1251,6 +1350,14 @@ public class StructureUtility {
if (block == null || defaultBlock == null) {
throw new IllegalArgumentException();
}
if (block == Blocks.air) {
if (PANIC_MODE) {
throw new IllegalArgumentException("ofBlock() does not accept air. use isAir() instead");
} else {
LOGGER.warn("ofBlock() does not accept air. use isAir() instead");
return isAir();
}
}
if (block instanceof ICustomBlockSetting) {
return new IStructureElement<T>() {
@@ -1260,6 +1367,11 @@ public class StructureUtility {
return block == worldBlock && meta == worldBlock.getDamageValue(world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
((ICustomBlockSetting) defaultBlock).setBlock(world, x, y, z, defaultMeta);
@@ -1287,6 +1399,11 @@ public class StructureUtility {
return block == worldBlock && meta == worldBlock.getDamageValue(world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
world.setBlock(x, y, z, defaultBlock, defaultMeta, 2);
@@ -1323,6 +1440,11 @@ public class StructureUtility {
return block == world.getBlock(x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
((ICustomBlockSetting) defaultBlock).setBlock(world, x, y, z, defaultMeta);
@@ -1350,6 +1472,11 @@ public class StructureUtility {
return block == world.getBlock(x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return check(t, world, x, y, z);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
world.setBlock(x, y, z, defaultBlock, defaultMeta, 2);
@@ -1416,6 +1543,13 @@ public class StructureUtility {
return iBlockAdder.apply(t, worldBlock, worldBlock.getDamageValue(world, x, y, z));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
// calling iBlockAdder can potentially modify external state
// therefore we assume this can always be valid.
return true;
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
((ICustomBlockSetting) defaultBlock).setBlock(world, x, y, z, defaultMeta);
@@ -1455,6 +1589,13 @@ public class StructureUtility {
return iBlockAdder.apply(t, worldBlock, worldBlock.getDamageValue(world, x, y, z));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
// calling iBlockAdder can potentially modify external state
// therefore we assume this can always be valid.
return true;
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
world.setBlock(x, y, z, defaultBlock, defaultMeta, 2);
@@ -1510,6 +1651,13 @@ public class StructureUtility {
return iTileAdder.apply(t, tileEntity);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
// calling iTileAdder can potentially modify external state
// therefore we assume this can always be valid.
return true;
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta);
@@ -1536,6 +1684,13 @@ public class StructureUtility {
return tileClass.isInstance(tileEntity) && iTileAdder.test(t, tileClass.cast(tileEntity));
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
// calling iTileAdder can potentially modify external state
// therefore we assume this can always be valid.
return true;
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta);
@@ -1569,6 +1724,11 @@ public class StructureUtility {
return check;
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return element.couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return element.placeBlock(t, world, x, y, z, trigger);
@@ -1620,6 +1780,11 @@ public class StructureUtility {
return check;
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return element.couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return element.placeBlock(t, world, x, y, z, trigger);
@@ -1678,6 +1843,13 @@ public class StructureUtility {
return predicate.test(t) && downstream.check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
// this COULD potentially impact external state
// but predicate really should not have side effects
return predicate.test(t) && downstream.couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return predicate.test(t) && downstream.spawnHint(t, world, x, y, z, trigger);
@@ -1774,6 +1946,11 @@ public class StructureUtility {
return elem.check(t.getCurrentContext(), world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return elem.couldBeValid(t.getCurrentContext(), world, x, y, z, trigger);
}
@Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return elem.spawnHint(t.getCurrentContext(), world, x, y, z, trigger);
@@ -1861,6 +2038,11 @@ public class StructureUtility {
return to.get().check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.get().couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.get().placeBlock(t, world, x, y, z, trigger);
@@ -1914,6 +2096,11 @@ public class StructureUtility {
return to.apply(t).check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.apply(t).couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.apply(t).placeBlock(t, world, x, y, z, trigger);
@@ -2126,6 +2313,11 @@ public class StructureUtility {
return to.apply(t, null).check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.apply(t, trigger).couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.apply(t, trigger).placeBlock(t, world, x, y, z, trigger);
@@ -2318,6 +2510,11 @@ public class StructureUtility {
return toCheck.apply(t).check(t, world, x, y, z);
}
@Override
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.apply(t, trigger).couldBeValid(t, world, x, y, z, trigger);
}
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return to.apply(t, trigger).placeBlock(t, world, x, y, z, trigger);
@@ -2562,6 +2759,11 @@ public class StructureUtility {
return backing.check(t, world, x, y, z);
}
public boolean couldBeValid(T t, World world, int x, int y, int z, ItemStack trigger) {
ItemStack newTrigger = ChannelDataAccessor.withChannel(trigger, channel);
return backing.couldBeValid(t, world, x, y, z, newTrigger);
}
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
ItemStack newTrigger = ChannelDataAccessor.withChannel(trigger, channel);
// We know spawnHint will only be called on client side, so the lack of player isn't quite an issue
@@ -1,3 +1,4 @@
tile.structurelib.blockhint.name=Hint
tile.structurelib.blockhint.0.name=Hint 1 dot
tile.structurelib.blockhint.1.name=Hint 2 dots
tile.structurelib.blockhint.2.name=Hint 3 dots
@@ -35,6 +36,10 @@ item.structurelib.constructableTrigger.gui.add=Add
item.structurelib.constructableTrigger.gui.set=Set
item.structurelib.constructableTrigger.gui.unset=Unset
item.structurelib.constructableTrigger.gui.wipe=§4Wipe
item.structurelib.constructableTrigger.gui.error.show=Show Errors
item.structurelib.constructableTrigger.gui.error.hide=Hide Errors
item.structurelib.constructableTrigger.gui.gt_no_hatch.enable=No Hatch
item.structurelib.constructableTrigger.gui.gt_no_hatch.disable=Hatches
structurelib.autoplace.built_stat=Built %s blocks
structurelib.autoplace.complete=§aThis multiblock has completed!
@@ -1,3 +1,4 @@
tile.structurelib.blockhint.name=提示方块
tile.structurelib.blockhint.0.name=提示方块:1号
tile.structurelib.blockhint.1.name=提示方块:2号
tile.structurelib.blockhint.2.name=提示方块:3号
@@ -35,6 +36,10 @@ item.structurelib.constructableTrigger.gui.add=添加
item.structurelib.constructableTrigger.gui.set=替换
item.structurelib.constructableTrigger.gui.unset=删除
item.structurelib.constructableTrigger.gui.wipe=§4全部清空
item.structurelib.constructableTrigger.gui.error.show=显示结构错误
item.structurelib.constructableTrigger.gui.error.hide=隐藏结构错误
item.structurelib.constructableTrigger.gui.gt_no_hatch.enable=跳过舱室
item.structurelib.constructableTrigger.gui.gt_no_hatch.disable=放置舱室
structurelib.autoplace.built_stat=已放置 %s 个方块
structurelib.autoplace.complete=§a这个多方块结构已经完成自动搭建!
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB