Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement notifications HUD #488

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.lambda.client.gui.hudgui.elements.client

import com.lambda.client.gui.hudgui.HudElement
import com.lambda.client.util.color.ColorHolder
import com.lambda.client.util.graphics.RenderUtils2D
import com.lambda.client.util.graphics.VertexHelper
import com.lambda.client.util.graphics.font.FontRenderAdapter
import com.lambda.client.util.math.Vec2d
import com.lambda.client.util.threads.runSafe
import com.lambda.client.util.threads.safeAsyncListener
import net.minecraft.client.renderer.GlStateManager
import net.minecraftforge.fml.common.gameevent.TickEvent

internal object Notifications : HudElement(
name = "Notifications",
category = Category.CLIENT,
description = "Shows notifications"
) {

private var cacheWidth = 90.0
private var cacheHeight = 23.0

override val hudWidth: Float
get() = cacheWidth.toFloat()
override val hudHeight: Float
get() = cacheHeight.toFloat()

private val notifications = mutableListOf<Notification>()

init {
safeAsyncListener<TickEvent.ClientTickEvent> { event ->
if (event.phase != TickEvent.Phase.END) return@safeAsyncListener

val removalList = notifications.filter { notification ->
notification.startTime + notification.duration < System.currentTimeMillis()
}
notifications.removeAll(removalList)

cacheHeight = if (notifications.isEmpty()) 23.0 else notifications.size * 26.0
}
}

override fun renderHud(vertexHelper: VertexHelper) {
super.renderHud(vertexHelper)

runSafe {
notifications.forEachIndexed { index, notification ->
GlStateManager.pushMatrix()

GlStateManager.translate(0.0, index * 28.0, 0.0)
drawNotification(vertexHelper, notification)

GlStateManager.popMatrix()
}
}
}

private fun drawNotification(vertexHelper: VertexHelper, notification: Notification) {

val color = when (notification.type) {
NotificationType.INFO -> ColorHolder(3, 169, 244)
NotificationType.WARNING -> ColorHolder(255, 255, 0)
NotificationType.ERROR -> ColorHolder(255, 0, 0)
}

val startTime = notification.startTime
val duration = notification.duration

val currentTime = System.currentTimeMillis()
val elapsedTime = currentTime - startTime
val timeout = (88 * elapsedTime) / duration
val timeoutBarWidth = if (timeout > 88) 88 else if (timeout < 0) 0 else timeout

// Draw background
RenderUtils2D.drawRectFilled(vertexHelper, Vec2d.ZERO, Vec2d(90.0, 23.0), ColorHolder(0, 0, 0, 127))
urFate marked this conversation as resolved.
Show resolved Hide resolved

// Draw timeout bar
RenderUtils2D.drawRectFilled(vertexHelper, Vec2d(timeoutBarWidth.toDouble(), 23.0), Vec2d(88.0, 22.0), color)

// Draw right border
RenderUtils2D.drawRectFilled(vertexHelper, Vec2d(90.0, 0.0), Vec2d(88.0, 23.0), color)

// Draw text
FontRenderAdapter.drawString(notification.text, 10.0f, 9.0f, true, ColorHolder(), 0.6f, true)
}

fun addNotification(notification: Notification) {
notifications.add(notification)
}
}

data class Notification(
val text: String,
val type: NotificationType,
val duration: Int,
val startTime: Long = System.currentTimeMillis(),
)

enum class NotificationType {
INFO,
WARNING,
ERROR
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
package com.lambda.client.manager.managers

import com.lambda.client.gui.hudgui.elements.client.Notification
import com.lambda.client.gui.hudgui.elements.client.NotificationType
import com.lambda.client.gui.hudgui.elements.client.Notifications
import com.lambda.client.manager.Manager
import com.lambda.client.util.text.MessageSendHelper
import com.lambda.client.util.threads.safeListener
import net.minecraftforge.fml.common.gameevent.TickEvent
import java.util.*

object NotificationManager : Manager {
private val pendingNotifications: Queue<String> = LinkedList()
private val pendingNotifications: Queue<Notification> = LinkedList()

init {
safeListener<TickEvent.ClientTickEvent> {
while (pendingNotifications.isNotEmpty()) {
MessageSendHelper.sendErrorMessage(pendingNotifications.poll())
val notification = pendingNotifications.poll()
Notifications.addNotification(notification)
}
}
}

fun registerNotification(message: String) {
pendingNotifications.add(message)
pendingNotifications.add(Notification(message, NotificationType.INFO, 3000))
}

fun registerNotification(message: String, type: NotificationType) {
pendingNotifications.add(Notification(message, type, 3000))
urFate marked this conversation as resolved.
Show resolved Hide resolved
}
}
4 changes: 4 additions & 0 deletions src/main/kotlin/com/lambda/client/module/AbstractModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import com.lambda.client.commons.interfaces.Nameable
import com.lambda.client.event.LambdaEventBus
import com.lambda.client.event.events.ModuleToggleEvent
import com.lambda.client.gui.clickgui.LambdaClickGui
import com.lambda.client.gui.hudgui.elements.client.NotificationType
import com.lambda.client.manager.managers.NotificationManager
import com.lambda.client.module.modules.client.ClickGUI
import com.lambda.client.setting.configs.NameableConfig
import com.lambda.client.setting.settings.AbstractSetting
Expand Down Expand Up @@ -59,6 +61,8 @@ abstract class AbstractModule(
enabled.value = !enabled.value
isPaused = false
if (enabled.value) clicks.value++

NotificationManager.registerNotification("$chatName ${if (enabled.value) "Enabled" else "Disabled"}", NotificationType.INFO)
}

fun enable() {
Expand Down