diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java index aa8fe58b8..680bac601 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/JavelinHudOverlay.java @@ -1,17 +1,26 @@ package com.atsuishio.superbwarfare.client.screens; -import com.atsuishio.superbwarfare.network.ModVariables; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.client.RenderHelper; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.network.ModVariables; +import com.atsuishio.superbwarfare.tools.EntityFindUtil; +import com.atsuishio.superbwarfare.tools.HudUtil; +import com.atsuishio.superbwarfare.tools.SeekTool; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RenderGuiEvent; import net.minecraftforge.eventbus.api.EventPriority; @@ -22,14 +31,21 @@ import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit; @Mod.EventBusSubscriber(value = Dist.CLIENT) public class JavelinHudOverlay { - + private static final ResourceLocation FRAME = ModUtils.loc("textures/screens/javelin/frame.png"); + private static final ResourceLocation FRAME_LOCK = ModUtils.loc("textures/screens/javelin/frame_lock.png"); private static float scopeScale = 1; + @SubscribeEvent(priority = EventPriority.LOWEST) public static void eventHandler(RenderGuiEvent.Pre event) { int w = event.getWindow().getGuiScaledWidth(); int h = event.getWindow().getGuiScaledHeight(); Player player = Minecraft.getInstance().player; + Minecraft mc = Minecraft.getInstance(); + Camera camera = mc.gameRenderer.getMainCamera(); + Vec3 cameraPos = camera.getPosition(); + PoseStack poseStack = event.getGuiGraphics().pose(); + if (player != null) { ItemStack stack = player.getMainHandItem(); @@ -60,6 +76,7 @@ public class JavelinHudOverlay { if (stack.getOrCreateTag().getInt("SeekTime") > 1 && stack.getOrCreateTag().getInt("SeekTime") < 20) { preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/javelin/seek.png"), k, l, 0, 0.0F, i, j, i, j); } + event.getGuiGraphics().fill(RenderType.guiOverlay(), 0, (int) l, (int) k + 3, (int) j1, -90, -16777216); event.getGuiGraphics().fill(RenderType.guiOverlay(), (int) i1, (int) l, w, (int) j1, -90, -16777216); RenderSystem.depthMask(true); @@ -67,6 +84,26 @@ public class JavelinHudOverlay { RenderSystem.enableDepthTest(); RenderSystem.disableBlend(); RenderSystem.setShaderColor(1, 1, 1, 1); + + Entity targetEntity = EntityFindUtil.findEntity(player.level(), stack.getOrCreateTag().getString("TargetEntity")); + Entity seekingEntity = SeekTool.seekEntity(player, player.level(), 512, 8); + + if (seekingEntity == null) return; + + Vec3 p = RenderHelper.worldToScreen(new Vec3(seekingEntity.getX(), seekingEntity.getEyeY(),seekingEntity.getZ()), cameraPos); + + if (p == null) return; + + boolean lockOn = stack.getOrCreateTag().getInt("SeekTime") > 20 && seekingEntity == targetEntity; + + poseStack.pushPose(); + + int x = (int) p.x; + int y = (int) p.y; + + HudUtil.blit(poseStack, lockOn ? FRAME_LOCK : FRAME, x-8, y-8, 0, 0, 16, 16, 16, 16, 1f); + + poseStack.popPose(); } else { scopeScale = 1; } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/RedTriangleOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/RedTriangleOverlay.java new file mode 100644 index 000000000..32ec5feee --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/RedTriangleOverlay.java @@ -0,0 +1,67 @@ +package com.atsuishio.superbwarfare.client.screens; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.client.RenderHelper; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.tools.HudUtil; +import com.atsuishio.superbwarfare.tools.SeekTool; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RenderGuiEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(value = Dist.CLIENT) +public class RedTriangleOverlay { + private static final ResourceLocation TRIANGLE = ModUtils.loc("textures/screens/red_triangle.png"); + + @SubscribeEvent(priority = EventPriority.NORMAL) + public static void eventHandler(RenderGuiEvent.Pre event) { + int w = event.getWindow().getGuiScaledWidth(); + int h = event.getWindow().getGuiScaledHeight(); + Minecraft mc = Minecraft.getInstance(); + Camera camera = mc.gameRenderer.getMainCamera(); + Vec3 cameraPos = camera.getPosition(); + PoseStack poseStack = event.getGuiGraphics().pose(); + + Player player = Minecraft.getInstance().player; + if (player == null) return; + + ItemStack stack = player.getMainHandItem(); + + if (stack.is(ModItems.RPG.get())) { + Entity idf = SeekTool.seekLivingEntity(player, player.level(),128,6); + + if (idf == null) return; + + Vec3 p = RenderHelper.worldToScreen(new Vec3(idf.getX(), idf.getEyeY() + 2,idf.getZ()), cameraPos); + + if (p == null) return; + + poseStack.pushPose(); + + int x = (int) p.x; + int y = (int) p.y; + + HudUtil.blit(poseStack, TRIANGLE, x-4, y-4, 0, 0, 8, 8, 8, 8, -65536); + + poseStack.popPose(); + + } + + RenderSystem.depthMask(true); + RenderSystem.defaultBlendFunc(); + RenderSystem.enableDepthTest(); + RenderSystem.disableBlend(); + RenderSystem.setShaderColor(1, 1, 1, 1); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java index f59de3a66..cc5e961f0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java @@ -21,7 +21,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.InteractionHand; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; @@ -155,9 +154,9 @@ public class JavelinItem extends GunItem implements GeoItem, AnimatedItem { } if (seekingEntity != null && tag.getInt("SeekTime") > 20) { - if (seekingEntity instanceof LivingEntity living) { - living.addEffect(new MobEffectInstance(MobEffects.GLOWING, 40, 0)); - } +// if (seekingEntity instanceof LivingEntity living) { +// living.addEffect(new MobEffectInstance(MobEffects.GLOWING, 40, 0)); +// } if (player instanceof ServerPlayer serverPlayer) { SoundTool.playLocalSound(serverPlayer, ModSounds.JAVELIN_LOCKON.get(), 2, 1); diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/HudUtil.java b/src/main/java/com/atsuishio/superbwarfare/tools/HudUtil.java new file mode 100644 index 000000000..e807c4b71 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/tools/HudUtil.java @@ -0,0 +1,87 @@ +package com.atsuishio.superbwarfare.tools; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; + +public class HudUtil { + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX, int pY, float pUOffset, float pVOffset, int pWidth, int pHeight, int pTextureWidth, int pTextureHeight, int color) { + blit(pose, pAtlasLocation, pX, pY, pWidth, pHeight, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight, color); + } + + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX, int pY, int pWidth, int pHeight, float pUOffset, float pVOffset, int pUWidth, int pVHeight, int pTextureWidth, int pTextureHeight, int color) { + blit(pose, pAtlasLocation, pX, pX + pWidth, pY, pY + pHeight, 0, pUWidth, pVHeight, pUOffset, pVOffset, pTextureWidth, pTextureHeight, color); + } + + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, int pUWidth, int pVHeight, float pUOffset, float pVOffset, int pTextureWidth, int pTextureHeight, int color) { + innerBlit(pose, pAtlasLocation, pX1, pX2, pY1, pY2, pBlitOffset, (pUOffset + 0.0F) / (float)pTextureWidth, (pUOffset + (float)pUWidth) / (float)pTextureWidth, (pVOffset + 0.0F) / (float)pTextureHeight, (pVOffset + (float)pVHeight) / (float)pTextureHeight, color); + } + + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX, int pY, float pUOffset, float pVOffset, int pWidth, int pHeight, int pTextureWidth, int pTextureHeight, float alpha, boolean opposite) { + blit(pose, pAtlasLocation, pX, pY, pWidth, pHeight, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight, alpha, opposite); + } + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX, int pY, float pUOffset, float pVOffset, int pWidth, int pHeight, int pTextureWidth, int pTextureHeight, float alpha) { + blit(pose, pAtlasLocation, pX, pY, pUOffset, pVOffset, pWidth, pHeight, pTextureWidth, pTextureHeight, alpha, false); + } + + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX, int pY, int pWidth, int pHeight, float pUOffset, float pVOffset, int pUWidth, int pVHeight, int pTextureWidth, int pTextureHeight, float alpha, boolean opposite) { + blit(pose, pAtlasLocation, pX, pX + pWidth, pY, pY + pHeight, 0, pUWidth, pVHeight, pUOffset, pVOffset, pTextureWidth, pTextureHeight, alpha, opposite); + } + + public static void blit(PoseStack pose, ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, int pUWidth, int pVHeight, float pUOffset, float pVOffset, int pTextureWidth, int pTextureHeight, float alpha, boolean opposite) { + innerBlit(pose, pAtlasLocation, pX1, pX2, pY1, pY2, pBlitOffset, (pUOffset + 0.0F) / (float)pTextureWidth, (pUOffset + (float)pUWidth) / (float)pTextureWidth, (pVOffset + 0.0F) / (float)pTextureHeight, (pVOffset + (float)pVHeight) / (float)pTextureHeight, alpha, opposite); + } + + private static void innerBlit(PoseStack pose, ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, int color) { + RenderSystem.setShaderTexture(0, pAtlasLocation); + RenderSystem.setShader(GameRenderer::getPositionColorTexShader); + + Matrix4f matrix4f = pose.last().pose(); + BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder(); + bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX); + + vertexC(pX1, pX2, pY1, pY2, pBlitOffset, pMinU, pMaxU, pMinV, pMaxV, color, matrix4f, bufferbuilder); + + BufferUploader.drawWithShader(bufferbuilder.end()); + } + + private static void innerBlit(PoseStack pose, ResourceLocation pAtlasLocation, int pX1, int pX2, int pY1, int pY2, int pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, float alpha, boolean opposite) { + RenderSystem.setShaderTexture(0, pAtlasLocation); + RenderSystem.setShader(GameRenderer::getPositionColorTexShader); + RenderSystem.enableBlend(); + Matrix4f matrix4f = pose.last().pose(); + BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder(); + bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX); + + if(opposite){ + vertex(pX1, pX2, pY1, pY2, pBlitOffset, pMaxU, pMinU, pMinV, pMaxV, alpha, matrix4f, bufferbuilder); + }else { + vertex(pX1, pX2, pY1, pY2, pBlitOffset, pMinU, pMaxU, pMinV, pMaxV, alpha, matrix4f, bufferbuilder); + } + + BufferUploader.drawWithShader(bufferbuilder.end()); + RenderSystem.disableBlend(); + } + + private static void vertex(float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, float alpha, Matrix4f matrix4f, BufferBuilder bufferbuilder) { + bufferbuilder.vertex(matrix4f, pX1, pY1, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMinU, pMinV).endVertex(); + bufferbuilder.vertex(matrix4f, pX1, pY2, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMinU, pMaxV).endVertex(); + bufferbuilder.vertex(matrix4f, pX2, pY2, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMaxU, pMaxV).endVertex(); + bufferbuilder.vertex(matrix4f, pX2, pY1, pBlitOffset).color(1f, 1f, 1f, alpha).uv(pMaxU, pMinV).endVertex(); + } + + private static void vertexC(float pX1, float pX2, float pY1, float pY2, float pBlitOffset, float pMinU, float pMaxU, float pMinV, float pMaxV, int color, Matrix4f matrix4f, BufferBuilder bufferbuilder) { + float r = (float)(color >> 16 & 255) / 255.0F; + float g = (float)(color >> 8 & 255) / 255.0F; + float b = (float)(color & 255) / 255.0F; + + bufferbuilder.vertex(matrix4f, pX1, pY1, pBlitOffset).color(r, g, b, 1f).uv(pMinU, pMinV).endVertex(); + bufferbuilder.vertex(matrix4f, pX1, pY2, pBlitOffset).color(r, g, b, 1f).uv(pMinU, pMaxV).endVertex(); + bufferbuilder.vertex(matrix4f, pX2, pY2, pBlitOffset).color(r, g, b, 1f).uv(pMaxU, pMaxV).endVertex(); + bufferbuilder.vertex(matrix4f, pX2, pY1, pBlitOffset).color(r, g, b, 1f).uv(pMaxU, pMinV).endVertex(); + } + + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java index 9e6fa29cc..5b303f991 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java @@ -1,5 +1,6 @@ package com.atsuishio.superbwarfare.tools; +import com.atsuishio.superbwarfare.entity.IVehicleEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -38,7 +39,7 @@ public class SeekTool { if (e.distanceTo(entity) <= seekRange && calculateAngle(e, entity) < seekAngle && e != entity && e.isAlive() - && e instanceof LivingEntity + && (e instanceof LivingEntity || e instanceof IVehicleEntity) && !(e instanceof Player player && (player.isCreative() || player.isSpectator())) && (!e.isAlliedTo(entity) || e.getTeam() == null || e.getTeam().getName().equals("TDM"))) { return level.clip(new ClipContext(entity.getEyePosition(), e.getEyePosition(), diff --git a/src/main/resources/assets/superbwarfare/textures/screens/javelin/frame.png b/src/main/resources/assets/superbwarfare/textures/screens/javelin/frame.png new file mode 100644 index 000000000..29c93af16 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/javelin/frame.png differ diff --git a/src/main/resources/assets/superbwarfare/textures/screens/javelin/frame_lock.png b/src/main/resources/assets/superbwarfare/textures/screens/javelin/frame_lock.png new file mode 100644 index 000000000..ffc05897b Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/javelin/frame_lock.png differ diff --git a/src/main/resources/assets/superbwarfare/textures/screens/javelin/red_triangle.png b/src/main/resources/assets/superbwarfare/textures/screens/javelin/red_triangle.png new file mode 100644 index 000000000..8ea63052e Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/javelin/red_triangle.png differ diff --git a/src/main/resources/assets/superbwarfare/textures/screens/red_triangle.png b/src/main/resources/assets/superbwarfare/textures/screens/red_triangle.png new file mode 100644 index 000000000..8ea63052e Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/red_triangle.png differ