diff options
| author | ohowe <42757516+carelesshippo@users.noreply.github.com> | 2021-06-02 11:55:36 -0600 |
|---|---|---|
| committer | ohowe <42757516+carelesshippo@users.noreply.github.com> | 2021-06-02 11:55:36 -0600 |
| commit | eeb5c45d71997cb259fc35330490a19db7865603 (patch) | |
| tree | 65771b27ed837896fa3140dec1af78306accebcd /src/main/java/io/github/moulberry/notenoughupdates/miscfeatures | |
| parent | 4d9e538ced80728bca74491698347333f515bfcc (diff) | |
| parent | 1b172089ce502803f7644611afd618ce00dcb860 (diff) | |
| download | notenoughupdates-eeb5c45d71997cb259fc35330490a19db7865603.tar.gz notenoughupdates-eeb5c45d71997cb259fc35330490a19db7865603.tar.bz2 notenoughupdates-eeb5c45d71997cb259fc35330490a19db7865603.zip | |
Merge branch 'Moulberry:master' into master
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/miscfeatures')
8 files changed, 1087 insertions, 81 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java index c2f778a5..553a5d40 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DamageCommas.java @@ -13,6 +13,7 @@ public class DamageCommas { private static final HashMap<Integer, ChatComponentText> replacementMap = new HashMap<>(); + //From [MVP++] HY7: private static final EnumChatFormatting[] colours = {EnumChatFormatting.RED, EnumChatFormatting.GOLD, EnumChatFormatting.YELLOW, EnumChatFormatting.WHITE}; public static void tick() { @@ -31,8 +32,8 @@ public class DamageCommas { return component; } - if(formatted.length() >= 7 && formatted.startsWith("\u00A7f\u2727") && - formatted.endsWith("\u2727\u00a7r")) { + if(formatted.length() >= 7 && (formatted.startsWith("\u00A7f\u2727") || formatted.startsWith("\u00A7f\u2694")) && + (formatted.endsWith("\u2727\u00a7r") || formatted.endsWith("\u2694\u00a7r"))) { if(NotEnoughUpdates.INSTANCE.config.misc.damageIndicatorStyle == 2) { String numbers = Utils.cleanColour(formatted.substring(3, formatted.length()-3)).trim().replaceAll("[^0-9]", ""); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FancyPortals.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FancyPortals.java new file mode 100644 index 00000000..a9be6fd5 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FancyPortals.java @@ -0,0 +1,303 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.cosmetics.CapeNode; +import io.github.moulberry.notenoughupdates.util.ReverseWorldRenderer; +import io.github.moulberry.notenoughupdates.util.TexLoc; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.chunk.CompiledChunk; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.play.server.S07PacketRespawn; +import net.minecraft.util.BlockPos; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.client.event.RenderLivingEvent; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.Project; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.nio.ByteBuffer; +import java.util.List; + +public class FancyPortals { + + private static ResourceLocation[] RENDERS = new ResourceLocation[6]; + + static { + for(int i=0; i<6; i++) { + RENDERS[i] = new ResourceLocation("notenoughupdates:portal_panoramas/nether/pansc-"+(i+1)+".png"); + } + } + + public static int perspectiveId = -1; + public static boolean overridePerspective() { + if(perspectiveId >= 0 && !Keyboard.isKeyDown(Keyboard.KEY_K)) { + if(perspectiveId == 0) { + GlStateManager.matrixMode(5889); + GlStateManager.loadIdentity(); + GlStateManager.ortho(0.0D, 7, 7, 0.0D, -100D, 100D); + GlStateManager.scale(1, 1, -1); + GlStateManager.matrixMode(5888); + GlStateManager.loadIdentity(); + GlStateManager.translate(3.5F, 3.5F, -1.0F); + GlStateManager.rotate(-90, 1, 0, 0); + } else if(perspectiveId <= 4) { + GlStateManager.matrixMode(5889); + GlStateManager.loadIdentity(); + Project.gluPerspective(90, 1, 0.05F, 160 * MathHelper.SQRT_2); + GlStateManager.matrixMode(5888); + GlStateManager.loadIdentity(); + GlStateManager.rotate(perspectiveId*90, 0, 1, 0); + GlStateManager.translate(0, -3.5f, 0); + } else { + GlStateManager.matrixMode(5889); + GlStateManager.loadIdentity(); + Project.gluPerspective(90, 1, 0.05F, 160 * MathHelper.SQRT_2); + GlStateManager.matrixMode(5888); + GlStateManager.loadIdentity(); + GlStateManager.rotate(-90, 1, 0, 0); + GlStateManager.translate(0, -3.5f, 0); + } + + return true; + } + return false; + } + + private static WorldRenderer surfaceWorldRenderer = null; + + private static WorldRenderer getSurfaceWorldRenderer() { + if(surfaceWorldRenderer != null && !Keyboard.isKeyDown(Keyboard.KEY_O)) { + return surfaceWorldRenderer; + } + + surfaceWorldRenderer = createSurfaceWorldRenderer(); + + return surfaceWorldRenderer; + } + + private static void drawPoint(WorldRenderer worldRenderer, int x, int y) { + float xDist = 1-Math.abs(x-50)/50f; + float yDist = 1-Math.abs(y-50)/50f; + float distToEdge = Math.min(xDist, yDist); + + float z = 0.4142f; + if(distToEdge < 1/3.5f) { + if(y > 50 && yDist < xDist) { + float circleH = 1.414f - distToEdge*3.5f*1.414f; + z = (float)Math.sqrt(2f-circleH*circleH); + z *= 0.4142f / 1.4142f; + } else { + float circleH = 1 - distToEdge*3.5f; + z = (float)Math.sqrt(2f-circleH*circleH)-1; + } + } + + worldRenderer.pos(x*7/100f, y*7/100f, z).tex(x/100f, y/100f).endVertex(); + } + + private static WorldRenderer createSurfaceWorldRenderer() { + WorldRenderer worldRenderer = new WorldRenderer(20*100*100); + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + + for(int x=0; x<100; x++) { + for(int y=0; y<100; y++) { + drawPoint(worldRenderer, x, y); + drawPoint(worldRenderer, x, y+1); + drawPoint(worldRenderer, x+1, y+1); + drawPoint(worldRenderer, x+1, y); + } + } + + return worldRenderer; + } + + private static long overridingRenderMillis = -1; + + public static void onRespawnPacket(S07PacketRespawn packet) { + if(true) return; + if (packet.getDimensionID() != Minecraft.getMinecraft().thePlayer.dimension) { + overridingRenderMillis = System.currentTimeMillis(); + } + } + + public static boolean shouldRenderLoadingScreen() { + return false; + } + + public static boolean shouldRenderWorldOverlay() { + if(overridingRenderMillis > 0) { + if(Minecraft.getMinecraft().theWorld != null && Minecraft.getMinecraft().thePlayer != null) { + RenderGlobal renderGlobal = Minecraft.getMinecraft().renderGlobal; + int loaded = 0; + for(RenderGlobal.ContainerLocalRenderInformation info : renderGlobal.renderInfos) { + CompiledChunk compiledchunk = info.renderChunk.compiledChunk; + + if (compiledchunk != CompiledChunk.DUMMY && !compiledchunk.isEmpty()) { + if(++loaded >= 5) { + overridingRenderMillis = -1; + return false; + } + } + } + } + if(System.currentTimeMillis() - overridingRenderMillis > 1000) { + overridingRenderMillis = -1; + return false; + } + return true; + } + return false; + } + + public static void onUpdateCameraAndRender(float partialTicks, long nanoTime) { + if(overridingRenderMillis > 0) { + if(Minecraft.getMinecraft().theWorld != null && Minecraft.getMinecraft().thePlayer != null) { + Minecraft.getMinecraft().thePlayer.timeInPortal = 0.3f; + Minecraft.getMinecraft().thePlayer.prevTimeInPortal = 0.3f; + } + + GlStateManager.rotate(90, 0, 1, 0); + renderWorld(); + + Minecraft.getMinecraft().ingameGUI.renderGameOverlay(partialTicks); + } + } + + @SubscribeEvent + public void onRenderEntityYeeter(RenderLivingEvent.Pre<EntityLivingBase> event) { + /*if(!Keyboard.isKeyDown(Keyboard.KEY_G)) return; + event.setCanceled(true); + if(event.entity instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) event.entity; + if(player.getUniqueID().version() == 4) { + event.setCanceled(true); + } + }*/ + } + + private static void renderWorld() { + for(int i=5; i>=0; i--) { + GlStateManager.pushMatrix(); + + GlStateManager.disableDepth(); + GlStateManager.disableLighting(); + + + GlStateManager.rotate(180, 0, 0, 1); + GlStateManager.rotate(-90, 0, 1, 0); + + if(i != 0) GlStateManager.translate(0, -3.49, 0); + + switch (i) { + case 1: + GlStateManager.rotate(90.0F, 0.0F, 1.0F, 0.0F); break; + case 2: + GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F); break; + case 3: + GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); break; + case 5: + GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); break; + case 0: + GlStateManager.rotate(-90.0F, 1.0F, 0.0F, 0.0F); break; + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(RENDERS[i]); + GlStateManager.color(1, 1, 1, 1); + if(i != 0) GlStateManager.translate(0, 0, 3.49); + + if(i != 0) { + GlStateManager.translate(-3.5f, -3.5f, 0); + WorldRenderer worldRenderer = getSurfaceWorldRenderer(); + VertexFormat vertexformat = worldRenderer.getVertexFormat(); + int stride = vertexformat.getNextOffset(); + ByteBuffer bytebuffer = worldRenderer.getByteBuffer(); + List<VertexFormatElement> list = vertexformat.getElements(); + + for (int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().preDraw(vertexformat, index, stride, bytebuffer); + } + + GL11.glDrawArrays(worldRenderer.getDrawMode(), 0, worldRenderer.getVertexCount()); + + for (int index = 0; index < list.size(); index++) { + VertexFormatElement vertexformatelement = list.get(index); + vertexformatelement.getUsage().postDraw(vertexformat, index, stride, bytebuffer); + } + } else { + Utils.drawTexturedRect(-3.5f, -3.5f, 7, 7, i == 0 ? GL11.GL_NEAREST : GL11.GL_LINEAR); + } + + GlStateManager.enableDepth(); + + GlStateManager.popMatrix(); + } + } + + @SubscribeEvent + public void onRenderLast(RenderWorldLastEvent event) { + if(true) return; + if(!Minecraft.getMinecraft().getFramebuffer().isStencilEnabled()) + Minecraft.getMinecraft().getFramebuffer().enableStencil(); + + GL11.glEnable(GL11.GL_STENCIL_TEST); + GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0xFF); + GL11.glStencilOp(GL11.GL_ZERO, GL11.GL_ZERO, GL11.GL_REPLACE); + GL11.glStencilMask(0xFF); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + GlStateManager.enableDepth(); + GlStateManager.enableCull(); + GlStateManager.cullFace(GL11.GL_BACK); + + GL11.glColorMask(false, false, false, false); + + Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); + double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * event.partialTicks; + double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * event.partialTicks; + double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * event.partialTicks; + GlStateManager.pushMatrix(); + + GlStateManager.translate(-viewerX+12+5/16f, -viewerY+100, -viewerZ+39); + GlStateManager.rotate(90, 0, 1, 0); + Gui.drawRect(0, 5, 3, 0, 0xffffffff); + GlStateManager.rotate(180, 0, 1, 0); + GlStateManager.translate(-3, 0, -6/16f); + Gui.drawRect(0, 5, 3, 0, 0xffffffff); + + GlStateManager.popMatrix(); + + + GL11.glColorMask(true, true, true, true); + + // Only pass stencil test if equal to 1 + GL11.glStencilMask(0x00); + GL11.glStencilFunc(GL11.GL_EQUAL, 1, 0xFF); + + GlStateManager.translate(-viewerX+12, -viewerY+100, -viewerZ+37.5f); + + renderWorld(); + + GL11.glDisable(GL11.GL_STENCIL_TEST); + GlStateManager.enableCull(); + } + + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java new file mode 100644 index 00000000..2c59fcd8 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FishingHelper.java @@ -0,0 +1,549 @@ +package io.github.moulberry.notenoughupdates.miscfeatures; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.SpecialColour; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.ISound; +import net.minecraft.client.audio.PositionedSound; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.opengl.GL11; + +import java.util.*; + +public class FishingHelper { + + private static final FishingHelper INSTANCE = new FishingHelper(); + + public static FishingHelper getInstance() { + return INSTANCE; + } + + public static class WakeChain { + public int particleNum = 0; + public long lastUpdate; + public double currentAngle; + public double currentX; + public double currentZ; + + public final HashMap<Integer, Double> distances = new HashMap<>(); + + public WakeChain(long lastUpdate, double currentAngle, double currentX, double currentZ) { + this.lastUpdate = lastUpdate; + this.currentAngle = currentAngle; + this.currentX = currentX; + this.currentZ = currentZ; + } + } + + private enum PlayerWarningState { + NOTHING, + FISH_INCOMING, + FISH_HOOKED + } + private PlayerWarningState warningState = PlayerWarningState.NOTHING; + private int hookedWarningStateTicks = 0; + + public final HashMap<Integer, EntityFishHook> hookEntities = new HashMap<>(); + public final HashMap<WakeChain, List<Integer>> chains = new HashMap<>(); + + private long lastCastRodMillis = 0; + private int pingDelayTicks = 0; + private final List<Integer> pingDelayList = new ArrayList<>(); + private int buildupSoundDelay = 0; + + private static final ResourceLocation FISHING_WARNING_EXCLAM = new ResourceLocation("notenoughupdates:fishing_warning_exclam.png"); + public void onRenderBobber(EntityFishHook hook) { + if(Minecraft.getMinecraft().thePlayer.fishEntity == hook && warningState != PlayerWarningState.NOTHING) { + GlStateManager.disableCull(); + GlStateManager.disableLighting(); + GL11.glDepthFunc(GL11.GL_ALWAYS); + GlStateManager.scale(1, -1, 1); + + float offset = warningState == PlayerWarningState.FISH_HOOKED ? 0.5f : 0f; + + float centerOffset = 0.5f/8f; + Minecraft.getMinecraft().getTextureManager().bindTexture(FISHING_WARNING_EXCLAM); + Utils.drawTexturedRect(centerOffset - 4f/8f, -20/8f, 1f, 2f, 0+offset, 0.5f+offset, 0, 1, GL11.GL_NEAREST); + + GlStateManager.scale(1, -1, 1); + GL11.glDepthFunc(GL11.GL_LEQUAL); + GlStateManager.enableLighting(); + GlStateManager.enableCull(); + } + } + + public void addEntity(int entityId, Entity entity) { + if(entity instanceof EntityFishHook) { + hookEntities.put(entityId, (EntityFishHook) entity); + + if(((EntityFishHook) entity).angler == Minecraft.getMinecraft().thePlayer) { + long currentTime = System.currentTimeMillis(); + long delay = currentTime - lastCastRodMillis; + if(delay > 0 && delay < 500) { + if(delay > 300) delay = 300; + pingDelayList.add(0, (int)delay); + } + } + } + } + + public void removeEntity(int entityId) { + hookEntities.remove(entityId); + } + + @SubscribeEvent + public void onWorldUnload(WorldEvent.Unload event) { + hookEntities.clear(); + chains.clear(); + } + + @SubscribeEvent + public void onPlayerInteract(PlayerInteractEvent event) { + if(event.action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR && + event.entityPlayer == Minecraft.getMinecraft().thePlayer) { + + ItemStack heldItem = event.entityPlayer.getHeldItem(); + + if(heldItem != null && heldItem.getItem() == Items.fishing_rod) { + long currentTime = System.currentTimeMillis(); + if(currentTime - lastCastRodMillis > 500) { + lastCastRodMillis = currentTime; + } + } + + } + } + + private int tickCounter = 0; + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if(Minecraft.getMinecraft().thePlayer != null && event.phase == TickEvent.Phase.END) { + if(buildupSoundDelay > 0) buildupSoundDelay--; + + if(NotEnoughUpdates.INSTANCE.config.fishing.incomingFishWarning) { + if(Minecraft.getMinecraft().thePlayer.fishEntity != null) { + if(!pingDelayList.isEmpty()) { + while(pingDelayList.size() > 5) pingDelayList.remove(pingDelayList.size()-1); + + int totalMS = 0; + for(int delay : pingDelayList) { + totalMS += delay; + } + + int averageMS = totalMS / pingDelayList.size(); + pingDelayTicks = (int)Math.ceil(averageMS/50f); + } + } + + if(hookedWarningStateTicks > 0) { + hookedWarningStateTicks--; + warningState = PlayerWarningState.FISH_HOOKED; + } else { + warningState = PlayerWarningState.NOTHING; + if(Minecraft.getMinecraft().thePlayer.fishEntity != null) { + int fishEntityId = Minecraft.getMinecraft().thePlayer.fishEntity.getEntityId(); + for(Map.Entry<WakeChain, List<Integer>> entry : chains.entrySet()) { + if(entry.getKey().particleNum >= 3 && entry.getValue().contains(fishEntityId)) { + warningState = PlayerWarningState.FISH_INCOMING; + break; + } + } + } + } + } + + if(tickCounter++ >= 20) { + long currentTime = System.currentTimeMillis(); + tickCounter = 0; + + Set<Integer> toRemoveEnt = new HashSet<>(); + for(Map.Entry<Integer, EntityFishHook> entry : hookEntities.entrySet()) { + if(entry.getValue().isDead) { + toRemoveEnt.add(entry.getKey()); + } + } + hookEntities.keySet().removeAll(toRemoveEnt); + + Set<WakeChain> toRemoveChain = new HashSet<>(); + for(Map.Entry<WakeChain, List<Integer>> entry : chains.entrySet()) { + if(currentTime - entry.getKey().lastUpdate > 200 || + entry.getValue().isEmpty() || + Collections.disjoint(entry.getValue(), hookEntities.keySet())) { + toRemoveChain.add(entry.getKey()); + } + } + chains.keySet().removeAll(toRemoveChain); + } + } + } + + private double calculateAngleFromOffsets(double xOffset, double zOffset) { + double angleX = Math.toDegrees(Math.acos(xOffset / 0.04f)); + double angleZ = Math.toDegrees(Math.asin(zOffset / 0.04f)); + + if(xOffset < 0) { + angleZ = 180 - angleZ; + } + if(zOffset < 0) { + angleX = 360 - angleX; + } + + angleX %= 360; + angleZ %= 360; + if(angleX < 0) angleX += 360; + if(angleZ < 0) angleZ += 360; + + double dist = angleX - angleZ; + if(dist < -180) dist += 360; + if(dist > 180) dist -= 360; + + return angleZ + dist/2; + } + + private boolean checkAngleWithinRange(double angle1, double angle2, double range) { + double dist = Math.abs(angle1 - angle2); + if(dist > 180) dist = 360 - dist; + + return dist <= range; + } + + private enum HookPossibleRet { + NOT_POSSIBLE, + EITHER, + ANGLE1, + ANGLE2 + } + + private HookPossibleRet isHookPossible(EntityFishHook hook, double particleX, double particleY, double particleZ, double angle1, double angle2) { + double dY = particleY - hook.posY; + if(Math.abs(dY) > 0.5f) { + return HookPossibleRet.NOT_POSSIBLE; + } + + double dX = particleX - hook.posX; + double dZ = particleZ - hook.posZ; + double dist = Math.sqrt(dX*dX + dZ*dZ); + + if(dist < 0.2) { + return HookPossibleRet.EITHER; + } else { + float angleAllowance = (float)Math.toDegrees(Math.atan2(0.03125f, dist))*1.5f; + float angleHook = (float) Math.toDegrees(Math.atan2(dX, dZ)); + angleHook %= 360; + if(angleHook < 0) angleHook += 360; + + if(checkAngleWithinRange(angle1, angleHook, angleAllowance)) { + return HookPossibleRet.ANGLE1; + } else if(checkAngleWithinRange(angle2, angleHook, angleAllowance)) { + return HookPossibleRet.ANGLE2; + } + } + return HookPossibleRet.NOT_POSSIBLE; + } + + public static EnumParticleTypes type = EnumParticleTypes.BARRIER; + + private static final float ZERO_PITCH = 1.0f; + private static final float MAX_PITCH = 0.1f; + private static final float MAX_DISTANCE = 5f; + private float calculatePitchFromDistance(float d) { + if(d < 0.1f) d = 0.1f; + if(d > MAX_DISTANCE) d = MAX_DISTANCE; + + return 1/(d + (1/(ZERO_PITCH-MAX_PITCH))) * (1 - d/MAX_DISTANCE) + MAX_PITCH; + } + + public boolean onSpawnParticle(EnumParticleTypes particleType, double x, double y, double z, double xOffset, double yOffset, double zOffset) { + if(!NotEnoughUpdates.INSTANCE.config.fishing.hideOtherPlayerAll && + !NotEnoughUpdates.INSTANCE.config.fishing.enableCustomParticles && + !NotEnoughUpdates.INSTANCE.config.fishing.incomingFishWarning) { + return false; + } + if(hookEntities.isEmpty()) { + return false; + } + + if(particleType == EnumParticleTypes.WATER_WAKE && Math.abs(yOffset - 0.01f) < 0.001f) { + double angle1 = calculateAngleFromOffsets(xOffset, -zOffset); + double angle2 = calculateAngleFromOffsets(-xOffset, zOffset); + + final List<Integer> possibleHooks1 = new ArrayList<>(); + final List<Integer> possibleHooks2 = new ArrayList<>(); + + for(EntityFishHook hook : hookEntities.values()) { + if(hook.isDead) continue; + if(possibleHooks1.contains(hook.getEntityId())) continue; + if(possibleHooks2.contains(hook.getEntityId())) continue; + + HookPossibleRet ret = isHookPossible(hook, x, y, z, angle1, angle2); + if(ret == HookPossibleRet.ANGLE1) { + possibleHooks1.add(hook.getEntityId()); + } else if(ret == HookPossibleRet.ANGLE2) { + possibleHooks2.add(hook.getEntityId()); + } else if(ret == HookPossibleRet.EITHER) { + possibleHooks1.add(hook.getEntityId()); + possibleHooks2.add(hook.getEntityId()); + } + } + + if(!possibleHooks1.isEmpty() || !possibleHooks2.isEmpty()) { + long currentTime = System.currentTimeMillis(); + + boolean isMainPlayer = false; + + boolean foundChain = false; + for(Map.Entry<WakeChain, List<Integer>> entry : chains.entrySet()) { + WakeChain chain = entry.getKey(); + + if(currentTime - chain.lastUpdate > 200) continue; + + double updateAngle; + List<Integer> possibleHooks; + if(checkAngleWithinRange(chain.currentAngle, angle1, 16)) { + possibleHooks = possibleHooks1; + updateAngle = angle1; + } else if(checkAngleWithinRange(chain.currentAngle, angle2, 16)) { + possibleHooks = possibleHooks2; + updateAngle = angle2; + } else { + continue; + } + + if(!Collections.disjoint(entry.getValue(), possibleHooks)) { + HashSet<Integer> newHooks = new HashSet<>(); + + for(int hookEntityId : possibleHooks) { + if(entry.getValue().contains(hookEntityId) && chain.distances.containsKey(hookEntityId)) { + EntityFishHook entity = hookEntities.get(hookEntityId); + + if(entity != null && !entity.isDead) { + double oldDistance = chain.distances.get(hookEntityId); + + double dX = entity.posX - x; + double dZ = entity.posZ - z; + double newDistance = Math.sqrt(dX*dX + dZ*dZ); + + double delta = oldDistance - newDistance; + + if(newDistance < 0.2 || (delta > -0.1 && delta < 0.3)) { + if(NotEnoughUpdates.INSTANCE.config.fishing.incomingFishWarning && + Minecraft.getMinecraft().thePlayer.fishEntity != null && + Minecraft.getMinecraft().thePlayer.fishEntity.getEntityId() == hookEntityId && + chain.particleNum > 3) { + + if(newDistance <= 0.2f + 0.1f*pingDelayTicks) { + if(NotEnoughUpdates.INSTANCE.config.fishing.incomingFishHookedSounds && + hookedWarningStateTicks <= 0) { + Minecraft.getMinecraft().getSoundHandler().playSound( + PositionedSoundRecord.create(new ResourceLocation("note.pling"), 2f)); + } + + hookedWarningStateTicks = 12; + } else if(newDistance >= 0.4f + 0.1f*pingDelayTicks) { + if(NotEnoughUpdates.INSTANCE.config.fishing.incomingFishIncSounds && + buildupSoundDelay <= 0) { + ISound sound = new PositionedSound(new ResourceLocation("note.pling")) {{ + volume = 0.1f; + pitch = calculatePitchFromDistance((float)newDistance - (0.3f+0.1f*pingDelayTicks)); + repeat = false; + repeatDelay = 0; + attenuationType = ISound.AttenuationType.NONE; + }}; + Minecraft.getMinecraft().getSoundHandler().playSound(sound); + buildupSoundDelay = 4; + } + } + } + + chain.distances.put(hookEntityId, newDistance); + newHooks.add(hookEntityId); + } + } + + } + } + if(newHooks.isEmpty()) { + continue; + } + + entry.getValue().retainAll(newHooks); + chain.distances.keySet().retainAll(newHooks); + + for(int i : entry.getValue()) { + EntityFishHook hook = hookEntities.get(i); + if(hook != null && hook.angler == Minecraft.getMinecraft().thePlayer) { + isMainPlayer = true; + break; + } + } + + chain.lastUpdate = currentTime; + chain.particleNum++; + chain.currentAngle = updateAngle; + + foundChain = true; + } + } + + + if(!foundChain) { + possibleHooks1.removeAll(possibleHooks2); + if(!possibleHooks1.isEmpty()) { + for(int i : possibleHooks1) { + EntityFishHook hook = hookEntities.get(i); + if(hook != null && hook.angler == Minecraft.getMinecraft().thePlayer) { + isMainPlayer = true; + break; + } + } + + WakeChain chain = new WakeChain(currentTime, angle1, x, z); + for(int hookEntityId : possibleHooks1) { + EntityFishHook entity = hookEntities.get(hookEntityId); + + if(entity != null && !entity.isDead) { + double dX = entity.posX - x; + double dZ = entity.posZ - z; + double newDistance = Math.sqrt(dX*dX + dZ*dZ); + chain.distances.put(hookEntityId, newDistance); + } + } + chains.put(chain, possibleHooks1); + } else if(!possibleHooks2.isEmpty()) { + for(int i : possibleHooks2) { + EntityFishHook hook = hookEntities.get(i); + if(hook != null && hook.angler == Minecraft.getMinecraft().thePlayer) { + isMainPlayer = true; + break; + } + } + + WakeChain chain = new WakeChain(currentTime, angle2, x, z); + for(int hookEntityId : possibleHooks2) { + EntityFishHook entity = hookEntities.get(hookEntityId); + + if(entity != null && !entity.isDead) { + double dX = entity.posX - x; + double dZ = entity.posZ - z; + double newDistance = Math.sqrt(dX*dX + dZ*dZ); + chain.distances.put(hookEntityId, newDistance); + } + } + chains.put(chain, possibleHooks2); + } |
