aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/util
diff options
context:
space:
mode:
authorGlease <4586901+Glease@users.noreply.github.com>2022-09-18 16:39:48 +0800
committerGitHub <noreply@github.com>2022-09-18 10:39:48 +0200
commit5748ba1e3e532cd451ee7ce6cfb3af32dca11e0e (patch)
tree5dd371a9a3d9ca01d907eb61b4cc4a725caf550a /src/main/java/gregtech/api/util
parentb321cb7a7dfe3ee4d1999a8589a444142f933369 (diff)
downloadGT5-Unofficial-5748ba1e3e532cd451ee7ce6cfb3af32dca11e0e.tar.gz
GT5-Unofficial-5748ba1e3e532cd451ee7ce6cfb3af32dca11e0e.tar.bz2
GT5-Unofficial-5748ba1e3e532cd451ee7ce6cfb3af32dca11e0e.zip
migrate to new survival autoplace api (#1382)
* migrate to new survival autoplace api * reduce type of blocks autoplace will use this does not prevent those blocks from not being accepted into the structures though * implement getBlocksToPlace * fix survivalConstruct code for assline and DT i hate variable size multi :( * fix AIOBE * allow disabling machine block updates on a per-thread basis * make a sensible guess at what texture to use on server side * spotless * implement hologram support for bbf * spotless
Diffstat (limited to 'src/main/java/gregtech/api/util')
-rw-r--r--src/main/java/gregtech/api/util/GT_HatchElementBuilder.java116
-rw-r--r--src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java2
-rw-r--r--src/main/java/gregtech/api/util/GT_StructureUtility.java146
3 files changed, 211 insertions, 53 deletions
diff --git a/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java b/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java
index 98f4f39297..d8e9289f54 100644
--- a/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java
+++ b/src/main/java/gregtech/api/util/GT_HatchElementBuilder.java
@@ -22,6 +22,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
public class GT_HatchElementBuilder<T> {
private interface Builtin {}
@@ -32,9 +33,10 @@ public class GT_HatchElementBuilder<T> {
private BiPredicate<? super T, ? super IGregTechTileEntity> mShouldSkip;
private BiFunction<? super T, ItemStack, ? extends Predicate<ItemStack>> mHatchItemFilter;
private Supplier<String> mHatchItemType;
- private Predicate<? super T> mReject, mBuiltinReject;
+ private Predicate<? super T> mReject;
private boolean mCacheHint;
private boolean mNoStop;
+ private EnumSet<ForgeDirection> mDisallowedDirection = EnumSet.noneOf(ForgeDirection.class);
private GT_HatchElementBuilder() {}
@@ -151,15 +153,6 @@ public class GT_HatchElementBuilder<T> {
return this;
}
- // avoid loooooong lines like
- // shouldSkip((BiPredicate<.....> & Builtin) (c, t) -> ....)
- // private <P extends BiPredicate<? super T, ? super IGregTechTileEntity> & Builtin> GT_HatchElementBuilder<T>
- // shouldSkipInternal(P aShouldSkip) {
- // if (mShouldSkip == null) mShouldSkip = aShouldSkip;
- // return this;
- // }
- // turns out javac doesn't like this... so...
-
public GT_HatchElementBuilder<T> shouldReject(Predicate<? super T> aShouldReject) {
if (aShouldReject == null) throw new IllegalArgumentException();
mReject = aShouldReject;
@@ -227,6 +220,37 @@ public class GT_HatchElementBuilder<T> {
mNoStop = false;
return this;
}
+
+ /**
+ * Help automatic hatch side determination code by ruling out some directions. Note the automatic hatch side
+ * determination code will choose to use the default facing if the final allowed facing set is empty.
+ * <p>
+ * This will clear the sides set by previous call to this or {@link #allowOnly(ForgeDirection...)}
+ * <p>
+ * Usually mandatory for multis with multiple slices, and otherwise not needed if it contains a single slice only.
+ * @param facings disallowed direction in ABC coordinate system
+ */
+ public GT_HatchElementBuilder<T> disallowOnly(ForgeDirection... facings) {
+ if (facings == null) throw new IllegalArgumentException();
+ mDisallowedDirection = EnumSet.copyOf(Arrays.asList(facings));
+ return this;
+ }
+
+ /**
+ * Help automatic hatch side determination code by allowing only some directions. Note the automatic hatch side
+ * determination code will choose to use the default facing if the final allowed facing set is empty.
+ * <p>
+ * This will clear the sides set by previous call to this or {@link #disallowOnly(ForgeDirection...)}
+ * <p>
+ * Usually mandatory for multis with multiple slices, and otherwise not needed if it contains a single slice only.
+ * @param facings allowed direction in ABC coordinate system
+ */
+ public GT_HatchElementBuilder<T> allowOnly(ForgeDirection... facings) {
+ if (facings == null) throw new IllegalArgumentException();
+ mDisallowedDirection = EnumSet.complementOf(EnumSet.copyOf(Arrays.asList(facings)));
+ mDisallowedDirection.remove(ForgeDirection.UNKNOWN);
+ return this;
+ }
// endregion
// region intermediate
@@ -352,6 +376,13 @@ public class GT_HatchElementBuilder<T> {
}
@Override
+ public BlocksToPlace getBlocksToPlace(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
+ return BlocksToPlace.create(mHatchItemFilter.apply(t, trigger));
+ }
+
+ @Deprecated
+ @Override
public PlaceResult survivalPlaceBlock(
T t,
World world,
@@ -362,24 +393,73 @@ public class GT_HatchElementBuilder<T> {
IItemSource s,
EntityPlayerMP actor,
Consumer<IChatComponent> chatter) {
+ return survivalPlaceBlock(
+ t, world, x, y, z, trigger, AutoPlaceEnvironment.fromLegacy(s, actor, chatter));
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
if (mShouldSkip != null) {
TileEntity tileEntity = world.getTileEntity(x, y, z);
if (tileEntity instanceof IGregTechTileEntity
&& mShouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return PlaceResult.SKIP;
}
- if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT;
+ if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor()))
+ return PlaceResult.REJECT;
if (mReject != null && mReject.test(t)) return PlaceResult.REJECT;
- ItemStack taken = s.takeOne(mHatchItemFilter.apply(t, trigger), true);
+ ItemStack taken = env.getSource().takeOne(mHatchItemFilter.apply(t, trigger), true);
if (GT_Utility.isStackInvalid(taken)) {
String type = getHint();
- chatter.accept(new ChatComponentTranslation("GT5U.autoplace.error.no_hatch", type));
+ env.getChatter().accept(new ChatComponentTranslation("GT5U.autoplace.error.no_hatch", type));
+ return PlaceResult.REJECT;
+ }
+ if (StructureUtility.survivalPlaceBlock(
+ taken,
+ ItemStackPredicate.NBTMode.IGNORE,
+ null,
+ true,
+ world,
+ x,
+ y,
+ z,
+ env.getSource(),
+ env.getActor())
+ != PlaceResult.ACCEPT) {
return PlaceResult.REJECT;
}
- return StructureUtility.survivalPlaceBlock(
- taken, ItemStackPredicate.NBTMode.IGNORE, null, true, world, x, y, z, s, actor)
- == PlaceResult.ACCEPT
- ? (mNoStop ? PlaceResult.ACCEPT : PlaceResult.ACCEPT_STOP)
- : PlaceResult.REJECT;
+ // try to infer facing
+ EnumSet<ForgeDirection> allowed = EnumSet.noneOf(ForgeDirection.class);
+ // first find which face of block is not contained in structure
+ if (env.getAPILevel() == AutoPlaceEnvironment.APILevel.Legacy) {
+ // a legacy decorator isn't passing down necessary information
+ // in that case, we just assume all facing is allowed
+ allowed.addAll(Arrays.asList(ForgeDirection.VALID_DIRECTIONS));
+ } else {
+ for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
+ // as noted on getWorldDirection Y axis should be flipped before use
+ if (env.isContainedInPiece(direction.offsetX, -direction.offsetY, direction.offsetZ)) continue;
+ // explicitly rejected, probably obstructed by another slice
+ if (mDisallowedDirection.contains(direction)) continue;
+ ForgeDirection rotated = env.getFacing()
+ .getWorldDirection(direction.offsetY != 0 ? direction.getOpposite() : direction);
+ allowed.add(rotated);
+ }
+ }
+ if (!allowed.isEmpty()) {
+ TileEntity tileEntity = world.getTileEntity(x, y, z);
+ if (tileEntity instanceof IGregTechTileEntity) {
+ ForgeDirection result = null;
+ // find the first facing available, but prefer a facing that isn't up/down
+ for (ForgeDirection facing : allowed) {
+ result = facing;
+ if (facing.offsetY == 0) break;
+ }
+ assert result != null;
+ ((IGregTechTileEntity) tileEntity).setFrontFacing((byte) result.ordinal());
+ }
+ }
+ return mNoStop ? PlaceResult.ACCEPT : PlaceResult.ACCEPT_STOP;
}
};
}
diff --git a/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java b/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java
index 626ca2690f..bd69f33a8a 100644
--- a/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java
+++ b/src/main/java/gregtech/api/util/GT_Multiblock_Tooltip_Builder.java
@@ -476,7 +476,7 @@ public class GT_Multiblock_Tooltip_Builder {
* @return Instance this method was called on.
*/
public GT_Multiblock_Tooltip_Builder addSubChannelUsage(String channel, String purpose) {
- sLines.add(StatCollector.translateToLocalFormatted("GT5U.MBTT.subchannel", channel, purpose));
+ sLines.add(TAB + StatCollector.translateToLocalFormatted("GT5U.MBTT.subchannel", channel, purpose));
return this;
}
diff --git a/src/main/java/gregtech/api/util/GT_StructureUtility.java b/src/main/java/gregtech/api/util/GT_StructureUtility.java
index ef7724db0a..756a1c3afa 100644
--- a/src/main/java/gregtech/api/util/GT_StructureUtility.java
+++ b/src/main/java/gregtech/api/util/GT_StructureUtility.java
@@ -1,10 +1,13 @@
package gregtech.api.util;
+import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.ACCEPT;
+import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.ACCEPT_STOP;
+import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.REJECT;
+import static com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult.SKIP;
+import static com.gtnewhorizon.structurelib.util.ItemStackPredicate.NBTMode.EXACT;
+
import com.gtnewhorizon.structurelib.StructureLibAPI;
-import com.gtnewhorizon.structurelib.structure.IItemSource;
-import com.gtnewhorizon.structurelib.structure.IStructureElement;
-import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement;
-import com.gtnewhorizon.structurelib.structure.StructureUtility;
+import com.gtnewhorizon.structurelib.structure.*;
import com.gtnewhorizon.structurelib.util.ItemStackPredicate;
import gregtech.api.GregTech_API;
import gregtech.api.enums.HeatingCoilLevel;
@@ -79,7 +82,7 @@ public class GT_StructureUtility {
@Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
- ItemStack tFrameStack = GT_OreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1);
+ ItemStack tFrameStack = getFrameStack();
if (!GT_Utility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock))
return false;
ItemBlock tFrameStackItem = (ItemBlock) tFrameStack.getItem();
@@ -87,6 +90,19 @@ public class GT_StructureUtility {
tFrameStack, null, world, x, y, z, 6, 0, 0, 0, Items.feather.getDamage(tFrameStack));
}
+ private ItemStack getFrameStack() {
+ return GT_OreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1);
+ }
+
+ @Override
+ public BlocksToPlace getBlocksToPlace(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
+ ItemStack tFrameStack = getFrameStack();
+ if (!GT_Utility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock))
+ return BlocksToPlace.errored;
+ return BlocksToPlace.create(tFrameStack);
+ }
+
@Override
public PlaceResult survivalPlaceBlock(
T t,
@@ -98,10 +114,17 @@ public class GT_StructureUtility {
IItemSource s,
EntityPlayerMP actor,
Consumer<IChatComponent> chatter) {
- if (check(t, world, x, y, z)) return PlaceResult.SKIP;
- ItemStack tFrameStack = GT_OreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1);
+ return survivalPlaceBlock(
+ t, world, x, y, z, trigger, AutoPlaceEnvironment.fromLegacy(s, actor, chatter));
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
+ if (check(t, world, x, y, z)) return SKIP;
+ ItemStack tFrameStack = getFrameStack();
if (!GT_Utility.isStackValid(tFrameStack) || !(tFrameStack.getItem() instanceof ItemBlock))
- return PlaceResult.REJECT; // honestly, this is more like a programming error or pack issue
+ return REJECT; // honestly, this is more like a programming error or pack issue
return StructureUtility.survivalPlaceBlock(
tFrameStack,
ItemStackPredicate.NBTMode.IGNORE_KNOWN_INSIGNIFICANT_TAGS,
@@ -111,9 +134,9 @@ public class GT_StructureUtility {
x,
y,
z,
- s,
- actor,
- chatter);
+ env.getSource(),
+ env.getActor(),
+ env.getChatter());
}
};
}
@@ -182,6 +205,14 @@ public class GT_StructureUtility {
}
@Override
+ public BlocksToPlace getBlocksToPlace(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
+ Class<? extends IMetaTileEntity> clazz = aMetaId.apply(t);
+ if (clazz == null) return BlocksToPlace.createEmpty();
+ return BlocksToPlace.create(is -> clazz.isInstance(GT_Item_Machines.getMetaTileEntity(is)));
+ }
+
+ @Override
public PlaceResult survivalPlaceBlock(
T t,
World world,
@@ -192,24 +223,33 @@ public class GT_StructureUtility {
IItemSource s,
EntityPlayerMP actor,
Consumer<IChatComponent> chatter) {
+ return survivalPlaceBlock(
+ t, world, x, y, z, trigger, AutoPlaceEnvironment.fromLegacy(s, actor, chatter));
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
if (shouldSkip != null) {
TileEntity tileEntity = world.getTileEntity(x, y, z);
if (tileEntity instanceof IGregTechTileEntity
- && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return PlaceResult.SKIP;
+ && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return SKIP;
}
- if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT;
+ if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return REJECT;
Class<? extends IMetaTileEntity> clazz = aMetaId.apply(t);
- if (clazz == null) return PlaceResult.REJECT;
- ItemStack taken = s.takeOne(is -> clazz.isInstance(GT_Item_Machines.getMetaTileEntity(is)), true);
+ if (clazz == null) return REJECT;
+ ItemStack taken =
+ env.getSource().takeOne(is -> clazz.isInstance(GT_Item_Machines.getMetaTileEntity(is)), true);
if (GT_Utility.isStackInvalid(taken)) {
- chatter.accept(new ChatComponentTranslation(
- "GT5U.autoplace.error.no_mte.class_name", clazz.getSimpleName()));
- return PlaceResult.REJECT;
+ env.getChatter()
+ .accept(new ChatComponentTranslation(
+ "GT5U.autoplace.error.no_mte.class_name", clazz.getSimpleName()));
+ return REJECT;
}
if (StructureUtility.survivalPlaceBlock(
- taken, ItemStackPredicate.NBTMode.IGNORE, null, true, world, x, y, z, s, actor)
- == PlaceResult.ACCEPT) return acceptType;
- return PlaceResult.REJECT;
+ taken, EXACT, null, true, world, x, y, z, env.getSource(), env.getActor())
+ == ACCEPT) return acceptType;
+ return REJECT;
}
};
}
@@ -245,6 +285,15 @@ public class GT_StructureUtility {
}
@Override
+ public BlocksToPlace getBlocksToPlace(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
+ GT_Item_Machines item = (GT_Item_Machines) Item.getItemFromBlock(GregTech_API.sBlockMachines);
+ int meta = aMetaId.applyAsInt(t);
+ if (meta < 0) return BlocksToPlace.createEmpty();
+ return BlocksToPlace.create(ItemStackPredicate.from(item).setMeta(meta));
+ }
+
+ @Override
public PlaceResult survivalPlaceBlock(
T t,
World world,
@@ -255,25 +304,33 @@ public class GT_StructureUtility {
IItemSource s,
EntityPlayerMP actor,
Consumer<IChatComponent> chatter) {
+ return survivalPlaceBlock(
+ t, world, x, y, z, trigger, AutoPlaceEnvironment.fromLegacy(s, actor, chatter));
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
if (shouldSkip != null) {
TileEntity tileEntity = world.getTileEntity(x, y, z);
if (tileEntity instanceof IGregTechTileEntity
- && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return PlaceResult.SKIP;
+ && shouldSkip.test(t, (IGregTechTileEntity) tileEntity)) return SKIP;
}
- if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT;
+ if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, env.getActor())) return REJECT;
GT_Item_Machines item = (GT_Item_Machines) Item.getItemFromBlock(GregTech_API.sBlockMachines);
int meta = aMetaId.applyAsInt(t);
- if (meta < 0) return PlaceResult.REJECT;
- ItemStack taken = s.takeOne(ItemStackPredicate.from(item).setMeta(meta), true);
+ if (meta < 0) return REJECT;
+ ItemStack taken =
+ env.getSource().takeOne(ItemStackPredicate.from(item).setMeta(meta), true);
if (GT_Utility.isStackInvalid(taken)) {
- chatter.accept(new ChatComponentTranslation("GT5U.autoplace.error.no_mte.id", meta));
- return PlaceResult.REJECT;
+ env.getChatter().accept(new ChatComponentTranslation("GT5U.autoplace.error.no_mte.id", meta));
+ return REJECT;
}
return StructureUtility.survivalPlaceBlock(
- taken, ItemStackPredicate.NBTMode.IGNORE, null, true, world, x, y, z, s, actor)
- == PlaceResult.ACCEPT
- ? PlaceResult.ACCEPT_STOP
- : PlaceResult.REJECT;
+ taken, EXACT, null, true, world, x, y, z, env.getSource(), env.getActor())
+ == ACCEPT
+ ? ACCEPT_STOP
+ : REJECT;
}
};
}
@@ -327,7 +384,7 @@ public class GT_StructureUtility {
IItemSource s,
EntityPlayerMP actor,
Consumer<IChatComponent> chatter) {
- if (check(t, world, x, y, z)) return PlaceResult.SKIP;
+ if (check(t, world, x, y, z)) return SKIP;
return StructureUtility.survivalPlaceBlock(
placeCasing, placeCasingMeta, world, x, y, z, s, actor, chatter);
}
@@ -398,6 +455,12 @@ public class GT_StructureUtility {
}
@Override
+ public BlocksToPlace getBlocksToPlace(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
+ return BlocksToPlace.create(GregTech_API.sBlockCasings5, getMetaFromHint(trigger));
+ }
+
+ @Override
public PlaceResult survivalPlaceBlock(
T t,
World world,
@@ -408,13 +471,28 @@ public class GT_StructureUtility {
IItemSource s,
EntityPlayerMP actor,
Consumer<IChatComponent> chatter) {
+ return survivalPlaceBlock(
+ t, world, x, y, z, trigger, AutoPlaceEnvironment.fromLegacy(s, actor, chatter));
+ }
+
+ @Override
+ public PlaceResult survivalPlaceBlock(
+ T t, World world, int x, int y, int z, ItemStack trigger, AutoPlaceEnvironment env) {
Block block = world.getBlock(x, y, z);
boolean isCoil = block instanceof IHeatingCoil
&& ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z))
== getHeatFromHint(trigger);
- if (isCoil) return PlaceResult.SKIP;
+ if (isCoil) return SKIP;
return StructureUtility.survivalPlaceBlock(
- GregTech_API.sBlockCasings5, getMetaFromHint(trigger), world, x, y, z, s, actor, chatter);
+ GregTech_API.sBlockCasings5,
+ getMetaFromHint(trigger),
+ world,
+ x,
+ y,
+ z,
+ env.getSource(),
+ env.getActor(),
+ env.getChatter());
}
};
}