diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f2f010..97de5c9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,6 +24,7 @@ jobs: with: java-version: '21' distribution: 'temurin' + cache: "gradle" - name: Build with Gradle uses: gradle/actions/setup-gradle@v3 diff --git a/.github/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml deleted file mode 100644 index ebf20f8..0000000 --- a/.github/workflows/nightly-ci.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Nightly Build -on: - workflow_dispatch: - schedule: - # Run this job every day - - cron: "30 0 * * *" -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - ref: master - fetch-depth: 0 - - - name: Setup JDK 21 - uses: actions/setup-java@v4 - with: - distribution: "temurin" - java-version: 21 - - - name: Generate assets - uses: gradle/actions/setup-gradle@v3 - with: - arguments: runData - - - name: Build repo - uses: gradle/actions/setup-gradle@v3 - with: - arguments: build - - - name: Create nightly release - uses: marvinpinto/action-automatic-releases@latest - with: - repo_token: ${{ secrets.GH_TOKEN }} - automatic_release_tag: nightly - prerelease: true - title: "EntityTrackerHUD Automate Build" - files: | - ./build/libs/*.jar \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index c584b7c..0d4c046 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,11 +13,12 @@ neo_version=21.1.209 neo_version_range=[21.1.0,) loader_version_range=[4,) -mod_id=entity_tracker -mod_name=Entity Tracker +mod_id=the_trackers +mod_name=The Trackers mod_license=LGPLv3 -mod_version=1.21.1-0.1.1 -mod_group_id=nowebsite.makertechno.entity_tracker +mod_version=1.21.1-0.2.3 +mod_group_id=nowebsite.makertechno.the_trackers mod_authors=MakerTechno -mod_description=Where did that entity just go? Did you see it? +mod_description=To follow the light to where all shadows begin. + diff --git a/src/generated/resources/.cache/79cfe5bfff7b55794fea56f3e0a9b0e39c575861 b/src/generated/resources/.cache/79cfe5bfff7b55794fea56f3e0a9b0e39c575861 new file mode 100644 index 0000000..0b0dcdd --- /dev/null +++ b/src/generated/resources/.cache/79cfe5bfff7b55794fea56f3e0a9b0e39c575861 @@ -0,0 +1,2 @@ +// 1.21.1 2025-12-30T03:29:47.8263854 Languages: en_us for mod: the_trackers +03304c51a90c9d9e2adcfc7f6ef3e7fe53f69a2a assets/the_trackers/lang/en_us.json diff --git a/src/generated/resources/.cache/a0461903e2a35cf0af5967717926c0c059908f2e b/src/generated/resources/.cache/a0461903e2a35cf0af5967717926c0c059908f2e deleted file mode 100644 index af2b97d..0000000 --- a/src/generated/resources/.cache/a0461903e2a35cf0af5967717926c0c059908f2e +++ /dev/null @@ -1,2 +0,0 @@ -// 1.21.1 2025-08-31T17:18:30.2729717 Languages: zh_cn for mod: entity_tracker -1325ba247d8c5b27cbe932953afd7c86b3ef491d assets/entity_tracker/lang/zh_cn.json diff --git a/src/generated/resources/.cache/b2f3caf9c625ed90e67d71f5bad9e3a1e1843905 b/src/generated/resources/.cache/b2f3caf9c625ed90e67d71f5bad9e3a1e1843905 deleted file mode 100644 index b055ce0..0000000 --- a/src/generated/resources/.cache/b2f3caf9c625ed90e67d71f5bad9e3a1e1843905 +++ /dev/null @@ -1,2 +0,0 @@ -// 1.21.1 2025-08-31T17:18:30.2709711 Languages: en_us for mod: entity_tracker -8e3a42323f42a20b38764e8343d58101b9e5d706 assets/entity_tracker/lang/en_us.json diff --git a/src/generated/resources/.cache/cbbc0b13008c21e8962ade032f423e5be1ab0b42 b/src/generated/resources/.cache/cbbc0b13008c21e8962ade032f423e5be1ab0b42 new file mode 100644 index 0000000..74c849b --- /dev/null +++ b/src/generated/resources/.cache/cbbc0b13008c21e8962ade032f423e5be1ab0b42 @@ -0,0 +1,2 @@ +// 1.21.1 2025-12-30T03:29:47.8323821 Languages: zh_cn for mod: the_trackers +1abacc820d2baf494f695dc25ede351aeb2a290c assets/the_trackers/lang/zh_cn.json diff --git a/src/generated/resources/assets/entity_tracker/lang/en_us.json b/src/generated/resources/assets/entity_tracker/lang/en_us.json deleted file mode 100644 index 24946b5..0000000 --- a/src/generated/resources/assets/entity_tracker/lang/en_us.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "entity_tracker.configuration.available": "Available", - "entity_tracker.configuration.available.tooltip": "Enable or disable the tracking process", - "entity_tracker.configuration.center_relative_available": "Center-relative hud available", - "entity_tracker.configuration.center_relative_available.tooltip": "Enable or disable center-relative cursors", - "entity_tracker.configuration.center_relative_tracking": "Tracking settings for center-relative cursors", - "entity_tracker.configuration.center_relative_tracking.button": "Settings for tracking entities", - "entity_tracker.configuration.center_relative_tracking.tooltip": "List of entity types with cursor types, separated with \"|\"", - "entity_tracker.configuration.gui_scale": "The scale of tracking cursors", - "entity_tracker.configuration.gui_scale.tooltip": "Usually 0.6 on 1080p monitors", - "entity_tracker.configuration.head_flat_available": "Longitude hud available", - "entity_tracker.configuration.head_flat_available.tooltip": "Enable or disable longitude display", - "entity_tracker.configuration.interval": "Interval between world pos update", - "entity_tracker.configuration.interval.tooltip": "Choose 1 by default, provides the fastest reaction", - "entity_tracker.configuration.project_algorithm": "Project Algorithm", - "entity_tracker.configuration.project_algorithm.tooltip": "Set the algorithm specific for the center-relative pointer", - "entity_tracker.configuration.quantity": "The max quantity of tracking", - "entity_tracker.configuration.quantity.tooltip": "Always shows those \"the top N closest\" to you", - "entity_tracker.configuration.section.entity.tracker.client.toml": "Entity Tracker", - "entity_tracker.configuration.section.entity.tracker.client.toml.title": "Entity Tracker Configuration", - "entity_tracker.configuration.title": "Entity Tracker Settings", - "entity_tracker.configuration.track_full_available": "Full screen tag hud available", - "entity_tracker.configuration.track_full_available.tooltip": "Enable or disable full screen tag cursors", - "entity_tracker.configuration.track_full_tracking": "Tracking settings for full-track cursors", - "entity_tracker.configuration.track_full_tracking.button": "Settings for tracking entities", - "entity_tracker.configuration.track_full_tracking.tooltip": "List of entity types with cursor types, separated with \"|\"" -} \ No newline at end of file diff --git a/src/generated/resources/assets/entity_tracker/lang/zh_cn.json b/src/generated/resources/assets/entity_tracker/lang/zh_cn.json deleted file mode 100644 index 59af439..0000000 --- a/src/generated/resources/assets/entity_tracker/lang/zh_cn.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "entity_tracker.configuration.available": "开关", - "entity_tracker.configuration.available.tooltip": "启用或禁用追踪指针", - "entity_tracker.configuration.center_relative_available": "中心环绕式指针开关", - "entity_tracker.configuration.center_relative_available.tooltip": "启用或禁用中心环绕式跟踪", - "entity_tracker.configuration.center_relative_tracking": "中心环绕式跟踪清单", - "entity_tracker.configuration.center_relative_tracking.button": "跟踪实体的设置", - "entity_tracker.configuration.center_relative_tracking.tooltip": "带有光标类型的实体类型列表,用\"|\"分隔", - "entity_tracker.configuration.gui_scale": "追踪指针大小", - "entity_tracker.configuration.gui_scale.tooltip": "默认值0.6,这在一般1080p设备上表现很好", - "entity_tracker.configuration.head_flat_available": "经度轴开关", - "entity_tracker.configuration.head_flat_available.tooltip": "启用或禁用经度轴条", - "entity_tracker.configuration.interval": "位置刷新间隔", - "entity_tracker.configuration.interval.tooltip": "默认为1的情况下,提供最实时的指示", - "entity_tracker.configuration.project_algorithm": "投影算法", - "entity_tracker.configuration.project_algorithm.tooltip": "设置特定于\"中心环绕型\"指针的算法\nMERCATOR: 墨卡托投影\nAITOFF: 艾托夫投影\nWINKEL_TRIPLE: 温克尔三角投影\n", - "entity_tracker.configuration.quantity": "最大追踪数量", - "entity_tracker.configuration.quantity.tooltip": "总是显示离你\"最近的N个\"实体", - "entity_tracker.configuration.section.entity.tracker.client.toml": "Entity Tracker", - "entity_tracker.configuration.section.entity.tracker.client.toml.title": "Entity Tracker 配置", - "entity_tracker.configuration.title": "实体追踪器设置", - "entity_tracker.configuration.track_full_available": "锁定定位式指针开关", - "entity_tracker.configuration.track_full_available.tooltip": "启用或禁用锁定定位式指针", - "entity_tracker.configuration.track_full_tracking": "绑定定位式跟踪清单", - "entity_tracker.configuration.track_full_tracking.button": "跟踪实体的设置", - "entity_tracker.configuration.track_full_tracking.tooltip": "带有光标类型的实体类型列表,用\"|\"分隔" -} \ No newline at end of file diff --git a/src/generated/resources/assets/the_trackers/lang/en_us.json b/src/generated/resources/assets/the_trackers/lang/en_us.json new file mode 100644 index 0000000..a1421cd --- /dev/null +++ b/src/generated/resources/assets/the_trackers/lang/en_us.json @@ -0,0 +1,27 @@ +{ + "the_trackers.configuration.available": "Available", + "the_trackers.configuration.available.tooltip": "Enable or disable the automatic tracking process", + "the_trackers.configuration.center_relative_available": "Center-relative hud available", + "the_trackers.configuration.center_relative_available.tooltip": "Enable or disable center-relative cursors", + "the_trackers.configuration.center_relative_tracking": "Tracking settings for center-relative cursors", + "the_trackers.configuration.center_relative_tracking.button": "Settings for tracking entities", + "the_trackers.configuration.center_relative_tracking.tooltip": "List of entity types with cursor types, separated with \"|\"", + "the_trackers.configuration.gui_scale": "The scale of tracking cursors", + "the_trackers.configuration.gui_scale.tooltip": "Usually 0.6 on 1080p monitors", + "the_trackers.configuration.head_flat_available": "Longitude hud available", + "the_trackers.configuration.head_flat_available.tooltip": "Enable or disable longitude display", + "the_trackers.configuration.interval": "Interval between world pos update", + "the_trackers.configuration.interval.tooltip": "Choose 1 by default, provides the fastest reaction", + "the_trackers.configuration.project_algorithm": "Project Algorithm", + "the_trackers.configuration.project_algorithm.tooltip": "Set the algorithm specific for the center-relative pointer", + "the_trackers.configuration.quantity": "The max quantity of tracking", + "the_trackers.configuration.quantity.tooltip": "Always shows those \"the top N closest\" to you", + "the_trackers.configuration.the.trackers.client.toml": "The Trackers", + "the_trackers.configuration.the.trackers.client.toml.title": "The Trackers Configuration", + "the_trackers.configuration.title": "The Trackers' Settings", + "the_trackers.configuration.track_full_available": "Full screen tag hud available", + "the_trackers.configuration.track_full_available.tooltip": "Enable or disable full screen tag cursors", + "the_trackers.configuration.track_full_tracking": "Tracking settings for full-track cursors", + "the_trackers.configuration.track_full_tracking.button": "Settings for tracking entities", + "the_trackers.configuration.track_full_tracking.tooltip": "List of entity types with cursor types, separated with \"|\"" +} \ No newline at end of file diff --git a/src/generated/resources/assets/the_trackers/lang/zh_cn.json b/src/generated/resources/assets/the_trackers/lang/zh_cn.json new file mode 100644 index 0000000..82f5d49 --- /dev/null +++ b/src/generated/resources/assets/the_trackers/lang/zh_cn.json @@ -0,0 +1,27 @@ +{ + "the_trackers.configuration.available": "开关", + "the_trackers.configuration.available.tooltip": "启用或禁用追踪指针", + "the_trackers.configuration.center_relative_available": "中心环绕式指针开关", + "the_trackers.configuration.center_relative_available.tooltip": "启用或禁用中心环绕式跟踪", + "the_trackers.configuration.center_relative_tracking": "中心环绕式跟踪清单", + "the_trackers.configuration.center_relative_tracking.button": "跟踪实体的设置", + "the_trackers.configuration.center_relative_tracking.tooltip": "带有光标类型的实体类型列表,用\"|\"分隔", + "the_trackers.configuration.gui_scale": "追踪指针大小", + "the_trackers.configuration.gui_scale.tooltip": "默认值0.6,这在一般1080p设备上表现很好", + "the_trackers.configuration.head_flat_available": "经度轴开关", + "the_trackers.configuration.head_flat_available.tooltip": "启用或禁用经度轴条", + "the_trackers.configuration.interval": "位置刷新间隔", + "the_trackers.configuration.interval.tooltip": "默认为1的情况下,提供最实时的指示", + "the_trackers.configuration.project_algorithm": "投影算法", + "the_trackers.configuration.project_algorithm.tooltip": "设置特定于\"中心环绕型\"指针的算法\nMERCATOR: 墨卡托投影\nAITOFF: 艾托夫投影\nWINKEL_TRIPLE: 温克尔三角投影\n", + "the_trackers.configuration.quantity": "最大追踪数量", + "the_trackers.configuration.quantity.tooltip": "总是显示离你\"最近的N个\"实体", + "the_trackers.configuration.the.trackers.client.toml": "The Trackers", + "the_trackers.configuration.the.trackers.client.toml.title": "The Trackers 配置", + "the_trackers.configuration.title": "追踪器设置", + "the_trackers.configuration.track_full_available": "锁定定位式指针开关", + "the_trackers.configuration.track_full_available.tooltip": "启用或禁用锁定定位式指针", + "the_trackers.configuration.track_full_tracking": "绑定定位式跟踪清单", + "the_trackers.configuration.track_full_tracking.button": "跟踪实体的设置", + "the_trackers.configuration.track_full_tracking.tooltip": "带有光标类型的实体类型列表,用\"|\"分隔" +} \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/TGuiStatics.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/TGuiStatics.java deleted file mode 100644 index 7fccc01..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/TGuiStatics.java +++ /dev/null @@ -1,8 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui; - -import net.minecraft.resources.ResourceLocation; -import nowebsite.makertechno.entity_tracker.EntityTracker; - -public class TGuiStatics { - public static final ResourceLocation POINTER = ResourceLocation.fromNamespaceAndPath(EntityTracker.MOD_ID, "pointer"); -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TDir3BodyCursor.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TDir3BodyCursor.java deleted file mode 100644 index bd6f56b..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TDir3BodyCursor.java +++ /dev/null @@ -1,132 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components; - -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.Minecraft; -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.entity_tracker.client.gui.components.base.tagpointer.TagPointerIconComponent; -import nowebsite.makertechno.entity_tracker.core.track.algorithm.CameraProjector; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.joml.Matrix4fStack; - -public class TDir3BodyCursor extends TDirectTagCursor{ - private final TagPointerIconComponent component2, component3; - private Transform tO = new Transform(0,0,0); - public TDir3BodyCursor(TagPointerIconComponent component1, TagPointerIconComponent component2, TagPointerIconComponent component3) { - super(component1); - this.component2 = component2; - this.component3 = component3; - } - - @Override - public void flush() { - super.flush(); - component2.flush(); - component3.flush(); - } - - @Override - public void render(@NotNull GuiGraphics graphics, float partialTick, @NotNull Player player, Vec3 target) { - tO = renderStatic(graphics, partialTick, player, target, component, component2, component3, scale, tO); - } - - private static @NotNull Transform renderStatic(@NotNull GuiGraphics graphics, float partialTick, @NotNull Player player, Vec3 target, TagPointerIconComponent component1, TagPointerIconComponent component2, TagPointerIconComponent component3, float scale, Transform tO) { - float[] projScrPoint = CameraProjector.projectToScreen( - renderer, - target, - player.getEyePosition(), - Minecraft.getInstance().gameRenderer.getMainCamera(), - graphics.guiWidth(), - graphics.guiHeight() - ); - - float alpha = 1; - if (projScrPoint[2] < 0.2* graphics.guiWidth()) alpha = (float) (projScrPoint[2]*0.6/(0.2* graphics.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 - ); - - float dx = projScrPoint[0] - tO.x; - float dy = projScrPoint[1] - tO.y; - float distance = (float) Math.sqrt(dx * dx + dy * dy); - float signedDelta = distance * 0.008F * Math.signum(dx); - float rot = tO.rot + signedDelta; - - Transform transformSmooth = tO.smoothModify(projScrPoint[0], projScrPoint[1], rot, partialTick); - - Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); - matrix4fStack.pushMatrix(); - - for (int i = 0; i < 3; i++) { - matrix4fStack.pushMatrix(); - - float r = (float) component1.getTagPointerIcon().height() * 1.6F * scale; - float a = transformSmooth.rot + i * Mth.TWO_PI / 3f; - float px = transformSmooth.x + (float) Math.cos(a) * r; - float py = transformSmooth.y + (float) Math.sin(a) * r; - - float theta = (float) Math.atan2(transformSmooth.y - py, transformSmooth.x - px) + Mth.HALF_PI; - - matrix4fStack.translate(px, py, 0f); - matrix4fStack.rotateZ(theta); - matrix4fStack.translate(-(float) switch (i) { - case 0 -> component1.getTagPointerIcon().width(); - case 1 -> component2.getTagPointerIcon().width(); - case 2 -> component3.getTagPointerIcon().width(); - default -> 0; - } / 2f * scale, -(float) switch (i) { - case 0 -> component1.getTagPointerIcon().height(); - case 1 -> component2.getTagPointerIcon().height(); - case 2 -> component3.getTagPointerIcon().height(); - default -> 0; - } / 2f * scale, 0f); - matrix4fStack.scale(scale); - - RenderSystem.applyModelViewMatrix(); - switch (i) { - case 0 -> component1.render(graphics, partialTick); - case 1 -> component2.render(graphics, partialTick); - case 2 -> component3.render(graphics, partialTick); - } - - matrix4fStack.popMatrix(); - } - - RenderSystem.resetTextureMatrix(); - matrix4fStack.popMatrix(); - - - RenderSystem.applyModelViewMatrix(); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderSystem.defaultBlendFunc(); - RenderSystem.disableBlend(); - return transformSmooth; - } - private static final class Transform { - private float x, y, rot; - private Transform(float x, float y, float rot) { - this.x = x; - this.y = y; - this.rot = rot; - } - @Contract("_, _, _, _ -> this") - private Transform smoothModify(float x, float y, float rot, float partialTick) { - this.x = Mth.lerp(partialTick, this.x, x); - this.y = Mth.lerp(partialTick, this.y, y); - this.rot = Mth.lerp(partialTick, this.rot, rot); - return this; - } - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TDirectTagCursor.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TDirectTagCursor.java deleted file mode 100644 index b4d361f..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TDirectTagCursor.java +++ /dev/null @@ -1,97 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components; - -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.phys.Vec3; -import nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer.TagPointerIconComponent; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import nowebsite.makertechno.entity_tracker.core.track.algorithm.CameraProjector; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.joml.Matrix4fStack; - -public class TDirectTagCursor implements TRenderComponent { - final TagPointerIconComponent component; - float scale; - private Transform tO = new Transform(0, 0); - static final GameRenderer renderer = Minecraft.getInstance().gameRenderer; - public TDirectTagCursor(TagPointerIconComponent component) { - this.component = component; - scale = (float) TConfig.scale; - } - @Override - public void flush() { - component.flush(); - scale = (float) TConfig.scale; - } - - @Override - public void render(@NotNull GuiGraphics graphics, float partialTick, @NotNull Player player, Vec3 target) { - tO = renderStatic(graphics, partialTick, player, target, component, scale, tO); - } - - private static @NotNull Transform renderStatic(@NotNull GuiGraphics graphics, float partialTick, @NotNull Player player, Vec3 target, TagPointerIconComponent component, float scale, Transform tO) { - float[] projScrPoint = CameraProjector.projectToScreen( - renderer, - target, - player.getEyePosition(), - Minecraft.getInstance().gameRenderer.getMainCamera(), - graphics.guiWidth(), - graphics.guiHeight() - ); - - float alpha = 1; - if (projScrPoint[2] < 0.2* graphics.guiWidth()) alpha = (float) (projScrPoint[2]*0.6/(0.2* graphics.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 - ); - - Transform transformSmooth = tO.smoothModify(projScrPoint[0], projScrPoint[1], partialTick); - - Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); - matrix4fStack.pushMatrix(); // 1 - matrix4fStack.translate(-(float) component.getTagPointerIcon().width() / 2 * scale, -(float) component.getTagPointerIcon().height() / 2 * scale, 0); - matrix4fStack.translate(transformSmooth.x, transformSmooth.y, 0); - RenderSystem.applyModelViewMatrix(); - - /* go on */ - component.render(graphics, partialTick); - /* 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(); - return transformSmooth; - } - - private static final class Transform { - private float x, y; - private Transform(float x, float y) { - this.x = x; - this.y = y; - } - @Contract("_, _, _ -> this") - private Transform smoothModify(float x, float y, float partialTick) { - this.x = Mth.lerp(partialTick, this.x, x); - this.y = Mth.lerp(partialTick, this.y, y); - return this; - } - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TRelativeCursor.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TRelativeCursor.java deleted file mode 100644 index 236c258..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TRelativeCursor.java +++ /dev/null @@ -1,166 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components; - -import com.mojang.blaze3d.platform.GlStateManager; -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.entity_tracker.client.gui.components.base.entityicon.EntityIconComponent; -import nowebsite.makertechno.entity_tracker.client.gui.components.base.pointer.PointerIconComponent; -import nowebsite.makertechno.entity_tracker.client.render.texture.EntityIcon; -import nowebsite.makertechno.entity_tracker.client.render.texture.PointerIcon; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import nowebsite.makertechno.entity_tracker.core.track.algorithm.RelativeProjector; -import org.jetbrains.annotations.NotNull; -import org.joml.Matrix4fStack; - -public class TRelativeCursor implements TRenderComponent{ - private final PointerIconComponent pointerIconComponent; - private final EntityIconComponent entityIconComponent; - private Transform tO = new Transform(0, 0); - private float scale; - public TRelativeCursor(PointerIconComponent pointerIconComponent, EntityIconComponent entityIconComponent) { - this.pointerIconComponent = pointerIconComponent; - this.entityIconComponent = entityIconComponent; - scale = (float) TConfig.scale; - } - - @Override - public void flush() { - pointerIconComponent.flush(); - entityIconComponent.flush(); - scale = (float) TConfig.scale; - } - - @Override - public void render(GuiGraphics graphics, float partialTick, Player player, Vec3 target) { - TransformBase transform = transformLocation(player, target, pointerIconComponent.getPointerIcon(), entityIconComponent.getEntityIcon()); - this.tO = TRelativeCursor.renderStatic(graphics, partialTick, transform, tO, pointerIconComponent, entityIconComponent, scale); - } - - private static @NotNull Transform renderStatic( - GuiGraphics graphics, - float partialTick, - @NotNull TransformBase transformBase, Transform tO, - PointerIconComponent pointerIconComponent, EntityIconComponent entityIconComponent, - float scale - ) { - // 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, transformBase.alpha); - - // matrix - Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); - - Transform tNew = renderInsights(graphics, pointerIconComponent, entityIconComponent, matrix4fStack, transformBase, tO, scale, partialTick); - - RenderSystem.applyModelViewMatrix(); - - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderSystem.defaultBlendFunc(); - RenderSystem.disableBlend(); - return tNew; - } - - private static Transform renderInsights( - @NotNull GuiGraphics graphics, - @NotNull PointerIconComponent pointerIconComponent, @NotNull EntityIconComponent entityIconComponent, - @NotNull Matrix4fStack matrix4fStack, - @NotNull TransformBase result, - Transform transform, - float scale, - float partialTick - ) { - float radius = (float) (-result.angleRadians - Math.PI/2); - - PointerIcon pointer = pointerIconComponent.getPointerIcon(); - EntityIcon entityIcon = entityIconComponent.getEntityIcon(); - - float pw = -(float) pointer.width() / 2 * scale, ph = -(float) pointer.height() / 2 * scale; - float ew = (float) entityIcon.width() / 2 * scale, eh = (float) entityIcon.height() / 2 * scale; - float dist = -(result.pickDirect - pointer.height() - (int) Math.ceil(Math.sqrt(2 * entityIcon.height()) + 2)) * scale; - - Transform transformSmooth = transform.smoothTransformModify(radius, dist, partialTick); - - matrix4fStack.pushMatrix(); // 1 - matrix4fStack.translate((float) graphics.guiWidth() / 2, (float) graphics.guiHeight() / 2, 0); - - matrix4fStack.rotateZ(transformSmooth.radius); - matrix4fStack.pushMatrix(); // 2 - matrix4fStack.translate(pw, ph, 0); - matrix4fStack.translate(0, -result.pickDirect * scale, 0); - matrix4fStack.scale(scale, scale, 1); - RenderSystem.applyModelViewMatrix(); - - /* go on */ - pointerIconComponent.render(graphics, partialTick); - /* end of pointer rend */ - - if (entityIcon != EntityIcon.NONE) { - // roll back - matrix4fStack.popMatrix(); // 1 - matrix4fStack.pushMatrix(); // 2 - matrix4fStack.translate(-ew, -eh, 0); - - // Maximum the distance as diagonal distance and round up. - matrix4fStack.translate(0, transformSmooth.dist, 0); - - matrix4fStack.translate(ew, eh, 0); - matrix4fStack.rotateZ(-radius); - matrix4fStack.translate(-ew, -eh, 0); - - matrix4fStack.scale(scale, scale, 1); - RenderSystem.applyModelViewMatrix(); - - /* go on */ - entityIconComponent.render(graphics, partialTick); - /* end of icon rend */ - RenderSystem.resetTextureMatrix(); - } - - matrix4fStack.popMatrix(); // 1 - matrix4fStack.popMatrix(); // 0 - return transformSmooth; - } - - private static @NotNull TransformBase transformLocation(@NotNull Player player, Vec3 target, @NotNull PointerIcon pointer, @NotNull EntityIcon entityIcon) { - double[] arcAndDist = RelativeProjector.calculateAngle( - player.getEyePosition(), - player.getViewVector(1f), - target, - TConfig.projectAlgorithm::project - ); - 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 25, 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.height() + entityIcon.height()))); - return new TransformBase(angleRadians, pickDirect, alpha); - } - - private record TransformBase(float angleRadians, float pickDirect, float alpha) {} - - private static final class Transform { - float radius; - float dist; - private Transform(float radius, float dist) { - this.radius = radius; - this.dist = dist; - } - public Transform smoothTransformModify(float radius, float dist, float partialTick) { - if(Mth.abs(this.radius - radius) < Mth.PI * 1.5) this.radius = Mth.lerp(partialTick, this.radius, radius); - else this.radius = radius; - this.dist = Mth.lerp(partialTick, this.dist, dist); - return this; - } - } -} \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/entityicon/EntityIconComponent.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/entityicon/EntityIconComponent.java deleted file mode 100644 index 786604f..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/entityicon/EntityIconComponent.java +++ /dev/null @@ -1,33 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.entityicon; - -import net.minecraft.client.gui.GuiGraphics; -import nowebsite.makertechno.entity_tracker.client.render.TRenderLike; -import nowebsite.makertechno.entity_tracker.client.render.texture.EntityIcon; -import nowebsite.makertechno.entity_tracker.client.render.texture.TextureCache; -import org.jetbrains.annotations.NotNull; - -public class EntityIconComponent implements TRenderLike { - private EntityIcon entityIcon; - public EntityIconComponent(EntityIcon icon) { - this.entityIcon = icon; - } - @Override - public void render(@NotNull GuiGraphics graphics, float partialTick) { - graphics.blit( - entityIcon.location(), - 0, 0, - 0, 0, - entityIcon.width(), entityIcon.height(), - entityIcon.width(), entityIcon.height() - ); - } - - public EntityIcon getEntityIcon() { - return entityIcon; - } - - @Override - public void flush() { - entityIcon = TextureCache.getEntityIcon(entityIcon.regName()); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/entityicon/EntityIconFactory.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/entityicon/EntityIconFactory.java deleted file mode 100644 index 1c91882..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/entityicon/EntityIconFactory.java +++ /dev/null @@ -1,21 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.entityicon; - -import nowebsite.makertechno.entity_tracker.client.render.texture.EntityIcon; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -public class EntityIconFactory { - @Contract(value = "_, _ -> new", pure = true) - public static @NotNull EntityIconComponent getEntityIconComponent(EntityIcon icon, String pattern) { - // 2025/8/27-19:05 TODO: Add pattern check and more component. - return new EntityIconComponent(icon); - } - @Contract(value = "_ -> new", pure = true) - public static @NotNull EntityIconComponent getDefault(EntityIcon icon) { - return new EntityIconComponent(icon); - } - - public static boolean hasElementPattern(String pattern) { - return false; - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/pointer/PointerFactory.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/pointer/PointerFactory.java deleted file mode 100644 index c9a46f8..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/pointer/PointerFactory.java +++ /dev/null @@ -1,21 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.pointer; - -import nowebsite.makertechno.entity_tracker.client.render.texture.PointerIcon; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -public class PointerFactory { - @Contract(value = "_, _ -> new", pure = true) - public static @NotNull PointerIconComponent getPointerComponent(PointerIcon icon, String pattern) { - // 2025/8/27-19:05 TODO: Add pattern check and more component. - return new PointerIconComponent(icon); - } - @Contract(value = "_ -> new", pure = true) - public static @NotNull PointerIconComponent getDefault(PointerIcon icon) { - return new PointerIconComponent(icon); - } - - public static boolean hasElementPattern(String pattern) { - return false; - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/pointer/PointerIconComponent.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/pointer/PointerIconComponent.java deleted file mode 100644 index 64e24b8..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/pointer/PointerIconComponent.java +++ /dev/null @@ -1,33 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.pointer; - -import net.minecraft.client.gui.GuiGraphics; -import nowebsite.makertechno.entity_tracker.client.render.TRenderLike; -import nowebsite.makertechno.entity_tracker.client.render.texture.PointerIcon; -import nowebsite.makertechno.entity_tracker.client.render.texture.TextureCache; -import org.jetbrains.annotations.NotNull; - -public class PointerIconComponent implements TRenderLike { - private PointerIcon pointerIcon; - public PointerIconComponent(PointerIcon icon) { - this.pointerIcon = icon; - } - @Override - public void render(@NotNull GuiGraphics graphics, float partialTick) { - graphics.blit( - pointerIcon.location(), - 0, 0, - 0, 0, - pointerIcon.width(), pointerIcon.height(), - pointerIcon.width(), pointerIcon.height() - ); - } - - public PointerIcon getPointerIcon() { - return pointerIcon; - } - - @Override - public void flush() { - pointerIcon = TextureCache.getPointer(pointerIcon.regName()); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/TagPointerIconComponent.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/TagPointerIconComponent.java deleted file mode 100644 index 80e71a1..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/TagPointerIconComponent.java +++ /dev/null @@ -1,30 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer; - -import net.minecraft.client.gui.GuiGraphics; -import nowebsite.makertechno.entity_tracker.client.render.TRenderLike; -import nowebsite.makertechno.entity_tracker.client.render.texture.TIcon; -import nowebsite.makertechno.entity_tracker.client.render.texture.TextureCache; -import org.jetbrains.annotations.NotNull; - -public class TagPointerIconComponent implements TRenderLike { - private TIcon tagPointerIcon; - public TagPointerIconComponent(TIcon icon) { - this.tagPointerIcon = icon; - } - @Override - public void render(@NotNull GuiGraphics graphics, float partialTick) { - graphics.blit(tagPointerIcon.location(), - 0,0, - 0,0, - tagPointerIcon.width(), tagPointerIcon.height(), - tagPointerIcon.width(), tagPointerIcon.height() - ); - } - public TIcon getTagPointerIcon() { - return tagPointerIcon; - } - @Override - public void flush() { - tagPointerIcon = TextureCache.getTagPointer(tagPointerIcon.regName()); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/TRenderLike.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/render/TRenderLike.java deleted file mode 100644 index 7ec01e1..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/TRenderLike.java +++ /dev/null @@ -1,8 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.render; - -import net.minecraft.client.gui.GuiGraphics; - -public interface TRenderLike { - void render(GuiGraphics graphics, float partialTick); - void flush(); -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/EntityIcon.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/EntityIcon.java deleted file mode 100644 index 9e986f8..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/EntityIcon.java +++ /dev/null @@ -1,7 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.render.texture; - -import net.minecraft.resources.ResourceLocation; - -public record EntityIcon(String regName, ResourceLocation location, int width, int height) implements TIcon{ - public static final EntityIcon NONE = new EntityIcon("none", null, 16, 16); -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/PointerIcon.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/PointerIcon.java deleted file mode 100644 index 1a64968..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/PointerIcon.java +++ /dev/null @@ -1,7 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.render.texture; - -import net.minecraft.resources.ResourceLocation; - -public record PointerIcon(String regName, ResourceLocation location, int width, int height) implements TIcon { - public static final PointerIcon NONE = new PointerIcon("none", null, 16, 8); -} \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TIcon.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TIcon.java deleted file mode 100644 index c05bfc0..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TIcon.java +++ /dev/null @@ -1,10 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.render.texture; - -import net.minecraft.resources.ResourceLocation; - -public interface TIcon { - String regName(); - ResourceLocation location(); - int width(); - int height(); -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TagPointerIcon.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TagPointerIcon.java deleted file mode 100644 index 8f5a294..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TagPointerIcon.java +++ /dev/null @@ -1,7 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.render.texture; - -import net.minecraft.resources.ResourceLocation; - -public record TagPointerIcon(String regName, ResourceLocation location, int width, int height) implements TIcon { - public static final TagPointerIcon NONE = new TagPointerIcon("none", null, 16, 16); -} \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TextureCache.java b/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TextureCache.java deleted file mode 100644 index aedcde5..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/render/texture/TextureCache.java +++ /dev/null @@ -1,102 +0,0 @@ -package nowebsite.makertechno.entity_tracker.client.render.texture; - -import net.minecraft.resources.ResourceLocation; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; -import nowebsite.makertechno.entity_tracker.EntityTracker; -import nowebsite.makertechno.entity_tracker.core.tool.TextureBuildTool; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -@OnlyIn(Dist.CLIENT) -public class TextureCache { - private static final Map ENTITY_ICON_CACHE = new HashMap<>(); - private static final Map POINTER_ICON_CACHE = new HashMap<>(); - private static final Map TAG_POINTER_ICON_CACHE = new HashMap<>(); - private static final Set MISCELLANEOUS_CACHE = new HashSet<>(); - - static { - initEntityIcons( - "ender_dragon_head", - "wither_head", - "king_slime", - "eye_of_cthulhu", - "brain_of_cthulhu", - "queen_bee", - "eater_of_worlds", - "skeletron" - ); - initPointers( - "normal_white", - "normal_red", - "normal_green" - ); - initTagPointers( - "point_x" - ); - } - - public static EntityIcon getEntityIcon(String regName) { - return ENTITY_ICON_CACHE.computeIfAbsent(regName, key -> { - ResourceLocation location = getResourceFromModLocale(key); - return TextureBuildTool.initTIcon(key, location, EntityIcon::new).orElse(EntityIcon.NONE); - }); - } - public static void initEntityIcons(String ...strings) { - if (strings != null) { - for (String key : strings) { - try { - ENTITY_ICON_CACHE.put(key, TextureBuildTool.initTIcon(key, getResourceFromModLocale(key), EntityIcon::new).orElseThrow()); - } catch (NoSuchElementException e) { - warnUnload(key); - } - } - } - } - public static PointerIcon getPointer(String regName) { - return POINTER_ICON_CACHE.computeIfAbsent(regName, key -> { - ResourceLocation location = getResourceFromModLocale(key); - return TextureBuildTool.initTIcon(key, location, PointerIcon::new).orElse(PointerIcon.NONE); - }); - } - public static void initPointers(String ...strings) { - if (strings != null) { - for (String key : strings) { - try { - POINTER_ICON_CACHE.put(key, TextureBuildTool.initTIcon(key, getResourceFromModLocale(key), PointerIcon::new).orElseThrow()); - } catch (NoSuchElementException e) { - warnUnload(key); - } - } - } - } - - public static TagPointerIcon getTagPointer(String regName) { - return TAG_POINTER_ICON_CACHE.computeIfAbsent(regName, key -> { - ResourceLocation location = getResourceFromModLocale(key); - return TextureBuildTool.initTIcon(key, location, TagPointerIcon::new).orElse(TagPointerIcon.NONE); - }); - } - public static void initTagPointers(String ...strings) { - if (strings != null) { - for (String key : strings) { - try { - TAG_POINTER_ICON_CACHE.put(key, TextureBuildTool.initTIcon(key, getResourceFromModLocale(key), TagPointerIcon::new).orElseThrow()); - } catch (NoSuchElementException e) { - warnUnload(key); - } - } - } - } - - private static void warnUnload(String key) { - EntityTracker.LOGGER.warn("Failed to load image named {}, check if it was not in EntityTracker's resource with a valid path or in invalid config file.", key); - } - - @Contract("_ -> new") - private static @NotNull ResourceLocation getResourceFromModLocale(String name) { - return ResourceLocation.fromNamespaceAndPath(EntityTracker.MOD_ID, "textures/gui/sprites/hud/"+name+".png"); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/event/TModClientGame.java b/src/main/java/nowebsite/makertechno/entity_tracker/core/event/TModClientGame.java deleted file mode 100644 index e2d1d21..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/event/TModClientGame.java +++ /dev/null @@ -1,17 +0,0 @@ -package nowebsite.makertechno.entity_tracker.core.event; - -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.client.event.ClientTickEvent; -import nowebsite.makertechno.entity_tracker.EntityTracker; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import nowebsite.makertechno.entity_tracker.core.track.TrackerLogic; - -@EventBusSubscriber(modid = EntityTracker.MOD_ID, value = Dist.CLIENT) -public class TModClientGame { - @SubscribeEvent - public static void onClientTick(ClientTickEvent.Pre event) { - if (TConfig.available) TrackerLogic.trigger(); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/TrackerLogic.java b/src/main/java/nowebsite/makertechno/entity_tracker/core/track/TrackerLogic.java deleted file mode 100644 index 5bb3ce5..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/TrackerLogic.java +++ /dev/null @@ -1,103 +0,0 @@ -package nowebsite.makertechno.entity_tracker.core.track; - -import com.mojang.datafixers.util.Pair; -import net.minecraft.client.Minecraft; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.entity.EntityTypeTest; -import net.minecraft.world.phys.AABB; -import net.neoforged.neoforge.entity.PartEntity; -import nowebsite.makertechno.entity_tracker.client.gui.TGui; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRenderComponent; -import nowebsite.makertechno.entity_tracker.client.gui.components.TrackerEntityState; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import org.jetbrains.annotations.NotNull; - -import java.util.*; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -public class TrackerLogic { - private static final Map RENDERING = new HashMap<>(); - public static final AABB PICK_RANGE = new AABB( - - 64.0D, - - 48.0D, - - 64.0D, - + 64.0D, - + 64.0D, - + 64.0D - ); - private static int count = 0; - - public static Map getRENDERING() { - return RENDERING; - } - - public static void trigger() { - if (++count >= TConfig.interval) { - count = 0; - process(); - } - } - - public static void process() { - Minecraft minecraft = Minecraft.getInstance(); - Player player = TGui.getCameraPlayer(minecraft); - - if (minecraft.level == null || player == null) return; - - List nearestEntities = minecraft.level.getEntities(null, PICK_RANGE.move(player.position())).stream() - .filter(entity -> !(entity instanceof PartEntity)) - .filter(TrackerLogic::isTargetEntity) - .sorted(Comparator.comparingDouble(entity -> entity.distanceToSqr(player))) - .limit(TConfig.maxTrackingQuantity) - .toList(); - - nearestEntities.stream() - .filter(entity -> !processExisting(entity)) - .forEach(TrackerLogic::tryCreateNew); - - Set retained = nearestEntities.stream() - .map(Entity::getUUID) - .collect(Collectors.toSet()); - - RENDERING.keySet().removeIf(key -> !retained.contains(key)); - } - - private static boolean processExisting(@NotNull Entity entity) { - TrackerEntityState state = RENDERING.get(entity.getUUID()); - if (state != null) { - state.updatePos(entity.getRopeHoldPosition(0)); - return true; - } - return false; - } - - private static void tryCreateNew(Entity entity) { - for (Pair, Supplier> pair : getAllEntityGroups()) { - if (isTargetType(pair.getFirst(), entity)) { - TrackerEntityState state = new TrackerEntityState(pair.getSecond().get()); - state.updatePos(entity.getRopeHoldPosition(0)); - RENDERING.put(entity.getUUID(), state); - } - } - } - - private static @NotNull List, Supplier>> getAllEntityGroups() { - List, Supplier>> all = new ArrayList<>(); - if (TConfig.centerRelativeAvailable) all.addAll(TConfig.CRCursorWithEntities); - if (TConfig.trackFullAvailable) all.addAll(TConfig.DTCursorWithEntities); - //all.addAll(else); - return all; - } - - private static boolean isTargetEntity(Entity entity) { - return getAllEntityGroups().stream() - .anyMatch(pair -> isTargetType(pair.getFirst(), entity)); - } - - private static boolean isTargetType(@NotNull EntityTypeTest entityTypeTest, Entity entity) { - return entityTypeTest.tryCast(entity) != null; - } -} \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModChineseLanguageProvider.java b/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModChineseLanguageProvider.java deleted file mode 100644 index f8e0ff7..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModChineseLanguageProvider.java +++ /dev/null @@ -1,51 +0,0 @@ -package nowebsite.makertechno.entity_tracker.data.datagen; - -import net.minecraft.data.PackOutput; -import net.neoforged.neoforge.common.data.LanguageProvider; -import nowebsite.makertechno.entity_tracker.EntityTracker; - -public class ModChineseLanguageProvider extends LanguageProvider { - public ModChineseLanguageProvider(PackOutput packOutput, String locale) { - super(packOutput, EntityTracker.MOD_ID, locale); - } - - protected void addTranslations() { - add("entity_tracker.configuration.title", "实体追踪器设置"); - add("entity_tracker.configuration.section.entity.tracker.client.toml", "Entity Tracker"); - add("entity_tracker.configuration.section.entity.tracker.client.toml.title", "Entity Tracker 配置"); - - add("entity_tracker.configuration.available", "开关"); - add("entity_tracker.configuration.available.tooltip", "启用或禁用追踪指针"); - - add("entity_tracker.configuration.gui_scale", "追踪指针大小"); - add("entity_tracker.configuration.gui_scale.tooltip", "默认值0.6,这在一般1080p设备上表现很好"); - add("entity_tracker.configuration.quantity", "最大追踪数量"); - add("entity_tracker.configuration.quantity.tooltip", "总是显示离你\"最近的N个\"实体"); - add("entity_tracker.configuration.interval", "位置刷新间隔"); - add("entity_tracker.configuration.interval.tooltip", "默认为1的情况下,提供最实时的指示"); - - add("entity_tracker.configuration.center_relative_available", "中心环绕式指针开关"); - add("entity_tracker.configuration.center_relative_available.tooltip", "启用或禁用中心环绕式跟踪"); - add("entity_tracker.configuration.project_algorithm", "投影算法"); - add("entity_tracker.configuration.project_algorithm.tooltip", - """ - 设置特定于"中心环绕型"指针的算法 - MERCATOR: 墨卡托投影 - AITOFF: 艾托夫投影 - WINKEL_TRIPLE: 温克尔三角投影 - """ - ); - add("entity_tracker.configuration.track_full_available", "锁定定位式指针开关"); - add("entity_tracker.configuration.track_full_available.tooltip", "启用或禁用锁定定位式指针"); - add("entity_tracker.configuration.head_flat_available", "经度轴开关"); - add("entity_tracker.configuration.head_flat_available.tooltip", "启用或禁用经度轴条"); - - add("entity_tracker.configuration.center_relative_tracking", "中心环绕式跟踪清单"); - add("entity_tracker.configuration.center_relative_tracking.button", "跟踪实体的设置"); - add("entity_tracker.configuration.center_relative_tracking.tooltip", "带有光标类型的实体类型列表,用\"|\"分隔"); - - add("entity_tracker.configuration.track_full_tracking", "绑定定位式跟踪清单"); - add("entity_tracker.configuration.track_full_tracking.button", "跟踪实体的设置"); - add("entity_tracker.configuration.track_full_tracking.tooltip", "带有光标类型的实体类型列表,用\"|\"分隔"); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModEnglishLanguageProvider.java b/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModEnglishLanguageProvider.java deleted file mode 100644 index ad7a92e..0000000 --- a/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModEnglishLanguageProvider.java +++ /dev/null @@ -1,44 +0,0 @@ -package nowebsite.makertechno.entity_tracker.data.datagen; - -import net.minecraft.data.PackOutput; -import net.neoforged.neoforge.common.data.LanguageProvider; -import nowebsite.makertechno.entity_tracker.EntityTracker; - -public class ModEnglishLanguageProvider extends LanguageProvider { - public ModEnglishLanguageProvider(PackOutput packOutput, String locale) { - super(packOutput, EntityTracker.MOD_ID, locale); - } - - protected void addTranslations() { - add("entity_tracker.configuration.title", "Entity Tracker Settings"); - add("entity_tracker.configuration.section.entity.tracker.client.toml", "Entity Tracker"); - add("entity_tracker.configuration.section.entity.tracker.client.toml.title", "Entity Tracker Configuration"); - - add("entity_tracker.configuration.available", "Available"); - add("entity_tracker.configuration.available.tooltip", "Enable or disable the tracking process"); - - add("entity_tracker.configuration.gui_scale", "The scale of tracking cursors"); - add("entity_tracker.configuration.gui_scale.tooltip", "Usually 0.6 on 1080p monitors"); - add("entity_tracker.configuration.quantity", "The max quantity of tracking"); - add("entity_tracker.configuration.quantity.tooltip", "Always shows those \"the top N closest\" to you"); - add("entity_tracker.configuration.interval", "Interval between world pos update"); - add("entity_tracker.configuration.interval.tooltip", "Choose 1 by default, provides the fastest reaction"); - - add("entity_tracker.configuration.center_relative_available", "Center-relative hud available"); - add("entity_tracker.configuration.center_relative_available.tooltip", "Enable or disable center-relative cursors"); - add("entity_tracker.configuration.project_algorithm", "Project Algorithm"); - add("entity_tracker.configuration.project_algorithm.tooltip", "Set the algorithm specific for the center-relative pointer"); - add("entity_tracker.configuration.track_full_available", "Full screen tag hud available"); - add("entity_tracker.configuration.track_full_available.tooltip", "Enable or disable full screen tag cursors"); - add("entity_tracker.configuration.head_flat_available", "Longitude hud available"); - add("entity_tracker.configuration.head_flat_available.tooltip", "Enable or disable longitude display"); - - add("entity_tracker.configuration.center_relative_tracking", "Tracking settings for center-relative cursors"); - add("entity_tracker.configuration.center_relative_tracking.button", "Settings for tracking entities"); - add("entity_tracker.configuration.center_relative_tracking.tooltip", "List of entity types with cursor types, separated with \"|\""); - - add("entity_tracker.configuration.track_full_tracking", "Tracking settings for full-track cursors"); - add("entity_tracker.configuration.track_full_tracking.button", "Settings for tracking entities"); - add("entity_tracker.configuration.track_full_tracking.tooltip", "List of entity types with cursor types, separated with \"|\""); - } -} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/EntityTracker.java b/src/main/java/nowebsite/makertechno/the_trackers/TheTrackers.java similarity index 62% rename from src/main/java/nowebsite/makertechno/entity_tracker/EntityTracker.java rename to src/main/java/nowebsite/makertechno/the_trackers/TheTrackers.java index 90c6f1f..3676623 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/EntityTracker.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/TheTrackers.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker; +package nowebsite.makertechno.the_trackers; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; @@ -7,20 +7,21 @@ import net.neoforged.fml.config.ModConfig; import net.neoforged.neoforge.client.gui.ConfigurationScreen; import net.neoforged.neoforge.client.gui.IConfigScreenFactory; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import nowebsite.makertechno.entity_tracker.data.datagen.ModDataGenerators; +import nowebsite.makertechno.the_trackers.core.config.TConfig; +import nowebsite.makertechno.the_trackers.data.datagen.ModDataGenerators; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Mod(value = EntityTracker.MOD_ID, dist = Dist.CLIENT) -public class EntityTracker { - public static final String MOD_ID = "entity_tracker"; - public static final Logger LOGGER = LoggerFactory.getLogger("TrackerLogic"); +@Mod(value = TheTrackers.MOD_ID, dist = Dist.CLIENT) +public class TheTrackers { + public static final String MOD_ID = "the_trackers"; + public static final Logger LOGGER = LoggerFactory.getLogger("TheTrackers"); - public EntityTracker(@NotNull IEventBus modEventBus, @NotNull ModContainer modContainer) { + public TheTrackers(@NotNull IEventBus modEventBus, @NotNull ModContainer modContainer) { modContainer.registerConfig(ModConfig.Type.CLIENT, TConfig.SPEC); modContainer.registerExtensionPoint(IConfigScreenFactory.class, ConfigurationScreen::new); modEventBus.addListener(ModDataGenerators::gatherData); } + } 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 new file mode 100644 index 0000000..400def7 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/component/ComponentBuilder.java @@ -0,0 +1,234 @@ +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 nowebsite.makertechno.the_trackers.client.gui.provider.TextureCache; +import nowebsite.makertechno.the_trackers.core.tool.TextureBuildTool; + +import javax.annotation.Nullable; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * 追踪指针构造器,构造并返回一个{@link BuilderResult}供后续注册指针使用。 + */ +@SuppressWarnings("unused") +public class ComponentBuilder { + private ComponentType type = ComponentType.DIRECT; + private String cursorPattern = null; + private Supplier icon1 = () -> Icon.NONE; + private String component1Pattern = null; + private Supplier icon2 = () -> Icon.NONE; + private String component2Pattern = null; + 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; + + + public ComponentBuilder() {} + + /** + * 设置指针类型,默认为三维投影型。 + */ + public ComponentBuilder setComponentType(ComponentType type) { + this.type = type; + return this; + } + + /** + * 设置指针数据。 + */ + public ComponentBuilder setCursorPattern(String pattern) { + this.cursorPattern = pattern; + return this; + } + + /** + *

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

