diff options
Diffstat (limited to 'src/main/java/at/hannibal2')
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt | 3 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java | 22 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt | 18 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/rift/ShyCruxWarnings.kt (renamed from src/main/java/at/hannibal2/skyhanni/features/rift/CruxWarnings.kt) | 2 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/rift/VoltHighlighter.kt | 117 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java | 10 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt | 93 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt | 26 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt | 13 |
9 files changed, 268 insertions, 36 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index be761a7c8..f6cd9389a 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -305,8 +305,9 @@ class SkyHanniMod { loadModule(GhostCounter) loadModule(RiftTimer()) loadModule(HighlightRiftGuide()) - loadModule(CruxWarnings()) + loadModule(ShyCruxWarnings()) loadModule(RiftLarva()) + loadModule(VoltHighlighter()) loadModule(RiftOdonata()) loadModule(RiftAgaricusCap()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java index 8cff848fd..4fb73b1ac 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java @@ -47,6 +47,28 @@ public class RiftConfig { "Useful if you play without volume.") @ConfigEditorBoolean public boolean shyWarning = true; + + + @Expose + @ConfigOption(name = "Volt Warning", desc = "Shows a warning while a volt is discharging lightning") + @ConfigEditorBoolean + public boolean voltWarning = true; + + @Expose + @ConfigOption(name = "Volt Range Highlighter", desc = "Shows the area in which a Volt might strike lightning") + @ConfigEditorBoolean + public boolean voltRange = true; + + @Expose + @ConfigOption(name = "Volt Range Highlighter Colour", desc = "In which colour should the volt range be highlighted") + @ConfigEditorColour + public String voltColour = "0:60:0:0:255"; + + @Expose + @ConfigOption(name = "Volt mood colour", desc = "Change the colour of the volt enemy depending on their mood") + @ConfigEditorBoolean + public boolean voltMoodMeter = false; + } @ConfigOption(name = "Larvas", desc = "") diff --git a/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt new file mode 100644 index 000000000..c9a67f154 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/EntityEquipmentChangeEvent.kt @@ -0,0 +1,18 @@ +package at.hannibal2.skyhanni.events + +import net.minecraft.entity.Entity +import net.minecraft.item.ItemStack + +data class EntityEquipmentChangeEvent( + val entity: Entity, + val equipmentSlot: Int, + val newItemStack: ItemStack? +) : LorenzEvent() { + companion object { + val EQUIPMENT_SLOT_HEAD = 4 + val EQUIPMENT_SLOT_CHEST = 3 + val EQUIPMENT_SLOT_LEGGINGS = 2 + val EQUIPMENT_SLOT_FEET = 1 + val EQUIPMENT_SLOT_HAND = 0 + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/CruxWarnings.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/ShyCruxWarnings.kt index 39834a6bd..0b7f60d30 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/rift/CruxWarnings.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/ShyCruxWarnings.kt @@ -8,7 +8,7 @@ import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer import net.minecraft.client.Minecraft import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -class CruxWarnings { +class ShyCruxWarnings { private val shyNames = arrayOf("I'm ugly! :(", "Eek!", "Don't look at me!", "Look away!") @SubscribeEvent diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/VoltHighlighter.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/VoltHighlighter.kt new file mode 100644 index 000000000..0d1a824e4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/VoltHighlighter.kt @@ -0,0 +1,117 @@ +package at.hannibal2.skyhanni.features.rift + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.TitleUtils +import at.hannibal2.skyhanni.events.EntityEquipmentChangeEvent +import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper +import at.hannibal2.skyhanni.utils.RenderUtils +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SpecialColour +import at.hannibal2.skyhanni.utils.TimeUtils +import net.minecraft.client.Minecraft +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.item.ItemSkull +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTUtil +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.awt.Color +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds + +class VoltHighlighter { + val config get() = SkyHanniMod.feature.rift.crux + + val LIGHTNING_DISTANCE = 7F + val ARMOR_SLOT_HEAD = 3 + val CHARGE_TIME = 12.seconds + var dischargingSince = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onArmorChange(event: EntityEquipmentChangeEvent) { + if (!RiftAPI.inRift() || !config.voltWarning) return + val player = Minecraft.getMinecraft().thePlayer ?: return + if (EntityEquipmentChangeEvent.EQUIPMENT_SLOT_HEAD == event.equipmentSlot + && getVoltState(event.entity) == VoltState.AVoltThatIsCurrentlyAtThisMomentActivelySpawningLightning + && event.entity.positionVector.squareDistanceTo(player.positionVector) <= LIGHTNING_DISTANCE * LIGHTNING_DISTANCE + ) { + dischargingSince = SimpleTimeMark.now() + } + } + + @SubscribeEvent + fun onRender(event: RenderWorldLastEvent) { + if (!RiftAPI.inRift() || !(config.voltRange || config.voltMoodMeter)) return + val dischargeTimeLeft = CHARGE_TIME - dischargingSince.passedSince() + if (dischargeTimeLeft > Duration.ZERO) { + TitleUtils.sendTitle( + "§eLightning: ${TimeUtils.formatDuration(dischargeTimeLeft, showMilliSeconds = true)}", + 50 + ) + } + val e = Minecraft.getMinecraft().theWorld?.loadedEntityList ?: return + for (e in e) { + if (e !is EntityLivingBase) continue + val s = getVoltState(e) + if (s == VoltState.NotAVolt) continue + + if (config.voltMoodMeter) + RenderLivingEntityHelper.setEntityColor( + e, when (s) { + VoltState.AVoltThatIsFriendly -> 0x8000FF00.toInt() + VoltState.AVoltThatIsCurrentlyAtThisMomentActivelySpawningLightning -> 0x800000FF.toInt() + VoltState.AVoltThatIsAggressiveButDoesNotDischargeAtmosphericElectricity -> 0x80FF0000.toInt() + else -> 0 + } + ) { true } + if (s == VoltState.AVoltThatIsCurrentlyAtThisMomentActivelySpawningLightning && config.voltRange) { + RenderUtils.drawCylinderInWorld( + Color(SpecialColour.specialToChromaRGB(config.voltColour), true), + e.posX, + e.posY - 4f, + e.posZ, + radius = LIGHTNING_DISTANCE, + partialTicks = event.partialTicks, + height = 20F + ) + } + } + } + + enum class VoltState { + NotAVolt, + AVoltThatIsFriendly, + AVoltThatIsAggressiveButDoesNotDischargeAtmosphericElectricity, + AVoltThatIsCurrentlyAtThisMomentActivelySpawningLightning, ; + } + + private fun getVoltState(itemStack: ItemStack): VoltState { + if (itemStack.item !is ItemSkull) return VoltState.NotAVolt + val skullOwnerNbt = itemStack.getSubCompound("SkullOwner", false) ?: return VoltState.NotAVolt + val profile = NBTUtil.readGameProfileFromNBT(skullOwnerNbt) ?: return VoltState.NotAVolt + val textures = profile.properties["textures"].singleOrNull() ?: return VoltState.NotAVolt + return when (textures.value) { + "ewogICJ0aW1lc3RhbXAiIDogMTY3Mzg4MzU3MjAzNSwKICAicHJvZmlsZUlkIiA6ICI0MDU4NDhjMmJjNTE0ZDhkOThkOTJkMGIwYzhiZDQ0YiIsCiAgInByb2ZpbGVOYW1lIiA6ICJMb3ZlT3dPIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2UxYjFiZmI1MzZiNjQxNmIyNmEyODNkMmQ4YWQ0YjE3NzFiYmU1Yjc2ODk2ZTI3MjdkNWU4MzNiYzg5NDk4MmQiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==" -> { + VoltState.AVoltThatIsCurrentlyAtThisMomentActivelySpawningLightning + } + + "ewogICJ0aW1lc3RhbXAiIDogMTY3MzYzNzQ1OTAwOCwKICAicHJvZmlsZUlkIiA6ICJmMTA0NzMxZjljYTU0NmI0OTkzNjM4NTlkZWY5N2NjNiIsCiAgInByb2ZpbGVOYW1lIiA6ICJ6aWFkODciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2FlYTYyNTFlNThlM2QyMDU1MmEwMzVkNDI0NTYxZWFlZTA4M2ZlYWNkMWU2Y2IzYzJhNWNmOTQ1Y2U2ZDc2ZSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9" -> { + VoltState.AVoltThatIsFriendly + } + + "ewogICJ0aW1lc3RhbXAiIDogMTY3Mzg4MzEwNjAwMywKICAicHJvZmlsZUlkIiA6ICI5NTE3OTkxNjljYzE0MGY1OGM2MmRjOGZmZTU3NjBiZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJZdWFyaWciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGY5ZWRlOTcwZDQwYzViMjQ1Y2JkNjUxMzQ5ZWUxNjZmNjk1ZDI1MDM0NWY4ZjBlNjNmY2IxMGNmYjVhMmI3OCIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9" -> { + VoltState.AVoltThatIsAggressiveButDoesNotDischargeAtmosphericElectricity + } + + else -> VoltState.NotAVolt + } + + } + + private fun getVoltState(entity: net.minecraft.entity.Entity): VoltState { + if (entity !is EntityArmorStand) return VoltState.NotAVolt + val helmet = entity.getCurrentArmor(ARMOR_SLOT_HEAD) ?: return VoltState.NotAVolt + return getVoltState(helmet) + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java index bd4107369..8d2f6c5d3 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java @@ -1,15 +1,19 @@ package at.hannibal2.skyhanni.mixins.transformers; +import at.hannibal2.skyhanni.events.EntityEquipmentChangeEvent; import at.hannibal2.skyhanni.mixins.hooks.NetHandlerPlayClientHookKt; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.entity.Entity; import net.minecraft.network.Packet; import net.minecraft.network.play.INetHandlerPlayClient; +import net.minecraft.network.play.server.S04PacketEntityEquipment; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(value = NetHandlerPlayClient.class, priority = 1001) public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient { @@ -21,4 +25,10 @@ public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient private void onSendPacket(Packet<?> packet, CallbackInfo ci) { NetHandlerPlayClientHookKt.onSendPacket(packet, ci); } + + @Inject(method = "handleEntityEquipment", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setCurrentItemOrArmor(ILnet/minecraft/item/ItemStack;)V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD) + public void onEntityEquipment(S04PacketEntityEquipment packetIn, CallbackInfo ci, Entity entity) { + new EntityEquipmentChangeEvent(entity, packetIn.getEquipmentSlot(), packetIn.getItemStack()).postAndCatch(); + } + } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 58e000ce7..cade8b0fe 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -93,28 +93,52 @@ object RenderUtils { * @author Moulberry * @author Mojang */ - fun drawFilledBoundingBox(aabb: AxisAlignedBB, c: Color, alphaMultiplier: Float = 1f) { + fun drawFilledBoundingBox( + aabb: AxisAlignedBB, + c: Color, + alphaMultiplier: Float = 1f, + /** + * If set to `true`, renders the box relative to the camera instead of relative to the world. + * If set to `false`, will be relativized to [RenderUtils.getViewerPos]. Setting this to `false` requires + * specifying [partialTicks]] + */ + renderRelativeToCamera: Boolean = true, + drawVerticalBarriers: Boolean = true, + partialTicks: Float = 0F + ) { GlStateManager.enableBlend() GlStateManager.disableLighting() - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) GlStateManager.disableTexture2D() + GlStateManager.disableCull() + val effectiveAABB = if (!renderRelativeToCamera) { + val vp = getViewerPos(partialTicks) + AxisAlignedBB( + aabb.minX - vp.x, aabb.minY - vp.y, aabb.minZ - vp.z, + aabb.maxX - vp.x, aabb.maxY - vp.y, aabb.maxZ - vp.z, + ) + } else { + aabb + } val tessellator = Tessellator.getInstance() val worldRenderer = tessellator.worldRenderer - GlStateManager.color(c.red / 255f, c.green / 255f, c.blue / 255f, c.alpha / 255f * alphaMultiplier) //vertical - worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() - tessellator.draw() - worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() - tessellator.draw() + if (drawVerticalBarriers) { + GlStateManager.color(c.red / 255f, c.green / 255f, c.blue / 255f, c.alpha / 255f * alphaMultiplier) + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + tessellator.draw() + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + tessellator.draw() + } GlStateManager.color( c.red / 255f * 0.8f, c.green / 255f * 0.8f, @@ -124,16 +148,16 @@ object RenderUtils { //x worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() tessellator.draw() worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() tessellator.draw() GlStateManager.color( c.red / 255f * 0.9f, @@ -143,18 +167,19 @@ object RenderUtils { ) //z worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.minZ).endVertex() tessellator.draw() worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex() - worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.minY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.maxX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() + worldRenderer.pos(effectiveAABB.minX, effectiveAABB.maxY, effectiveAABB.maxZ).endVertex() tessellator.draw() GlStateManager.enableTexture2D() + GlStateManager.enableCull() GlStateManager.disableBlend() } @@ -180,7 +205,7 @@ object RenderUtils { GlStateManager.enableTexture2D() GlStateManager.tryBlendFuncSeparate(770, 1, 1, 0) GlStateManager.enableBlend() - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) val time = Minecraft.getMinecraft().theWorld.totalWorldTime + partialTicks.toDouble() val d1 = MathHelper.func_181162_h( -time * 0.2 - MathHelper.floor_double(-time * 0.1) @@ -321,7 +346,7 @@ object RenderUtils { GlStateManager.disableLighting() GlStateManager.depthMask(false) GlStateManager.enableBlend() - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) val tessellator = Tessellator.getInstance() val worldrenderer = tessellator.worldRenderer val i = 0 @@ -591,7 +616,7 @@ object RenderUtils { GlStateManager.enableBlend() GlStateManager.depthFunc(GL11.GL_LEQUAL) GlStateManager.disableCull() - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) GlStateManager.enableAlpha() GlStateManager.disableTexture2D() color.bindColor() diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt new file mode 100644 index 000000000..bd682b913 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/SimpleTimeMark.kt @@ -0,0 +1,26 @@ +package at.hannibal2.skyhanni.utils + +import java.time.Instant +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds + +@JvmInline +value class SimpleTimeMark(val millis: Long) { + operator fun minus(other: SimpleTimeMark) = + (millis - other.millis).milliseconds + + operator fun plus(other: Duration) = + SimpleTimeMark(millis + other.inWholeMilliseconds) + + fun passedSince() = if (millis == 0L) Duration.INFINITE else now() - this + + override fun toString(): String { + if (millis == 0L) return "The Far Past" + return Instant.ofEpochMilli(millis).toString() + } + + companion object { + fun now() = SimpleTimeMark(System.currentTimeMillis()) + fun farPast() = SimpleTimeMark(0) + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt index f7cd79b40..a0b6e91d8 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt @@ -2,11 +2,23 @@ package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import kotlin.time.Duration object TimeUtils { private val pattern = "(?:(?<y>\\d+) ?y(?:\\w* ?)?)?(?:(?<d>\\d+) ?d(?:\\w* ?)?)?(?:(?<h>\\d+) ?h(?:\\w* ?)?)?(?:(?<m>\\d+) ?m(?:\\w* ?)?)?(?:(?<s>\\d+) ?s(?:\\w* ?)?)?".toPattern() + + fun formatDuration( + duration: Duration, + biggestUnit: TimeUnit = TimeUnit.YEAR, + showMilliSeconds: Boolean = false, + longName: Boolean = false, + maxUnits: Int = -1 + ): String = formatDuration( + duration.inWholeMilliseconds - 999, biggestUnit, showMilliSeconds, longName, maxUnits + ) + fun formatDuration( millis: Long, biggestUnit: TimeUnit = TimeUnit.YEAR, @@ -14,6 +26,7 @@ object TimeUtils { longName: Boolean = false, maxUnits: Int = -1 ): String { + // TODO: if this weird offset gets removed, also remove that subtraction from formatDuration(kotlin.time.Duration) var milliseconds = millis + 999 val map = mutableMapOf<TimeUnit, Int>() for (unit in TimeUnit.values()) { |