fixes, wip hotbar hover text, fix crash in TextElement with empty lines

This commit is contained in:
Bixilon 2021-10-23 23:11:50 +02:00
parent 565b5b1950
commit 14d7eb0d89
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 74 additions and 26 deletions

View File

@ -25,8 +25,8 @@ Minosoft is an open source minecraft client, written from scratch in kotlin (and
## System requirements
- CPU: Minosoft works mostly asynchronous, so multiple cores are good. For FPS more clock speed is better.
- RAM: ~500Mib. With overhead, etc 2Gib recommended
- Disk space: Minosoft itself is pretty small (2-3 Mib), the libraries are a bit bigger (~80 Mib). You also need to have the "normal" minecraft assets (~ 300 MB per minecraft version).
- RAM: Minimum 300 MiB, 1 GiB recommended
- Disk space: Minosoft itself is pretty small (2-3 MiB), the libraries are a bit bigger (~80 MiB). You also need to have the "normal" minecraft assets (~ 300 MiB per minecraft version).
- GPU: OpenGL 3.3+. Every modern GPU works and is recommended.
- Java 11+, newest version recommended (This is really important, we use features that are only available in this version. Java 8 is currently **not** supported).

View File

@ -119,7 +119,7 @@ abstract class Element(val hudRenderer: HUDRenderer) {
if (RenderConstants.DISABLE_GUI_CACHE || !cacheEnabled) {
return forceRender(offset, z, consumer, options)
}
if (!cacheUpToDate || cache.offset != offset || hudRenderer.matrixChange || cache.matrix != hudRenderer.matrix || z != cache.z) {
if (!cacheUpToDate || cache.offset != offset || hudRenderer.matrixChange || cache.matrix !== hudRenderer.matrix || z != cache.z) {
val cache = GUIMeshCache(hudRenderer.matrix)
cache.offset = offset
cache.z = z

View File

@ -39,11 +39,11 @@ class FadingTextElement(
) : TextElement(hudRenderer = hudRenderer, text = text, fontAlignment = fontAlignment, background = background, backgroundColor = backgroundColor, noBorder = noBorder, parent), Pollable {
override var cacheEnabled: Boolean
get() {
if (!super.cacheEnabled || hidden) {
return true
if (hidden || !super.cacheEnabled) {
return false
}
val time = System.currentTimeMillis()
return !((time < fadeInEndTime) || (time in (fadeInEndTime + 1) until fadeOutEndTime))
return (time >= fadeInEndTime) && (time < fadeOutStartTime)
}
set(value) {
super.cacheEnabled = value
@ -76,6 +76,7 @@ class FadingTextElement(
}
fun show() {
// ToDo: Check if already showing
val time = System.currentTimeMillis()
fadeInStartTime = time
fadeInEndTime = fadeInStartTime + fadeInTime
@ -84,6 +85,18 @@ class FadingTextElement(
hidden = false
}
fun hide() {
if (hidden) {
return
}
// ToDo: Eventually fade out when fading in
val time = System.currentTimeMillis()
fadeInStartTime = -1L
fadeInEndTime = -1L
fadeOutStartTime = time
fadeOutEndTime = fadeOutStartTime + fadeOutTime
}
fun forceHide() {
hidden = true
}
@ -104,8 +117,11 @@ class FadingTextElement(
if (hidden) {
return 0
}
val time = System.currentTimeMillis()
if (time > fadeOutEndTime) {
return 0
}
alpha = 1.0f
if (time < fadeInEndTime) {
@ -116,7 +132,6 @@ class FadingTextElement(
} else if (time < fadeOutEndTime) {
alpha = (fadeOutEndTime - time) / fadeOutTime.toFloat()
} else {
alpha = 0.0f
return 0
}

View File

@ -100,20 +100,16 @@ open class TextElement(
override fun forceSilentApply() {
val size = Vec2i.EMPTY
if (chatComponent.message.contains("pitch=")) {
val a = maxSize
var b = 1
}
val renderInfo = TextRenderInfo(
fontAlignment = fontAlignment,
charHeight = charHeight,
charMargin = charMargin,
)
if (!emptyMessage) {
val renderInfo = TextRenderInfo(
fontAlignment = fontAlignment,
charHeight = charHeight,
charMargin = charMargin,
)
ChatComponentRenderer.render(Vec2i.EMPTY, Vec2i.EMPTY, size, 0, this, renderWindow, null, null, renderInfo, chatComponent)
renderInfo.currentLineNumber = 0
this.renderInfo = renderInfo
}
this.renderInfo = renderInfo
this.cacheUpToDate = false
_size = size

View File

@ -49,11 +49,9 @@ class HotbarBaseElement(hudRenderer: HUDRenderer) : Element(hudRenderer), Pollab
frame.render(offset + it.start - HORIZONTAL_MARGIN + FRAME_OFFSET, z + 1, consumer, options)
}
val inventoryZ = inventoryElement.render(offset, z + 2, consumer, options)
val inventoryZ = inventoryElement.render(offset + HORIZONTAL_MARGIN, z + 2, consumer, options)
// ToDo: Item rendering
return 2 + inventoryZ// bar + frame
return 2 + inventoryZ // bar + frame
}
override fun poll(): Boolean {

View File

@ -41,6 +41,9 @@ class HotbarElement(hudRenderer: HUDRenderer) : Element(hudRenderer) {
private val topRight = RowLayout(hudRenderer, HorizontalAlignments.RIGHT, 1) // contains hunger, air
val hoverText = FadingTextElement(hudRenderer, text = "", fadeInTime = 300, stayTime = 3000, fadeOutTime = 500, background = false, noBorder = true)
private var hoverTextShown = false
private val itemText = FadingTextElement(hudRenderer, text = "", fadeInTime = 300, stayTime = 1500, fadeOutTime = 500, background = false, noBorder = true)
private var lastItemStackNameShown: ItemStack? = null
private var lastItemSlot = -1
@ -51,8 +54,11 @@ class HotbarElement(hudRenderer: HUDRenderer) : Element(hudRenderer) {
private var renderElements = setOf(
base,
experience,
topLeft,
topRight,
itemText,
hoverText,
)
override var cacheEnabled: Boolean = false // ToDo: Cache correctly
@ -79,12 +85,17 @@ class HotbarElement(hudRenderer: HUDRenderer) : Element(hudRenderer) {
base.parent = this
experience.parent = this
itemText.parent = this
hoverText.parent = this
forceSilentApply()
}
override fun forceRender(offset: Vec2i, z: Int, consumer: GUIVertexConsumer, options: GUIVertexOptions?): Int {
var maxZ = 0
if (hoverTextShown) {
hoverText.render(offset + Vec2i(HorizontalAlignments.CENTER.getOffset(size.x, hoverText.size.x), 0), z, consumer, options)
offset.y += hoverText.size.y + HOVER_TEXT_OFFSET
}
if (itemTextShown) {
itemText.render(offset + Vec2i(HorizontalAlignments.CENTER.getOffset(size.x, itemText.size.x), 0), z, consumer, options)
offset.y += itemText.size.y + ITEM_NAME_OFFSET
@ -125,6 +136,12 @@ class HotbarElement(hudRenderer: HUDRenderer) : Element(hudRenderer) {
size.x = max(size.x, itemText.size.x)
}
hoverTextShown = !hoverText.hidden
if (hoverTextShown) {
size.y += hoverText.size.y + HOVER_TEXT_OFFSET
size.x = max(size.x, hoverText.size.x)
}
_size = size
cacheUpToDate = false
}
@ -135,8 +152,12 @@ class HotbarElement(hudRenderer: HUDRenderer) : Element(hudRenderer) {
if (currentItem != lastItemStackNameShown || itemSlot != lastItemSlot) {
lastItemStackNameShown = currentItem
lastItemSlot = itemSlot
itemText.text = hudRenderer.connection.player.inventory.getHotbarSlot()?.displayName ?: "" // ToDo: This calls silentApply again...
itemText.show()
currentItem?.displayName?.let { itemText.text = it } // ToDo: This calls silentApply again...
if (currentItem == null) {
itemText.hide()
} else {
itemText.show()
}
}
forceSilentApply() // ToDo: Check stuff
@ -150,16 +171,19 @@ class HotbarElement(hudRenderer: HUDRenderer) : Element(hudRenderer) {
override fun tick() {
silentApply()
hoverText.tick()
itemText.tick()
base.tick()
if (gamemode.survival) {
topLeft.tick()
topRight.tick()
}
experience.tick()
base.tick()
}
companion object {
private const val HOVER_TEXT_OFFSET = 15
private const val ITEM_NAME_OFFSET = 5
private const val VERTICAL_SPACING = 1
}

View File

@ -13,11 +13,13 @@
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.other.game.event.handlers.gamemode.GamemodeChangeEvent
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDElement
import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent
import de.bixilon.minosoft.modding.event.events.ExperienceChangeEvent
import de.bixilon.minosoft.modding.event.events.SelectHotbarSlotEvent
import de.bixilon.minosoft.modding.event.events.container.ContainerRevisionChangeEvent
@ -59,6 +61,14 @@ class HotbarHUDElement(hudRenderer: HUDRenderer) : HUDElement<HotbarElement>(hud
}
layout.base.apply()
})
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
if (it.position != ChatTextPositions.ABOVE_HOTBAR) {
return@of
}
layout.hoverText.text = it.message
layout.hoverText.show()
})
}

View File

@ -18,6 +18,7 @@ import de.bixilon.minosoft.modding.event.EventInitiators
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.play.ChatMessageS2CP
import de.bixilon.minosoft.protocol.packets.s2c.play.title.HotbarTextSetS2CP
import java.util.*
class ChatMessageReceiveEvent(
@ -30,4 +31,6 @@ class ChatMessageReceiveEvent(
constructor(connection: PlayConnection, packet: ChatMessageS2CP) : this(connection, EventInitiators.SERVER, packet.message, packet.position, packet.sender)
constructor(connection: PlayConnection, packet: HotbarTextSetS2CP) : this(connection, EventInitiators.SERVER, packet.text, ChatTextPositions.ABOVE_HOTBAR, null)
}

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.packets.s2c.play.title
import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
@ -29,5 +30,6 @@ class HotbarTextSetS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
override fun handle(connection: PlayConnection) {
Log.log(LogMessageType.CHAT_IN) { "[HOTBAR] $text" }
connection.fireEvent(ChatMessageReceiveEvent(connection, this))
}
}

View File

@ -123,7 +123,7 @@ object MicrosoftOAuthUtils {
response.body!!
if (response.statusCode != 200) {
throw LoginException(response.statusCode, "Could not get minecraft access token ", response.body["errorMessage"].unsafeCast())
throw LoginException(response.statusCode, "Could not get minecraft access token ", (response.body["errorMessage"] ?: response.body["error"] ?: "unknown").unsafeCast())
}
return response.body["access_token"].unsafeCast()
}