diff --git a/ALGORITHM.MD b/ALGORITHM.MD index acb17c9..fa31680 100644 --- a/ALGORITHM.MD +++ b/ALGORITHM.MD @@ -8,7 +8,7 @@ - 渲染:按运算结果渲染 ## 算法概述 -### 中心环绕型 +### 中心环绕型 #### 固有转换:经度锁定 - 计算玩家视坐标到目标坐标的位向量(概念上是三维射线的意思) - 三维变换归一化获得在“单位球壳”上的坐标点 @@ -17,7 +17,7 @@ - 对球壳上两点(玩家视觉点与目标位置点)进行选择的投影,获得平面点 - 求得视坐标投影点->位坐标投影点的弧度、距离 -投影类型 +投影类型 : 墨卡托投影 : 艾托夫投影 : 温克尔三重投影(线性混合) @@ -40,7 +40,7 @@ 该投影逻辑为 : 获取游戏的V(经过视坐标转换)、P矩阵,合为一个转换矩阵 -: 将目标坐标包装成带有距离缩放信息的向量(即四维向量,w基础值为1.0f) +: 将目标坐标包装成带有距离缩放信息的向量(即三维上使用的齐次坐标,w基础值为1.0f) : 使目标四维向量与转换矩阵相乘,得到实际V模式对应信息 : 计算并转换成屏幕坐标(包括边界框限制性取值) @@ -48,8 +48,10 @@ 将会在第三种投影完成后对第一种投影进行完全重构 +> 26.01.26注: 或许我可以先留着中心的投影, 它可能更加符合人的转动倾向 + > 一路走来,了解的知识越多,对未知的恐惧就越大——知识是无穷无尽的 -> +> > 我们站在诸位巨人的肩膀上,并渴望着成为巨人 ### 经度轴提示型 diff --git a/README.MD b/README.MD index 5fd0319..a140396 100644 --- a/README.MD +++ b/README.MD @@ -1,19 +1,34 @@ -# Entity Tracker (简体中文|[English](README_EN.MD)) -这是一个用于在MC中跟踪实体的HUD模组。 +# The Trackers (简体中文|[English](README_EN.MD)) +这是一个用于在MC中跟踪实体的纯客户端HUD工具模组。 + +同时也是一个使用HUD icon标记三维坐标的实用功能库。 + +作为玩家使用本模组,可以通过模组配置设置需要追踪的实体。 + +作为开发者使用本模组,可以便捷地声明指针模板,并快速使用模板注册指针并应用。 + ### 工作原理 使用投影计算在2D屏幕上显示标志以表示实体位置。 -详见[算法](ALGORITHM.MD) +在代码层面,额外支持渲染物品。 + +投影内容详见详见[算法-中文](ALGORITHM.MD) + ### 特性 -- 直接通过指示显示实体的位置 -- 可自定义某实体类型的实体定位 -- 可自定义HUD指针 +- 直接通过指示图标表示世界上的位置 +- 自动扫描附近的实体 +- 可自定义指示某种实体 +- 可自定义HUD指针样式 +- 在代码层面简化屏上HUD图标的创建 +- 自动的、可控的指针回收机制 ### 作者 [@MakerTechno](https://github.com/MakerTechno) + ### 协议 [LGPLv3](https://www.gnu.org/licenses/lgpl-3.0.html) + ### 依赖 无 + ### 联动 [汇流来世 Confluence Of The Afterlife](https://github.com/MagicHarp/confluence) - diff --git a/README_EN.MD b/README_EN.MD index 87f80df..108b0be 100644 --- a/README_EN.MD +++ b/README_EN.MD @@ -1,13 +1,27 @@ -# Entity Tracker (English|[简体中文](README.MD)) -This is a simple HUD for tracking entities in Minecraft. +# The Trackers (English|[简体中文](README.MD)) +This is a client-side HUD mod for tracking entities in Minecraft. + +It also serves as a utility library for marking 3D coordinates with HUD icons. + +As a player, you can configure the mod to track specific entities. + +As a developer, you can conveniently define pointer templates and quickly register and apply them. + ### How it works -Using a set of projection, it displays entities' positions in 2D with customized icon. +It uses projection calculations to display icons on the 2D screen representing entity positions. + +At the code level, it additionally supports rendering items. + +For details on the projection algorithm, see [ALGORITHM (Chinese only)](ALGORITHM.MD) for details. -See [ALGORITHM (Chinese only)](ALGORITHM.MD) for details. ### Features -- Display entities' positions in 2D -- Specific entities tracking -- Customizable HUD pointers +- Display world positions directly with HUD icons +- Automatically scan for nearby entities +- Customizable tracking targets for specific entities +- Customizable HUD pointer styles +- Simplified creation of HUD icons at the code level +- Automatic and controllable pointer recycling mechanism + ### Author [@MakerTechno](https://github.com/MakerTechno) ### License diff --git a/gradle.properties b/gradle.properties index 0d4c046..25f76cc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,14 +9,14 @@ parchment_mappings_version=2024.11.13 minecraft_version=1.21.1 minecraft_version_range=[1.21.1, 1.22) -neo_version=21.1.209 +neo_version=21.1.218 neo_version_range=[21.1.0,) loader_version_range=[4,) mod_id=the_trackers mod_name=The Trackers mod_license=LGPLv3 -mod_version=1.21.1-0.2.3 +mod_version=1.21.1-0.2.5 mod_group_id=nowebsite.makertechno.the_trackers mod_authors=MakerTechno mod_description=To follow the light to where all shadows begin. diff --git a/src/main/java/nowebsite/makertechno/the_trackers/api/component/ComponentBuilder.java b/src/main/java/nowebsite/makertechno/the_trackers/api/component/ComponentBuilder.java index 400def7..f131258 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/api/component/ComponentBuilder.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/component/ComponentBuilder.java @@ -1,14 +1,16 @@ package nowebsite.makertechno.the_trackers.api.component; -import net.minecraft.data.models.model.TextureMapping; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponentFactory; -import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; +import net.minecraft.world.item.ItemStack; +import nowebsite.makertechno.the_trackers.client.gui.components.BasicComponentFactory; +import nowebsite.makertechno.the_trackers.client.gui.components.IRenderElement; +import nowebsite.makertechno.the_trackers.client.gui.components.Icon; +import nowebsite.makertechno.the_trackers.client.gui.components.ItemComponent; import nowebsite.makertechno.the_trackers.client.gui.provider.TextureCache; import nowebsite.makertechno.the_trackers.core.tool.TextureBuildTool; import javax.annotation.Nullable; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -19,16 +21,17 @@ public class ComponentBuilder { private ComponentType type = ComponentType.DIRECT; private String cursorPattern = null; - private Supplier icon1 = () -> Icon.NONE; + private Supplier icon1 = () -> Icon.NONE; private String component1Pattern = null; - private Supplier icon2 = () -> Icon.NONE; + private Supplier icon2 = () -> Icon.NONE; private String component2Pattern = null; - private Supplier icon3 = () -> Icon.NONE; + private Supplier icon3 = () -> Icon.NONE; private String component3Pattern = null; private boolean isSmoothMove = false; private boolean affectedByPlayerSettingsScale = false; private boolean autoLifecycle = false; - private Function definedScaleMultiple = scale -> scale; + private Function rescaleFunc = scale -> scale; + private BiFunction alphaTransformer = (distance, alpha) -> alpha; public ComponentBuilder() {} @@ -60,10 +63,9 @@ public ComponentBuilder setIcon1(ResourceLocation location) { /** *

对于一般情况,该方法设置其中心图标。具有多个图标位的指针需要填充其它icon。

- *

将传入的物品的贴图作为图标。图标默认为空。

