wip: fluid, entity, block raycasting

This commit is contained in:
Bixilon 2021-06-22 00:02:48 +02:00
parent 8271827750
commit caf75b323b
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
27 changed files with 325 additions and 79 deletions

View File

@ -33,8 +33,9 @@ import de.bixilon.minosoft.data.registries.registry.ResourceLocationDeserializer
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.gui.rendering.TintColorCalculator
import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i
import kotlin.random.Random
@ -111,6 +112,10 @@ open class Block(
open fun onEntityCollision(connection: PlayConnection, entity: Entity, blockState: BlockState, blockPosition: Vec3i) {}
open fun getOutlineShape(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): VoxelShape {
return blockState.outlineShape
}
companion object : ResourceLocationDeserializer<Block> {
private val CONSTRUCTORS: Map<String, (resourceLocation: ResourceLocation, registries: Registries, data: JsonObject) -> Block> = mapOf(
"FluidBlock" to { resourceLocation, registries, data -> FluidBlock(resourceLocation, registries, data) },

View File

@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.items.tools.ShovelItem
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.campfire.CampfireSmokeParticle
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.fire.SmokeParticle
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava.LavaParticle

View File

@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.materials.DefaultMaterials
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i

View File

@ -18,9 +18,13 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.fluid.Fluid
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.FluidRenderer
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3
import glm_.vec3.Vec3i
import kotlin.random.Random
@ -38,6 +42,10 @@ open class FluidBlock(resourceLocation: ResourceLocation, registries: Registries
}
}
override fun getOutlineShape(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): VoxelShape {
return VoxelShape(mutableListOf(AABB(Vec3.EMPTY, Vec3(1.0f, fluid.getHeight(blockState), 1.0f))))
}
override fun randomTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) {
super.randomTick(connection, blockState, blockPosition, random)
// ToDO

View File

@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i

View File

@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i

View File

@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i

View File

@ -24,7 +24,7 @@ import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.particle.data.DustParticleData
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.data.text.Colors
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.dust.DustParticle
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
import de.bixilon.minosoft.protocol.network.connection.PlayConnection

View File

@ -18,16 +18,15 @@ import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.player.Hands
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockPlaceC2SP
import glm_.vec3.Vec3
import glm_.vec3.Vec3i
open class BlockItem(
resourceLocation: ResourceLocation,
@ -36,11 +35,15 @@ open class BlockItem(
) : Item(resourceLocation, registries, data) {
val block: Block = registries.blockRegistry[data["block"].asInt]
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
override fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
if (!connection.player.gamemode.canBuild) {
return BlockUsages.PASS
}
if (raycastHit !is BlockRaycastHit) {
return super.use(connection, raycastHit, hands, itemStack)
}
val placePosition = raycastHit.blockPosition + raycastHit.hitDirection
if (!connection.world.isPositionChangeable(placePosition)) {
return BlockUsages.PASS

View File

@ -27,9 +27,8 @@ import de.bixilon.minosoft.data.registries.registry.RegistryItem
import de.bixilon.minosoft.data.registries.registry.ResourceLocationDeserializer
import de.bixilon.minosoft.data.registries.registry.Translatable
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i
open class Item(
override val resourceLocation: ResourceLocation,
@ -51,7 +50,7 @@ open class Item(
return 1.0f
}
open fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
open fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
return BlockUsages.PASS
}

View File

@ -18,14 +18,13 @@ import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.player.Hands
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import glm_.vec3.Vec3i
open class AxeItem(
resourceLocation: ResourceLocation,
@ -41,12 +40,15 @@ open class AxeItem(
entries.toMap()
}
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
override fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
if (!Minosoft.config.config.game.controls.enableStripping) {
return BlockUsages.CONSUME
}
if (raycastHit !is BlockRaycastHit) {
return super.use(connection, raycastHit, hands, itemStack)
}
return super.interactWithTool(connection, blockPosition, strippableBlocks?.get(blockState.block)?.withProperties(blockState.properties))
return super.interactWithTool(connection, raycastHit.blockPosition, strippableBlocks?.get(raycastHit.blockState.block)?.withProperties(raycastHit.blockState.properties))
}
companion object {

View File

@ -23,11 +23,11 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import glm_.vec3.Vec3i
open class HoeItem(
resourceLocation: ResourceLocation,
@ -43,16 +43,19 @@ open class HoeItem(
entries.toMap()
}
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
override fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
if (!Minosoft.config.config.game.controls.enableTilling) {
return BlockUsages.CONSUME
}
if (raycastHit !is BlockRaycastHit) {
return super.use(connection, raycastHit, hands, itemStack)
}
if (connection.world[blockPosition + Directions.UP] != null) {
if (connection.world[raycastHit.blockPosition + Directions.UP] != null) {
return BlockUsages.PASS
}
return super.interactWithTool(connection, blockPosition, tillableBlockStates?.get(blockState.block))
return super.interactWithTool(connection, raycastHit.blockPosition, tillableBlockStates?.get(raycastHit.blockState.block))
}
companion object {

View File

@ -23,11 +23,11 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import glm_.vec3.Vec3i
open class ShovelItem(
resourceLocation: ResourceLocation,
@ -44,16 +44,19 @@ open class ShovelItem(
}
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
override fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
if (!Minosoft.config.config.game.controls.enableFlattening) {
return BlockUsages.CONSUME
}
if (raycastHit !is BlockRaycastHit) {
return super.use(connection, raycastHit, hands, itemStack)
}
if (connection.world[blockPosition + Directions.UP] != null) {
if (connection.world[raycastHit.blockPosition + Directions.UP] != null) {
return BlockUsages.PASS
}
return super.interactWithTool(connection, blockPosition, flattenableBlockStates?.get(blockState.block))
return super.interactWithTool(connection, raycastHit.blockPosition, flattenableBlockStates?.get(raycastHit.blockState.block))
}

View File

@ -35,7 +35,6 @@ import java.util.Base64;
public class GUITools {
public static final Image MINOSOFT_LOGO = new Image(GUITools.class.getResourceAsStream("/assets/minosoft/textures/icons/window_icon.png"));
public static final ObservableList<Version> VERSIONS = FXCollections.observableArrayList();
public static final JFXComboBox<Version> VERSION_COMBO_BOX = new JFXComboBox<>(VERSIONS);
static {
VERSIONS.add(Versions.AUTOMATIC_VERSION);
@ -49,6 +48,8 @@ public class GUITools {
});
}
public static final JFXComboBox<Version> VERSION_COMBO_BOX = new JFXComboBox<>(VERSIONS);
public static Image getImageFromBase64(String base64) {
if (base64 == null) {
return null;

View File

@ -21,11 +21,13 @@ import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.nullCast
import glm_.vec3.Vec3i
class BlockOutlineRenderer(
@ -56,7 +58,7 @@ class BlockOutlineRenderer(
}
override fun draw() {
val raycastHit = renderWindow.inputHandler.camera.getTargetBlock()
val raycastHit = renderWindow.inputHandler.camera.target?.nullCast<BlockRaycastHit>()
var currentMesh = currentMesh

View File

@ -18,14 +18,19 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderBuilder
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.hud.nodes.primitive.LabelNode
import de.bixilon.minosoft.gui.rendering.hud.nodes.properties.NodeAlignment
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.FluidRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.modding.loading.ModLoader
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.GitInfo
import de.bixilon.minosoft.util.SystemInformation
import de.bixilon.minosoft.util.UnitFormatter
import de.bixilon.minosoft.util.UnitFormatter.formatBytes
import glm_.vec2.Vec2
import org.lwjgl.opengl.GL11.*
@ -73,8 +78,25 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
text()
}
private val targetPosition = text("TBA")
private val targetBlockState = text("TBA")
private val target = text("TBA")
init {
text()
}
private val targetBlock = text()
init {
text()
}
private val targetFluid = text()
init {
text()
}
private val targetEntity = text()
override fun init() {
gpuText.sText = "GPU: " + (glGetString(GL_RENDERER) ?: "unknown")
@ -92,17 +114,36 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
memoryText.sText = "Memory: ${getUsedMemoryPercent()}% ${getFormattedUsedMemory()}/${SystemInformation.MAX_MEMORY_TEXT}"
allocatedMemoryText.sText = "Allocated: ${getAllocatedMemoryPercent()}% ${getFormattedAllocatedMemory()}"
gpuMemoryText.sText = "VRAM: ${UnitFormatter.formatBytes(hudRenderer.renderWindow.renderSystem.usedVRAM)} / ${UnitFormatter.formatBytes(hudRenderer.renderWindow.renderSystem.availableVRAM)} | ${UnitFormatter.formatBytes(hudRenderer.renderWindow.renderSystem.maximumVRAM)}"
gpuMemoryText.sText = "VRAM: ${hudRenderer.renderWindow.renderSystem.usedVRAM.formatBytes()} / ${hudRenderer.renderWindow.renderSystem.availableVRAM.formatBytes()} | ${hudRenderer.renderWindow.renderSystem.maximumVRAM.formatBytes()}"
val rayCastHit = hudRenderer.renderWindow.inputHandler.camera.getTargetBlock()
if (rayCastHit == null) {
targetPosition.sText = ""
targetBlockState.sText = ""
} else {
targetPosition.sText = "Target block: ${rayCastHit.blockPosition}"
targetBlockState.sText = rayCastHit.blockState.toString()
val target = hudRenderer.renderWindow.inputHandler.camera.target
val targetClass = target?.let { it::class.java }
this.target.sText = target?.let {
val targetType = when (targetClass) {
FluidRaycastHit::class.java -> "Fluid"
BlockRaycastHit::class.java -> "Block"
EntityRaycastHit::class.java -> "Entity"
else -> "Unknown"
}
"Target: $targetType: $it"
} ?: "No target!"
if (target != null) {
fun addTarget(labelNode: LabelNode, raycastHit: RaycastHit?, name: String) {
labelNode.sText = if (raycastHit != null && targetClass != raycastHit::class.java) {
"$name target: $raycastHit"
} else {
""
}
}
val camera = hudRenderer.renderWindow.inputHandler.camera
addTarget(this.targetBlock, camera.blockTarget, "Block")
addTarget(this.targetFluid, camera.fluidTarget, "Fluid")
addTarget(this.targetEntity, camera.entityTarget, "Entity")
}
lastPrepareTime = System.currentTimeMillis()
}
@ -111,7 +152,7 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
}
private fun getFormattedUsedMemory(): String {
return UnitFormatter.formatBytes(getUsedMemory())
return getUsedMemory().formatBytes()
}
private fun getAllocatedMemory(): Long {
@ -119,7 +160,7 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
}
private fun getFormattedAllocatedMemory(): String {
return UnitFormatter.formatBytes(getAllocatedMemory())
return getAllocatedMemory().formatBytes()
}
private fun getUsedMemoryPercent(): Long {

View File

@ -25,11 +25,13 @@ import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
import de.bixilon.minosoft.data.registries.items.tools.MiningToolItem
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.modding.event.events.BlockBreakAckEvent
import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockBreakC2SP
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.nullCast
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
import glm_.pow
import glm_.vec3.Vec3i
@ -98,7 +100,7 @@ class LeftClickHandler(
cancelDigging()
return false
}
val raycastHit = renderWindow.inputHandler.camera.getTargetBlock()
val raycastHit = renderWindow.inputHandler.camera.target?.nullCast<BlockRaycastHit>()
if (raycastHit == null) {
cancelDigging()

View File

@ -18,10 +18,12 @@ import de.bixilon.minosoft.data.player.Hands
import de.bixilon.minosoft.data.registries.blocks.BlockUsages
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockPlaceC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.ItemUseC2SP
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.nullCast
import glm_.vec3.Vec3
class RightClickHandler(
@ -45,7 +47,7 @@ class RightClickHandler(
return
}
val raycastHit = renderWindow.inputHandler.camera.getTargetBlock() ?: return
val raycastHit = renderWindow.inputHandler.camera.target?.nullCast<BlockRaycastHit>() ?: return
if (raycastHit.distance > RenderConstants.MAX_BLOCK_OUTLINE_RAYCAST_DISTANCE) {
return
@ -94,7 +96,7 @@ class RightClickHandler(
}
when (itemInHand.item.use(connection, raycastHit.blockState, raycastHit.blockPosition, raycastHit, Hands.MAIN_HAND, itemInHand)) {
when (itemInHand.item.use(connection, raycastHit, Hands.MAIN_HAND, itemInHand)) {
BlockUsages.SUCCESS -> {
connection.sendPacket(ArmSwingC2SP(Hands.MAIN_HAND))

View File

@ -17,8 +17,13 @@ import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.data.player.LocalPlayerEntity
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.FluidRaycastHit
import de.bixilon.minosoft.gui.rendering.input.camera.hit.RaycastHit
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
import de.bixilon.minosoft.gui.rendering.modding.events.CameraPositionChangeEvent
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
@ -52,6 +57,15 @@ class Camera(
var cameraRight = Vec3d(0.0, 0.0, -1.0)
private var cameraUp = Vec3d(0.0, 1.0, 0.0)
var target: RaycastHit? = null
private set
var blockTarget: BlockRaycastHit? = null
private set
var fluidTarget: FluidRaycastHit? = null
private set
var entityTarget: EntityRaycastHit? = null
private set
val fov: Double
get() {
val fov = Minosoft.config.config.game.camera.fov / (zoom + 1.0)
@ -199,13 +213,20 @@ class Camera(
}
// ToDo: Only update if changed
onPositionChange()
val eyePosition = entity.eyePosition
val cameraFront = cameraFront
target = raycast(eyePosition, cameraFront, blocks = true, fluids = true, entities = true)
blockTarget = raycast(eyePosition, cameraFront, blocks = true, fluids = false, entities = false) as BlockRaycastHit?
fluidTarget = raycast(eyePosition, cameraFront, blocks = false, fluids = true, entities = false) as FluidRaycastHit?
entityTarget = raycast(eyePosition, cameraFront, blocks = false, fluids = false, entities = true) as EntityRaycastHit?
}
fun getTargetBlock(): RaycastHit? {
return raycast(entity.eyePosition, cameraFront)
}
private fun raycast(origin: Vec3d, direction: Vec3d): RaycastHit? {
private fun raycast(origin: Vec3d, direction: Vec3d, blocks: Boolean, fluids: Boolean, entities: Boolean): RaycastHit? {
if (!blocks && !fluids && entities) {
return null // ToDo: Raycast entities
}
val currentPosition = Vec3d(origin)
fun getTotalDistance(): Double {
@ -215,21 +236,44 @@ class Camera(
for (i in 0..RAYCAST_MAX_STEPS) {
val blockPosition = currentPosition.floor
val blockState = connection.world[blockPosition]
if (blockState != null) {
val voxelShapeRaycastResult = (blockState.outlineShape + blockPosition + blockPosition.getWorldOffset(blockState.block)).raycast(currentPosition, direction)
if (voxelShapeRaycastResult.hit) {
currentPosition += direction * voxelShapeRaycastResult.distance
return RaycastHit(
if (blockState == null) {
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
continue
}
val voxelShapeRaycastResult = (blockState.block.getOutlineShape(connection, blockState, blockPosition) + blockPosition + blockPosition.getWorldOffset(blockState.block)).raycast(currentPosition, direction)
if (voxelShapeRaycastResult.hit) {
val distance = getTotalDistance()
currentPosition += direction * voxelShapeRaycastResult.distance
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
if (blockState.block is FluidBlock) {
if (!fluids) {
continue
}
return FluidRaycastHit(
currentPosition,
blockPosition,
getTotalDistance(),
blockState,
distance,
voxelShapeRaycastResult.direction,
i,
blockState,
blockPosition,
blockState.block.fluid,
)
}
if (!blocks) {
continue
}
return BlockRaycastHit(
currentPosition,
distance,
voxelShapeRaycastResult.direction,
blockState,
blockPosition,
)
} else {
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
}
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
}
return null
}

View File

@ -0,0 +1,47 @@
/*
* Minosoft
* Copyright (C) 2021 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.camera.hit
import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.util.KUtil.format
import glm_.vec3.Vec3d
import glm_.vec3.Vec3i
open class BlockRaycastHit(
position: Vec3d,
distance: Double,
hitDirection: Directions,
val blockState: BlockState,
val blockPosition: Vec3i,
) : RaycastHit(position, distance, hitDirection) {
val hitPosition = position - blockPosition
override fun toString(): String {
val ret = StringBuilder()
ret.append(blockPosition)
ret.append(": ")
ret.append(blockState.block.resourceLocation)
for ((key, value) in blockState.properties) {
ret.append('\n')
ret.append(' ')
ret.append(key.group)
ret.append(": ")
ret.append(value.format())
}
return ret.toString()
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2021 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.camera.hit
import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.entities.entities.Entity
import glm_.vec3.Vec3d
class EntityRaycastHit(
position: Vec3d,
distance: Double,
hitDirection: Directions,
val entity: Entity,
) : RaycastHit(position, distance, hitDirection) {
override fun toString(): String {
return "$position: ${entity.entityType.resourceLocation}"
}
}

View File

@ -0,0 +1,35 @@
/*
* Minosoft
* Copyright (C) 2021 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.camera.hit
import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.fluid.Fluid
import glm_.vec3.Vec3d
import glm_.vec3.Vec3i
class FluidRaycastHit(
position: Vec3d,
distance: Double,
hitDirection: Directions,
blockState: BlockState,
blockPosition: Vec3i,
val fluid: Fluid,
) : BlockRaycastHit(position, distance, hitDirection, blockState, blockPosition) {
override fun toString(): String {
return "$blockPosition: ${fluid.resourceLocation}\n Height: ${fluid.getHeight(blockState)}\n Level: ${blockState.properties[BlockProperties.FLUID_LEVEL]}"
}
}

View File

@ -11,20 +11,13 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.input.camera
package de.bixilon.minosoft.gui.rendering.input.camera.hit
import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.registries.blocks.BlockState
import glm_.vec3.Vec3d
import glm_.vec3.Vec3i
data class RaycastHit(
abstract class RaycastHit(
val position: Vec3d,
val blockPosition: Vec3i,
val distance: Double,
val blockState: BlockState,
val hitDirection: Directions,
val steps: Int,
) {
val hitPosition = position.minus(blockPosition)
}
)

View File

@ -104,8 +104,8 @@ object GitInfo {
IS_INITIALIZED = true
} catch (exception: Throwable) {
Log.log(LogMessageType.OTHER, level = LogLevels.WARN) { exception }
Log.log(LogMessageType.OTHER, level = LogLevels.WARN) { "Could not load git information." }
Log.log(LogMessageType.OTHER, level = LogLevels.WARN) { exception }
}
}
}

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.util
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.collections.SynchronizedMap
@ -183,4 +184,28 @@ object KUtil {
}
return list.toList()
}
fun Any.format(): ChatComponent {
return ChatComponent.of(when (this) {
is Boolean -> {
if (this) {
"§atrue"
} else {
"§cfalse"
}
}
is Enum<*> -> {
val name = this.name
if (name.length == 1) {
name
} else {
name.lowercase()
}
}
is Number -> {
"§d$this"
}
else -> this.toString()
})
}
}

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.util
import de.bixilon.minosoft.util.UnitFormatter.formatBytes
import oshi.SystemInfo
object SystemInformation {
@ -20,7 +21,7 @@ object SystemInformation {
val SYSTEM_INFO = SystemInfo()
val HARDWARE_SYSTEM_INFO = SYSTEM_INFO.hardware
val SYSTEM_MEMORY_TEXT: String = UnitFormatter.formatBytes(HARDWARE_SYSTEM_INFO.memory.total)
val SYSTEM_MEMORY_TEXT: String = HARDWARE_SYSTEM_INFO.memory.total.formatBytes()
val OS_TEXT: String = "${System.getProperty("os.name")}: ${SYSTEM_INFO.operatingSystem.family} ${SYSTEM_INFO.operatingSystem.bitness}bit"
val PROCESSOR_TEXT = " ${RUNTIME.availableProcessors()}x ${HARDWARE_SYSTEM_INFO.processor.processorIdentifier.name.replace("\\s{2,}".toRegex(), "")}"
@ -34,7 +35,7 @@ object SystemInformation {
}
private fun getFormattedMaxMemory(): String {
return UnitFormatter.formatBytes(getMaxMemory())
return getMaxMemory().formatBytes()
}
}

View File

@ -18,11 +18,11 @@ object UnitFormatter {
private val UNITS = arrayOf("", "k", "M", "G", "T", "P", "E", "Z", "Y")
private val TIME_UNITS = arrayOf("ns", "μs", "ms", "s", "m", "h", "d", "w", "M", "Y")
fun formatBytes(bytes: Long): String {
if (bytes < 0) {
fun Long.formatBytes(): String {
if (this < 0) {
return "Unknown"
}
return formatUnit(bytes, BYTE_UNITS, 1024L)
return formatUnit(this, BYTE_UNITS, 1024L)
}
fun formatNumber(number: Int): String {