+ *

传入的索引应为图标索引。图标默认为空。

+ */ + public ComponentBuilder setIcon1(ResourceLocation location) { + icon1 = () -> getIcon(location); + return this; + } + + /** + *

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

+ *

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

+ */ + public ComponentBuilder setIcon1(Item item) { + icon1 = () -> getIcon(TextureMapping.getItemTexture(item).withPrefix("textures/")); + return this; + } + + /** + *

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

+ *

传入的值应为内部实体D。图标默认为空

+ */ + public ComponentBuilder setIcon1(String key) { + icon1 = () -> TextureCache.getIcon(key); + return this; + } + + /** + * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link IconComponentFactory} + */ + public ComponentBuilder setIcon1Pattern(String pattern) { + this.component1Pattern = pattern; + return this; + } + + + /** + *

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

+ *

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

+ */ + public ComponentBuilder setIcon2(Item item) { + icon2 = () -> getIcon(TextureMapping.getItemTexture(item).withPrefix("textures/")); + return this; + } + + /** + *

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

+ *

传入的值应为内部实体贴图ID。图标默认为空

+ */ + public ComponentBuilder setIcon2(String key) { + icon2 = () -> TextureCache.getIcon(key); + return this; + } + + /** + * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link IconComponentFactory} + */ + public ComponentBuilder setIcon2Pattern(String pattern) { + this.component2Pattern = pattern; + return this; + } + + + /** + *

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

+ *

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

+ */ + public ComponentBuilder setIcon3(Item item) { + icon3 = () -> getIcon(TextureMapping.getItemTexture(item).withPrefix("textures/")); + return this; + } + + /** + *

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

+ *

传入的值应为内部实体贴图ID。图标默认为空

+ */ + public ComponentBuilder setIcon3(String key) { + icon3 = () -> TextureCache.getIcon(key); + return this; + } + + /** + * 设置图标1的容器。默认为null(获取时使用default),设置请参见{@link IconComponentFactory} + */ + public ComponentBuilder setIcon3Pattern(String pattern) { + this.component3Pattern = pattern; + return this; + } + + /** + * 设置是否启用插值帧移动。 + */ + public ComponentBuilder setSmoothMove(boolean smoothMove) { + isSmoothMove = smoothMove; + return this; + } + + /** + * 设置是否受到用户设置大小的影响。 + */ + public ComponentBuilder setAffectedByPlayerSettingsScale(boolean affectedByPlayerSettingsScale) { + this.affectedByPlayerSettingsScale = affectedByPlayerSettingsScale; + return this; + } + + /** + * 设置是否自动管理生命周期。仅对实体类指针生效,当实体不再扫描到时清理指针。 + */ + public ComponentBuilder setAutoLifecycle(boolean autoLifecycle) { + this.autoLifecycle = autoLifecycle; + return this; + } + + /** + * 设置乘数再运算器,一般建议在这里对最终大小进行区间移动和缩放。 + * */ + public ComponentBuilder defineScaleMultiple(Function definedScaleMultipleApplier) { + this.definedScaleMultiple = definedScaleMultipleApplier; + return this; + } + + public BuilderResult build() { + return new BuilderResult( + type, + icon1, + component1Pattern, + icon2, + component2Pattern, + icon3, + component3Pattern, + cursorPattern, + isSmoothMove, + autoLifecycle, + affectedByPlayerSettingsScale, + definedScaleMultiple + ); + } + + private static Icon getIcon(ResourceLocation location) { + return TextureBuildTool.initIcon("dynamic", location.withSuffix(".png"), Icon::new).orElse(Icon.NONE); + } + + 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 boolean isSmoothMove, autoLifecycle, affectedBySettings; + public final Function multiple; + private BuilderResult( + ComponentType type, + Supplier icon1, + @Nullable String component1Pattern, + Supplier icon2, + @Nullable String component2Pattern, + Supplier icon3, + @Nullable String component3Pattern, + @Nullable String cursorPattern, + boolean isSmoothMove, + boolean autoLifecycle, + boolean affectedBySettings, + Function multiple + ) { + this.type = type; + this.icon1 = icon1; + this.component1Pattern = component1Pattern; + this.icon2 = icon2; + this.component2Pattern = component2Pattern; + this.icon3 = icon3; + this.component3Pattern = component3Pattern; + this.cursorPattern = cursorPattern; + this.isSmoothMove = isSmoothMove; + this.autoLifecycle = autoLifecycle; + this.affectedBySettings = affectedBySettings; + this.multiple = multiple; + } + } + + public enum ComponentType { + RELATIVE, + DIRECT, + HEAD_TAG + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/api/component/SimpleComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/api/component/SimpleComponent.java new file mode 100644 index 0000000..4390b3b --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/component/SimpleComponent.java @@ -0,0 +1,12 @@ +package nowebsite.makertechno.the_trackers.api.component; + +import net.minecraft.world.phys.Vec3; + +@SuppressWarnings("unused") +public interface SimpleComponent { + void setVisible(boolean visible); + boolean isVisible(); + void close(); + boolean isClosed(); + Vec3 getPos(); +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/api/component/StaticComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/api/component/StaticComponent.java new file mode 100644 index 0000000..555d03a --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/component/StaticComponent.java @@ -0,0 +1,18 @@ +package nowebsite.makertechno.the_trackers.api.component; + +import net.minecraft.world.phys.Vec3; + +import java.util.function.Function; + +@SuppressWarnings("unused") +public interface StaticComponent extends SimpleComponent { + Function ZERO = vec3 -> Vec3.ZERO; + Function NORTH = vec3 -> vec3.add(100, 0, 0); + Function EAST = vec3 -> vec3.add(0, 0, 100); + Function SOUTH = vec3 -> vec3.add(-100, 0, 0); + Function WEST = vec3 -> vec3.add(0, 0, -100); + /** + * 传入: 玩家位置。传出: 渲染目标的位置。本接口提供了诸如{@link #NORTH}的便捷实现供选择,你也可以自己写。 + */ + void posUpdater(Function applier); +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/api/component/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/api/component/package-info.java new file mode 100644 index 0000000..9d3f874 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/component/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.api.component; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file 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 new file mode 100644 index 0000000..b30b9b1 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/api/examples/TestAdd1.java @@ -0,0 +1,53 @@ +package nowebsite.makertechno.the_trackers.api.examples; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.DeathScreen; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Items; +import net.minecraft.world.phys.Vec3; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.client.event.ScreenEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import nowebsite.makertechno.the_trackers.TheTrackers; +import nowebsite.makertechno.the_trackers.api.component.ComponentBuilder; +import nowebsite.makertechno.the_trackers.api.component.StaticComponent; +import nowebsite.makertechno.the_trackers.core.track.TrackersMonitor; +import nowebsite.makertechno.the_trackers.core.track.WorldSingletonTracker; + +//@EventBusSubscriber(Dist.CLIENT) +/** An example adding death point tag to world. */ +public class TestAdd1 { + private static final ComponentBuilder.BuilderResult posTo0 = new ComponentBuilder() + .setComponentType(ComponentBuilder.ComponentType.DIRECT) + .setIcon1(Items.DIAMOND) + .setIcon1Pattern("rainbow:2") + .defineScaleMultiple(scale -> (float) (1F + Math.min(scale / 2.2, 1f) * Math.min(scale / 2.2, 1f))) + .setSmoothMove(true) + .build(); + + private static Vec3 pos; + + @SubscribeEvent + public static void onScreenOpen(ScreenEvent.Opening event) { + if (event.getScreen() instanceof DeathScreen) { + Player player = Minecraft.getInstance().player; + if (player != null) { + pos = player.position(); + } + } + } + @SubscribeEvent + public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { + if (!event.isEndConquered() && pos != null) { + WorldSingletonTracker tracker = TrackersMonitor.getTracker(); + if (tracker != null) { + StaticComponent component = tracker.addStaticPosComponent(TheTrackers.MOD_ID, "death point", posTo0, true); + component.posUpdater(vec3 -> { + if (vec3.distanceTo(pos) < 5) component.close(); + return pos; + }); + } + } + + } +} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/RendererToScreen.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/RendererToScreen.java similarity index 100% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/RendererToScreen.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/RendererToScreen.java diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/TGui.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/TGui.java similarity index 55% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/TGui.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/TGui.java index cff5350..444409d 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/TGui.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/TGui.java @@ -1,18 +1,20 @@ -package nowebsite.makertechno.entity_tracker.client.gui; +package nowebsite.makertechno.the_trackers.client.gui; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.LayeredDraw; import net.minecraft.world.entity.player.Player; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; -import nowebsite.makertechno.entity_tracker.core.track.TrackerLogic; +import nowebsite.makertechno.the_trackers.core.config.TConfig; +import nowebsite.makertechno.the_trackers.core.track.EntityTracker; +import nowebsite.makertechno.the_trackers.core.track.WorldSingletonTracker; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; public class TGui implements LayeredDraw.Layer { private final Minecraft minecraft; + private static @Nullable WorldSingletonTracker tracker = null; public TGui(Minecraft minecraft) { this.minecraft = minecraft; @@ -25,7 +27,12 @@ public static Player getCameraPlayer(@NotNull Minecraft minecraft) { public void render(@NotNull GuiGraphics guiGraphics, @NotNull DeltaTracker deltaTracker) { Player player = getCameraPlayer(this.minecraft); if (!minecraft.options.hideGui && player != null && TConfig.available){ - TrackerLogic.getRENDERING().forEach((uuid, state) -> state.renderComponent(guiGraphics, deltaTracker.getGameTimeDeltaTicks(), player)); + EntityTracker.getRENDERING().forEach((uuid, state) -> state.renderComponent(guiGraphics, deltaTracker.getGameTimeDeltaTicks(), player)); + if (tracker != null) tracker.render(guiGraphics, deltaTracker.getGameTimeDeltaTicks(), player); } } + + public static synchronized void setExtendTracker(@Nullable WorldSingletonTracker tracker) { + TGui.tracker = tracker; + } } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/TGuiStatics.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/TGuiStatics.java new file mode 100644 index 0000000..34552ab --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/TGuiStatics.java @@ -0,0 +1,8 @@ +package nowebsite.makertechno.the_trackers.client.gui; + +import net.minecraft.resources.ResourceLocation; +import nowebsite.makertechno.the_trackers.TheTrackers; + +public class TGuiStatics { + public static final ResourceLocation POINTER = ResourceLocation.fromNamespaceAndPath(TheTrackers.MOD_ID, "pointer"); +} 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/components/TAbstractCursor.java new file mode 100644 index 0000000..f533dfd --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TAbstractCursor.java @@ -0,0 +1,76 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; +import nowebsite.makertechno.the_trackers.core.config.TConfig; + +import java.util.function.Function; + +public abstract class TAbstractCursor implements TRenderComponent{ + + protected float scaleCached; + protected boolean smoothMove = true; + protected boolean affectedByPlayerScale = true; + protected Function multiple = scale -> scale ; + + protected TAbstractCursor() { + this.scaleCached = (float) TConfig.scale; + } + + public void setSmoothMove(boolean smoothMove) { + this.smoothMove = smoothMove; + } + + public void setAffectedByPlayerScale(boolean affectedByPlayerScale) { + this.affectedByPlayerScale = affectedByPlayerScale; + } + + public void setMultiple(Function multiple) { + this.multiple = multiple; + } + + @Override + public void flush() { + this.scaleCached = (float) TConfig.scale; + } + + @Override + public void render(GuiGraphics graphics, Player player, Vec3 target, float partialTick) { + + float[] projScrPoint = getProjectScr(graphics, player, target); + + float scale = multiple.apply(calculateScale(projScrPoint)); + + updateTransformer(projScrPoint, partialTick, scale); + RenderSystemInit(getAlpha(projScrPoint)); + renderInsights(graphics, projScrPoint, partialTick, scale); + RenderSystemRestore(); + } + protected abstract float[] getProjectScr(GuiGraphics graphics, Player player, Vec3 target); + protected float calculateScale(float[] projScrPoint) { + return affectedByPlayerScale ? scaleCached : 1; + } + protected abstract void updateTransformer(float[] projScrPoint, float partialTick, float scale); + protected abstract float getAlpha(float[] projScrPoint); + protected abstract void renderInsights(GuiGraphics graphics, float[] projScrPoint, float partialTick, float scale); + + protected static void RenderSystemInit(float alpha) { + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate( + GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, + GlStateManager.SourceFactor.ONE, + GlStateManager.DestFactor.ZERO + ); + } + + protected static void RenderSystemRestore() { + 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/TDir3BodyCursor.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDir3BodyCursor.java new file mode 100644 index 0000000..201374a --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDir3BodyCursor.java @@ -0,0 +1,120 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +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 org.joml.Matrix4fStack; + +/** + * 三维投影指针变体,指针位于目标外侧环绕目标。 + */ +public class TDir3BodyCursor extends TDirectProjCursor { + + /** + * 平滑器。不建议不同渲染逻辑的类共用 + */ + protected static class B3Transformer extends Transformer { + protected float rot; + protected B3Transformer(float x, float y, float rot) { + super(x, y); + this.rot = rot; + } + protected void setRot(float rot) { + this.rot = rot; + } + protected void makeSmooth(float x, float y, float rot, float partialTick) { + super.makeSmooth(x, y, partialTick); + this.rot = Mth.lerp(partialTick, this.rot, rot); + } + } + + protected final IconComponent component2, component3; + + protected boolean shouldFaceCenter = false; + + private final B3Transformer b3Transformer = new B3Transformer(0,0,0); + + + public TDir3BodyCursor(IconComponent component1, IconComponent component2, IconComponent component3) { + super(component1); + this.component2 = component2; + this.component3 = component3; + } + + public void setFaceCenter(boolean shouldFaceCenter) { + this.shouldFaceCenter = shouldFaceCenter; + } + + @Override + public void flush() { + super.flush(); + this.component2.flush(); + this.component3.flush(); + } + + @Override + protected void updateTransformer(float[] projScrPoint, float partialTick, float scale) { + float dx = projScrPoint[0] - b3Transformer.x; + float dy = projScrPoint[1] - b3Transformer.y; + float distance = (float) Math.sqrt(dx * dx + dy * dy); + float signedDelta = distance * 0.008F * Math.signum(dx); + float rot = b3Transformer.rot + signedDelta; + if (smoothMove) b3Transformer.makeSmooth(projScrPoint[0], projScrPoint[1], rot, partialTick); + else { + b3Transformer.set(projScrPoint[0], projScrPoint[1]); + b3Transformer.setRot(rot); + } + } + + @Override + protected void translateAndRenderComponents( + GuiGraphics graphics, + IconComponent component, + Matrix4fStack stack, + float partialTick, + float scale + ) { + + for (int i = 0; i < 3; i++) { + stack.pushMatrix(); + + renderComponent(graphics, component, stack, partialTick, scale, i); + + stack.popMatrix(); + } + + RenderSystem.resetTextureMatrix(); + } + + + private void renderComponent(GuiGraphics graphics, IconComponent component, Matrix4fStack stack, float partialTick, float scale, int index) { + float radius = (float) component.getIcon().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; + float theta = shouldFaceCenter ? (float) Math.atan2(b3Transformer.y - py, b3Transformer.x - px) + Mth.HALF_PI : angle; + + 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(); + default -> 0; + } / 2f * scale, -(float) switch (index) { + case 0 -> component.getIcon().height(); + case 1 -> component2.getIcon().height(); + case 2 -> component3.getIcon().height(); + default -> 0; + } / 2f * scale, 0f); + stack.scale(scale); + + RenderSystem.applyModelViewMatrix(); + switch (index) { + case 0 -> component.render(graphics, partialTick); + case 1 -> component2.render(graphics, partialTick); + case 2 -> component3.render(graphics, partialTick); + } + } +} 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/components/TDirectProjCursor.java new file mode 100644 index 0000000..97ea543 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TDirectProjCursor.java @@ -0,0 +1,114 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.GameRenderer; +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.core.track.algorithm.CameraProjector; +import org.jetbrains.annotations.NotNull; +import org.joml.Matrix4fStack; + +/** + * 三维投影型指针,直接反应世界坐标投影。 + */ +public class TDirectProjCursor extends TAbstractCursor { + + /** + * 平滑器。不建议不同渲染逻辑的类共用 + */ + protected static class Transformer { + protected float x, y; + + protected Transformer(float x, float y) { + this.x = x; + this.y = y; + } + + protected void set(float x, float y) { + this.x = x; + this.y = y; + } + + protected void makeSmooth(float x, float y, float partialTick) { + this.x = Mth.lerp(partialTick, this.x, x); + this.y = Mth.lerp(partialTick, this.y, y); + } + } + + + protected static final GameRenderer RENDERER = Minecraft.getInstance().gameRenderer; + + protected final IconComponent component; + + private final Transformer transformer = new Transformer(0, 0); + + public TDirectProjCursor(IconComponent component) { + super(); + this.component = component; + } + + @Override + public void flush() { + super.flush(); + this.component.flush(); + } + + protected float @NotNull [] getProjectScr(GuiGraphics graphics, Player player, Vec3 target) { + return CameraProjector.projectToScreen( + RENDERER, + target, + player.getEyePosition(), + Minecraft.getInstance().gameRenderer.getMainCamera(), + graphics.guiWidth(), + graphics.guiHeight() + ); + } + + @Override + protected float calculateScale(float[] projScrPoint) { + return super.calculateScale(projScrPoint) / projScrPoint[3] * 15; + } + + protected void updateTransformer(float[] projScrPoint, float partialTick, float scale) { + if (smoothMove) transformer.makeSmooth(projScrPoint[0], projScrPoint[1], partialTick); + else transformer.set(projScrPoint[0], projScrPoint[1]); + } + + @Override + protected float getAlpha(float[] projScrPoint) { + return 1; + } + + protected void renderInsights(GuiGraphics graphics, float[] projScrPoint, float partialTick, float scale) { + Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack(); + matrix4fStack.pushMatrix(); + translateAndRenderComponents(graphics, component, matrix4fStack, partialTick, scale); + matrix4fStack.popMatrix(); + RenderSystem.applyModelViewMatrix(); + } + + protected void translateAndRenderComponents( + GuiGraphics graphics, + IconComponent component, + Matrix4fStack stack, + float partialTick, + float scale + ) { + stack.translate( + -(float) component.getIcon().width() * scale / 2, + -(float) component.getIcon().height() * scale / 2, + 0 + ); + stack.translate(transformer.x , transformer.y, 0); + stack.scale(scale, scale, 1); + RenderSystem.applyModelViewMatrix(); + + component.render(graphics, partialTick); + + RenderSystem.resetTextureMatrix(); + } +} 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/components/TRelativeCursor.java new file mode 100644 index 0000000..e52e5ad --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRelativeCursor.java @@ -0,0 +1,150 @@ +package nowebsite.makertechno.the_trackers.client.gui.components; + +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.core.config.TConfig; +import nowebsite.makertechno.the_trackers.core.track.algorithm.RelativeProjector; +import org.joml.Matrix4fStack; + +public class TRelativeCursor extends TAbstractCursor { + + protected static class Transformer { + float radius; + float dist; + + private Transformer(float radius, float dist) { + this.radius = radius; + this.dist = dist; + } + + public void set(float radius, float dist) { + this.radius = radius; + this.dist = dist; + } + + public void makeSmooth(float radius, float dist, float partialTick) { + if(Mth.abs(this.radius - radius) < Mth.PI * 1.5) this.radius = Mth.lerp(partialTick, this.radius, radius); + else this.radius = radius; + this.dist = Mth.lerp(partialTick, this.dist, dist); + } + } + + + private final IconComponent pointerIconComponent, entityIconComponent; + private final Transformer transformer = new Transformer(0, 0); + private float pickDirect = 0; + + public TRelativeCursor(IconComponent pointerIconComponent, IconComponent entityIconComponent) { + super(); + this.pointerIconComponent = pointerIconComponent; + this.entityIconComponent = entityIconComponent; + } + + @Override + public void flush() { + super.flush(); + pointerIconComponent.flush(); + entityIconComponent.flush(); + } + + @Override + protected float[] getProjectScr(GuiGraphics graphics, Player player, Vec3 target) { + return RelativeProjector.calculateAngle( + player.getEyePosition(), + player.getViewVector(1f), + target, + TConfig.projectAlgorithm::project + ); + } + + @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(); + // 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); + float dist = -(pickDirect - pointer.height() - (int) Math.ceil(Math.sqrt(2 * icon.height()) + 2)) * scale; + + if (smoothMove) transformer.makeSmooth(radius, dist, partialTick); + else transformer.set(radius, dist); + } + + @Override + protected float getAlpha(float[] projScrPoint) { + Icon pointer = pointerIconComponent.getIcon(); + Icon icon = entityIconComponent.getIcon(); + return Math.min(1, Math.max(0, (pickDirect - 25) / (pointer.height() + icon.height()))); + } + + @Override + protected void renderInsights(GuiGraphics graphics, float[] projScrPoint, float partialTick, float scale) { + Matrix4fStack stack = RenderSystem.getModelViewStack(); + stack.pushMatrix(); + translateAndRenderComponents(graphics, projScrPoint, pointerIconComponent, entityIconComponent, stack, partialTick, scale); + stack.popMatrix(); + RenderSystem.applyModelViewMatrix(); + } + + protected void translateAndRenderComponents( + GuiGraphics graphics, + float[] projScrPoint, + IconComponent pointerComponent, + IconComponent entityComponent, + Matrix4fStack stack, + float partialTick, + float scale + ) { + float radius = (float) (-projScrPoint[0] - Math.PI/2); + Icon pointer = pointerComponent.getIcon(); + Icon icon = entityComponent.getIcon(); + + 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; + + stack.translate((float) graphics.guiWidth() / 2, (float) graphics.guiHeight() / 2, 0); + + stack.rotateZ(transformer.radius); + stack.pushMatrix(); // 2 + { + stack.translate(pw, ph, 0); + stack.translate(0, -this.pickDirect* scale, 0); + stack.scale(scale, scale, 1); + RenderSystem.applyModelViewMatrix(); + + /* go on */ + pointerIconComponent.render(graphics, partialTick); + /* end of pointer rend */ + + if (icon != Icon.NONE) { + // roll back + stack.popMatrix(); // 1 + stack.pushMatrix(); // 2 + stack.translate(-ew, -eh, 0); + + // Maximum the distance as diagonal distance and round up. + stack.translate(0, transformer.dist, 0); + + stack.translate(ew, eh, 0); + stack.rotateZ(-radius); // A funny delayed rot for icon + stack.translate(-ew, -eh, 0); + + stack.scale(scale, scale, 1); + RenderSystem.applyModelViewMatrix(); + + /* go on */ + entityIconComponent.render(graphics, partialTick); + /* end of icon rend */ + RenderSystem.resetTextureMatrix(); + } + } + stack.popMatrix(); // 1 + } + +} \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TRenderComponent.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRenderComponent.java similarity index 51% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TRenderComponent.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRenderComponent.java index fe8ab52..bf50b2d 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TRenderComponent.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/TRenderComponent.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components; +package nowebsite.makertechno.the_trackers.client.gui.components; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.world.entity.player.Player; @@ -6,9 +6,14 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; +import java.util.function.Function; + public interface TRenderComponent { + void setSmoothMove(boolean smoothMove); + void setAffectedByPlayerScale(boolean affectedByPlayerScale); + void setMultiple(Function multiple); void flush(); - void render(GuiGraphics graphics, float partialTick, Player player, Vec3 target); + void render(GuiGraphics graphics, Player player, Vec3 target, float partialTick); @Contract(pure = true) static @Nullable TRenderComponent ofNull() { return null; 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 new file mode 100644 index 0000000..84a2d63 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/components/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.client.gui.components; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/BlinkTagPointer.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/BlinkIconComponent.java similarity index 80% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/BlinkTagPointer.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/BlinkIconComponent.java index 81d739c..c7dc8d3 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/BlinkTagPointer.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/BlinkIconComponent.java @@ -1,16 +1,15 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer; +package nowebsite.makertechno.the_trackers.client.gui.icons; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; -import nowebsite.makertechno.entity_tracker.client.render.texture.TIcon; import org.jetbrains.annotations.NotNull; -public class BlinkTagPointer extends TagPointerIconComponent{ +public class BlinkIconComponent extends IconComponent { private final int intervalBlink; private int intervalCount; private float alpha; private boolean reverse; - public BlinkTagPointer(TIcon icon, int intervalBlink) { + public BlinkIconComponent(Icon icon, int intervalBlink) { super(icon); this.intervalBlink = intervalBlink; this.intervalCount = 0; 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 new file mode 100644 index 0000000..e467f22 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/Icon.java @@ -0,0 +1,9 @@ +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 new file mode 100644 index 0000000..0ea41e0 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponent.java @@ -0,0 +1,28 @@ +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/entity_tracker/client/gui/components/base/tagpointer/TagPointerFactory.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponentFactory.java similarity index 51% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/TagPointerFactory.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponentFactory.java index a3384f0..39be83f 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/TagPointerFactory.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/IconComponentFactory.java @@ -1,41 +1,48 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer; +package nowebsite.makertechno.the_trackers.client.gui.icons; -import nowebsite.makertechno.entity_tracker.client.render.texture.TIcon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.function.Supplier; -public class TagPointerFactory { +public class IconComponentFactory { + + @Contract(value = "_ -> new", pure = true) + public static @NotNull Supplier getDefault(Icon icon) { + return () -> new IconComponent(icon); + } + + /** + * 传入语句: "(blink/rainbow):(specific pattern)" + */ @Contract(value = "_, _ -> new", pure = true) - public static @NotNull Supplier getPointerComponent(TIcon icon, @NotNull String pattern) { + public static @NotNull Supplier getIconComponent(Icon icon, @NotNull String pattern) { String [] patterns = pattern.split(":"); try { int countNum; if (patterns[0].equals("blink")) { countNum = Integer.parseInt(patterns[1]); - if (BlinkTagPointer.isValidPatterns(countNum)) return () -> new BlinkTagPointer(icon, countNum); + if (BlinkIconComponent.isValidPatterns(countNum)) return () -> new BlinkIconComponent(icon, countNum); } else if (patterns[0].equals("rainbow")) { countNum = Integer.parseInt(patterns[1]); - if (RainbowTagPointer.isValidPatterns(countNum)) return () -> new RainbowTagPointer(icon, countNum); + if (RainbowIconComponent.isValidPatterns(countNum)) return () -> new RainbowIconComponent(icon, countNum); } } catch (NumberFormatException ignored) {} - return () -> new TagPointerIconComponent(icon); - } - @Contract(value = "_ -> new", pure = true) - public static @NotNull Supplier getDefault(TIcon icon) { - return () -> new TagPointerIconComponent(icon); + return getDefault(icon); } + /** + * 传入语句: "(blink/rainbow):(specific pattern)" + */ public static boolean hasElementPattern(@NotNull String pattern) { String [] patterns = pattern.split(":"); if (patterns.length != 2) return false; try { if (patterns[0].equals("blink")) { - if (BlinkTagPointer.isValidPatterns(Integer.parseInt(patterns[1]))) return true; + if (BlinkIconComponent.isValidPatterns(Integer.parseInt(patterns[1]))) return true; } else if (patterns[0].equals("rainbow")) { - if (RainbowTagPointer.isValidPatterns(Integer.parseInt(patterns[1]))) return true; + if (RainbowIconComponent.isValidPatterns(Integer.parseInt(patterns[1]))) return true; } } catch (NumberFormatException e) { return false; diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/RainbowTagPointer.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/RainbowIconComponent.java similarity index 78% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/RainbowTagPointer.java rename to src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/RainbowIconComponent.java index ecace95..1a6a302 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/base/tagpointer/RainbowTagPointer.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/RainbowIconComponent.java @@ -1,18 +1,17 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer; +package nowebsite.makertechno.the_trackers.client.gui.icons; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.GuiGraphics; -import nowebsite.makertechno.entity_tracker.client.render.texture.TIcon; import org.jetbrains.annotations.NotNull; import java.awt.*; -public class RainbowTagPointer extends TagPointerIconComponent{ +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 RainbowTagPointer(TIcon icon, int intervalColor) { + public RainbowIconComponent(Icon icon, int intervalColor) { super(icon); this.intervalColor = intervalColor; } 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 new file mode 100644 index 0000000..c68f731 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/icons/package-info.java @@ -0,0 +1,7 @@ +@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/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/package-info.java new file mode 100644 index 0000000..04c198f --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.client.gui; + +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 new file mode 100644 index 0000000..17488f4 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/BuilderResultComposer.java @@ -0,0 +1,67 @@ +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 org.jetbrains.annotations.Nullable; + +public final class BuilderResultComposer { + private BuilderResultComposer() {} + + public static TRenderComponent compose(ComponentBuilder.BuilderResult result) { + TRenderComponent 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); + return component; + } + + public static TRenderComponent composeRelativeComponent(ComponentBuilder.BuilderResult result) { + return new TRelativeCursor( + getIconComponent(result.component1Pattern, result.icon1.get()), + getIconComponent(result.component2Pattern, result.icon2.get()) + ); + } + + public static TRenderComponent 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()) + ); + } else { + cursor = new TDir3BodyCursor( + getIconComponent(result.component1Pattern, result.icon1.get()), + getIconComponent(result.component2Pattern, result.icon2.get()), + getIconComponent(result.component3Pattern, result.icon3.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.icon1.get())); + return cursor; + } + /*public static TRenderComponent composeHeadTagComponent(ComponentBuilder.BuilderResult result) { + return null; + }*/ + + + private static IconComponent getIconComponent(@Nullable String pattern, Icon icon) { + return pattern == null + ? IconComponentFactory.getDefault(icon).get() + : IconComponentFactory.getIconComponent(icon, 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 new file mode 100644 index 0000000..1fec934 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/TextureCache.java @@ -0,0 +1,62 @@ +package nowebsite.makertechno.the_trackers.client.gui.provider; + +import net.minecraft.resources.ResourceLocation; +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.core.tool.TextureBuildTool; +import org.jetbrains.annotations.Contract; + +import java.util.*; + +@OnlyIn(Dist.CLIENT) +public class TextureCache { + private static final Map ICON_CACHE = new HashMap<>(); + + static { + initIcons( + /* entity icons */ + "ender_dragon_head", + "wither_head", + "king_slime", + "eye_of_cthulhu", + "brain_of_cthulhu", + "queen_bee", + "eater_of_worlds", + "skeletron", + + + /* pointers */ + "normal_white", + "normal", + "normal_green", + "point_x" + ); + } + + public static Icon getIcon(String regName) { + return ICON_CACHE.computeIfAbsent(regName, key -> { + ResourceLocation location = getResourceFromModLocale(key); + return TextureBuildTool.initIcon(key, location, Icon::new).orElse(Icon.NONE); + }); + } + public static void initIcons(String ...strings) { + for (String key : strings) { + try { + ICON_CACHE.put(key, TextureBuildTool.initIcon(key, getResourceFromModLocale(key), Icon::new).orElseThrow()); + } catch (NoSuchElementException e) { + warnUnload(key); + } + } + } + + private static void warnUnload(String key) { + TheTrackers.LOGGER.warn("Failed to load image named {}, check if it was not in The Trackers' resource with a valid path or in invalid config file.", key); + } + + @Contract("_ -> new") + private static ResourceLocation getResourceFromModLocale(String name) { + return ResourceLocation.fromNamespaceAndPath(TheTrackers.MOD_ID, "textures/icons/"+name+".png"); + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/package-info.java new file mode 100644 index 0000000..14977e1 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/client/gui/provider/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.client.gui.provider; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/config/ConfigProcessor.java b/src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java similarity index 61% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/config/ConfigProcessor.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java index 09fa231..9b780f0 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/config/ConfigProcessor.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/config/ConfigProcessor.java @@ -1,17 +1,16 @@ -package nowebsite.makertechno.entity_tracker.core.config; +package nowebsite.makertechno.the_trackers.core.config; import com.mojang.datafixers.util.Pair; import net.minecraft.world.entity.EntityType; -import nowebsite.makertechno.entity_tracker.client.gui.components.TDir3BodyCursor; -import nowebsite.makertechno.entity_tracker.client.gui.components.TDirectTagCursor; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRelativeCursor; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRenderComponent; -import nowebsite.makertechno.entity_tracker.client.gui.components.base.entityicon.EntityIconFactory; -import nowebsite.makertechno.entity_tracker.client.gui.components.base.pointer.PointerFactory; -import nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer.TagPointerFactory; -import nowebsite.makertechno.entity_tracker.client.gui.components.base.tagpointer.TagPointerIconComponent; -import nowebsite.makertechno.entity_tracker.client.render.texture.*; -import nowebsite.makertechno.entity_tracker.core.event.TModClient; +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.provider.TextureCache; +import nowebsite.makertechno.the_trackers.core.event.TModClient; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -34,13 +33,13 @@ public static boolean isValidEntityBindCRCursor(Object o) { Optional> typeOpt = EntityType.byString(split[0]); if (typeOpt.isEmpty()) return false; - if (TModClient.isLoaded && !split[1].equals("none") && TextureCache.getPointer(split[1]).equals(PointerIcon.NONE)) return false; - if (TModClient.isLoaded && !split[2].equals("none") && TextureCache.getEntityIcon(split[2]).equals(EntityIcon.NONE)) return false; + if (TModClient.isLoaded && !split[1].equals("none") && TextureCache.getIcon(split[1]).equals(Icon.NONE)) return false; + if (TModClient.isLoaded && !split[2].equals("none") && TextureCache.getIcon(split[2]).equals(Icon.NONE)) return false; if (split.length == 4) { String[] patterns = split[3].split("&"); if (patterns.length != 2) return false; - return PointerFactory.hasElementPattern(patterns[0]) && EntityIconFactory.hasElementPattern(patterns[1]); + return IconComponentFactory.hasElementPattern(patterns[0]) && IconComponentFactory.hasElementPattern(patterns[1]); } return true; @@ -57,30 +56,30 @@ public static Set, Supplier>> col if (typeOpt.isEmpty()) return OF_EMPTY; EntityType entityType = typeOpt.get(); - PointerIcon pointerIcon = TextureCache.getPointer(split[1]); - if (!split[1].equals("none") && pointerIcon.equals(PointerIcon.NONE)) return OF_EMPTY; + Icon pointerIcon = TextureCache.getIcon(split[1]); + if (!split[1].equals("none") && pointerIcon.equals(Icon.NONE)) return OF_EMPTY; - EntityIcon entityIcon = TextureCache.getEntityIcon(split[2]); - if (!split[2].equals("none") && entityIcon.equals(EntityIcon.NONE)) return OF_EMPTY; + Icon icon = TextureCache.getIcon(split[2]); + if (!split[2].equals("none") && icon.equals(Icon.NONE)) return OF_EMPTY; Supplier supplier; if (split.length == 4) { String[] patterns = split[3].split("&"); if (patterns.length == 2 && - PointerFactory.hasElementPattern(patterns[0]) && - EntityIconFactory.hasElementPattern(patterns[1])) { + IconComponentFactory.hasElementPattern(patterns[0]) && + IconComponentFactory.hasElementPattern(patterns[1])) { supplier = () -> new TRelativeCursor( - PointerFactory.getPointerComponent(pointerIcon, patterns[0]), - EntityIconFactory.getEntityIconComponent(entityIcon, patterns[1]) + IconComponentFactory.getIconComponent(pointerIcon, patterns[0]).get(), + IconComponentFactory.getIconComponent(icon, patterns[1]).get() ); return new Pair, Supplier>(entityType, supplier); } } supplier = () -> new TRelativeCursor( - PointerFactory.getDefault(pointerIcon), - EntityIconFactory.getDefault(entityIcon) + IconComponentFactory.getDefault(pointerIcon).get(), + IconComponentFactory.getDefault(icon).get() ); return new Pair, Supplier>(entityType, supplier); }) @@ -103,13 +102,13 @@ public static boolean isValidCREntityBindDTCursor(Object o) { if (style.length != 2) return false; if (TModClient.isLoaded) { - if (!style[1].equals("none") && TextureCache.getPointer(style[1]).equals(PointerIcon.NONE)) - if (TextureCache.getEntityIcon(style[1]).equals(EntityIcon.NONE)) return false; + if (!style[1].equals("none") && TextureCache.getIcon(style[1]).equals(Icon.NONE)) + if (TextureCache.getIcon(style[1]).equals(Icon.NONE)) return false; } if (!(style[0].equals("normal") || style[0].equals("3body"))) return false; - if (split.length == 3) return TagPointerFactory.hasElementPattern(split[2]); + if (split.length == 3) return IconComponentFactory.hasElementPattern(split[2]); return true; } @@ -127,20 +126,20 @@ public static Set, Supplier>> col String[] style = split[1].split(":"); if (style.length != 2) return OF_EMPTY; - TIcon icon = TextureCache.getTagPointer(style[1]); - if (!style[1].equals("none") && icon.equals(TagPointerIcon.NONE)) { - icon = TextureCache.getEntityIcon(style[1]); - if (icon.equals(EntityIcon.NONE)) return OF_EMPTY; + Icon icon = TextureCache.getIcon(style[1]); + if (!style[1].equals("none") && icon.equals(Icon.NONE)) { + icon = TextureCache.getIcon(style[1]); + if (icon.equals(Icon.NONE)) return OF_EMPTY; } - Supplier cps; - if (split.length == 3) cps = TagPointerFactory.getPointerComponent(icon, split[2]); - else cps = TagPointerFactory.getDefault(icon); + Supplier cps; + if (split.length == 3) cps = IconComponentFactory.getIconComponent(icon, split[2]); + else cps = IconComponentFactory.getDefault(icon); Supplier supplier; if (style[0].equals("3body")){ supplier = () -> new TDir3BodyCursor(cps.get(), cps.get(), cps.get()); } else if (style[0].equals("normal")){ - supplier = () -> new TDirectTagCursor(cps.get()); + supplier = () -> new TDirectProjCursor(cps.get()); } else return OF_EMPTY; return new Pair, Supplier>(entityType, supplier); diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/config/TConfig.java b/src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java similarity index 57% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/config/TConfig.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java index 38f825e..9443929 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/config/TConfig.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/config/TConfig.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.core.config; +package nowebsite.makertechno.the_trackers.core.config; import com.mojang.datafixers.util.Pair; import net.minecraft.world.entity.EntityType; @@ -6,106 +6,106 @@ import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.config.ModConfigEvent; import net.neoforged.neoforge.common.ModConfigSpec; -import nowebsite.makertechno.entity_tracker.EntityTracker; -import nowebsite.makertechno.entity_tracker.client.gui.components.TRenderComponent; -import nowebsite.makertechno.entity_tracker.core.event.TModClient; -import nowebsite.makertechno.entity_tracker.core.track.TrackerLogic; -import nowebsite.makertechno.entity_tracker.core.track.algorithm.ProjectAlgorithmLib; +import nowebsite.makertechno.the_trackers.TheTrackers; +import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; +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; import java.util.List; import java.util.Set; import java.util.function.Supplier; -@EventBusSubscriber(modid = EntityTracker.MOD_ID) +@EventBusSubscriber(modid = TheTrackers.MOD_ID) public class TConfig { private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); /* Basic settings. */ private static final ModConfigSpec.BooleanValue AVAILABLE = BUILDER .comment("Enable tracking pointer") - .translation("entity_tracker.configuration.available") + .translation("the_trackers.configuration.available") .define("Available", true); private static final ModConfigSpec.DoubleValue GUI_SCALE = BUILDER .comment("Scale of cursor") - .translation("entity_tracker.configuration.gui_scale") + .translation("the_trackers.configuration.gui_scale") .defineInRange("Scale",0.6, 0.01, 4); private static final ModConfigSpec.IntValue MAX_TRACK_QUANTITY = BUILDER .comment("Max tracking quantity") - .translation("entity_tracker.configuration.quantity") + .translation("the_trackers.configuration.quantity") .defineInRange("Max quantity",10, 1, 400); private static final ModConfigSpec.IntValue REFRESH_POS_INTERVAL = BUILDER .comment("Interval between world position refresh") - .translation("entity_tracker.configuration.interval") + .translation("the_trackers.configuration.interval") .defineInRange("Interval", 1, 1, 160); /* HUD mode control. */ private static final ModConfigSpec.BooleanValue CENTER_RELATIVE_AVAILABLE = BUILDER .comment("Enable center relative icon display") - .translation("entity_tracker.configuration.center_relative_available") + .translation("the_trackers.configuration.center_relative_available") .define("Center relative available", true); // Specific setting for center relative mode. public static final ModConfigSpec.EnumValue PROJECT_ALGORITHM = BUILDER .comment("The algorithm of center rela projection") - .translation("entity_tracker.configuration.project_algorithm") + .translation("the_trackers.configuration.project_algorithm") .defineEnum("Project algorithm", ProjectAlgorithmLib.Type.AITOFF); private static final ModConfigSpec.BooleanValue TRACK_FULL_AVAILABLE = BUILDER .comment("Enable full track icon display") - .translation("entity_tracker.configuration.track_full_available") + .translation("the_trackers.configuration.track_full_available") .define("Track full available", false); private static final ModConfigSpec.BooleanValue HEAD_FLAT_AVAILABLE = BUILDER .comment("Enable longitude icon display") - .translation("entity_tracker.configuration.head_flat_available") - .define("Head flat available", true); + .translation("the_trackers.configuration.head_flat_available") + .define("Head flat available", false); public static final ModConfigSpec.ConfigValue> CENTER_RELATIVE_BIND = BUILDER .comment("List of entity types with cursors for center relative display, separated with \"|\"") - .translation("entity_tracker.configuration.center_relative_tracking") + .translation("the_trackers.configuration.center_relative_tracking") .defineList( "EntityType|PointerIconType|EntityIconType(|OptionalValue)", List.of( - "minecraft:ender_dragon|normal_red|ender_dragon_head", + "minecraft:ender_dragon|normal|ender_dragon_head", "minecraft:wither|normal_white|wither_head", - "terra_entity:king_slime|normal_red|king_slime", - "terra_entity:eye_of_cthulhu|normal_red|eye_of_cthulhu", - "terra_entity:brain_of_cthulhu|normal_red|brain_of_cthulhu", - "terra_entity:eater_of_worlds|normal_red|eater_of_worlds", - "terra_entity:queen_bee|normal_red|queen_bee", - "terra_entity:skeletron|normal_red|skeletron", - "terra_entity:hill_of_flesh|normal_red|wall_of_flesh", - "terra_entity:wall_of_flesh|normal_red|wall_of_flesh", + "terra_entity:king_slime|normal|king_slime", + "terra_entity:eye_of_cthulhu|normal|eye_of_cthulhu", + "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:skeletron|normal|skeletron", + "terra_entity:hill_of_flesh|normal|wall_of_flesh", + "terra_entity:wall_of_flesh|normal|wall_of_flesh", - "terra_entity:demon_eye|normal_red|none", - "terra_entity:flying_fish|normal_red|none", - "terra_entity:crimera|normal_red|none", - "terra_entity:eater_of_souls|normal_red|none", - "terra_entity:giant_worm|normal_red|none", - "terra_entity:tomb_crawler|normal_red|none", - "terra_entity:devourer|normal_red|none", - "terra_entity:cave_bat|normal_red|none", - "terra_entity:jungle_bat|normal_red|none", - "terra_entity:snatcher|normal_red|none", - "terra_entity:man_eater|normal_red|none", - "terra_entity:hornet|normal_red|none", - "terra_entity:hell_bat|normal_red|none", - "terra_entity:ice_bat|normal_red|none", - "terra_entity:spore_bat|normal_red|none", - "terra_entity:harpy|normal_red|none", - "terra_entity:cursed_skull|normal_red|none", - "terra_entity:dark_caster|normal_red|none", - "terra_entity:antlion_swarmer|normal_red|none", - "terra_entity:giant_antlion_swarmer|normal_red|none", - "terra_entity:wyvern|normal_red|none", - "terra_entity:granite_elemental|normal_red|none", - "terra_entity:ghost|normal_red|none", - "terra_entity:fire_imp|normal_red|none", - "terra_entity:demon|normal_red|none", - "terra_entity:voodoo_demon|normal_red|none", - "terra_entity:bone_serpent|normal_red|none", - "terra_entity:wither_bone_serpent|normal_red|none", - "terra_entity:meteor_head|normal_red|none" + "terra_entity:demon_eye|normal|none", + "terra_entity:flying_fish|normal|none", + "terra_entity:crimera|normal|none", + "terra_entity:eater_of_souls|normal|none", + "terra_entity:giant_worm|normal|none", + "terra_entity:tomb_crawler|normal|none", + "terra_entity:devourer|normal|none", + "terra_entity:cave_bat|normal|none", + "terra_entity:jungle_bat|normal|none", + "terra_entity:snatcher|normal|none", + "terra_entity:man_eater|normal|none", + "terra_entity:hornet|normal|none", + "terra_entity:hell_bat|normal|none", + "terra_entity:ice_bat|normal|none", + "terra_entity:spore_bat|normal|none", + "terra_entity:harpy|normal|none", + "terra_entity:cursed_skull|normal|none", + "terra_entity:dark_caster|normal|none", + "terra_entity:antlion_swarmer|normal|none", + "terra_entity:giant_antlion_swarmer|normal|none", + "terra_entity:wyvern|normal|none", + "terra_entity:granite_elemental|normal|none", + "terra_entity:ghost|normal|none", + "terra_entity:fire_imp|normal|none", + "terra_entity:demon|normal|none", + "terra_entity:voodoo_demon|normal|none", + "terra_entity:bone_serpent|normal|none", + "terra_entity:wither_bone_serpent|normal|none", + "terra_entity:meteor_head|normal|none" ), () -> "minecraft:player|normal_green|none", ConfigProcessor::isValidEntityBindCRCursor @@ -113,7 +113,7 @@ public class TConfig { public static final ModConfigSpec.ConfigValue> TRACK_FULL_BIND = BUILDER .comment("List of entity types with cursors for full track display, separated with \"|\"") - .translation("entity_tracker.configuration.track_full_tracking") + .translation("the_trackers.configuration.track_full_tracking") .defineList( "entityType|type:icon(|optionalPattern)", List.of( @@ -138,7 +138,7 @@ public class TConfig { @SubscribeEvent static void onLoad(final ModConfigEvent event) { available = AVAILABLE.get(); - scale = GUI_SCALE.get(); + scale = GUI_SCALE.get() * 0.6; interval = REFRESH_POS_INTERVAL.get(); maxTrackingQuantity = MAX_TRACK_QUANTITY.get(); centerRelativeAvailable = CENTER_RELATIVE_AVAILABLE.get(); @@ -148,12 +148,13 @@ static void onLoad(final ModConfigEvent event) { if(TModClient.isLoaded) { CRCursorWithEntities = ConfigProcessor.collectCREntityBindCursor(CENTER_RELATIVE_BIND.get()); DTCursorWithEntities = ConfigProcessor.collectDTEntityBindCursor(TRACK_FULL_BIND.get()); + EntityTracker.reCalcAllEntityGroups(); } - TrackerLogic.getRENDERING().forEach((uuid, trackerEntityState) -> trackerEntityState.getComponent().flush()); + EntityTracker.getRENDERING().forEach((uuid, trackerEntityState) -> trackerEntityState.getComponent().flush()); } @SubscribeEvent 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/config/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/core/config/package-info.java new file mode 100644 index 0000000..92177f3 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/config/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.core.config; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/event/TModClient.java b/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClient.java similarity index 58% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/event/TModClient.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClient.java index eb17c75..ecbd2d2 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/event/TModClient.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClient.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.core.event; +package nowebsite.makertechno.the_trackers.core.event; import net.minecraft.client.Minecraft; import net.neoforged.api.distmarker.Dist; @@ -7,14 +7,15 @@ import net.neoforged.fml.event.lifecycle.FMLLoadCompleteEvent; import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; import net.neoforged.neoforge.client.gui.VanillaGuiLayers; -import nowebsite.makertechno.entity_tracker.EntityTracker; -import nowebsite.makertechno.entity_tracker.client.gui.TGui; -import nowebsite.makertechno.entity_tracker.client.gui.TGuiStatics; -import nowebsite.makertechno.entity_tracker.core.config.ConfigProcessor; -import nowebsite.makertechno.entity_tracker.core.config.TConfig; +import nowebsite.makertechno.the_trackers.TheTrackers; +import nowebsite.makertechno.the_trackers.client.gui.TGui; +import nowebsite.makertechno.the_trackers.client.gui.TGuiStatics; +import nowebsite.makertechno.the_trackers.core.config.ConfigProcessor; +import nowebsite.makertechno.the_trackers.core.config.TConfig; +import nowebsite.makertechno.the_trackers.core.track.EntityTracker; import org.jetbrains.annotations.NotNull; -@EventBusSubscriber(modid = EntityTracker.MOD_ID, value = Dist.CLIENT) +@EventBusSubscriber(modid = TheTrackers.MOD_ID, value = Dist.CLIENT) public final class TModClient { public static boolean isLoaded = false; @SubscribeEvent @@ -22,9 +23,10 @@ public static void onLoadComplete(FMLLoadCompleteEvent event) { isLoaded = true; TConfig.CRCursorWithEntities = ConfigProcessor.collectCREntityBindCursor(TConfig.CENTER_RELATIVE_BIND.get()); TConfig.DTCursorWithEntities = ConfigProcessor.collectDTEntityBindCursor(TConfig.TRACK_FULL_BIND.get()); + EntityTracker.reCalcAllEntityGroups(); } @SubscribeEvent public static void regRenderer(@NotNull RegisterGuiLayersEvent event){ - event.registerBelow(VanillaGuiLayers.PLAYER_HEALTH, TGuiStatics.POINTER, new TGui(Minecraft.getInstance())); + event.registerBelow(VanillaGuiLayers.CAMERA_OVERLAYS, TGuiStatics.POINTER, new TGui(Minecraft.getInstance())); } } 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 new file mode 100644 index 0000000..b50a019 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/event/TModClientGame.java @@ -0,0 +1,23 @@ +package nowebsite.makertechno.the_trackers.core.event; + +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +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; + +@EventBusSubscriber(modid = TheTrackers.MOD_ID, value = Dist.CLIENT) +public class TModClientGame { + @SubscribeEvent + public static void onClientTick(ClientTickEvent.Pre event) { + if (TConfig.available) TrackersMonitor.trigger(); + } + + @SubscribeEvent + public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { + TrackersMonitor.quit(); + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/event/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/core/event/package-info.java new file mode 100644 index 0000000..2411e5c --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/event/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.core.event; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/tool/TextureBuildTool.java b/src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java similarity index 82% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/tool/TextureBuildTool.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java index 8519c39..8a71882 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/tool/TextureBuildTool.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/tool/TextureBuildTool.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.core.tool; +package nowebsite.makertechno.the_trackers.core.tool; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.TextureUtil; @@ -9,8 +9,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; -import nowebsite.makertechno.entity_tracker.EntityTracker; -import nowebsite.makertechno.entity_tracker.client.render.texture.TIcon; +import nowebsite.makertechno.the_trackers.TheTrackers; +import nowebsite.makertechno.the_trackers.client.gui.icons.Icon; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -20,7 +20,7 @@ public final class TextureBuildTool { private static final ResourceManager RESOURCE_MANAGER = Minecraft.getInstance().getResourceManager(); - public static Optional initTIcon(String name, ResourceLocation location, @NotNull Function4 element) { + public static Optional initIcon(String name, ResourceLocation location, @NotNull Function4 element) { try { Resource resource = RESOURCE_MANAGER.getResource(location).orElseThrow(); try (InputStream inputstream = resource.open()) { @@ -30,7 +30,7 @@ public static Optional initTIcon(String name, ResourceLocat } } catch (NoSuchElementException ignored) { } catch (IOException e) { - EntityTracker.LOGGER.warn("Failed to load texture: {}", location.getPath(), e); + TheTrackers.LOGGER.warn("Failed to load texture: {}", location.getPath(), e); } return Optional.empty(); } @@ -40,7 +40,7 @@ private static void pushCacheConf(ResourceLocation location, Resource resource, try { texturemetadatasection = resource.metadata().getSection(TextureMetadataSection.SERIALIZER).orElse(null); } catch (RuntimeException runtimeexception) { - EntityTracker.LOGGER.warn("Failed reading metadata of: {}", location, runtimeexception); + TheTrackers.LOGGER.warn("Failed reading metadata of: {}", location, runtimeexception); throw new IOException(runtimeexception); } boolean flag, flag1; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/tool/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/core/tool/package-info.java new file mode 100644 index 0000000..a8f8289 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/tool/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.core.tool; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file 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 new file mode 100644 index 0000000..99254b3 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/EntityTracker.java @@ -0,0 +1,123 @@ +package nowebsite.makertechno.the_trackers.core.track; + +import com.mojang.datafixers.util.Pair; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +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.core.config.TConfig; +import nowebsite.makertechno.the_trackers.core.track.states.TrackerStepState; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * 追踪实体的主逻辑类,刷新并标记追踪的实体,有缓存能力。 + */ +public class EntityTracker { + /** 缓存的渲染队列 */ + private static final Map RENDERING = new HashMap<>(); + /** 规则组 */ + private static final List, Supplier>> ALL_GROUPS = new ArrayList<>(); + /** 框选距离 */ + public static final AABB PICK_RANGE = new AABB( + - 64.0D, + - 48.0D, + - 64.0D, + + 64.0D, + + 64.0D, + + 64.0D + ); + + /** 获取缓存的指针对队列 */ + public static Map getRENDERING() { + return RENDERING; + } + + /** 主处理逻辑: 获取范围内所有实体,先提供给外部,后自己筛选,获取UUID并依此清除已缓存指针中的已消失实体,更新对应的缓存指针并尝试为新扫入的实体创建指针 */ + public static @Nullable Map process() { + Minecraft minecraft = Minecraft.getInstance(); + Player player = TGui.getCameraPlayer(minecraft); + if (minecraft.level == null || player == null) return null; + + Set allScanned = minecraft.level.getEntities(null, PICK_RANGE.move(player.position())).stream() + .filter(entity -> !(entity instanceof PartEntity)) + .collect(Collectors.toSet()); + + List nearestEntities = allScanned.stream() + .filter(EntityTracker::isTargetEntity) + .sorted(Comparator.comparingDouble(entity -> entity.distanceToSqr(player))) + .limit(TConfig.maxTrackingQuantity) + .toList(); // 最近N个实体 + // TODO: 加入优先级筛表 + + Set retained = nearestEntities.stream() + .map(Entity::getUUID) + .collect(Collectors.toSet()); // 所有扫到的实体的UUID + + RENDERING.keySet().removeIf(key -> !retained.contains(key)); // 移除不存在对应UUID的缓存指针 + + nearestEntities.stream() + .filter(entity -> !processExisting(entity)) // 刷新已缓存部分 + .forEach(EntityTracker::tryCreateNew); // 创建指针 + + return allScanned.stream().collect(Collectors.toMap(Entity::getUUID, entity -> entity)); + } + + /** + * 更新已存在的指针对。 + * @return 缓存中存在则返回true,缓存中不存在则返回false + */ + private static boolean processExisting(@NotNull Entity entity) { + TrackerStepState state = RENDERING.get(entity.getUUID()); + if (state != null) { + state.updatePos(entity.getRopeHoldPosition(0)); + return true; + } + return false; + } + + /** + * 判断实体种类并尝试为其创建对应种类的指针对。 + */ + private static void tryCreateNew(Entity entity) { + for (Pair, Supplier> pair : ALL_GROUPS) { + if (isTargetType(pair.getFirst(), entity)) { + TrackerStepState state = new TrackerStepState(pair.getSecond().get()); + state.updatePos(entity.getRopeHoldPosition(0)); + RENDERING.put(entity.getUUID(), state); + } + } + } + + /** + * 所有目标实体类型和指针类型的绑定。当配置变更时,需要重新计算该表 + */ + public static void reCalcAllEntityGroups() { + ALL_GROUPS.clear(); + if (TConfig.centerRelativeAvailable) ALL_GROUPS.addAll(TConfig.CRCursorWithEntities); + if (TConfig.trackFullAvailable) ALL_GROUPS.addAll(TConfig.DTCursorWithEntities); + //all.addAll(else); + } + + /** + * 判断是否为定位目标 + */ + private static boolean isTargetEntity(Entity entity) { + return ALL_GROUPS.stream().anyMatch(pair -> isTargetType(pair.getFirst(), 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/entity_tracker/core/track/StableTracker.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/StableTracker.java similarity index 100% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/track/StableTracker.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/track/StableTracker.java 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 new file mode 100644 index 0000000..671bf10 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/TrackersMonitor.java @@ -0,0 +1,38 @@ +package nowebsite.makertechno.the_trackers.core.track; + +import net.minecraft.world.entity.Entity; +import nowebsite.makertechno.the_trackers.client.gui.TGui; +import nowebsite.makertechno.the_trackers.core.config.TConfig; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.UUID; + +public class TrackersMonitor { + private static WorldSingletonTracker tracker; + /** 更新时间跳刻计数 */ + private static int count = 0; + /** 触发一次更新,注意这不代表触发一次计算,具体跳过时间刻由配置决定 */ + public static void trigger() { + if (tracker == null) { + tracker = WorldSingletonTracker.getInstance(); + TGui.setExtendTracker(tracker); + } + + if (++count >= TConfig.interval) { + count = 0; + Map cached = EntityTracker.process(); + + if (cached != null) tracker.trigger(cached); + } + } + public static void quit() { + TGui.setExtendTracker(null); + if (tracker != null) tracker.clean(); + tracker = null; + } + + public static @Nullable WorldSingletonTracker getTracker() { + return tracker; + } +} 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 new file mode 100644 index 0000000..b865f26 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/WorldSingletonTracker.java @@ -0,0 +1,187 @@ +package nowebsite.makertechno.the_trackers.core.track; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import nowebsite.makertechno.the_trackers.api.component.ComponentBuilder; +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.provider.BuilderResultComposer; +import nowebsite.makertechno.the_trackers.core.track.states.ControllableTrackerState; +import nowebsite.makertechno.the_trackers.core.track.states.ControllableTrackerStateEx; +import nowebsite.makertechno.the_trackers.core.track.states.TickLimitedTrackerState; +import nowebsite.makertechno.the_trackers.core.track.states.TrackerStepState; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.function.Function; + +@SuppressWarnings("unused") +public class WorldSingletonTracker { + private static WorldSingletonTracker INSTANCE = null; + + public static synchronized WorldSingletonTracker getInstance() { + if (INSTANCE == null) INSTANCE = new WorldSingletonTracker(); + return INSTANCE; + } + + public final Map> entityPointers = new HashMap<>(); + public final Map> staticPointers = new HashMap<>(); + public final Map questSortedEntityPointers = new HashMap<>(); + + + /** + * 通过预构内容添加一个UUID指针,指向世界中的实体。 + * 注意一个UUID只能注册一种对应指针。如果您希望对一个目标注册注册多个,请访问{@link #addDynamicMultiComponent(String, String, ComponentBuilder.BuilderResult[], UUID, boolean)} + * 或{@link #attendMultiComponent(String, String, ComponentBuilder.BuilderResult[], UUID)} + * @return 返回注册成功的指针。 + */ + public SimpleComponent addDynamicComponent(String modID, String identifyName, ComponentBuilder.BuilderResult result, UUID target, boolean isVisible) throws IllegalArgumentException { + synchronized (questSortedEntityPointers) { + if (questSortedEntityPointers.containsKey(target)) throw new IllegalArgumentException("UUID named " + target + " still on tracking!"); + ControllableTrackerState state = new ControllableTrackerState(identifyName, BuilderResultComposer.compose(result), isVisible, result.autoLifecycle); + entityPointers.computeIfAbsent(modID, s -> new ArrayList<>()).add(state); + questSortedEntityPointers.put(target, state); + return state; + } + } + + /** + * 通过预构内容添加一个计时的UUID指针,指向世界中的实体。 + * 注意一个UUID只能注册一种对应指针,切计时的指针无法转换成混合指针。 + * @return 返回注册成功的指针。 + */ + public SimpleComponent addDynamicTickLimitedComponent(String modID, String identifyName, ComponentBuilder.BuilderResult result, UUID target, int tickForTime, boolean isVisible) throws IllegalArgumentException { + synchronized (questSortedEntityPointers) { + if (questSortedEntityPointers.containsKey(target)) throw new IllegalArgumentException("UUID named " + target + " still on tracking!"); + ControllableTrackerState state = new TickLimitedTrackerState(identifyName, BuilderResultComposer.compose(result), tickForTime, isVisible); + entityPointers.computeIfAbsent(modID, s -> new ArrayList<>()).add(state); + questSortedEntityPointers.put(target, state); + return state; + } + } + + /** + * 通过预构内容添加一组UUID指针,指向世界中的实体。 + * 因为是一次性注册,同样不允许注册已在追踪的目标。如果真的需要,建议使用{@link #attendMultiComponent(String, String, ComponentBuilder.BuilderResult[], UUID)} + * @return 当对应UUID已存在占用指针时返回null,表示注册失败; 否则返回注册成功的指针。 + * @throws IllegalFormatException 已经存在对应的指针 + */ + 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]; + for (int i = 0; i < results.length; i++) { + components[i] = BuilderResultComposer.compose(results[i]); + } + ControllableTrackerStateEx state = new ControllableTrackerStateEx(identifyName, components, isVisible, results[0].autoLifecycle); + entityPointers.computeIfAbsent(modID, s -> new ArrayList<>()).add(state); + questSortedEntityPointers.put(target, state); + return state; + } + } + + /** + * 通过预构内容添加一组UUID指针,指向世界中的实体。 + * 警告: 该方法会立刻停止已持有的单模式指针,另外计时指针无法重组。 + * @return 返回注册成功的指针。 + */ + public SimpleComponent attendMultiComponent(String modID, String identifyName, ComponentBuilder.BuilderResult[] results, UUID target) throws IllegalArgumentException, UnsupportedOperationException { + @Nullable ControllableTrackerState trackerState = questSortedEntityPointers.get(target); + switch (trackerState) { + 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]; + for (int i = 0; i < results.length; i++) { + components[i] = BuilderResultComposer.compose(results[i]); + } + TrackerStepState[] newCP = Arrays.copyOf(ex.getStates(), ex.getStates().length + results.length); + for (int i = 0; i < results.length; i++) { + newCP[ex.getStates().length + i] = new TrackerStepState(components[i]); + } + ex.setStates(newCP); + return ex; + } + default -> {} + } + synchronized (questSortedEntityPointers) { + TRenderComponent[] components = new TRenderComponent[results.length + 1]; + for (int i = 0; i < results.length; i++) { + components[i] = BuilderResultComposer.compose(results[i]); + } + components[results.length] = trackerState.getState().getComponent(); + ControllableTrackerStateEx stateEx = new ControllableTrackerStateEx(identifyName, components, trackerState.isVisible(), results[0].autoLifecycle); + trackerState.close(); + entityPointers.computeIfAbsent(modID, s -> new ArrayList<>()).add(stateEx); + questSortedEntityPointers.put(target, stateEx); + return stateEx; + } + } + + /** + * 添加一个静态指针,可以通过{@link StaticComponent#posUpdater(Function)}定一个位置。 + */ + public StaticComponent addStaticPosComponent(String modID, String identifyName, ComponentBuilder.BuilderResult result, boolean isVisible) { + ControllableTrackerState state = new ControllableTrackerState(identifyName, BuilderResultComposer.compose(result), isVisible, result.autoLifecycle); + staticPointers.computeIfAbsent(modID, s -> new ArrayList<>()).add(state); + return state; + } + + /** + * 添加一个静态计时指针,可以通过{@link StaticComponent#posUpdater(Function)}定一个位置。 + */ + public StaticComponent addStaticPosTickLimitedComponent(String modID, String identifyName, ComponentBuilder.BuilderResult result, int tickForTime, boolean isVisible) { + ControllableTrackerState state = new TickLimitedTrackerState(identifyName, BuilderResultComposer.compose(result), tickForTime, isVisible); + staticPointers.computeIfAbsent(modID, s -> new ArrayList<>()).add(state); + return state; + } + + + public @Nullable List getEntityTrackingComponentFromModId(String modId) { + return entityPointers.get(modId); + } + + public @Nullable List getEntityTrackingComponentFromModId(String modId, String identifyName) { + List states = getEntityTrackingComponentFromModId(modId); + return states == null ? null : states.stream().filter(pointer -> pointer.getIdentifyName().equals(identifyName)).toList(); + } + + + public void trigger(Map cached) { + if (!entityPointers.isEmpty()) entityPointers.forEach((id, states) -> states.removeIf(ControllableTrackerState::isClosed)); + if (!questSortedEntityPointers.isEmpty()) { + questSortedEntityPointers.entrySet().removeIf(entry -> entry.getValue().isClosed()); + cached.forEach((uuid, entity) -> { + ControllableTrackerState state = questSortedEntityPointers.get(uuid); + if (state != null) state.setPosEntity(entity); + }); + questSortedEntityPointers.values().forEach(state -> { + if (!state.isAlive() && state.isAutoDelete()) state.close(); + }); + } + + if (!staticPointers.isEmpty()) { + staticPointers.forEach((id, states) -> states.removeIf(ControllableTrackerState::isClosed)); + + Player player = TGui.getCameraPlayer(Minecraft.getInstance()); + if (Minecraft.getInstance().level == null || player == null) return; + + staticPointers.forEach((s, states) -> states.forEach(state -> state.setPosEntity(player))); + } + } + + public void clean() { + entityPointers.clear(); + staticPointers.clear(); + questSortedEntityPointers.clear(); + INSTANCE = null; + } + public void render(GuiGraphics graphics, float partialTick, Player player) { + questSortedEntityPointers.values().forEach(state -> state.render(graphics, partialTick, player)); + staticPointers.values().forEach(states -> states.forEach(state -> state.render(graphics, partialTick, player))); + } +} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/CameraProjector.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/CameraProjector.java similarity index 76% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/CameraProjector.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/CameraProjector.java index 1d6cae4..af55998 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/CameraProjector.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/CameraProjector.java @@ -1,8 +1,7 @@ -package nowebsite.makertechno.entity_tracker.core.track.algorithm; +package nowebsite.makertechno.the_trackers.core.track.algorithm; import net.minecraft.client.Camera; import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -23,17 +22,22 @@ public class CameraProjector { Vector4f target4f = new Vector4f((float) targetPos.x, (float) targetPos.y, (float) targetPos.z, 1.0f) .mul(mat); - if (target4f.w <= 0.0f) { - target4f.y = windowHeight; - target4f.x = -target4f.x; - } - float x = (int) ((target4f.x() / target4f.z() * 0.5F + 0.5F) * windowWidth); - float y = (int) ((1.0F - (target4f.y() / target4f.z() * 0.5F + 0.5F)) * windowHeight); + float x = (int) ((target4f.x() / target4f.w() * 0.5F + 0.5F) * windowWidth); + float y = (int) ((1.0F - (target4f.y() / target4f.w() * 0.5F + 0.5F)) * windowHeight); float distanceToCenter = Vector2f.distance(x, y, (float) (windowWidth*0.5), (float) (windowHeight*0.5)); float distanceToTarget = Vector3f.distance((float) targetPos.x, (float) targetPos.y, (float) targetPos.z, (float) cameraPos.x, (float) cameraPos.y, (float) cameraPos.z); - return new float[]{Mth.clamp(x, 16, windowWidth - 16), Mth.clamp(y, 16, windowHeight - 16), distanceToCenter, distanceToTarget}; + if (target4f.w <= 0.0f) { + if (target4f.x < 0) { + x = -100; + y = -100; + } else { + x = windowWidth + 100; + y = -100; + } + } + return new float[]{x, y, distanceToCenter, distanceToTarget}; } } diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/ProjectAlgorithmLib.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/ProjectAlgorithmLib.java similarity index 97% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/ProjectAlgorithmLib.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/ProjectAlgorithmLib.java index d913ff9..74cbe59 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/ProjectAlgorithmLib.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/ProjectAlgorithmLib.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.core.track.algorithm; +package nowebsite.makertechno.the_trackers.core.track.algorithm; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/ProjectToAngleAndDistance.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/ProjectToAngleAndDistance.java similarity index 69% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/ProjectToAngleAndDistance.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/ProjectToAngleAndDistance.java index 1d4fe3a..c3cd1dd 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/ProjectToAngleAndDistance.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/ProjectToAngleAndDistance.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.core.track.algorithm; +package nowebsite.makertechno.the_trackers.core.track.algorithm; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/RelativeProjector.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/RelativeProjector.java similarity index 80% rename from src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/RelativeProjector.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/RelativeProjector.java index 1b9bef4..0a875fa 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/core/track/algorithm/RelativeProjector.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/RelativeProjector.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.core.track.algorithm; +package nowebsite.makertechno.the_trackers.core.track.algorithm; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; @@ -15,7 +15,7 @@ public class RelativeProjector { } // 计算玩家和生物位置的投影并计算角度 - public static double @NotNull [] calculateAngle(Vec3 playerPos, Vec3 playerEyeSight, @NotNull Vec3 entityPos, @NotNull ProjectToAngleAndDistance projector) { + public static float[] calculateAngle(Vec3 playerPos, Vec3 playerEyeSight, @NotNull Vec3 entityPos, @NotNull ProjectToAngleAndDistance projector) { // 计算玩家位置的投影 Vec2 base = projector.project(eyeAlignedProjection(playerEyeSight, playerEyeSight)); // 计算生物位置的投影 @@ -26,6 +26,6 @@ public class RelativeProjector { // 计算距离 double distance = Math.sqrt(Math.pow(target.x - base.x, 2) + Math.pow(target.y - base.y, 2)); - return new double[]{Math.atan2(result.y, result.x) + Math.PI, distance}; + return new float[]{(float) (Math.atan2(result.y, result.x) + Math.PI), (float) distance}; } } diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/package-info.java new file mode 100644 index 0000000..9443380 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/algorithm/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.core.track.algorithm; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/package-info.java new file mode 100644 index 0000000..1b40ad0 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.core.track; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file 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 new file mode 100644 index 0000000..0867590 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerState.java @@ -0,0 +1,90 @@ +package nowebsite.makertechno.the_trackers.core.track.states; + +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.entity.Entity; +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 java.util.function.Function; + +public class ControllableTrackerState implements StaticComponent { + protected final String identifyName; + protected final TrackerStepState state; + protected final boolean autoDelete; + + protected Entity posIn; + protected boolean isVisible; + protected boolean isClosed = false; + protected boolean isAlive = true; + + protected Function applier = vec3 -> vec3; + public ControllableTrackerState(String identifyName, TRenderComponent component, boolean isVisible, boolean isAutoDelete) { + this.identifyName = identifyName; + this.state = new TrackerStepState(component); + this.isVisible = isVisible; + this.autoDelete = isAutoDelete; + } + + @Override + public void setVisible(boolean visible) { + this.isVisible = visible; + } + + @Override + public boolean isVisible() { + return isVisible; + } + + /** + * 正常更新实体的时候传入的是实体坐标,applier不应该被改动。 + * 静态模式下会传入玩家位置供判断。 + */ + public void setPosEntity(Entity entity) { + this.posIn = entity; + } + + public Vec3 getPos() { + return state.getPos(); + } + + public void render(GuiGraphics graphics, float partialTick, Player player) { + if (posIn != null && posIn.isAlive()) { + state.updatePos(applier.apply(posIn.position())); + this.isAlive = true; + } + if (isVisible && isAlive) state.renderComponent(graphics, partialTick, player); + } + + public boolean isAlive() { + return isAlive; + } + + public boolean isAutoDelete() { + return autoDelete; + } + + public String getIdentifyName() { + return identifyName; + } + + @Override + public void close() { + isClosed = true; + } + + @Override + public boolean isClosed() { + return isClosed; + } + + public TrackerStepState getState() { + return state; + } + + @Override + public void posUpdater(Function applier) { + this.applier = applier; + } +} 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 new file mode 100644 index 0000000..cb75d96 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/ControllableTrackerStateEx.java @@ -0,0 +1,49 @@ +package nowebsite.makertechno.the_trackers.core.track.states; + +import net.minecraft.client.gui.GuiGraphics; +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 java.util.Arrays; + +public class ControllableTrackerStateEx extends ControllableTrackerState { + private TrackerStepState[] states; + + @SuppressWarnings("all") + public ControllableTrackerStateEx(String identifyName, TRenderComponent[] 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])); + } + + @Override + public void setPosEntity(Entity entity) { + for (TrackerStepState stepState : states) { + stepState.updatePos(entity.position()); + } + } + + @Override + public Vec3 getPos() { + return states[0].getPos(); + } + + @Override + public void render(GuiGraphics graphics, float partialTick, Player player) { + if (isVisible) { + for (TrackerStepState stepState : states) { + stepState.renderComponent(graphics, partialTick, player); + } + } + } + + public void setStates(TrackerStepState[] states) { + this.states = states; + } + + public TrackerStepState[] getStates() { + return states; + } +} 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 new file mode 100644 index 0000000..4ff535a --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TickLimitedTrackerState.java @@ -0,0 +1,21 @@ +package nowebsite.makertechno.the_trackers.core.track.states; + +import net.minecraft.world.entity.Entity; +import nowebsite.makertechno.the_trackers.client.gui.components.TRenderComponent; + +public class TickLimitedTrackerState extends ControllableTrackerState{ + private final int maxTicked; + + private int ticking = 0; + public TickLimitedTrackerState(String identifyName, TRenderComponent component, int maxTicked, boolean isVisible) { + super(identifyName, component, isVisible, false); + this.maxTicked = maxTicked; + } + + @Override + public void setPosEntity(Entity entity) { + super.setPosEntity(entity); + if (ticking < maxTicked) ticking++; + else this.close(); + } +} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TrackerEntityState.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java similarity index 56% rename from src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TrackerEntityState.java rename to src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java index b2382d6..9cc7046 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/client/gui/components/TrackerEntityState.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/TrackerStepState.java @@ -1,20 +1,24 @@ -package nowebsite.makertechno.entity_tracker.client.gui.components; +package nowebsite.makertechno.the_trackers.core.track.states; 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; -public class TrackerEntityState { +public class TrackerStepState { private Vec3 currentPos; private final TRenderComponent component; - public TrackerEntityState(TRenderComponent component) { + public TrackerStepState(TRenderComponent component) { this.component = component; } public void updatePos(Vec3 pos) { this.currentPos = pos; } + public Vec3 getPos() { + return currentPos; + } public void renderComponent(GuiGraphics guiGraphics, float partialTick, Player player) { - component.render(guiGraphics, partialTick, player, currentPos); + if (currentPos != null) component.render(guiGraphics, player, currentPos, partialTick); } public TRenderComponent getComponent() { return component; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/package-info.java new file mode 100644 index 0000000..24b48aa --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/core/track/states/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.core.track.states; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModChineseLanguageProvider.java b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModChineseLanguageProvider.java new file mode 100644 index 0000000..2da2535 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModChineseLanguageProvider.java @@ -0,0 +1,73 @@ +package nowebsite.makertechno.the_trackers.data.datagen; + +import net.minecraft.data.PackOutput; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.neoforge.common.data.LanguageProvider; +import nowebsite.makertechno.the_trackers.TheTrackers; + +public class ModChineseLanguageProvider extends LanguageProvider { + public ModChineseLanguageProvider(PackOutput packOutput, String locale) { + super(packOutput, TheTrackers.MOD_ID, locale); + } + + protected void addTranslations() { + addConfigurationTitleTranslation("追踪器设置"); + addConfigurationTomlTranslation( + ModConfig.Type.CLIENT, + "The Trackers", + "The Trackers 配置" + ); + + addConfigurationTranslation("available", "开关", "启用或禁用追踪指针"); + + addConfigurationTranslation("gui_scale", "追踪指针大小", "默认值0.6,这在一般1080p设备上表现很好"); + addConfigurationTranslation("quantity", "最大追踪数量", "总是显示离你\"最近的N个\"实体"); + addConfigurationTranslation("interval", "位置刷新间隔", "默认为1的情况下,提供最实时的指示"); + + addConfigurationTranslation("center_relative_available", "中心环绕式指针开关", "启用或禁用中心环绕式跟踪"); + addConfigurationTranslation( + "project_algorithm", + "投影算法", + """ + 设置特定于"中心环绕型"指针的算法 + MERCATOR: 墨卡托投影 + AITOFF: 艾托夫投影 + WINKEL_TRIPLE: 温克尔三角投影 + """ + ); + addConfigurationTranslation("track_full_available", "锁定定位式指针开关", "启用或禁用锁定定位式指针"); + addConfigurationTranslation("head_flat_available", "经度轴开关", "启用或禁用经度轴条"); + + addConfigurationButtonTranslation( + "center_relative_tracking", + "中心环绕式跟踪清单", + "跟踪实体的设置", + "带有光标类型的实体类型列表,用\"|\"分隔" + ); + + addConfigurationButtonTranslation( + "track_full_tracking", + "绑定定位式跟踪清单", + "跟踪实体的设置", + "带有光标类型的实体类型列表,用\"|\"分隔" + ); + } + + + public void addConfigurationTitleTranslation(String description) { + add(TheTrackers.MOD_ID + ".configuration.title", description); + } + public void addConfigurationTomlTranslation(ModConfig.Type type, String name, String title) { + add(TheTrackers.MOD_ID + ".configuration.the.trackers." + type.extension() + ".toml", name); + add(TheTrackers.MOD_ID + ".configuration.the.trackers." + type.extension() + ".toml.title", title); + } + public void addConfigurationTranslation(String id, String description, String tooltip) { + add(TheTrackers.MOD_ID + ".configuration." + id, description); + add(TheTrackers.MOD_ID + ".configuration." + id + ".tooltip", tooltip); + } + public void addConfigurationButtonTranslation(String id, String description, String button, String tooltip) { + add(TheTrackers.MOD_ID + ".configuration." + id, description); + add(TheTrackers.MOD_ID + ".configuration." + id + ".button", button); + add(TheTrackers.MOD_ID + ".configuration." + id + ".tooltip", tooltip); + } +} diff --git a/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModDataGenerators.java b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModDataGenerators.java similarity index 90% rename from src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModDataGenerators.java rename to src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModDataGenerators.java index f5e83b3..4c88f54 100644 --- a/src/main/java/nowebsite/makertechno/entity_tracker/data/datagen/ModDataGenerators.java +++ b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModDataGenerators.java @@ -1,4 +1,4 @@ -package nowebsite.makertechno.entity_tracker.data.datagen; +package nowebsite.makertechno.the_trackers.data.datagen; import net.minecraft.data.DataGenerator; import net.minecraft.data.PackOutput; diff --git a/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModEnglishLanguageProvider.java b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModEnglishLanguageProvider.java new file mode 100644 index 0000000..5ce0664 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/ModEnglishLanguageProvider.java @@ -0,0 +1,92 @@ +package nowebsite.makertechno.the_trackers.data.datagen; + +import net.minecraft.data.PackOutput; +import net.neoforged.fml.config.ModConfig; +import net.neoforged.neoforge.common.data.LanguageProvider; +import nowebsite.makertechno.the_trackers.TheTrackers; + +public class ModEnglishLanguageProvider extends LanguageProvider { + public ModEnglishLanguageProvider(PackOutput packOutput, String locale) { + super(packOutput, TheTrackers.MOD_ID, locale); + } + + protected void addTranslations() { + addConfigurationTitleTranslation("The Trackers' Settings"); + addConfigurationTomlTranslation( + ModConfig.Type.CLIENT, + "The Trackers", + "The Trackers Configuration" + ); + + addConfigurationTranslation("available", "Available", "Enable or disable the automatic tracking process"); + + + addConfigurationTranslation( + "gui_scale", + "The scale of tracking cursors", + "Usually 0.6 on 1080p monitors" + ); + addConfigurationTranslation( + "quantity", + "The max quantity of tracking", + "Always shows those \"the top N closest\" to you" + ); + addConfigurationTranslation( + "interval", + "Interval between world pos update", + "Choose 1 by default, provides the fastest reaction" + ); + + + addConfigurationTranslation( + "center_relative_available", + "Center-relative hud available", + "Enable or disable center-relative cursors" + ); + addConfigurationTranslation( + "project_algorithm", + "Project Algorithm", + "Set the algorithm specific for the center-relative pointer" + ); + addConfigurationTranslation( + "track_full_available", + "Full screen tag hud available", + "Enable or disable full screen tag cursors" + ); + addConfigurationTranslation( + "head_flat_available", + "Longitude hud available", + "Enable or disable longitude display" + ); + + addConfigurationButtonTranslation( + "center_relative_tracking", + "Tracking settings for center-relative cursors", + "Settings for tracking entities", + "List of entity types with cursor types, separated with \"|\"" + ); + addConfigurationButtonTranslation( + "track_full_tracking", + "Tracking settings for full-track cursors", + "Settings for tracking entities", + "List of entity types with cursor types, separated with \"|\"" + ); + + } + public void addConfigurationTitleTranslation(String description) { + add(TheTrackers.MOD_ID + ".configuration.title", description); + } + public void addConfigurationTomlTranslation(ModConfig.Type type, String name, String title) { + add(TheTrackers.MOD_ID + ".configuration.the.trackers." + type.extension() + ".toml", name); + add(TheTrackers.MOD_ID + ".configuration.the.trackers." + type.extension() + ".toml.title", title); + } + public void addConfigurationTranslation(String id, String description, String tooltip) { + add(TheTrackers.MOD_ID + ".configuration." + id, description); + add(TheTrackers.MOD_ID + ".configuration." + id + ".tooltip", tooltip); + } + public void addConfigurationButtonTranslation(String id, String description, String button, String tooltip) { + add(TheTrackers.MOD_ID + ".configuration." + id, description); + add(TheTrackers.MOD_ID + ".configuration." + id + ".button", button); + add(TheTrackers.MOD_ID + ".configuration." + id + ".tooltip", tooltip); + } +} diff --git a/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/package-info.java b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/package-info.java new file mode 100644 index 0000000..11f3ee3 --- /dev/null +++ b/src/main/java/nowebsite/makertechno/the_trackers/data/datagen/package-info.java @@ -0,0 +1,7 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +package nowebsite.makertechno.the_trackers.data.datagen; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index 47c49df..1256c9b 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -35,7 +35,7 @@ displayName="${mod_name}" #mandatory #displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional # A file name (in the root of the mod JAR) containing a logo for display -logoFile= "entity_tracker.png" #optional +logoFile= "the_trackers.png" #optional # A text field displayed in the mod UI #credits="" #optional @@ -44,7 +44,10 @@ logoFile= "entity_tracker.png" #optional authors="${mod_authors}" #optional # The description text for the mod (multi line!) (#mandatory) -description='''${mod_description}''' +description=''' +${mod_description} +逐光溯影,追梦而行 +''' # The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded. #[[mixins]] diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/brain_of_cthulhu.png b/src/main/resources/assets/the_trackers/textures/icons/brain_of_cthulhu.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/brain_of_cthulhu.png rename to src/main/resources/assets/the_trackers/textures/icons/brain_of_cthulhu.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/eater_of_worlds.png b/src/main/resources/assets/the_trackers/textures/icons/eater_of_worlds.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/eater_of_worlds.png rename to src/main/resources/assets/the_trackers/textures/icons/eater_of_worlds.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/ender_dragon_head.png b/src/main/resources/assets/the_trackers/textures/icons/ender_dragon_head.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/ender_dragon_head.png rename to src/main/resources/assets/the_trackers/textures/icons/ender_dragon_head.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/eye_of_cthulhu.png b/src/main/resources/assets/the_trackers/textures/icons/eye_of_cthulhu.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/eye_of_cthulhu.png rename to src/main/resources/assets/the_trackers/textures/icons/eye_of_cthulhu.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/king_slime.png b/src/main/resources/assets/the_trackers/textures/icons/king_slime.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/king_slime.png rename to src/main/resources/assets/the_trackers/textures/icons/king_slime.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/normal_red.png b/src/main/resources/assets/the_trackers/textures/icons/normal.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/normal_red.png rename to src/main/resources/assets/the_trackers/textures/icons/normal.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/normal_green.png b/src/main/resources/assets/the_trackers/textures/icons/normal_green.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/normal_green.png rename to src/main/resources/assets/the_trackers/textures/icons/normal_green.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/normal_white.png b/src/main/resources/assets/the_trackers/textures/icons/normal_white.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/normal_white.png rename to src/main/resources/assets/the_trackers/textures/icons/normal_white.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/point_x.png b/src/main/resources/assets/the_trackers/textures/icons/point_x.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/point_x.png rename to src/main/resources/assets/the_trackers/textures/icons/point_x.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/queen_bee.png b/src/main/resources/assets/the_trackers/textures/icons/queen_bee.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/queen_bee.png rename to src/main/resources/assets/the_trackers/textures/icons/queen_bee.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/skeletron.png b/src/main/resources/assets/the_trackers/textures/icons/skeletron.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/skeletron.png rename to src/main/resources/assets/the_trackers/textures/icons/skeletron.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/wall_of_flesh.png b/src/main/resources/assets/the_trackers/textures/icons/wall_of_flesh.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/wall_of_flesh.png rename to src/main/resources/assets/the_trackers/textures/icons/wall_of_flesh.png diff --git a/src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/wither_head.png b/src/main/resources/assets/the_trackers/textures/icons/wither_head.png similarity index 100% rename from src/main/resources/assets/entity_tracker/textures/gui/sprites/hud/wither_head.png rename to src/main/resources/assets/the_trackers/textures/icons/wither_head.png diff --git a/src/main/resources/entity_tracker.png b/src/main/resources/the_trackers.png similarity index 100% rename from src/main/resources/entity_tracker.png rename to src/main/resources/the_trackers.png