*/ - public ComponentBuilder setIcon1(Item item) { - icon1 = () -> getIcon(TextureMapping.getItemTexture(item).withPrefix("textures/")); + public ComponentBuilder setIcon1(ItemStack itemStack) { + icon1 = () -> getItemComponent(itemStack); return this; } @@ -77,7 +79,7 @@ public ComponentBuilder setIcon1(String key) { } /** - * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link IconComponentFactory} + * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link BasicComponentFactory} */ public ComponentBuilder setIcon1Pattern(String pattern) { this.component1Pattern = pattern; @@ -89,8 +91,8 @@ public ComponentBuilder setIcon1Pattern(String pattern) { *

对于一般情况,该方法设置其中心图标。具有多个图标位的指针需要填充其它icon。

*

将传入的物品的贴图作为图标。图标默认为空。

*/ - public ComponentBuilder setIcon2(Item item) { - icon2 = () -> getIcon(TextureMapping.getItemTexture(item).withPrefix("textures/")); + public ComponentBuilder setIcon2(ItemStack itemStack) { + icon2 = () -> getItemComponent(itemStack); return this; } @@ -104,7 +106,7 @@ public ComponentBuilder setIcon2(String key) { } /** - * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link IconComponentFactory} + * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link BasicComponentFactory} */ public ComponentBuilder setIcon2Pattern(String pattern) { this.component2Pattern = pattern; @@ -116,8 +118,8 @@ public ComponentBuilder setIcon2Pattern(String pattern) { *

对于一般情况,该方法设置其中心图标。具有多个图标位的指针需要填充其它icon。

*

将传入的物品的贴图作为图标。图标默认为空。

*/ - public ComponentBuilder setIcon3(Item item) { - icon3 = () -> getIcon(TextureMapping.getItemTexture(item).withPrefix("textures/")); + public ComponentBuilder setIcon3(ItemStack itemStack) { + icon3 = () -> getItemComponent(itemStack); return this; } @@ -131,7 +133,7 @@ public ComponentBuilder setIcon3(String key) { } /** - * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link IconComponentFactory} + * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link BasicComponentFactory} */ public ComponentBuilder setIcon3Pattern(String pattern) { this.component3Pattern = pattern; @@ -165,8 +167,16 @@ public ComponentBuilder setAutoLifecycle(boolean autoLifecycle) { /** * 设置乘数再运算器,一般建议在这里对最终大小进行区间移动和缩放。 * */ - public ComponentBuilder defineScaleMultiple(Function definedScaleMultipleApplier) { - this.definedScaleMultiple = definedScaleMultipleApplier; + public ComponentBuilder defineRescale(Function rescale) { + this.rescaleFunc = rescale; + return this; + } + + /** + * 设置透明度再运算器。 + * */ + public ComponentBuilder defineAlphaTransformer(BiFunction alphaTransformer) { + this.alphaTransformer = alphaTransformer; return this; } @@ -183,7 +193,8 @@ public BuilderResult build() { isSmoothMove, autoLifecycle, affectedByPlayerSettingsScale, - definedScaleMultiple + rescaleFunc, + alphaTransformer ); } @@ -191,38 +202,45 @@ private static Icon getIcon(ResourceLocation location) { return TextureBuildTool.initIcon("dynamic", location.withSuffix(".png"), Icon::new).orElse(Icon.NONE); } + private static ItemComponent getItemComponent(ItemStack stack) { + return new ItemComponent(stack); + } + public static final class BuilderResult { public final @Nullable String component1Pattern, component2Pattern, component3Pattern, cursorPattern; public final ComponentType type; - public final Supplier icon1, icon2, icon3; + public final Supplier element1, element2, element3; public final boolean isSmoothMove, autoLifecycle, affectedBySettings; - public final Function multiple; + public final Function rescale; + public final BiFunction transformAlpha; private BuilderResult( ComponentType type, - Supplier icon1, + Supplier element1, @Nullable String component1Pattern, - Supplier icon2, + Supplier element2, @Nullable String component2Pattern, - Supplier icon3, + Supplier element3, @Nullable String component3Pattern, @Nullable String cursorPattern, boolean isSmoothMove, boolean autoLifecycle, boolean affectedBySettings, - Function multiple + Function rescale, + BiFunction transformAlpha ) { this.type = type; - this.icon1 = icon1; + this.element1 = element1; this.component1Pattern = component1Pattern; - this.icon2 = icon2; + this.element2 = element2; this.component2Pattern = component2Pattern; - this.icon3 = icon3; + this.element3 = element3; this.component3Pattern = component3Pattern; this.cursorPattern = cursorPattern; this.isSmoothMove = isSmoothMove; this.autoLifecycle = autoLifecycle; this.affectedBySettings = affectedBySettings; - this.multiple = multiple; + this.rescale = rescale; + this.transformAlpha = transformAlpha; } } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/api/examples/TestAdd1.java b/src/main/java/nowebsite/makertechno/the_trackers/api/examples/TestAdd1.java index b30b9b1..f764438 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/api/examples/TestAdd1.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/examples/TestAdd1.java @@ -19,9 +19,9 @@ public class TestAdd1 { private static final ComponentBuilder.BuilderResult posTo0 = new ComponentBuilder() .setComponentType(ComponentBuilder.ComponentType.DIRECT) - .setIcon1(Items.DIAMOND) + .setIcon1(Items.DIAMOND.getDefaultInstance()) .setIcon1Pattern("rainbow:2") - .defineScaleMultiple(scale -> (float) (1F + Math.min(scale / 2.2, 1f) * Math.min(scale / 2.2, 1f))) + .defineRescale(scale -> (float) (1F + Math.min(scale / 2.2, 1f) * Math.min(scale / 2.2, 1f))) .setSmoothMove(true) .build(); diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/RendererToScreen.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/RendererToScreen.java deleted file mode 100644 index 5d53755..0000000 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/RendererToScreen.java +++ /dev/null @@ -1,167 +0,0 @@ -/* -package nowebsite.makertechno.entity_tracker.client.gui; - -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.datafixers.util.Pair; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRenderComponent; -import nowebsite.makertechno.entity_tracker.core.track.algorithm.CameraProjector; -import nowebsite.makertechno.entity_tracker.core.track.algorithm.RelativeProjector; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRelativeCursor; -import nowebsite.makertechno.entity_tracker.client.gui.components.TEntityIcon; -import nowebsite.makertechno.entity_tracker.client.gui.components.TPointer; -import org.jetbrains.annotations.NotNull; -import org.joml.Matrix4fStack; - -public class RendererToScreen { - public static void centerRelativePointer(@NotNull GuiGraphics guiGraphics, @NotNull Player player, @NotNull Pair vec3CursorsPair) { - double[] arcAndDist = RelativeProjector.calculateAngle( - player.getEyePosition(), - player.getViewVector(1f), - vec3CursorsPair.getFirst(), - TConfig.projectAlgorithm::project - ); - TPointer pointer = vec3CursorsPair.getSecond().pointer(); - TEntityIcon icon = vec3CursorsPair.getSecond().icon(); - float angleRadians = (float) arcAndDist[0]; - double direct = arcAndDist[1]; - - // pickDirect is ease-in-out from 15 to 2(pointer.getHeight() + icon.getHeight()) when direct is in [0, 0.8), and infinity closes to 2(pointer.getHeight() + icon.getHeight()) when direct bigger than 1 - float pickDirect = 15 + (float) (Math.atan(direct / 0.8) * 140 / Math.PI); - //alpha close to 0 when pickDirect close to 15, close to 1 when pickDirect close to x, equal to 1 when pickDirect greater than x - float alpha = Math.min(1, Math.max(0, (pickDirect - 25) / (pointer.getHeight() + icon.getHeight()))); - - // init - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate( - GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, - GlStateManager.SourceFactor.ONE, - GlStateManager.DestFactor.ZERO - ); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); - // matrix - Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); - matrix4fStack.pushMatrix(); // 1 - matrix4fStack.translate((float) guiGraphics.guiWidth() / 2, (float) guiGraphics.guiHeight() / 2, 0); - matrix4fStack.rotateZ((float) (-angleRadians - Math.PI/2)); - matrix4fStack.pushMatrix(); // 2 - matrix4fStack.translate(-(float) pointer.getWidth() / 2, -(float) pointer.getHeight() / 2, 0); - matrix4fStack.translate(0, -pickDirect, 0); - RenderSystem.applyModelViewMatrix(); - - */ -/* go on *//* - - guiGraphics.blit( - pointer.getLocation(), - 0, 0, - 0, 0, - pointer.getWidth(), pointer.getHeight(), - pointer.getWidth(), pointer.getHeight() - ); - */ -/* end of pointer rend *//* - - - if (icon != TEntityIcon.NONE) { - // roll back - matrix4fStack.popMatrix(); // 1 - matrix4fStack.pushMatrix(); // 2 - matrix4fStack.translate(-(float) icon.getWidth() / 2, -(float) icon.getHeight() / 2, 0); - matrix4fStack.translate(0, -(pickDirect - pointer.getHeight() - (int) Math.ceil(Math.sqrt(2 * icon.getHeight()) + 2)), 0); - - matrix4fStack.translate((float) icon.getWidth() / 2, (float) icon.getHeight() / 2, 0); - matrix4fStack.rotateZ((float) (angleRadians + Math.PI / 2)); - matrix4fStack.translate(-(float) icon.getWidth() / 2, -(float) icon.getHeight() / 2, 0); - - RenderSystem.applyModelViewMatrix(); - - */ -/* go on *//* - - guiGraphics.blit( - icon.getLocation(), - 0, 0, - 0, 0, - icon.getWidth(), icon.getHeight(), - icon.getWidth(), icon.getHeight() - ); - */ -/* end of icon rend *//* - - RenderSystem.resetTextureMatrix(); - } - - matrix4fStack.popMatrix(); // 1 - matrix4fStack.popMatrix(); // 0 - RenderSystem.applyModelViewMatrix(); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderSystem.defaultBlendFunc(); - RenderSystem.disableBlend(); - } - - public static void fullScreenPointer(@NotNull GuiGraphics guiGraphics, @NotNull Player player, @NotNull Pair vec3CursorsPair, GameRenderer renderer) { - float[] projScrPoint = CameraProjector.projectToScreen( - renderer, - vec3CursorsPair.getFirst(), - player.getEyePosition(), - Minecraft.getInstance().gameRenderer.getMainCamera(), - guiGraphics.guiWidth(), - guiGraphics.guiHeight() - ); - TRelativeCursor cursor = vec3CursorsPair.getSecond(); - TEntityIcon icon = cursor.icon(); - - float alpha = 1; - if (projScrPoint[2] < 0.2*guiGraphics.guiWidth()) alpha = (float) (projScrPoint[2]*0.6/(0.2*guiGraphics.guiWidth()) + 0.4); - - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); - - // init - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate( - GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, - GlStateManager.SourceFactor.ONE, - GlStateManager.DestFactor.ZERO - ); - - Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); - matrix4fStack.pushMatrix(); // 1 - matrix4fStack.translate(-(float) icon.getWidth() / 2, -(float) icon.getHeight() / 2, 0); - matrix4fStack.translate(projScrPoint[0], projScrPoint[1], 0); - RenderSystem.applyModelViewMatrix(); - - if (icon != TEntityIcon.NONE) { - - */ -/* go on *//* - - guiGraphics.blit( - icon.getLocation(), - 0, 0, - 0, 0, - icon.getWidth(), icon.getHeight(), - icon.getWidth(), icon.getHeight() - ); - */ -/* end of icon rend *//* - - RenderSystem.resetTextureMatrix(); - } - - matrix4fStack.popMatrix(); // 0 - RenderSystem.applyModelViewMatrix(); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderSystem.defaultBlendFunc(); - RenderSystem.disableBlend(); - } -} -*/ diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BaseComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BaseComponent.java new file mode 100644 index 0000000..ca29be8 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BaseComponent.java @@ -0,0 +1,36 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import net.minecraft.client.gui.GuiGraphics; +import org.jetbrains.annotations.NotNull; + +public class BaseComponent implements IRenderElement{ + private IRenderElement element; + public BaseComponent(IRenderElement element) { + this.element = element; + } + public void render(@NotNull GuiGraphics graphics, float partialTick) { + element.render(graphics, partialTick); + } + public IRenderElement getElement() { + return element; + } + public IRenderElement flush() { + element = element.flush(); + return element; + } + + @Override + public int width() { + return element.width(); + } + + @Override + public int height() { + return element.height(); + } + + @Override + public float rescale() { + return element.rescale(); + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponentFactory.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BasicComponentFactory.java similarity index 58% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponentFactory.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BasicComponentFactory.java index 39be83f..a48ff6c 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponentFactory.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BasicComponentFactory.java @@ -1,35 +1,35 @@ -package nowebsite.makertechno.the_trackers.client.gui.icons; +package nowebsite.makertechno.the_trackers.client.gui.components; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; -public class IconComponentFactory { +public class BasicComponentFactory { @Contract(value = "_ -> new", pure = true) - public static @NotNull Supplier getDefault(Icon icon) { - return () -> new IconComponent(icon); + public static @NotNull Supplier getDefault(IRenderElement element) { + return () -> new BaseComponent(element); } /** * 传入语句: "(blink/rainbow):(specific pattern)" */ @Contract(value = "_, _ -> new", pure = true) - public static @NotNull Supplier getIconComponent(Icon icon, @NotNull String pattern) { + public static @NotNull Supplier getElementComponent(IRenderElement element, @NotNull String pattern) { String [] patterns = pattern.split(":"); try { int countNum; if (patterns[0].equals("blink")) { countNum = Integer.parseInt(patterns[1]); - if (BlinkIconComponent.isValidPatterns(countNum)) return () -> new BlinkIconComponent(icon, countNum); + if (BlinkComponent.isValidPatterns(countNum)) return () -> new BlinkComponent(element, countNum); } else if (patterns[0].equals("rainbow")) { countNum = Integer.parseInt(patterns[1]); - if (RainbowIconComponent.isValidPatterns(countNum)) return () -> new RainbowIconComponent(icon, countNum); + if (RainbowComponent.isValidPatterns(countNum)) return () -> new RainbowComponent(element, countNum); } } catch (NumberFormatException ignored) {} - return getDefault(icon); + return getDefault(element); } /** @@ -40,9 +40,9 @@ public static boolean hasElementPattern(@NotNull String pattern) { if (patterns.length != 2) return false; try { if (patterns[0].equals("blink")) { - if (BlinkIconComponent.isValidPatterns(Integer.parseInt(patterns[1]))) return true; + if (BlinkComponent.isValidPatterns(Integer.parseInt(patterns[1]))) return true; } else if (patterns[0].equals("rainbow")) { - if (RainbowIconComponent.isValidPatterns(Integer.parseInt(patterns[1]))) return true; + if (RainbowComponent.isValidPatterns(Integer.parseInt(patterns[1]))) return true; } } catch (NumberFormatException e) { return false; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/BlinkIconComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BlinkComponent.java similarity index 83% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/BlinkIconComponent.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BlinkComponent.java index c7dc8d3..8a4b423 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/BlinkIconComponent.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/BlinkComponent.java @@ -1,16 +1,16 @@ -package nowebsite.makertechno.the_trackers.client.gui.icons; +package nowebsite.makertechno.the_trackers.client.gui.components; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; import org.jetbrains.annotations.NotNull; -public class BlinkIconComponent extends IconComponent { +public class BlinkComponent extends BaseComponent { private final int intervalBlink; private int intervalCount; private float alpha; private boolean reverse; - public BlinkIconComponent(Icon icon, int intervalBlink) { - super(icon); + public BlinkComponent(IRenderElement element, int intervalBlink) { + super(element); this.intervalBlink = intervalBlink; this.intervalCount = 0; } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/IRenderElement.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/IRenderElement.java new file mode 100644 index 0000000..cf4b2e8 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/IRenderElement.java @@ -0,0 +1,15 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import net.minecraft.client.gui.GuiGraphics; +import org.jetbrains.annotations.NotNull; + +public interface IRenderElement { + void render(@NotNull GuiGraphics graphics, float partialTick); + IRenderElement flush(); + int width(); + int height(); + + default float rescale() { + return 1F; + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/Icon.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/Icon.java new file mode 100644 index 0000000..1ff8701 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/Icon.java @@ -0,0 +1,30 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.resources.ResourceLocation; +import nowebsite.makertechno.the_trackers.client.gui.provider.TextureCache; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; + +public record Icon(String regName, @Nullable ResourceLocation location, int width, int height) implements IRenderElement { + public static final Icon NONE = new Icon("none", null, 16, 16); + public static final String DYNAMIC = "dynamic"; + + @SuppressWarnings("all") + @Override + public void render(@NotNull GuiGraphics graphics, float partialTick) { + if (this.equals(Icon.NONE)) return; + graphics.blit(location(), + 0,0, + 0,0, + width(), height(), + width(), height() + ); + } + + @Override + public IRenderElement flush() { + return regName.equals(DYNAMIC) ? this : TextureCache.getIcon(regName()); + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/ItemComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/ItemComponent.java new file mode 100644 index 0000000..cc38959 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/ItemComponent.java @@ -0,0 +1,38 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class ItemComponent implements IRenderElement{ + private final ItemStack itemStack; + public ItemComponent(ItemStack itemStack) { + this.itemStack = itemStack.copy(); + } + @Override + public void render(@NotNull GuiGraphics graphics, float partialTick) { + graphics.renderItem(itemStack, 0, 0); + } + + @Override + public IRenderElement flush() { + return this; + } + + @Override + public int width() { + return 16; + } + + @Override + public int height() { + return 16; + } + + @Override + public float rescale() { + return 0.8f; + } + + // 2026/1/10-20:54 TODO: Interface, Render, and others. +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/RainbowComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/RainbowComponent.java new file mode 100644 index 0000000..329d0a4 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/RainbowComponent.java @@ -0,0 +1,86 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.GuiGraphics; + +public class RainbowComponent extends BaseComponent { + private final int intervalColor; + private int intervalCount; + private float hue; + private float r = 1.0F, g = 1.0F, b = 1.0F; + public RainbowComponent(IRenderElement element, int intervalColor) { + super(element); + this.intervalColor = intervalColor; + } + public static boolean isValidPatterns(int intervalColor) { + return intervalColor > 1; + } + @Override + public void render(GuiGraphics graphics, float partialTick) { + if (++intervalCount >= intervalColor) { + osc(); + intervalCount = 0; + } + RenderSystem.setShaderColor(r, g, b, 1.0f); + super.render(graphics, partialTick); + } + + private void osc() { + hue += 0.01F; + if (hue > 1f) hue -= 1f; + int rgb = HSBtoRGB(hue, 1f, 1f); + + r = ((rgb >> 16) & 0xFF) / 255f; + g = ((rgb >> 8) & 0xFF) / 255f; + b = (rgb & 0xFF) / 255f; + } + + /// 有些Java构建版本没有awt + private static int HSBtoRGB(float hue, float saturation, float brightness) { + int r = 0; + int g = 0; + int b = 0; + if (saturation == 0.0F) { + r = g = b = (int)(brightness * 255.0F + 0.5F); + } else { + float h = (hue - (float)Math.floor(hue)) * 6.0F; + float f = h - (float)Math.floor(h); + float p = brightness * (1.0F - saturation); + float q = brightness * (1.0F - saturation * f); + float t = brightness * (1.0F - saturation * (1.0F - f)); + switch ((int)h) { + case 0: + r = (int)(brightness * 255.0F + 0.5F); + g = (int)(t * 255.0F + 0.5F); + b = (int)(p * 255.0F + 0.5F); + break; + case 1: + r = (int)(q * 255.0F + 0.5F); + g = (int)(brightness * 255.0F + 0.5F); + b = (int)(p * 255.0F + 0.5F); + break; + case 2: + r = (int)(p * 255.0F + 0.5F); + g = (int)(brightness * 255.0F + 0.5F); + b = (int)(t * 255.0F + 0.5F); + break; + case 3: + r = (int)(p * 255.0F + 0.5F); + g = (int)(q * 255.0F + 0.5F); + b = (int)(brightness * 255.0F + 0.5F); + break; + case 4: + r = (int)(t * 255.0F + 0.5F); + g = (int)(p * 255.0F + 0.5F); + b = (int)(brightness * 255.0F + 0.5F); + break; + case 5: + r = (int)(brightness * 255.0F + 0.5F); + g = (int)(p * 255.0F + 0.5F); + b = (int)(q * 255.0F + 0.5F); + } + } + + return -16777216 | r << 16 | g << 8 | b; + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/package-info.java index 84a2d63..73014fe 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/package-info.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/package-info.java @@ -4,4 +4,4 @@ import net.minecraft.MethodsReturnNonnullByDefault; -import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TAbstractCursor.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TAbstractCursor.java similarity index 75% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TAbstractCursor.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TAbstractCursor.java index f533dfd..5334b5c 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TAbstractCursor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TAbstractCursor.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.the_trackers.client.gui.components; +package nowebsite.makertechno.the_trackers.client.gui.cursors; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; @@ -7,14 +7,16 @@ import net.minecraft.world.phys.Vec3; import nowebsite.makertechno.the_trackers.core.config.TConfig; +import java.util.function.BiFunction; import java.util.function.Function; -public abstract class TAbstractCursor implements TRenderComponent{ +public abstract class TAbstractCursor implements TRenderCursor { protected float scaleCached; protected boolean smoothMove = true; protected boolean affectedByPlayerScale = true; - protected Function multiple = scale -> scale ; + protected Function rescale = scale -> scale; + protected BiFunction transformAlpha = (distance, alpha) -> alpha; protected TAbstractCursor() { this.scaleCached = (float) TConfig.scale; @@ -28,8 +30,12 @@ public void setAffectedByPlayerScale(boolean affectedByPlayerScale) { this.affectedByPlayerScale = affectedByPlayerScale; } - public void setMultiple(Function multiple) { - this.multiple = multiple; + public void setRescale(Function rescale) { + this.rescale = rescale; + } + + public void setTransformAlpha(BiFunction transformAlpha) { + this.transformAlpha = transformAlpha; } @Override @@ -42,14 +48,15 @@ public void render(GuiGraphics graphics, Player player, Vec3 target, float parti float[] projScrPoint = getProjectScr(graphics, player, target); - float scale = multiple.apply(calculateScale(projScrPoint)); + float scale = rescale.apply(calculateScale(projScrPoint)); updateTransformer(projScrPoint, partialTick, scale); - RenderSystemInit(getAlpha(projScrPoint)); + RenderSystemInit(transformAlpha.apply(getScrDistance(projScrPoint), getAlpha(projScrPoint))); renderInsights(graphics, projScrPoint, partialTick, scale); RenderSystemRestore(); } protected abstract float[] getProjectScr(GuiGraphics graphics, Player player, Vec3 target); + protected abstract float getScrDistance(float[] projectScrPoint); protected float calculateScale(float[] projScrPoint) { return affectedByPlayerScale ? scaleCached : 1; } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDir3BodyCursor.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TDir3BodyCursor.java similarity index 74% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDir3BodyCursor.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TDir3BodyCursor.java index 201374a..a412c40 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDir3BodyCursor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TDir3BodyCursor.java @@ -1,9 +1,9 @@ -package nowebsite.makertechno.the_trackers.client.gui.components; +package nowebsite.makertechno.the_trackers.client.gui.cursors; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.util.Mth; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponent; +import nowebsite.makertechno.the_trackers.client.gui.components.BaseComponent; import org.joml.Matrix4fStack; /** @@ -29,14 +29,14 @@ protected void makeSmooth(float x, float y, float rot, float partialTick) { } } - protected final IconComponent component2, component3; + protected final BaseComponent component2, component3; protected boolean shouldFaceCenter = false; private final B3Transformer b3Transformer = new B3Transformer(0,0,0); - public TDir3BodyCursor(IconComponent component1, IconComponent component2, IconComponent component3) { + public TDir3BodyCursor(BaseComponent component1, BaseComponent component2, BaseComponent component3) { super(component1); this.component2 = component2; this.component3 = component3; @@ -69,13 +69,12 @@ protected void updateTransformer(float[] projScrPoint, float partialTick, float @Override protected void translateAndRenderComponents( - GuiGraphics graphics, - IconComponent component, - Matrix4fStack stack, - float partialTick, + GuiGraphics graphics, + BaseComponent component, + Matrix4fStack stack, + float partialTick, float scale ) { - for (int i = 0; i < 3; i++) { stack.pushMatrix(); @@ -88,8 +87,14 @@ protected void translateAndRenderComponents( } - private void renderComponent(GuiGraphics graphics, IconComponent component, Matrix4fStack stack, float partialTick, float scale, int index) { - float radius = (float) component.getIcon().height() * 1.6F * scale; + private void renderComponent(GuiGraphics graphics, BaseComponent component, Matrix4fStack stack, float partialTick, float scale, int index) { + scale = switch (index) { + case 0 -> scale * component.rescale(); + case 1 -> scale * component2.rescale(); + case 2 -> scale * component3.rescale(); + default -> 0; + }; + float radius = (float) component.getElement().height() * 1.6F * scale; float angle = b3Transformer.rot + index * Mth.TWO_PI / 3f; float px = b3Transformer.x + (float) Math.cos(angle) * radius; float py = b3Transformer.y + (float) Math.sin(angle) * radius; @@ -98,14 +103,14 @@ private void renderComponent(GuiGraphics graphics, IconComponent component, Matr stack.translate(px, py, 0f); stack.rotateZ(theta); stack.translate(-(float) switch (index) { - case 0 -> component.getIcon().width(); - case 1 -> component2.getIcon().width(); - case 2 -> component3.getIcon().width(); + case 0 -> component.getElement().width(); + case 1 -> component2.getElement().width(); + case 2 -> component3.getElement().width(); default -> 0; } / 2f * scale, -(float) switch (index) { - case 0 -> component.getIcon().height(); - case 1 -> component2.getIcon().height(); - case 2 -> component3.getIcon().height(); + case 0 -> component.getElement().height(); + case 1 -> component2.getElement().height(); + case 2 -> component3.getElement().height(); default -> 0; } / 2f * scale, 0f); stack.scale(scale); diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDirectProjCursor.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TDirectProjCursor.java similarity index 84% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDirectProjCursor.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TDirectProjCursor.java index 97ea543..1e6ab64 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDirectProjCursor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TDirectProjCursor.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.the_trackers.client.gui.components; +package nowebsite.makertechno.the_trackers.client.gui.cursors; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; @@ -7,7 +7,7 @@ import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponent; +import nowebsite.makertechno.the_trackers.client.gui.components.BaseComponent; import nowebsite.makertechno.the_trackers.core.track.algorithm.CameraProjector; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4fStack; @@ -42,11 +42,11 @@ protected void makeSmooth(float x, float y, float partialTick) { protected static final GameRenderer RENDERER = Minecraft.getInstance().gameRenderer; - protected final IconComponent component; + protected final BaseComponent component; private final Transformer transformer = new Transformer(0, 0); - public TDirectProjCursor(IconComponent component) { + public TDirectProjCursor(BaseComponent component) { super(); this.component = component; } @@ -68,6 +68,11 @@ public void flush() { ); } + @Override + protected float getScrDistance(float[] projectScrPoint) { + return projectScrPoint[3]; + } + @Override protected float calculateScale(float[] projScrPoint) { return super.calculateScale(projScrPoint) / projScrPoint[3] * 15; @@ -93,14 +98,15 @@ protected void renderInsights(GuiGraphics graphics, float[] projScrPoint, float protected void translateAndRenderComponents( GuiGraphics graphics, - IconComponent component, + BaseComponent component, Matrix4fStack stack, float partialTick, float scale ) { + scale = scale * component.rescale(); stack.translate( - -(float) component.getIcon().width() * scale / 2, - -(float) component.getIcon().height() * scale / 2, + -(float) component.getElement().width() * scale / 2, + -(float) component.getElement().height() * scale / 2, 0 ); stack.translate(transformer.x , transformer.y, 0); diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRelativeCursor.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TRelativeCursor.java similarity index 74% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRelativeCursor.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TRelativeCursor.java index e52e5ad..291bc7f 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRelativeCursor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TRelativeCursor.java @@ -1,12 +1,13 @@ -package nowebsite.makertechno.the_trackers.client.gui.components; +package nowebsite.makertechno.the_trackers.client.gui.cursors; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponent; -import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; +import nowebsite.makertechno.the_trackers.client.gui.components.BaseComponent; +import nowebsite.makertechno.the_trackers.client.gui.components.IRenderElement; +import nowebsite.makertechno.the_trackers.client.gui.components.Icon; import nowebsite.makertechno.the_trackers.core.config.TConfig; import nowebsite.makertechno.the_trackers.core.track.algorithm.RelativeProjector; import org.joml.Matrix4fStack; @@ -35,11 +36,11 @@ public void makeSmooth(float radius, float dist, float partialTick) { } - private final IconComponent pointerIconComponent, entityIconComponent; + private final BaseComponent pointerIconComponent, entityIconComponent; private final Transformer transformer = new Transformer(0, 0); private float pickDirect = 0; - public TRelativeCursor(IconComponent pointerIconComponent, IconComponent entityIconComponent) { + public TRelativeCursor(BaseComponent pointerIconComponent, BaseComponent entityIconComponent) { super(); this.pointerIconComponent = pointerIconComponent; this.entityIconComponent = entityIconComponent; @@ -62,11 +63,16 @@ protected float[] getProjectScr(GuiGraphics graphics, Player player, Vec3 target ); } + @Override + protected float getScrDistance(float[] projectScrPoint) { + return projectScrPoint[1]; + } + @Override protected void updateTransformer(float[] projScrPoint, float partialTick, float scale) { float radius = (float) (-projScrPoint[0] - Math.PI/2); - Icon pointer = pointerIconComponent.getIcon(); - Icon icon = entityIconComponent.getIcon(); + IRenderElement pointer = pointerIconComponent.getElement(); + IRenderElement icon = entityIconComponent.getElement(); // pickDirect is ease-in-out from 15 to 2(pointer.getHeight() + icon.getHeight()) when direct is in [0, 0.8), // and infinity closes to 2(pointer.getHeight() + icon.getHeight()) when direct bigger than 1 this.pickDirect = 20 + (float) (Math.atan(projScrPoint[1] / 0.8) * 240 / Math.PI); @@ -78,8 +84,8 @@ protected void updateTransformer(float[] projScrPoint, float partialTick, float @Override protected float getAlpha(float[] projScrPoint) { - Icon pointer = pointerIconComponent.getIcon(); - Icon icon = entityIconComponent.getIcon(); + IRenderElement pointer = pointerIconComponent.getElement(); + IRenderElement icon = entityIconComponent.getElement(); return Math.min(1, Math.max(0, (pickDirect - 25) / (pointer.height() + icon.height()))); } @@ -91,22 +97,25 @@ protected void renderInsights(GuiGraphics graphics, float[] projScrPoint, float stack.popMatrix(); RenderSystem.applyModelViewMatrix(); } - + protected void translateAndRenderComponents( GuiGraphics graphics, float[] projScrPoint, - IconComponent pointerComponent, - IconComponent entityComponent, + BaseComponent pointerComponent, + BaseComponent entityComponent, Matrix4fStack stack, float partialTick, float scale ) { + float pointerScale = scale * pointerComponent.rescale(); + float entityScale = scale * entityComponent.rescale(); + float radius = (float) (-projScrPoint[0] - Math.PI/2); - Icon pointer = pointerComponent.getIcon(); - Icon icon = entityComponent.getIcon(); + IRenderElement pointer = pointerComponent.getElement(); + IRenderElement icon = entityComponent.getElement(); - float pw = -(float) pointer.width() / 2 * scale, ph = -(float) pointer.height() / 2 * scale; - float ew = (float) icon.width() / 2 * scale, eh = (float) icon.height() / 2 * scale; + float pw = -(float) pointer.width() / 2 * pointerScale, ph = -(float) pointer.height() / 2 * pointerScale; + float ew = (float) icon.width() / 2 * entityScale, eh = (float) icon.height() / 2 * entityScale; stack.translate((float) graphics.guiWidth() / 2, (float) graphics.guiHeight() / 2, 0); @@ -114,8 +123,8 @@ protected void translateAndRenderComponents( stack.pushMatrix(); // 2 { stack.translate(pw, ph, 0); - stack.translate(0, -this.pickDirect* scale, 0); - stack.scale(scale, scale, 1); + stack.translate(0, -this.pickDirect* pointerScale, 0); + stack.scale(pointerScale, pointerScale, 1); RenderSystem.applyModelViewMatrix(); /* go on */ @@ -135,7 +144,7 @@ protected void translateAndRenderComponents( stack.rotateZ(-radius); // A funny delayed rot for icon stack.translate(-ew, -eh, 0); - stack.scale(scale, scale, 1); + stack.scale(entityScale, entityScale, 1); RenderSystem.applyModelViewMatrix(); /* go on */ @@ -147,4 +156,4 @@ protected void translateAndRenderComponents( stack.popMatrix(); // 1 } -} \ No newline at end of file +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRenderComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TRenderCursor.java similarity index 63% rename from src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRenderComponent.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TRenderCursor.java index bf50b2d..ddb0893 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRenderComponent.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/TRenderCursor.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.the_trackers.client.gui.components; +package nowebsite.makertechno.the_trackers.client.gui.cursors; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.world.entity.player.Player; @@ -6,16 +6,18 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; +import java.util.function.BiFunction; import java.util.function.Function; -public interface TRenderComponent { +public interface TRenderCursor { void setSmoothMove(boolean smoothMove); void setAffectedByPlayerScale(boolean affectedByPlayerScale); - void setMultiple(Function multiple); + void setRescale(Function rescale); + void setTransformAlpha(BiFunction transformAlpha); void flush(); void render(GuiGraphics graphics, Player player, Vec3 target, float partialTick); @Contract(pure = true) - static @Nullable TRenderComponent ofNull() { + static @Nullable TRenderCursor ofNull() { return null; } } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/package-info.java new file mode 100644 index 0000000..388efc5 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/cursors/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.client.gui.cursors; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/Icon.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/Icon.java deleted file mode 100644 index e467f22..0000000 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/Icon.java +++ /dev/null @@ -1,9 +0,0 @@ -package nowebsite.makertechno.the_trackers.client.gui.icons; - -import net.minecraft.resources.ResourceLocation; - -import javax.annotation.Nullable; - -public record Icon(String regName, @Nullable ResourceLocation location, int width, int height) { - public static final Icon NONE = new Icon("none", null, 16, 16); -} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponent.java deleted file mode 100644 index 0ea41e0..0000000 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponent.java +++ /dev/null @@ -1,28 +0,0 @@ -package nowebsite.makertechno.the_trackers.client.gui.icons; - -import net.minecraft.client.gui.GuiGraphics; -import nowebsite.makertechno.the_trackers.client.gui.provider.TextureCache; -import org.jetbrains.annotations.NotNull; - -public class IconComponent { - private Icon icon; - public IconComponent(Icon icon) { - this.icon = icon; - } - @SuppressWarnings("all") - public void render(@NotNull GuiGraphics graphics, float partialTick) { - if (icon.equals(Icon.NONE)) return; - graphics.blit(icon.location(), - 0,0, - 0,0, - icon.width(), icon.height(), - icon.width(), icon.height() - ); - } - public Icon getIcon() { - return icon; - } - public void flush() { - icon = TextureCache.getIcon(icon.regName()); - } -} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/RainbowIconComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/RainbowIconComponent.java deleted file mode 100644 index 1a6a302..0000000 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/RainbowIconComponent.java +++ /dev/null @@ -1,40 +0,0 @@ -package nowebsite.makertechno.the_trackers.client.gui.icons; - -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.gui.GuiGraphics; -import org.jetbrains.annotations.NotNull; - -import java.awt.*; - -public class RainbowIconComponent extends IconComponent { - private final int intervalColor; - private int intervalCount; - private float hue; - private float r = 1.0F, g = 1.0F, b = 1.0F; - public RainbowIconComponent(Icon icon, int intervalColor) { - super(icon); - this.intervalColor = intervalColor; - } - public static boolean isValidPatterns(int intervalColor) { - return intervalColor > 1; - } - @Override - public void render(@NotNull GuiGraphics graphics, float partialTick) { - if (++intervalCount >= intervalColor) { - osc(); - intervalCount = 0; - } - RenderSystem.setShaderColor(r, g, b, 1.0f); - super.render(graphics, partialTick); - } - - private void osc() { - hue += 0.01F; - if (hue > 1f) hue -= 1f; - int rgb = Color.HSBtoRGB(hue, 1f, 1f); - - r = ((rgb >> 16) & 0xFF) / 255f; - g = ((rgb >> 8) & 0xFF) / 255f; - b = (rgb & 0xFF) / 255f; - } -} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/package-info.java deleted file mode 100644 index c68f731..0000000 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@ParametersAreNonnullByDefault -@MethodsReturnNonnullByDefault -package nowebsite.makertechno.the_trackers.client.gui.icons; - -import net.minecraft.MethodsReturnNonnullByDefault; - -import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/BuilderResultComposer.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/BuilderResultComposer.java index 17488f4..f2e0e12 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/BuilderResultComposer.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/BuilderResultComposer.java @@ -1,67 +1,68 @@ package nowebsite.makertechno.the_trackers.client.gui.provider; import nowebsite.makertechno.the_trackers.api.component.ComponentBuilder; -import nowebsite.makertechno.the_trackers.client.gui.components.*; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponent; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponentFactory; -import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; +import nowebsite.makertechno.the_trackers.client.gui.components.IRenderElement; +import nowebsite.makertechno.the_trackers.client.gui.cursors.*; +import nowebsite.makertechno.the_trackers.client.gui.components.BaseComponent; +import nowebsite.makertechno.the_trackers.client.gui.components.BasicComponentFactory; import org.jetbrains.annotations.Nullable; public final class BuilderResultComposer { private BuilderResultComposer() {} - public static TRenderComponent compose(ComponentBuilder.BuilderResult result) { - TRenderComponent component = switch (result.type) { + public static TRenderCursor compose(ComponentBuilder.BuilderResult result) { + TRenderCursor component = switch (result.type) { case RELATIVE -> composeRelativeComponent(result); case DIRECT -> composeDirectComponent(result); case HEAD_TAG -> composeRelativeComponent(result); // TODO }; component.setSmoothMove(result.isSmoothMove); component.setAffectedByPlayerScale(result.affectedBySettings); - component.setMultiple(result.multiple); + component.setRescale(result.rescale); + component.setTransformAlpha(result.transformAlpha); return component; } - public static TRenderComponent composeRelativeComponent(ComponentBuilder.BuilderResult result) { + public static TRenderCursor composeRelativeComponent(ComponentBuilder.BuilderResult result) { return new TRelativeCursor( - getIconComponent(result.component1Pattern, result.icon1.get()), - getIconComponent(result.component2Pattern, result.icon2.get()) + getIconComponent(result.component1Pattern, result.element1.get()), + getIconComponent(result.component2Pattern, result.element2.get()) ); } - public static TRenderComponent composeDirectComponent(ComponentBuilder.BuilderResult result) { + public static TRenderCursor composeDirectComponent(ComponentBuilder.BuilderResult result) { TAbstractCursor cursor; if (result.cursorPattern != null) { String[] patterns = result.cursorPattern.split(","); if (patterns[0].equals("3body")) { if (result.component2Pattern == null){ cursor = new TDir3BodyCursor( - getIconComponent(result.component1Pattern, result.icon1.get()), - getIconComponent(result.component1Pattern, result.icon1.get()), - getIconComponent(result.component1Pattern, result.icon1.get()) + getIconComponent(result.component1Pattern, result.element1.get()), + getIconComponent(result.component1Pattern, result.element1.get()), + getIconComponent(result.component1Pattern, result.element1.get()) ); } else { cursor = new TDir3BodyCursor( - getIconComponent(result.component1Pattern, result.icon1.get()), - getIconComponent(result.component2Pattern, result.icon2.get()), - getIconComponent(result.component3Pattern, result.icon3.get()) + getIconComponent(result.component1Pattern, result.element1.get()), + getIconComponent(result.component2Pattern, result.element2.get()), + getIconComponent(result.component3Pattern, result.element3.get()) ); } if (patterns.length > 1 && patterns[1].equals("faceCenter")) ((TDir3BodyCursor)cursor).setFaceCenter(true); } - else cursor = new TDirectProjCursor(getIconComponent(result.component1Pattern, result.icon1.get())); + else cursor = new TDirectProjCursor(getIconComponent(result.component1Pattern, result.element1.get())); } - else cursor = new TDirectProjCursor(getIconComponent(result.component1Pattern, result.icon1.get())); + else cursor = new TDirectProjCursor(getIconComponent(result.component1Pattern, result.element1.get())); return cursor; } - /*public static TRenderComponent composeHeadTagComponent(ComponentBuilder.BuilderResult result) { + /* TODO:public static TRenderCursor composeHeadTagComponent(ComponentBuilder.BuilderResult result) { return null; }*/ - private static IconComponent getIconComponent(@Nullable String pattern, Icon icon) { + private static BaseComponent getIconComponent(@Nullable String pattern, IRenderElement element) { return pattern == null - ? IconComponentFactory.getDefault(icon).get() - : IconComponentFactory.getIconComponent(icon, pattern).get(); + ? BasicComponentFactory.getDefault(element).get() + : BasicComponentFactory.getElementComponent(element, pattern).get(); } } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/TextureCache.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/TextureCache.java index 1fec934..1e0062d 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/TextureCache.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/TextureCache.java @@ -4,7 +4,7 @@ import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import nowebsite.makertechno.the_trackers.TheTrackers; -import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; +import nowebsite.makertechno.the_trackers.client.gui.components.Icon; import nowebsite.makertechno.the_trackers.core.tool.TextureBuildTool; import org.jetbrains.annotations.Contract; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java b/src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java index 9b780f0..a05f176 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java @@ -2,13 +2,13 @@ import com.mojang.datafixers.util.Pair; import net.minecraft.world.entity.EntityType; -import nowebsite.makertechno.the_trackers.client.gui.components.TDir3BodyCursor; -import nowebsite.makertechno.the_trackers.client.gui.components.TDirectProjCursor; -import nowebsite.makertechno.the_trackers.client.gui.components.TRelativeCursor; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; -import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponentFactory; -import nowebsite.makertechno.the_trackers.client.gui.icons.IconComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TDir3BodyCursor; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TDirectProjCursor; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRelativeCursor; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; +import nowebsite.makertechno.the_trackers.client.gui.components.Icon; +import nowebsite.makertechno.the_trackers.client.gui.components.BasicComponentFactory; +import nowebsite.makertechno.the_trackers.client.gui.components.BaseComponent; import nowebsite.makertechno.the_trackers.client.gui.provider.TextureCache; import nowebsite.makertechno.the_trackers.core.event.TModClient; import org.jetbrains.annotations.NotNull; @@ -20,8 +20,8 @@ import java.util.stream.Collectors; public final class ConfigProcessor { - - private static final Pair, Supplier> OF_EMPTY =new Pair<>(null, TRenderComponent::ofNull); + + private static final Pair, Supplier> OF_EMPTY =new Pair<>(null, TRenderCursor::ofNull); public static boolean isValidEntityBindCRCursor(Object o) { /* entityType|pointer|entityIcon(|optionalPatterns) */ @@ -39,14 +39,14 @@ public static boolean isValidEntityBindCRCursor(Object o) { if (split.length == 4) { String[] patterns = split[3].split("&"); if (patterns.length != 2) return false; - return IconComponentFactory.hasElementPattern(patterns[0]) && IconComponentFactory.hasElementPattern(patterns[1]); + return BasicComponentFactory.hasElementPattern(patterns[0]) && BasicComponentFactory.hasElementPattern(patterns[1]); } return true; } @NotNull - public static Set, Supplier>> collectCREntityBindCursor(@NotNull List list) { + public static Set, Supplier>> collectCREntityBindCursor(@NotNull List list) { return list.stream() .map(s -> { String[] split = s.split("\\|"); @@ -62,26 +62,26 @@ public static Set, Supplier>> col Icon icon = TextureCache.getIcon(split[2]); if (!split[2].equals("none") && icon.equals(Icon.NONE)) return OF_EMPTY; - Supplier supplier; + Supplier supplier; if (split.length == 4) { String[] patterns = split[3].split("&"); if (patterns.length == 2 && - IconComponentFactory.hasElementPattern(patterns[0]) && - IconComponentFactory.hasElementPattern(patterns[1])) { + BasicComponentFactory.hasElementPattern(patterns[0]) && + BasicComponentFactory.hasElementPattern(patterns[1])) { supplier = () -> new TRelativeCursor( - IconComponentFactory.getIconComponent(pointerIcon, patterns[0]).get(), - IconComponentFactory.getIconComponent(icon, patterns[1]).get() + BasicComponentFactory.getElementComponent(pointerIcon, patterns[0]).get(), + BasicComponentFactory.getElementComponent(icon, patterns[1]).get() ); - return new Pair, Supplier>(entityType, supplier); + return new Pair, Supplier>(entityType, supplier); } } supplier = () -> new TRelativeCursor( - IconComponentFactory.getDefault(pointerIcon).get(), - IconComponentFactory.getDefault(icon).get() + BasicComponentFactory.getDefault(pointerIcon).get(), + BasicComponentFactory.getDefault(icon).get() ); - return new Pair, Supplier>(entityType, supplier); + return new Pair, Supplier>(entityType, supplier); }) .filter(p -> p != OF_EMPTY) .collect(Collectors.toSet()); @@ -108,12 +108,12 @@ public static boolean isValidCREntityBindDTCursor(Object o) { if (!(style[0].equals("normal") || style[0].equals("3body"))) return false; - if (split.length == 3) return IconComponentFactory.hasElementPattern(split[2]); + if (split.length == 3) return BasicComponentFactory.hasElementPattern(split[2]); return true; } @NotNull - public static Set, Supplier>> collectDTEntityBindCursor(@NotNull List list) { + public static Set, Supplier>> collectDTEntityBindCursor(@NotNull List list) { return list.stream() .map(s -> { String[] split = s.split("\\|"); @@ -131,18 +131,18 @@ public static Set, Supplier>> col icon = TextureCache.getIcon(style[1]); if (icon.equals(Icon.NONE)) return OF_EMPTY; } - Supplier cps; - if (split.length == 3) cps = IconComponentFactory.getIconComponent(icon, split[2]); - else cps = IconComponentFactory.getDefault(icon); + Supplier cps; + if (split.length == 3) cps = BasicComponentFactory.getElementComponent(icon, split[2]); + else cps = BasicComponentFactory.getDefault(icon); - Supplier supplier; + Supplier supplier; if (style[0].equals("3body")){ supplier = () -> new TDir3BodyCursor(cps.get(), cps.get(), cps.get()); } else if (style[0].equals("normal")){ supplier = () -> new TDirectProjCursor(cps.get()); } else return OF_EMPTY; - return new Pair, Supplier>(entityType, supplier); + return new Pair, Supplier>(entityType, supplier); }) .filter(p -> p != OF_EMPTY) .collect(Collectors.toSet()); diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java b/src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java index 9443929..6e784a2 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java @@ -7,7 +7,7 @@ import net.neoforged.fml.event.config.ModConfigEvent; import net.neoforged.neoforge.common.ModConfigSpec; import nowebsite.makertechno.the_trackers.TheTrackers; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; import nowebsite.makertechno.the_trackers.core.event.TModClient; import nowebsite.makertechno.the_trackers.core.track.EntityTracker; import nowebsite.makertechno.the_trackers.core.track.algorithm.ProjectAlgorithmLib; @@ -72,6 +72,7 @@ public class TConfig { "terra_entity:brain_of_cthulhu|normal|brain_of_cthulhu", "terra_entity:eater_of_worlds|normal|eater_of_worlds", "terra_entity:queen_bee|normal|queen_bee", + "terra_entity:deerclops|normal|deerclops", "terra_entity:skeletron|normal|skeletron", "terra_entity:hill_of_flesh|normal|wall_of_flesh", "terra_entity:wall_of_flesh|normal|wall_of_flesh", @@ -132,8 +133,8 @@ public class TConfig { public static boolean trackFullAvailable; public static boolean headFlatAvailable; public static ProjectAlgorithmLib.Type projectAlgorithm; - public static Set, Supplier>> CRCursorWithEntities; - public static Set, Supplier>> DTCursorWithEntities; + public static Set, Supplier>> CRCursorWithEntities; + public static Set, Supplier>> DTCursorWithEntities; @SubscribeEvent static void onLoad(final ModConfigEvent event) { @@ -157,4 +158,4 @@ static void onLoad(final ModConfigEvent event) { static void onFileChanged(final ModConfigEvent.Reloading event) { onLoad(event); } -} \ No newline at end of file +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClientGame.java b/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClientGame.java index b50a019..a1cc4b8 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClientGame.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClientGame.java @@ -3,8 +3,8 @@ import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; import net.neoforged.neoforge.client.event.ClientTickEvent; -import net.neoforged.neoforge.event.entity.player.PlayerEvent; import nowebsite.makertechno.the_trackers.TheTrackers; import nowebsite.makertechno.the_trackers.core.config.TConfig; import nowebsite.makertechno.the_trackers.core.track.TrackersMonitor; @@ -17,7 +17,7 @@ public static void onClientTick(ClientTickEvent.Pre event) { } @SubscribeEvent - public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { + public static void clientPlayerNetwork$LoggingOut(ClientPlayerNetworkEvent.LoggingOut event) { TrackersMonitor.quit(); } } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java b/src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java index 8a71882..9b502c1 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java @@ -10,7 +10,7 @@ import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; import nowebsite.makertechno.the_trackers.TheTrackers; -import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; +import nowebsite.makertechno.the_trackers.client.gui.components.Icon; import org.jetbrains.annotations.NotNull; import java.io.IOException; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/EntityTracker.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/EntityTracker.java index 99254b3..509e0d5 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/EntityTracker.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/EntityTracker.java @@ -8,7 +8,7 @@ import net.minecraft.world.phys.AABB; import net.neoforged.neoforge.entity.PartEntity; import nowebsite.makertechno.the_trackers.client.gui.TGui; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; import nowebsite.makertechno.the_trackers.core.config.TConfig; import nowebsite.makertechno.the_trackers.core.track.states.TrackerStepState; import org.jetbrains.annotations.NotNull; @@ -25,7 +25,7 @@ public class EntityTracker { /** 缓存的渲染队列 */ private static final Map RENDERING = new HashMap<>(); /** 规则组 */ - private static final List, Supplier>> ALL_GROUPS = new ArrayList<>(); + private static final List, Supplier>> ALL_GROUPS = new ArrayList<>(); /** 框选距离 */ public static final AABB PICK_RANGE = new AABB( - 64.0D, @@ -88,7 +88,7 @@ private static boolean processExisting(@NotNull Entity entity) { * 判断实体种类并尝试为其创建对应种类的指针对。 */ private static void tryCreateNew(Entity entity) { - for (Pair, Supplier> pair : ALL_GROUPS) { + for (Pair, Supplier> pair : ALL_GROUPS) { if (isTargetType(pair.getFirst(), entity)) { TrackerStepState state = new TrackerStepState(pair.getSecond().get()); state.updatePos(entity.getRopeHoldPosition(0)); @@ -120,4 +120,4 @@ private static boolean isTargetEntity(Entity entity) { private static boolean isTargetType(@NotNull EntityType entityType, @NotNull Entity entity) { return entityType == entity.getType(); } -} \ No newline at end of file +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/StableTracker.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/StableTracker.java deleted file mode 100644 index 27d4975..0000000 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/StableTracker.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -package nowebsite.makertechno.entity_tracker.core.track; - -import com.mojang.datafixers.util.Pair; -import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRelativeCursor; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -public class StableTracker { - private static final Set> UUID_BOUND = new HashSet<>(); - private static final Set> POSITIONS = new HashSet<>(); - private final Map - - public void updateEntities(Set> currentEntities, long tick) { - Set seenThisTick = new HashSet<>(); - - for (Pair pair : currentEntities) { - Entity entity = pair.getFirst(); - UUID id = entity.getUUID(); - seenThisTick.add(id); - - trackedEntities.compute(id, (uuid, state) -> { - if (state == null) { - return new TrackedEntityState(id, entity.position(), pair.getSecond(), tick); - } else { - state.update(entity.position(), tick); - return state; - } - }); - } - - // 清理离开的实体(可选) - trackedEntities.entrySet().removeIf(entry -> tick - entry.getValue().lastSeenTick > 20); - } - - public Collection getTrackedStates() { - return trackedEntities.values(); - } -} -*/ diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/TrackersMonitor.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/TrackersMonitor.java index 671bf10..3a753ea 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/TrackersMonitor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/TrackersMonitor.java @@ -1,6 +1,7 @@ package nowebsite.makertechno.the_trackers.core.track; import net.minecraft.world.entity.Entity; +import nowebsite.makertechno.the_trackers.TheTrackers; import nowebsite.makertechno.the_trackers.client.gui.TGui; import nowebsite.makertechno.the_trackers.core.config.TConfig; import org.jetbrains.annotations.Nullable; @@ -23,12 +24,14 @@ public static void trigger() { count = 0; Map cached = EntityTracker.process(); - if (cached != null) tracker.trigger(cached); + if (cached != null && tracker != null) tracker.trigger(cached); + if (tracker == null) TheTrackers.LOGGER.error("WorldSingletonTracker is null, this is an unexpected state. If you see this, please report it to developers."); } } public static void quit() { + TheTrackers.LOGGER.debug("TrackerMonitor quit."); TGui.setExtendTracker(null); - if (tracker != null) tracker.clean(); + if (tracker != null) tracker.close(); tracker = null; } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/WorldSingletonTracker.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/WorldSingletonTracker.java index b865f26..aae202f 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/WorldSingletonTracker.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/WorldSingletonTracker.java @@ -8,7 +8,7 @@ import nowebsite.makertechno.the_trackers.api.component.SimpleComponent; import nowebsite.makertechno.the_trackers.api.component.StaticComponent; import nowebsite.makertechno.the_trackers.client.gui.TGui; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; import nowebsite.makertechno.the_trackers.client.gui.provider.BuilderResultComposer; import nowebsite.makertechno.the_trackers.core.track.states.ControllableTrackerState; import nowebsite.makertechno.the_trackers.core.track.states.ControllableTrackerStateEx; @@ -32,6 +32,16 @@ public static synchronized WorldSingletonTracker getInstance() { public final Map> staticPointers = new HashMap<>(); public final Map questSortedEntityPointers = new HashMap<>(); + private boolean isClosed; + + public void close() { + this.clean(); + this.isClosed = true; + } + + public boolean isClosed() { + return this.isClosed; + } /** * 通过预构内容添加一个UUID指针,指向世界中的实体。 @@ -73,7 +83,7 @@ public SimpleComponent addDynamicTickLimitedComponent(String modID, String ident public SimpleComponent addDynamicMultiComponent(String modID, String identifyName, ComponentBuilder.BuilderResult[] results, UUID target, boolean isVisible) throws IllegalArgumentException { synchronized (questSortedEntityPointers) { if (questSortedEntityPointers.containsKey(target)) throw new IllegalArgumentException("UUID named " + target + " still on tracking!"); - TRenderComponent[] components = new TRenderComponent[results.length]; + TRenderCursor[] components = new TRenderCursor[results.length]; for (int i = 0; i < results.length; i++) { components[i] = BuilderResultComposer.compose(results[i]); } @@ -95,7 +105,7 @@ public SimpleComponent attendMultiComponent(String modID, String identifyName, C case null -> throw new IllegalArgumentException("UUID named " + target + " not found on tracking list!"); case TickLimitedTrackerState ignored -> throw new UnsupportedOperationException("Tick limited component couldn't be replaced"); case ControllableTrackerStateEx ex -> { - TRenderComponent[] components = new TRenderComponent[results.length]; + TRenderCursor[] components = new TRenderCursor[results.length]; for (int i = 0; i < results.length; i++) { components[i] = BuilderResultComposer.compose(results[i]); } @@ -109,7 +119,7 @@ public SimpleComponent attendMultiComponent(String modID, String identifyName, C default -> {} } synchronized (questSortedEntityPointers) { - TRenderComponent[] components = new TRenderComponent[results.length + 1]; + TRenderCursor[] components = new TRenderCursor[results.length + 1]; for (int i = 0; i < results.length; i++) { components[i] = BuilderResultComposer.compose(results[i]); } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerState.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerState.java index 0867590..6857304 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerState.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerState.java @@ -5,7 +5,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import nowebsite.makertechno.the_trackers.api.component.StaticComponent; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; import java.util.function.Function; @@ -20,7 +20,7 @@ public class ControllableTrackerState implements StaticComponent { protected boolean isAlive = true; protected Function applier = vec3 -> vec3; - public ControllableTrackerState(String identifyName, TRenderComponent component, boolean isVisible, boolean isAutoDelete) { + public ControllableTrackerState(String identifyName, TRenderCursor component, boolean isVisible, boolean isAutoDelete) { this.identifyName = identifyName; this.state = new TrackerStepState(component); this.isVisible = isVisible; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerStateEx.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerStateEx.java index cb75d96..c06b4f3 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerStateEx.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerStateEx.java @@ -4,7 +4,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; import java.util.Arrays; @@ -12,7 +12,7 @@ public class ControllableTrackerStateEx extends ControllableTrackerState { private TrackerStepState[] states; @SuppressWarnings("all") - public ControllableTrackerStateEx(String identifyName, TRenderComponent[] components, boolean isVisible, boolean isAutoDelete) { + public ControllableTrackerStateEx(String identifyName, TRenderCursor[] components, boolean isVisible, boolean isAutoDelete) { super(identifyName, null, isVisible, isAutoDelete); this.states = new TrackerStepState[components.length]; Arrays.setAll(this.states, i -> new TrackerStepState(components[i])); diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TickLimitedTrackerState.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TickLimitedTrackerState.java index 4ff535a..c7de75c 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TickLimitedTrackerState.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TickLimitedTrackerState.java @@ -1,13 +1,13 @@ package nowebsite.makertechno.the_trackers.core.track.states; import net.minecraft.world.entity.Entity; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; public class TickLimitedTrackerState extends ControllableTrackerState{ private final int maxTicked; private int ticking = 0; - public TickLimitedTrackerState(String identifyName, TRenderComponent component, int maxTicked, boolean isVisible) { + public TickLimitedTrackerState(String identifyName, TRenderCursor component, int maxTicked, boolean isVisible) { super(identifyName, component, isVisible, false); this.maxTicked = maxTicked; } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java index 9cc7046..7cf6591 100644 --- a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java @@ -3,12 +3,12 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +import nowebsite.makertechno.the_trackers.client.gui.cursors.TRenderCursor; public class TrackerStepState { private Vec3 currentPos; - private final TRenderComponent component; - public TrackerStepState(TRenderComponent component) { + private final TRenderCursor component; + public TrackerStepState(TRenderCursor component) { this.component = component; } public void updatePos(Vec3 pos) { @@ -20,7 +20,7 @@ public Vec3 getPos() { public void renderComponent(GuiGraphics guiGraphics, float partialTick, Player player) { if (currentPos != null) component.render(guiGraphics, player, currentPos, partialTick); } - public TRenderComponent getComponent() { + public TRenderCursor getComponent() { return component; } } diff --git a/src/main/resources/assets/the_trackers/textures/icons/deerclops.png b/src/main/resources/assets/the_trackers/textures/icons/deerclops.png new file mode 100644 index 0000000..af74df3 Binary files /dev/null and b/src/main/resources/assets/the_trackers/textures/icons/deerclops.png differ