From a12722c4b0a26a55699f3c1c130d473764f6fe15 Mon Sep 17 00:00:00 2001 From: Glease <4586901+Glease@users.noreply.github.com> Date: Tue, 23 Aug 2022 18:56:47 +0800 Subject: [PATCH] configurable autoplace --- .../structurelib/ConfigurationHandler.java | 29 +++++++++++++ .../constructable/ChannelDataAccessor.java | 10 ++--- .../constructable/ConstructableUtility.java | 43 +++++++++++-------- .../item/ItemConstructableTrigger.java | 18 -------- .../SurvivalBuildStructureWalker.java | 1 - .../assets/structurelib/lang/en_US.lang | 2 +- .../assets/structurelib/lang/zh_CN.lang | 2 +- 7 files changed, 61 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java b/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java index c3ece97b..61bf6869 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java +++ b/src/main/java/com/gtnewhorizon/structurelib/ConfigurationHandler.java @@ -15,6 +15,8 @@ public enum ConfigurationHandler { private Configuration config; private int maxCoexistingHologram; private boolean removeCollidingHologram; + private int autoPlaceBudget; + private int autoPlaceInterval; ConfigurationHandler() { FMLCommonHandler.instance().bus().register(this); @@ -50,6 +52,25 @@ public enum ConfigurationHandler { "client.hologram", true, "An attempt will be made to remove an existing hologram if it collides with a new hologram."); + autoPlaceBudget = config.getInt( + "autoPlaceBudget", + "common.hologram", + 25, + 1, + 200, + "Max number of elements can be placed in one round of auto place.\n" + + "As expected, server side settings will overrides client settings.\n" + + "Certain larger multi might increase these values beyond this configured value."); + autoPlaceInterval = config.getInt( + "autoPlaceInterval", + "common.hologram", + 300, + 0, + 20000, + "Unit: milisecond. Minimal interval between two auto place round.\n" + + "As expected, server side settings will overrides client settings.\n" + + "Note this relates to the wall clock, not in game ticks.\n" + + "Value smaller than default is likely to be perceived as no minimal interval whatsoever."); if (config.hasChanged()) { config.save(); @@ -71,6 +92,14 @@ public enum ConfigurationHandler { return removeCollidingHologram; } + public int getAutoPlaceBudget() { + return autoPlaceBudget; + } + + public int getAutoPlaceInterval() { + return autoPlaceInterval; + } + Configuration getConfig() { return config; } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java index 32a028bf..3dd2a473 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ChannelDataAccessor.java @@ -1,20 +1,18 @@ package com.gtnewhorizon.structurelib.alignment.constructable; +import static com.gtnewhorizon.structurelib.util.MiscUtils.getTagKeys; +import static net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND; + +import com.gtnewhorizon.structurelib.StructureLib; import java.util.Locale; import java.util.Map.Entry; import java.util.stream.Stream; - -import com.gtnewhorizon.structurelib.StructureLib; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.common.util.Constants.NBT; import org.apache.commons.lang3.tuple.ImmutablePair; - -import static com.gtnewhorizon.structurelib.util.MiscUtils.getTagKeys; -import static net.minecraftforge.common.util.Constants.NBT.TAG_COMPOUND; - public class ChannelDataAccessor { private static final String SECONDARY_HINT_TAG = "channels"; diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java index ed5dc377..5b2c7527 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/constructable/ConstructableUtility.java @@ -1,14 +1,15 @@ package com.gtnewhorizon.structurelib.alignment.constructable; +import com.gtnewhorizon.structurelib.ConfigurationHandler; import com.gtnewhorizon.structurelib.StructureLib; import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.alignment.IAlignment; import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.structure.IItemSource; +import java.util.WeakHashMap; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ChatComponentTranslation; import net.minecraft.world.World; @@ -17,9 +18,8 @@ import net.minecraftforge.common.util.ForgeDirection; public class ConstructableUtility { - // TODO make these configurable and expose this to external world - public static final int COOLDOWN = 5; - private static final int BUDGET = 25; + private static final WeakHashMap lastUse = new WeakHashMap<>(); + private static long clientSideLastUse = 0; private ConstructableUtility() {} @@ -41,10 +41,11 @@ public class ConstructableUtility { // not sneaking - client side will generate hologram. nothing to do on server side if (!aPlayer.isSneaking()) return true; - long timePast = StructureLib.getOverworldTime() - getLastUseTick(aStack); - if (timePast < COOLDOWN) { + long timePast = System.currentTimeMillis() - getLastUseMilis(aPlayer); + if (timePast < ConfigurationHandler.INSTANCE.getAutoPlaceInterval()) { aPlayer.addChatComponentMessage(new ChatComponentTranslation( - "item.structurelib.constructableTrigger.too_fast", COOLDOWN - timePast)); + "item.structurelib.constructableTrigger.too_fast", + ConfigurationHandler.INSTANCE.getAutoPlaceInterval() - timePast)); return true; } } else if (!StructureLib.isCurrentPlayer(aPlayer)) { @@ -74,13 +75,17 @@ public class ConstructableUtility { constructable.construct(aStack, false); } else if (constructable instanceof ISurvivalConstructable) { int built = ((ISurvivalConstructable) constructable) - .survivalConstruct(aStack, BUDGET, IItemSource.fromPlayer(playerMP), playerMP); + .survivalConstruct( + aStack, + ConfigurationHandler.INSTANCE.getAutoPlaceBudget(), + IItemSource.fromPlayer(playerMP), + playerMP); if (built > 0) { playerMP.addChatMessage(new ChatComponentTranslation("structurelib.autoplace.built_stat", built)); } else if (built == -1) { playerMP.addChatMessage(new ChatComponentTranslation("structurelib.autoplace.complete")); } - setLastUseTickToStackTag(aStack); + setLastUseMilis(aPlayer); } else { playerMP.addChatMessage(new ChatComponentTranslation("structurelib.autoplace.error.not_enabled")); } @@ -89,19 +94,23 @@ public class ConstructableUtility { // client side // particles and text constructable.construct(aStack, true); - if (getLastUseTick(aStack) == 0) + if (System.currentTimeMillis() - getLastUseMilis(aPlayer) >= 300) StructureLib.addClientSideChatMessages(constructable.getStructureDescription(aStack)); + setLastUseMilis(aPlayer); return false; } - private static long getLastUseTick(ItemStack aStack) { - return aStack.hasTagCompound() ? aStack.getTagCompound().getLong("LastUse") : 0; + private static void setLastUseMilis(EntityPlayer aPlayer) { + if (!(aPlayer instanceof EntityPlayerMP)) + // assume client side + clientSideLastUse = System.currentTimeMillis(); + else lastUse.put((EntityPlayerMP) aPlayer, System.currentTimeMillis()); } - private static void setLastUseTickToStackTag(ItemStack aStack) { - NBTTagCompound tag = aStack.stackTagCompound; - if (tag == null) tag = aStack.stackTagCompound = new NBTTagCompound(); - // here we force use the overworld tick time, in case the current world is over - tag.setLong("LastUse", StructureLib.getOverworldTime()); + private static long getLastUseMilis(EntityPlayer aPlayer) { + if (!(aPlayer instanceof EntityPlayerMP)) + // assume client side + return clientSideLastUse; + return lastUse.getOrDefault(aPlayer, 0L); } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java index 962bfb1b..6cd14704 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java +++ b/src/main/java/com/gtnewhorizon/structurelib/item/ItemConstructableTrigger.java @@ -9,11 +9,9 @@ import com.gtnewhorizon.structurelib.StructureLib; import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; import java.util.List; -import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import org.lwjgl.input.Keyboard; @@ -75,20 +73,4 @@ public class ItemConstructableTrigger extends Item { aList.add(translateToLocal("item.structurelib.constructableTrigger.desc.5")); } } - - @Override - public void onUpdate( - ItemStack p_77663_1_, World p_77663_2_, Entity p_77663_3_, int p_77663_4_, boolean p_77663_5_) { - // remove LastUse tags if it times out, - // so it can stack with other trigger item stacks - // don't remove it too soon though, to prevent chat spam - // this might be perceived as a hack, but ok this is simple enough to implement - if (p_77663_1_.hasTagCompound() - && p_77663_1_.getTagCompound().getLong("LastUse") + ConstructableUtility.COOLDOWN * 2 - < StructureLib.getOverworldTime()) { - NBTTagCompound tag = p_77663_1_.getTagCompound(); - tag.removeTag("LastUse"); - if (tag.hasNoTags()) p_77663_1_.setTagCompound(null); - } - } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java b/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java index 42e4accf..b131e8ca 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/SurvivalBuildStructureWalker.java @@ -1,7 +1,6 @@ package com.gtnewhorizon.structurelib.structure; import com.gtnewhorizon.structurelib.StructureLibAPI; -import com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility; import com.gtnewhorizon.structurelib.structure.IStructureElement.PlaceResult; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; diff --git a/src/main/resources/assets/structurelib/lang/en_US.lang b/src/main/resources/assets/structurelib/lang/en_US.lang index 72414bf4..49783f87 100644 --- a/src/main/resources/assets/structurelib/lang/en_US.lang +++ b/src/main/resources/assets/structurelib/lang/en_US.lang @@ -28,7 +28,7 @@ item.structurelib.constructableTrigger.desc.3=(Sneak use on controller to build) item.structurelib.constructableTrigger.desc.4=Quantity of schematics in item stack affects tier/mode/type item.structurelib.constructableTrigger.desc.5=Hold §l[LSHIFT]§r to display channel data item.structurelib.constructableTrigger.desc.lshift.0=Contain %d sub channel. -item.structurelib.constructableTrigger.too_fast=Please wait %d ticks before another autoplace... +item.structurelib.constructableTrigger.too_fast=Please wait %d milliseconds before another autoplace... item.structurelib.constructableTrigger.gui.key=Key: item.structurelib.constructableTrigger.gui.value=Value: item.structurelib.constructableTrigger.gui.add=Add diff --git a/src/main/resources/assets/structurelib/lang/zh_CN.lang b/src/main/resources/assets/structurelib/lang/zh_CN.lang index 77f433ac..3c72056f 100644 --- a/src/main/resources/assets/structurelib/lang/zh_CN.lang +++ b/src/main/resources/assets/structurelib/lang/zh_CN.lang @@ -28,7 +28,7 @@ item.structurelib.constructableTrigger.desc.3= (潜行右键可以直接完成 item.structurelib.constructableTrigger.desc.4=此物品堆叠数量会影响显示的机器等级/模式/类型 item.structurelib.constructableTrigger.desc.5=按下 §l[左SHIFT]§r 以显示子信道 item.structurelib.constructableTrigger.desc.lshift.0=包含 %d 个子信道 -item.structurelib.constructableTrigger.too_fast=请在下一次自动搭建前等待%dtick... +item.structurelib.constructableTrigger.too_fast=请在下一次自动搭建前等待%d毫秒... item.structurelib.constructableTrigger.gui.key=信道名: item.structurelib.constructableTrigger.gui.value=值: item.structurelib.constructableTrigger.gui.add=添加