diff options
author | Glease <4586901+Glease@users.noreply.github.com> | 2022-09-18 16:39:48 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-18 10:39:48 +0200 |
commit | 5748ba1e3e532cd451ee7ce6cfb3af32dca11e0e (patch) | |
tree | 5dd371a9a3d9ca01d907eb61b4cc4a725caf550a /src/main/java/gregtech/api/util | |
parent | b321cb7a7dfe3ee4d1999a8589a444142f933369 (diff) | |
download | GT5-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')
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()); } }; } |