Skip to content

Commit

Permalink
Add error hint when block is invalid (#31)
Browse files Browse the repository at this point in the history
Co-authored-by: kstvr32 <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
  • Loading branch information
3 people authored Dec 14, 2024
1 parent 6337536 commit 43fc39c
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/gtnewhorizon/structurelib/StructureLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ public Item getTabIconItem() {
}
};

public static boolean isGTLoaded;

@Mod.EventHandler
public void preInit(FMLPreInitializationEvent e) {
ConfigurationHandler.INSTANCE.init(e.getSuggestedConfigurationFile());
Expand All @@ -118,6 +120,8 @@ public void preInit(FMLPreInitializationEvent e) {
if (Loader.isModLoaded(STRUCTURECOMPAT_MODID)) {
COMPAT = Loader.instance().getIndexedModList().get(STRUCTURECOMPAT_MODID).getMod();
}

isGTLoaded = Loader.isModLoaded("gregtech");
}

@Mod.EventHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@

public class GuiScreenConfigureChannels extends GuiScreen implements IGuiScreen {

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;
Expand Down Expand Up @@ -128,29 +137,43 @@ public void setText(String p_146180_1_) {

addButton(
new GuiButton(
0,
ADD_BTN,
guiLeft + 12,
guiTop + 157,
47,
20,
I18n.format("item.structurelib.constructableTrigger.gui.add")));
addButton(
new GuiButton(
1,
UNSET_BTN,
guiLeft + 65,
guiTop + 157,
47,
20,
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();
}

Expand All @@ -171,7 +194,7 @@ public int getXSize() {

@Override
public int getYSize() {
return 188;
return 211;
}

@Override
Expand Down Expand Up @@ -250,10 +273,27 @@ private void updateButtons() {
// 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(ADD_BTN).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).enabled = !StringUtils.isBlank(value.getText());
getButtonList().get(UNSET_BTN).enabled = existing && !StringUtils.isBlank(value.getText());

if (ChannelDataAccessor.hasSubChannel(trigger, SHOW_ERROR_CHANNEL)) {
getButtonList().get(SHOW_ERROR_BTN).displayString = "Hide Errors";
} else {
getButtonList().get(SHOW_ERROR_BTN).displayString = "Show Errors";
}

// 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 = "Hatches";
} else {
getButtonList().get(GT_NO_HATCH_BTN).displayString = "No Hatch";
}
}

}

private int getValue() {
Expand All @@ -268,18 +308,35 @@ private int getValue() {
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);
}

Expand Down Expand Up @@ -350,6 +407,7 @@ protected boolean elementClicked(int elementIndex, boolean doubleClick, int mXRe
Entry<String, Integer> e = getElementAt(elementIndex);
if (e != null) {
ChannelDataAccessor.unsetChannelData(trigger, e.getKey());
updateButtons();
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

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;

Expand Down Expand Up @@ -50,7 +51,7 @@
* 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> {
Expand All @@ -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.
Expand Down Expand Up @@ -107,7 +108,7 @@ default boolean check(T object, String piece, World world, ExtendedFacing extend

/**
* 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.
Expand Down Expand Up @@ -320,7 +321,7 @@ default int survivalBuild(T object, ItemStack trigger, String piece, World world

/**
* Low level utility.
*
*
* @param object context object. usually multiblock controller.
* @param trigger The trigger item that contains channel data.
* @param elements the structure piece
Expand Down Expand Up @@ -394,6 +395,10 @@ static <T> boolean iterate(T object, ItemStack trigger, IStructureElement<T>[] e
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");
Expand All @@ -420,7 +425,7 @@ static <T> boolean iterate(T object, ItemStack trigger, IStructureElement<T>[] e

/**
* Create a new instance of builder.
*
*
* @param <T> type of context object
*/
static <T> StructureDefinition.Builder<T> builder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -185,6 +195,11 @@ public boolean check(T t, World world, int x, int y, int z) {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ default boolean check(T t, World world, int x, int y, int z) {
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()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trig
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ default boolean check(T t, World world, int x, int y, int z) {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public boolean check(T t, World world, int x, int y, int z) {
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);
Expand Down
Loading

0 comments on commit 43fc39c

Please sign in to comment.