Merge branch 'gui/wawla'

This commit is contained in:
Bixilon 2023-01-18 16:13:01 +01:00
commit ceee18b5d4
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
21 changed files with 662 additions and 11 deletions

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -16,8 +16,10 @@ package de.bixilon.minosoft.config.profile.profiles.gui.hud
import de.bixilon.minosoft.config.profile.profiles.gui.GUIProfile
import de.bixilon.minosoft.config.profile.profiles.gui.hud.crosshair.CrosshairC
import de.bixilon.minosoft.config.profile.profiles.gui.hud.hotbar.HotbarC
import de.bixilon.minosoft.config.profile.profiles.gui.hud.wawla.WawlaC
class HudC(profile: GUIProfile) {
val crosshair = CrosshairC(profile)
val hotbar = HotbarC(profile)
val wawla = WawlaC(profile)
}

View File

@ -0,0 +1,29 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.config.profile.profiles.gui.hud.wawla
import de.bixilon.minosoft.config.profile.delegate.primitive.BooleanDelegate
import de.bixilon.minosoft.config.profile.profiles.gui.GUIProfile
import de.bixilon.minosoft.config.profile.profiles.gui.hud.wawla.block.BlockC
import de.bixilon.minosoft.config.profile.profiles.gui.hud.wawla.entity.EntityC
class WawlaC(profile: GUIProfile) {
var enabled by BooleanDelegate(profile, true)
var limitReach by BooleanDelegate(profile, true)
var identifier by BooleanDelegate(profile, false)
val block = BlockC(profile)
val entity = EntityC(profile)
}

View File

@ -0,0 +1,21 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.config.profile.profiles.gui.hud.wawla.block
import de.bixilon.minosoft.config.profile.delegate.primitive.BooleanDelegate
import de.bixilon.minosoft.config.profile.profiles.gui.GUIProfile
class BlockC(profile: GUIProfile) {
var enabled by BooleanDelegate(profile, true)
}

View File

@ -0,0 +1,24 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.config.profile.profiles.gui.hud.wawla.entity
import de.bixilon.minosoft.config.profile.delegate.primitive.BooleanDelegate
import de.bixilon.minosoft.config.profile.profiles.gui.GUIProfile
class EntityC(profile: GUIProfile) {
var enabled by BooleanDelegate(profile, true)
var health by BooleanDelegate(profile, true)
var hand by BooleanDelegate(profile, false)
}

View File

