Compare commits

...
4 Commits
Author SHA1 Message Date
Glease 9bd19b9254 fix frustrum culling using wrong bounding box 2022-09-09 17:43:12 +08:00
Glease df4c54ea8d address inspections 2022-09-06 16:34:46 +08:00
くぁーりぃ e71edd50b0 Allow client to auto build multiblocks (#12) 2022-09-05 19:42:57 +08:00
iouterandGlease 1b7cee7c4e Update zh_CN.lang (#11)
Co-authored-by: Glease <4586901+Glease@users.noreply.github.com>
2022-09-03 16:14:16 +08:00
15 changed files with 71 additions and 86 deletions

No files matched your search

@@ -268,7 +268,11 @@ public class ClientProxy extends CommonProxy {
private static class HintParticleInfo {
private final World w;
// these are the block coordinate for e.g. w.getBlock()
private final int x, y, z;
// these are the lower bounds for rendering. the upper bound would be X + size
// currently size is fixed to be 0.5
// it is not made into a constants because this will allow for easy changing during debug
private final double X, Y, Z;
private final IIcon[] icons;
private short[] tint;
@@ -319,7 +323,7 @@ public class ClientProxy extends CommonProxy {
}
public boolean isInFrustrum(Frustrum frustrum) {
return frustrum.isBoxInFrustum(x, y, z, X, Y, Z);
return frustrum.isBoxInFrustum(X, Y, Z, X + 0.5, Y + 0.5, Z + 0.5);
}
public void draw(Tessellator tes) {
@@ -78,7 +78,7 @@ public enum ConfigurationHandler {
300,
0,
20000,
"Unit: milisecond. Minimal interval between two auto place round.\n"
"Unit: millisecond. 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.");
@@ -1,51 +0,0 @@
package com.gtnewhorizon.structurelib;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.ARBVertexBufferObject;
import org.lwjgl.opengl.ContextCapabilities;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GLContext;
class GLHelper {
public static final boolean vboSupported;
private static final boolean arbVbo;
static {
ContextCapabilities contextcapabilities = GLContext.getCapabilities();
arbVbo = !contextcapabilities.OpenGL15 && contextcapabilities.GL_ARB_vertex_buffer_object;
vboSupported = contextcapabilities.OpenGL15 || arbVbo;
}
public static int glGenBuffers() {
return arbVbo ? ARBVertexBufferObject.glGenBuffersARB() : GL15.glGenBuffers();
}
public static void glBindBuffer(int target, int buffer) {
if (arbVbo) {
ARBVertexBufferObject.glBindBufferARB(target, buffer);
} else {
GL15.glBindBuffer(target, buffer);
}
}
public static void glBufferData(int target, ByteBuffer data, int usage) {
if (arbVbo) {
ARBVertexBufferObject.glBufferDataARB(target, data, usage);
} else {
GL15.glBufferData(target, data, usage);
}
}
public static void glDeleteBuffers(int buffer) {
if (arbVbo) {
ARBVertexBufferObject.glDeleteBuffersARB(buffer);
} else {
GL15.glDeleteBuffers(buffer);
}
}
public static boolean useVbo() {
return vboSupported;
}
}
@@ -42,14 +42,14 @@ public class StructureLib {
private static final String STRUCTURECOMPAT_MODID = "structurecompat";
public static boolean DEBUG_MODE;
public static boolean PANIC_MODE = Boolean.getBoolean("structurelib.panic");
public static Logger LOGGER = LogManager.getLogger("StructureLib");
public static final Logger LOGGER = LogManager.getLogger("StructureLib");
@SidedProxy(
serverSide = "com.gtnewhorizon.structurelib.CommonProxy",
clientSide = "com.gtnewhorizon.structurelib.ClientProxy")
static CommonProxy proxy;
static SimpleNetworkWrapper net = NetworkRegistry.INSTANCE.newSimpleChannel(StructureLibAPI.MOD_ID);
static final SimpleNetworkWrapper net = NetworkRegistry.INSTANCE.newSimpleChannel(StructureLibAPI.MOD_ID);
static {
net.registerMessage(
@@ -122,7 +122,7 @@ public interface IAlignmentLimits {
}
/**
* Prefers rotation over flip, so both flip will get translated to opposite rotation and no flip
* Prefers rotation to flip, so both flip will get translated to opposite rotation and no flip
*
* @param flip the preferred flip to be used Horizontal or vertical
* @return this
@@ -29,10 +29,10 @@ import org.lwjgl.opengl.GL11;
public abstract class GuiScrollableList<T> {
protected final int slotHeight;
private final Minecraft mc = Minecraft.getMinecraft();
protected int originX;
protected int originY;
protected int width;
protected int height;
protected final int originX;
protected final int originY;
protected final int width;
protected final int height;
protected int minY;
protected int maxY;
protected int minX;
@@ -41,7 +41,7 @@ public abstract class GuiScrollableList<T> {
protected int mouseY;
protected int selectedIndex = -1;
protected int margin = 4;
protected List<ListSelectionListener<T>> listeners = new CopyOnWriteArrayList<>();
protected final List<ListSelectionListener<T>> listeners = new CopyOnWriteArrayList<>();
private int scrollUpButtonID;
private int scrollDownButtonID;
private float initialClickY = -2.0F;
@@ -153,11 +153,11 @@ public abstract class GuiScrollableList<T> {
public void actionPerformed(GuiButton b) {
if (b.enabled) {
if (b.id == scrollUpButtonID) {
amountScrolled -= slotHeight * 2 / 3;
amountScrolled -= slotHeight * 2f / 3;
initialClickY = -2.0F;
clampScrollToBounds();
} else if (b.id == scrollDownButtonID) {
amountScrolled += slotHeight * 2 / 3;
amountScrolled += slotHeight * 2f / 3;
initialClickY = -2.0F;
clampScrollToBounds();
}
@@ -325,9 +325,9 @@ public abstract class GuiScrollableList<T> {
public void handleDWheel(int mouseWheelDelta) {
if (!Mouse.isButtonDown(0)) {
if (mouseWheelDelta > 0) {
amountScrolled -= slotHeight / 2;
amountScrolled -= slotHeight / 2f;
} else /* if (mouseWheelDelta < 0) */ {
amountScrolled += slotHeight / 2;
amountScrolled += slotHeight / 2f;
}
}
}
@@ -56,12 +56,12 @@ public class ItemBlockHint extends ItemBlock {
"structurelib.blockhint.desc.4")); // Make sure it does not contain Air material.
break;
case 15:
aList.add(EnumChatFormatting.BLUE.toString()
aList.add(EnumChatFormatting.BLUE
+ translateToLocal("structurelib.blockhint.desc.5")); // ERROR, what did u expect?
break;
default: // WTF?
aList.add("Damn son where did you get that!?");
aList.add(EnumChatFormatting.BLUE.toString() + "From outer space... I guess...");
aList.add(EnumChatFormatting.BLUE + "From outer space... I guess...");
}
}
@@ -45,10 +45,6 @@ public abstract class AlignmentMessage implements IMessage {
ByteBufUtils.writeTag(pBuffer, tFXTag);
}
/**
* {@link com.gtnewhorizon.structurelib.structure.IStructureDefinition#check(Object, String, World, ExtendedFacing, int, int, int, int, int, int, boolean)}
* @param provider
*/
private AlignmentMessage(IAlignmentProvider provider) {
if (!(provider instanceof TileEntity)) throw new IllegalArgumentException("Provider must be a TileEntity");
IAlignment alignment = provider.getAlignment();
@@ -17,7 +17,7 @@ import net.minecraft.item.ItemStack;
import org.apache.commons.lang3.tuple.Pair;
public class SetChannelDataMessage implements IMessage {
private List<Map.Entry<String, Integer>> data = new ArrayList<>();
private final List<Map.Entry<String, Integer>> data = new ArrayList<>();
public SetChannelDataMessage() {}
@@ -11,19 +11,32 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
/**
* Represent an item source. Take only, cannot be placed back.
*/
public interface IItemSource {
/**
* We are probably not going to need to get a lot of items from this method
* We are probably not going to need to get a lot of items from this method,
* so I don't care about the overhead of storing all fetched items even if downstream code doesn't need it
*/
@Nonnull
Map<ItemStack, Integer> take(Predicate<ItemStack> predicate, boolean simulate, int count);
/**
* Take exactly one item that matches the predicate.
*
* @return item stack, or null if none matches
*/
default ItemStack takeOne(Predicate<ItemStack> predicate, boolean simulate) {
Map<ItemStack, Integer> take = take(predicate, simulate, 1);
return take.isEmpty() ? null : take.keySet().iterator().next();
}
/**
* Take exactly count amount of items matching predicate.
*
* @return true if at least count amount of items can be/is taken.
*/
default boolean takeAll(Predicate<ItemStack> predicate, boolean simulate, int count) {
// fast path for 1 item take requests
if (count == 1) return takeOne(predicate, simulate) != null;
@@ -33,22 +46,38 @@ public interface IItemSource {
return true;
}
/**
* Take exactly one item. ItemStack given must have a stack size of 1.
*
* @return true if found. false otherwise
*/
default boolean takeOne(ItemStack stack, boolean simulate) {
if (stack == null || stack.getItem() == null || stack.stackSize != 1) throw new IllegalArgumentException();
ItemStack took = takeOne(ItemStackPredicate.from(stack, NBTMode.EXACT), simulate);
return took == null || took.stackSize <= 0;
}
/**
* Take some item. Will not take item if it cannot find enough items to take.
*
* @return true if enough item can be/has been extracted. false otherwise
*/
default boolean takeAll(ItemStack stack, boolean simulate) {
// fast path for 1 item take requests
if (stack.stackSize == 1) return takeOne(stack, simulate);
ItemStackPredicate predicate = ItemStackPredicate.from(stack, NBTMode.EXACT);
Map<ItemStack, Integer> have = take(predicate, true, stack.stackSize);
if (have.values().stream().mapToInt(Integer::intValue).sum() < stack.stackSize) return false;
take(predicate, simulate, stack.stackSize);
if (simulate) return true;
take(predicate, false, stack.stackSize);
return true;
}
/**
* Construct an IItemSource from inventories associated with given player.
* <p>
* This will be backed by {@link InventoryUtility}
*/
static IItemSource fromPlayer(EntityPlayerMP player) {
return new IItemSource() {
@Nonnull
@@ -71,6 +100,11 @@ public interface IItemSource {
};
}
/**
* Construct an IItemSource from given inventory
* <p>
* This will be backed by {@link InventoryUtility}
*/
static IItemSource fromInventory(IInventory inv) {
return (p, s, c) -> InventoryUtility.takeFromInventory(new InventoryIterable<>(inv), p, s, c, true);
}
@@ -141,7 +141,7 @@ public interface IStructureDefinition<T> {
}
/**
* Build the multi in creative mode on a best effort basis. Does not guarantee the structure is correct after a
* Build the multi in creative mode on a best-effort basis. Does not guarantee the structure is correct after a
* successful call.
*
* @param object context object. usually multiblock controller.
@@ -324,7 +324,7 @@ public interface IStructureDefinition<T> {
int basePositionC,
boolean hintsOnly,
Boolean checkBlocksIfNotNullForceCheckAllIfTrue) {
if (world.isRemote ^ hintsOnly) {
if (!world.isRemote && hintsOnly) {
return false;
}
@@ -402,7 +402,6 @@ public interface IStructureDefinition<T> {
/**
* Create a new instance of builder.
* @return
* @param <T> type of context object
*/
static <T> StructureDefinition.Builder<T> builder() {
@@ -3,7 +3,7 @@ package com.gtnewhorizon.structurelib.structure;
/**
* Implement this and use {@link StructureUtility#withContext(IStructureElement)} in case you need to record some
* temporary states that don't need to live in your main context, which would usually live for the whole lifetime of the
* structure than just during structure check. Usually just save some few bytes, but becomes non trivial if you need to
* structure than just during structure check. Usually just save some few bytes, but becomes non-trivial if you need to
* record too much stuff.
* <p>
* You will have to reset the context yourself though. The API can't guess when the old context becomes invalid.
@@ -53,7 +53,7 @@ public class StructureDefinition<T> implements IStructureDefinition<T> {
* + is anything but air
* - is air checks
* space bar is skip
* ~ is also skip (but marks controller position, optional and logically it is a space...)
* ~ is also skip (but marks controller position, optional. implementation wise it is a space...)
* rest needs to be defined
* <p>
* next char is next block(a)
@@ -1947,6 +1947,7 @@ public class StructureUtility {
* @deprecated renamed to partitionBy
*/
@SafeVarargs
@Deprecated
public static <T> IStructureElementDeferred<T> defer(
Function<T, Integer> keyExtractor, IStructureElement<T>... array) {
return partitionBy(keyExtractor, array);
@@ -2015,7 +2016,7 @@ public class StructureUtility {
* @param array all possible structure element
* @deprecated renamed to partitionBy
*/
@SuppressWarnings("unchecked")
@Deprecated
public static <T> IStructureElementDeferred<T> defer(
Function<T, Integer> keyExtractor, List<IStructureElement<T>> array) {
return partitionBy(keyExtractor, array);
@@ -2036,7 +2037,7 @@ public class StructureUtility {
@SuppressWarnings("unchecked")
public static <T> IStructureElementDeferred<T> partitionBy(
Function<T, Integer> keyExtractor, List<IStructureElement<T>> array) {
return defer(keyExtractor, array.toArray(new IStructureElement[0]));
return partitionBy(keyExtractor, array.toArray(new IStructureElement[0]));
}
/**
@@ -2568,6 +2569,7 @@ public class StructureUtility {
* @deprecated renamed to partitionBy
*/
@SafeVarargs
@Deprecated
public static <T> IStructureElementDeferred<T> defer(
Function<T, Integer> keyExtractorCheck,
BiFunction<T, ItemStack, Integer> keyExtractor,
@@ -2651,7 +2653,7 @@ public class StructureUtility {
* @param array all possible structure element
* @deprecated renamed to partitionBy
*/
@SuppressWarnings("unchecked")
@Deprecated
public static <T> IStructureElementDeferred<T> defer(
Function<T, Integer> keyExtractorCheck,
BiFunction<T, ItemStack, Integer> keyExtractor,
@@ -2680,7 +2682,7 @@ public class StructureUtility {
Function<T, Integer> keyExtractorCheck,
BiFunction<T, ItemStack, Integer> keyExtractor,
List<IStructureElement<T>> array) {
return defer(keyExtractorCheck, keyExtractor, array.toArray(new IStructureElement[0]));
return partitionBy(keyExtractorCheck, keyExtractor, array.toArray(new IStructureElement[0]));
}
// endregion
@@ -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=请在下一次自动搭建前等待%d毫秒...
item.structurelib.constructableTrigger.too_fast=请在下一次自动搭建前等待 %d 毫秒...
item.structurelib.constructableTrigger.gui.key=信道名:
item.structurelib.constructableTrigger.gui.value=值:
item.structurelib.constructableTrigger.gui.add=添加
@@ -39,8 +39,9 @@ item.structurelib.constructableTrigger.gui.wipe=§4全部清空
structurelib.autoplace.built_stat=已放置 %s 个方块
structurelib.autoplace.complete=§a这个多方块结构已经完成自动搭建!
structurelib.autoplace.error.not_enabled=§c这个多方块结构不支持在生存模式下自动搭建!
structurelib.autoplace.error.no_simple_block=§c建议放置§r%s§c,但没有找到它
structurelib.autoplace.error.no_item_stack=§c建议使用§r%s§c放置方块,但没有找到它
structurelib.autoplace.error.no_simple_block=§c建议放置 §r%s§c ,但没有找到它
structurelib.autoplace.error.no_item_stack=§c建议使用 §r%s§c 放置方块,但没有找到它
structurelib.autoplace.warning.no_explicit_channel=§6这个结构依赖于不存在的子信道 §r%s§6 。已使用主信道值替代。
structurelib.blockhint.desc.0=帮助你搭建机器
structurelib.blockhint.0.name=提示方块:1号