Files
StructureLib/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java
T
Yoshyandgithub-actions[bot] 287e8317c9 Add reject_continue to PlaceResult and make SKIP short-circuit in ofChain (#63)
ofChain survival placement had a bug where SKIP (returned when a block
already exists) would not stop the chain, causing fallback alternatives
to replace already valid blocks , for example:
<img width="436" height="477" alt="image"
src="https://github.com/user-attachments/assets/7ff3d6fa-de98-4716-823f-3ad2abab7394"
/>

SKIP now short-circuits the chain, remaining alternatives are skipped
because the position is already valid.
To keep correct behavior for elements without autobuild (which
previously returned SKIP as a "no implementation" signal), a new
REJECT_CONTINUE value is added, which: continues silently like SKIP (no
error, not counted) in the walker and in the chain tries the next
alternative like REJECT
Default survivalPlaceBlock and IStructureElementCheckOnly now return
REJECT_CONTINUE instead of SKIP for unhandled paths.

Tested this with the example above, and fixed the issue:
<img width="435" height="498" alt="image"
src="https://github.com/user-attachments/assets/d92bce4d-b5ad-4051-af79-ffd8c819f9f7"
/>
survival placement also still works:
<img width="1234" height="916" alt="image"
src="https://github.com/user-attachments/assets/632d5556-524d-4dc5-a7f5-75c859cb6b70"
/>

this should ideally merged before
https://github.com/GTNewHorizons/GT5-Unofficial/pull/6922 , to fix this
underlying bug, but if possible not be tagged without the other PR,
which would cause all NEI previews of multis with water to not show any
water anymore

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-06 18:10:11 +02:00

72 lines
2.5 KiB
Java

package com.gtnewhorizon.structurelib.structure;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import com.gtnewhorizon.structurelib.StructureLibAPI;
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult;
class SurvivalBuildStructureWalker<T> implements IStructureWalker<T> {
final T object;
final ItemStack trigger;
private final int elementBudget;
private final ISurvivalBuildEnvironment params;
private final boolean check;
private int built = -1;
private final AutoPlaceEnvironment env;
public SurvivalBuildStructureWalker(T object, ItemStack trigger, int elementBudget,
ISurvivalBuildEnvironment params, IStructureDefinition<?> definition, String piece, ExtendedFacing facing,
int[] baseOffsetABC, boolean check) {
this.object = object;
this.trigger = trigger;
this.elementBudget = elementBudget;
this.params = params;
this.check = check;
env = new AutoPlaceEnvironment(
params.getActor(),
params.getActor()::addChatComponentMessage,
definition,
piece,
facing,
baseOffsetABC);
}
@Override
public boolean visit(IStructureElement<T> element, World world, int x, int y, int z, int a, int b, int c) {
env.offsetABC[0] = a;
env.offsetABC[1] = b;
env.offsetABC[2] = c;
env.setSource(params.getSource());
PlaceResult placeResult = element.survivalPlaceBlock(object, world, x, y, z, trigger, env);
if (placeResult != PlaceResult.SKIP && placeResult != PlaceResult.REJECT_CONTINUE && built == -1) built = 0;
switch (placeResult) {
case SKIP:
case REJECT_CONTINUE:
return true;
case ACCEPT:
if (check) element.check(object, world, x, y, z);
return ++built < elementBudget;
case REJECT:
StructureLibAPI.markHintParticleError(params.getActor(), world, x, y, z);
return false;
case ACCEPT_STOP:
if (check) element.check(object, world, x, y, z);
built += 1;
// intentional fallthrough
case STOP:
return false;
default:
throw new NullPointerException();
}
}
public int getBuilt() {
return built;
}
}