@ -19,14 +19,17 @@ import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.entities.data.EntityData
import de.bixilon.minosoft.data.entities.data.EntityDataField
import de.bixilon.minosoft.data.entities.entities.SynchronizedEntityData
import de.bixilon.minosoft.data.entities.wawla.EntityWawlaProvider
import de.bixilon.minosoft.data.registries.entities.EntityFactory
import de.bixilon.minosoft.data.registries.entities.EntityType
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil
open class ItemFrame(connection: PlayConnection, entityType: EntityType, data: EntityData, position: Vec3d, rotation: EntityRotation) : HangingEntity(connection, entityType, data, position, rotation) {
open class ItemFrame(connection: PlayConnection, entityType: EntityType, data: EntityData, position: Vec3d, rotation: EntityRotation) : HangingEntity(connection, entityType, data, position, rotation), EntityWawlaProvider {
@get:SynchronizedEntityData
val item: ItemStack?
@ -39,10 +42,15 @@ open class ItemFrame(connection: PlayConnection, entityType: EntityType, data: E
@get:SynchronizedEntityData
var facing: Directions = Directions.NORTH
override fun setObjectData(data: Int) {
facing = Directions[data]
}
override fun getWawlaInformation(connection: PlayConnection, target: EntityTarget): ChatComponent {
return TextComponent("Item: $item")
}
companion object : EntityFactory<ItemFrame> {
override val identifier: ResourceLocation = minecraft("item_frame")
private val ITEM_DATA = EntityDataField("ITEM_FRAME_ITEM")

View File

@ -0,0 +1,23 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.entities.wawla
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
interface EntityWawlaProvider {
fun getWawlaInformation(connection: PlayConnection, target: EntityTarget): ChatComponent
}

View File

@ -16,16 +16,39 @@ package de.bixilon.minosoft.data.registries.blocks.types.plant
import de.bixilon.minosoft.data.registries.blocks.BlockFactory
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.MinecraftBlocks
import de.bixilon.minosoft.data.registries.blocks.wawla.BlockWawlaProvider
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.registries.Registries
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.world.chunk.light.SectionLight.Companion.BLOCK_LIGHT_MASK
import de.bixilon.minosoft.data.world.chunk.light.SectionLight.Companion.SKY_LIGHT_MASK
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
open class CropBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : PlantBlock(resourceLocation, registries, data) {
open class CropBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : PlantBlock(resourceLocation, registries, data), BlockWawlaProvider {
override fun canPlaceOn(blockState: BlockState): Boolean {
return blockState.block.identifier == MinecraftBlocks.FARMLAND
}
override fun getWawlaInformation(connection: PlayConnection, target: BlockTarget): ChatComponent {
val light = connection.world.getLight(target.blockPosition)
val blockLight = light and BLOCK_LIGHT_MASK
val skyLight = (light and SKY_LIGHT_MASK) shr 4
val component = BaseComponent("Light: ")
component += if (blockLight < MIN_LIGHT_LEVEL) "§4$blockLight§r" else "§a$blockLight§r"
component += " ($skyLight)"
return component
}
companion object : BlockFactory<CropBlock> {
const val MIN_LIGHT_LEVEL = 7
override fun build(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>): CropBlock {
return CropBlock(resourceLocation, registries, data)

View File

@ -0,0 +1,23 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks.wawla
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
interface BlockWawlaProvider {
fun getWawlaInformation(connection: PlayConnection, target: BlockTarget): ChatComponent
}

View File

@ -0,0 +1,20 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.wawla
import de.bixilon.minosoft.data.text.ChatComponent
interface WawlaInformation {
val text: ChatComponent
}

View File

@ -0,0 +1,43 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.text
object ChatComponentUtil {
fun BaseComponent.removeTrailingNewlines() {
val iterator = this.parts.iterator()
for (part in iterator) {
val message = part.message
if (message.isEmptyOrNewline()) {
iterator.remove()
continue
}
break
}
for (index in parts.size - 1 downTo 0) {
val message = parts[index].message
if (message.isEmptyOrNewline()) {
parts.removeAt(index)
continue
}
break
}
}
private fun String.isEmptyOrNewline(): Boolean {
return isEmpty() || this == "\n" || this == "\r" || this == "\n\r" || this == "\r\n"
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -50,7 +50,6 @@ class TargetHandler(
private set
fun raycast() {
val eyePosition = camera.matrixHandler.entity.eyePosition.toVec3d
val cameraFront = camera.matrixHandler.entity.rotation.front.toVec3d
@ -134,14 +133,19 @@ class TargetHandler(
break
}
if (!blocks) {
continue
}
val entity = currentChunk?.getBlockEntity(blockPosition.inChunkPosition)
target = BlockTarget(
currentPosition,
distance,
voxelShapeRaycastResult.direction,
blockState,
entity,
blockPosition,
)
break

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.camera.target.targets
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.entities.block.BlockEntity
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
@ -27,6 +28,7 @@ open class BlockTarget(
distance: Double,
direction: Directions,
val blockState: BlockState,
val entity: BlockEntity?,
val blockPosition: Vec3i,
) : GenericTarget(position, distance, direction), TextFormattable {
val hitPosition = position - blockPosition

View File

@ -37,6 +37,7 @@ import de.bixilon.minosoft.gui.rendering.gui.hud.elements.other.PerformanceHUDEl
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.scoreboard.ScoreboardSideElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.tab.TabListElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.title.TitleElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.WawlaHUDElement
import de.bixilon.minosoft.gui.rendering.renderer.drawable.AsyncDrawable
import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable
import de.bixilon.minosoft.util.KUtil.toResourceLocation
@ -138,6 +139,7 @@ class HUDManager(
PerformanceHUDElement,
TitleElement,
ScoreboardSideElement,
WawlaHUDElement,
)
}
}

View File

@ -0,0 +1,66 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.Identified
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
import de.bixilon.minosoft.util.KUtil.format
abstract class WawlaElement(protected val wawla: WawlaHUDElement) : Element(wawla.guiRenderer) {
abstract val elements: List<Element?>
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
for (element in elements) {
if (element == null) continue
element.render(offset, consumer, options)
offset.y += element.size.y
}
}
override fun forceSilentApply() {
val size = Vec2i.EMPTY
for (element in elements) {
if (element == null) continue
val elementSize = element.size
size.x = maxOf(size.x, elementSize.x)
size.y += elementSize.y
}
this.size = size
}
protected fun createNameElement(translationKey: ResourceLocation?): TextElement {
val name = wawla.context.connection.language.translate(translationKey)
name.setFallbackColor(ChatColors.WHITE)
return TextElement(guiRenderer, name, background = false, scale = 1.2f)
}
protected fun createIdentifierElement(item: Identified): TextElement? {
if (!wawla.profile.identifier) {
return null
}
return TextElement(guiRenderer, item.identifier.format(), background = false, scale = 0.8f)
}
}

View File

@ -0,0 +1,91 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asRGBAColor
import de.bixilon.minosoft.data.text.formatting.color.RGBColor.Companion.asRGBColor
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.LayoutedElement
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ColorElement
import de.bixilon.minosoft.gui.rendering.gui.gui.LayoutedGUIElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.block.BlockWawlaElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.entity.EntityWawlaElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.renderer.drawable.AsyncDrawable
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class WawlaHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedElement, AsyncDrawable {
private var element: WawlaElement? = null
val profile = guiRenderer.connection.profiles.gui.hud.wawla
override val layoutOffset: Vec2i
get() = Vec2i((guiRenderer.scaledSize.x - ((element?.size?.x ?: 0) + BACKGROUND_SIZE)) / 2, BACKGROUND_SIZE)
override val skipDraw: Boolean
get() = !profile.enabled
override fun drawAsync() {
val target = context.camera.targetHandler.target
if (target == null) {
this.element = null
forceSilentApply()
return
}
val distance = target.distance
val element: WawlaElement? = when {
target is BlockTarget && profile.block.enabled && (!profile.limitReach || distance <= context.connection.player.reachDistance) -> BlockWawlaElement(this, target)
target is EntityTarget && profile.entity.enabled && (!profile.limitReach || distance <= 3.0) -> EntityWawlaElement(this, target) // TODO: use constant for distance
else -> null
}
this.element = element
forceSilentApply()
}
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
val element = this.element ?: return
val size = element.size
ColorElement(guiRenderer, size + BACKGROUND_SIZE * 2, 0x3c05aa.asRGBColor()).render(offset, consumer, options)
ColorElement(guiRenderer, size + (BACKGROUND_SIZE - 2) * 2, 0x160611A0.asRGBAColor()).render(offset + (BACKGROUND_SIZE - (BACKGROUND_SIZE - 2)), consumer, options)
element.forceRender(offset + BACKGROUND_SIZE, consumer, options)
}
override fun onChildChange(child: Element) {
forceSilentApply()
super.onChildChange(this)
}
override fun forceSilentApply() {
cacheUpToDate = false
}
companion object : HUDBuilder<LayoutedGUIElement<WawlaHUDElement>> {
private const val BACKGROUND_SIZE = 5
override val identifier: ResourceLocation = "minosoft:wawla".toResourceLocation()
override fun build(guiRenderer: GUIRenderer): LayoutedGUIElement<WawlaHUDElement> {
return LayoutedGUIElement(WawlaHUDElement(guiRenderer))
}
}
}

View File

@ -0,0 +1,74 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.block
import de.bixilon.minosoft.data.registries.blocks.wawla.BlockWawlaProvider
import de.bixilon.minosoft.data.registries.identified.Namespaces
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponentUtil.removeTrailingNewlines
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.WawlaElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.WawlaHUDElement
class BlockWawlaElement(wawla: WawlaHUDElement, val target: BlockTarget) : WawlaElement(wawla) {
override val elements: List<Element?> = listOf(
createName(),
createAdditionalInformation(),
createIdentifierElement(target.blockState.block),
createMod(),
WawlaBreakProgressElement(this),
)
init {
parent = wawla
forceSilentApply()
}
private fun createName(): TextElement {
return createNameElement(target.blockState.block.item.translationKey) // TODO: use key of block and not item
}
private fun createMod(): TextElement? {
val namespace = target.blockState.block.identifier.namespace
if (namespace == Namespaces.DEFAULT) {
return null
}
return TextElement(guiRenderer, TextComponent(namespace).color(ChatColors.BLUE), background = false)
}
private fun createAdditionalInformation(): TextElement? {
val component = BaseComponent()
if (target.blockState.block is BlockWawlaProvider) {
component += target.blockState.block.getWawlaInformation(context.connection, target)
component += "\n"
}
if (target.entity is BlockWawlaProvider) {
component += target.entity.getWawlaInformation(context.connection, target)
component += "\n"
}
component.removeTrailingNewlines()
if (component.parts.isEmpty()) return null
component.setFallbackColor(ChatColors.GRAY)
return TextElement(guiRenderer, component, background = false)
}
}

View File

@ -0,0 +1,58 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.block
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ColorElement
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.input.interaction.BlockBreakStatus
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
class WawlaBreakProgressElement(block: BlockWawlaElement) : Element(block.guiRenderer) {
private val `break` = context.inputHandler.interactionManager.`break`
private val status = `break`.status
private val progress = if (status != null) `break`.breakProgress else null
init {
parent = block
forceSilentApply()
}
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
if (progress == null) {
return
}
val maxWidth = parent?.size?.x ?: 0
if (status == BlockBreakStatus.USELESS) {
ColorElement(guiRenderer, Vec2i(maxWidth, size.y), color = ChatColors.RED).forceRender(offset, consumer, options)
return
}
val width = (progress * (maxWidth - 1)).toInt() + 1 // bar is always 1 pixel wide
val color = when (status) {
BlockBreakStatus.INEFFECTIVE -> ChatColors.RED
BlockBreakStatus.SLOW -> ChatColors.YELLOW
else -> ChatColors.GREEN
}
ColorElement(guiRenderer, Vec2i(width, size.y), color).render(offset, consumer, options)
}
override fun forceSilentApply() {
this.size = if (progress == null) Vec2i.EMPTY else Vec2i(-1, 3)
}
}

View File

@ -0,0 +1,91 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.entity
import de.bixilon.kutil.math.simple.DoubleMath.rounded10
import de.bixilon.minosoft.data.container.EquipmentSlots
import de.bixilon.minosoft.data.entities.entities.LivingEntity
import de.bixilon.minosoft.data.entities.wawla.EntityWawlaProvider
import de.bixilon.minosoft.data.registries.effects.attributes.DefaultStatusEffectAttributeNames
import de.bixilon.minosoft.data.registries.identified.Namespaces
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponentUtil.removeTrailingNewlines
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.elements.text.TextElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.WawlaElement
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.wawla.WawlaHUDElement
class EntityWawlaElement(wawla: WawlaHUDElement, private val target: EntityTarget) : WawlaElement(wawla) {
override val elements: List<Element?> = listOf(
createName(),
createBaseInformation(),
createAdditionalInformation(),
createIdentifierElement(target.entity.type),
createMod(),
)
init {
forceSilentApply()
}
private fun createName(): TextElement {
return createNameElement(target.entity.type.translationKey)
}
private fun createMod(): TextElement? {
val namespace = target.entity.type.identifier.namespace
if (namespace == Namespaces.DEFAULT) {
return null
}
return TextElement(guiRenderer, TextComponent(namespace).color(ChatColors.BLUE), background = false)
}
private fun createBaseInformation(): TextElement? {
val entity = target.entity
val component = BaseComponent()
if (entity is LivingEntity && wawla.profile.entity.health) {
component += TextComponent("Health: ${entity.health.rounded10}/${java.lang.Float.max(0.0f, entity.getAttributeValue(DefaultStatusEffectAttributeNames.GENERIC_MAX_HEALTH).toFloat() + entity.absorptionHearts)}")
component += "\n"
}
val hand = entity.equipment[EquipmentSlots.MAIN_HAND]
if (wawla.profile.entity.hand && hand != null) {
component += TextComponent("Hand: ${hand.item.count}x ${hand.item.item}")
component += "\n"
}
component.removeTrailingNewlines()
if (component.length == 0) return null
component.setFallbackColor(ChatColors.GRAY)
return TextElement(guiRenderer, component, background = false)
}
private fun createAdditionalInformation(): TextElement? {
if (target.entity !is EntityWawlaProvider) return null
val text = target.entity.getWawlaInformation(context.connection, target)
if (text is BaseComponent) text.removeTrailingNewlines()
if (text.length == 0) return null // isEmpty
text.setFallbackColor(ChatColors.GRAY)
return TextElement(guiRenderer, text, background = false)
}
}

View File

@ -0,0 +1,38 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.input.interaction
enum class BlockBreakStatus {
/**
* Block can not be broken
*/
USELESS,
/**
* Block can only be broken with tool
*/
INEFFECTIVE,
/**
* Breaking can be faster with the correct tool
*/
SLOW,
/**
* Current tool is effective
*/
EFFECTIVE,
;
}

View File

@ -48,8 +48,8 @@ class BreakInteractionHandler(
private var breakBlockState: BlockState? = null
var breakProgress = Double.NEGATIVE_INFINITY
private set
val breakingBlock: Boolean
get() = breakPosition != null
var status: BlockBreakStatus? = null
private set
private var breakSelectedSlot: Int = -1
@ -63,6 +63,7 @@ class BreakInteractionHandler(
breakPosition = null
breakBlockState = null
breakProgress = Double.NEGATIVE_INFINITY
status = null
breakSelectedSlot = -1
}
@ -238,6 +239,15 @@ class BreakInteractionHandler(
}
}
// TODO: properly set slow status if block drops without tool
this.status = when {
damage <= 0.0f -> BlockBreakStatus.USELESS
speedMultiplier <= 1.0f -> BlockBreakStatus.SLOW
isBestTool -> BlockBreakStatus.EFFECTIVE
target.blockState.requiresTool -> BlockBreakStatus.INEFFECTIVE
else -> BlockBreakStatus.SLOW
}
if (breakProgress >= 1.0f) {
finishDigging()
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -14,7 +14,6 @@
package de.bixilon.minosoft.gui.rendering.input.interaction
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kutil.time.TimeUtil
import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.config.key.KeyActions
import de.bixilon.minosoft.config.key.KeyBinding
@ -167,7 +166,7 @@ class InteractInteractionHandler(
}
fun useItem() {
if (interactionManager.`break`.breakingBlock) {
if (interactionManager.`break`.status != null) {
return
}