mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
Merge branch 'work/camera' into 'master'
Refactor camera See merge request bixilon/minosoft!37
This commit is contained in:
commit
543dda505a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
target/
|
/target/
|
||||||
out/
|
out/
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
|
@ -5,17 +5,3 @@ There is a config file located in:
|
|||||||
* Windows: `%AppData%\Minosoft`
|
* Windows: `%AppData%\Minosoft`
|
||||||
* MacOS: `"~/Library/Application Support/Minosoft"`
|
* MacOS: `"~/Library/Application Support/Minosoft"`
|
||||||
* Linux (and all others): `~\Minosoft`
|
* Linux (and all others): `~\Minosoft`
|
||||||
|
|
||||||
|
|
||||||
- Profiles
|
|
||||||
- Select profile per server
|
|
||||||
- Config reloading
|
|
||||||
- From disk
|
|
||||||
- In eros
|
|
||||||
- Per key combination
|
|
||||||
- Migration
|
|
||||||
- Automatic saving (periodic, per event, maybe use delegates?)
|
|
||||||
- Config editor
|
|
||||||
- Config value checker
|
|
||||||
- Change event, batch those, apply event
|
|
||||||
- Multiple config files (e.g. eros, key combinations, particles, accounts, log, audio, blocks, entities, hit boxes, world, network, assets, physics, hud, other)
|
|
||||||
|
@ -15,14 +15,14 @@ package de.bixilon.minosoft.data.entities
|
|||||||
import glm_.func.cos
|
import glm_.func.cos
|
||||||
import glm_.func.rad
|
import glm_.func.rad
|
||||||
import glm_.func.sin
|
import glm_.func.sin
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
data class EntityRotation(
|
data class EntityRotation(
|
||||||
val yaw: Double,
|
val yaw: Double,
|
||||||
val pitch: Double,
|
val pitch: Double,
|
||||||
) {
|
) {
|
||||||
val front: Vec3d
|
val front: Vec3
|
||||||
get() = Vec3d(
|
get() = Vec3(
|
||||||
(yaw + 90).rad.cos * (-pitch).rad.cos,
|
(yaw + 90).rad.cos * (-pitch).rad.cos,
|
||||||
(-pitch).rad.sin,
|
(-pitch).rad.sin,
|
||||||
(yaw + 90).rad.sin * (-pitch).rad.cos
|
(yaw + 90).rad.sin * (-pitch).rad.cos
|
||||||
|
@ -49,7 +49,7 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
|||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.horizontal
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.horizontal
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
@ -128,10 +128,10 @@ abstract class Entity(
|
|||||||
}
|
}
|
||||||
open val positionInfo = EntityPositionInfo(connection, this)
|
open val positionInfo = EntityPositionInfo(connection, this)
|
||||||
|
|
||||||
val eyePosition: Vec3d
|
val eyePosition: Vec3
|
||||||
get() = cameraPosition + Vec3(0.0f, eyeHeight, 0.0f)
|
get() = cameraPosition + Vec3(0.0f, eyeHeight, 0.0f)
|
||||||
|
|
||||||
var cameraPosition: Vec3d = position.toVec3d
|
var cameraPosition: Vec3 = position.toVec3
|
||||||
private set
|
private set
|
||||||
|
|
||||||
open val spawnSprintingParticles: Boolean
|
open val spawnSprintingParticles: Boolean
|
||||||
@ -362,7 +362,7 @@ abstract class Entity(
|
|||||||
postTick()
|
postTick()
|
||||||
lastTickTime = currentTime
|
lastTickTime = currentTime
|
||||||
}
|
}
|
||||||
cameraPosition = VecUtil.lerp((currentTime - lastTickTime) / ProtocolDefinition.TICK_TIMEd, previousPosition, position)
|
cameraPosition = VecUtil.lerp((currentTime - lastTickTime) / ProtocolDefinition.TICK_TIMEf, Vec3(previousPosition), Vec3(position))
|
||||||
}
|
}
|
||||||
|
|
||||||
open val pushableByFluids: Boolean = false
|
open val pushableByFluids: Boolean = false
|
||||||
|
@ -28,7 +28,7 @@ import de.bixilon.minosoft.data.registries.items.Item
|
|||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem
|
import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem
|
||||||
import de.bixilon.minosoft.data.registries.registries.registry.ResourceLocationDeserializer
|
import de.bixilon.minosoft.data.registries.registries.registry.ResourceLocationDeserializer
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.gui.rendering.tint.TintProvider
|
import de.bixilon.minosoft.gui.rendering.tint.TintProvider
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
@ -75,7 +75,7 @@ open class Block(
|
|||||||
return resourceLocation.full
|
return resourceLocation.full
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getPlacementState(connection: PlayConnection, hit: BlockRaycastHit): BlockState? = defaultState
|
open fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? = defaultState
|
||||||
|
|
||||||
open fun onBreak(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState, blockEntity: BlockEntity?) = Unit
|
open fun onBreak(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState, blockEntity: BlockEntity?) = Unit
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ open class Block(
|
|||||||
|
|
||||||
open fun canPlaceAt(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState): Boolean = true
|
open fun canPlaceAt(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState): Boolean = true
|
||||||
|
|
||||||
open fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
open fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
if (blockEntityType == null) {
|
if (blockEntityType == null) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||||
import de.bixilon.minosoft.data.registries.items.tools.ShovelItem
|
import de.bixilon.minosoft.data.registries.items.tools.ShovelItem
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.campfire.CampfireSmokeParticle
|
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.fire.SmokeParticle
|
||||||
@ -92,13 +92,13 @@ open class CampfireBlock(resourceLocation: ResourceLocation, registries: Registr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
// ToDo: Ignite (flint and steel, etc)
|
// ToDo: Ignite (flint and steel, etc)
|
||||||
if (itemStack?.item !is ShovelItem || hit.blockState.properties[BlockProperties.LIT] != true) {
|
if (itemStack?.item !is ShovelItem || target.blockState.properties[BlockProperties.LIT] != true) {
|
||||||
return super.onUse(connection, hit, hand, itemStack)
|
return super.onUse(connection, target, hand, itemStack)
|
||||||
}
|
}
|
||||||
connection.world.setBlockState(hit.blockPosition, hit.blockState.withProperties(BlockProperties.LIT to false))
|
connection.world.setBlockState(target.blockPosition, target.blockState.withProperties(BlockProperties.LIT to false))
|
||||||
extinguish(connection, hit.blockState, hit.blockPosition)
|
extinguish(connection, target.blockState, target.blockPosition)
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,22 +21,22 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||||
import de.bixilon.minosoft.data.registries.materials.DefaultMaterials
|
import de.bixilon.minosoft.data.registries.materials.DefaultMaterials
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
open class DoorBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : DoubleSizeBlock(resourceLocation, registries, data) {
|
open class DoorBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : DoubleSizeBlock(resourceLocation, registries, data) {
|
||||||
|
|
||||||
override fun getPlacementState(connection: PlayConnection, hit: BlockRaycastHit): BlockState? {
|
override fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? {
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
if (hit.blockState.material.resourceLocation == DefaultMaterials.METAL) {
|
if (target.blockState.material.resourceLocation == DefaultMaterials.METAL) {
|
||||||
return InteractionResults.CONSUME
|
return InteractionResults.CONSUME
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.world[hit.blockPosition] = hit.blockState.cycle(BlockProperties.DOOR_OPEN)
|
connection.world[target.blockPosition] = target.blockState.cycle(BlockProperties.DOOR_OPEN)
|
||||||
|
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,13 @@ import de.bixilon.minosoft.data.player.Hands
|
|||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
import de.bixilon.minosoft.data.registries.blocks.BlockFactory
|
import de.bixilon.minosoft.data.registries.blocks.BlockFactory
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
open class NoteBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : Block(resourceLocation, registries, data) {
|
open class NoteBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : Block(resourceLocation, registries, data) {
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,17 +19,17 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
abstract class AbstractButtonBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : Block(resourceLocation, registries, data) {
|
abstract class AbstractButtonBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : Block(resourceLocation, registries, data) {
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
if (hit.blockState.properties[BlockProperties.POWERED] == true) {
|
if (target.blockState.properties[BlockProperties.POWERED] == true) {
|
||||||
return InteractionResults.CONSUME
|
return InteractionResults.CONSUME
|
||||||
}
|
}
|
||||||
connection.world[hit.blockPosition] = hit.blockState.withProperties(BlockProperties.POWERED to true)
|
connection.world[target.blockPosition] = target.blockState.withProperties(BlockProperties.POWERED to true)
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.MinecraftBlocks
|
import de.bixilon.minosoft.data.registries.blocks.MinecraftBlocks
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
@ -30,12 +30,12 @@ open class PlantBlock(resourceLocation: ResourceLocation, registries: Registries
|
|||||||
return blockState.block.resourceLocation == MinecraftBlocks.DIRT || blockState.block.resourceLocation == MinecraftBlocks.FARMLAND
|
return blockState.block.resourceLocation == MinecraftBlocks.DIRT || blockState.block.resourceLocation == MinecraftBlocks.FARMLAND
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlacementState(connection: PlayConnection, hit: BlockRaycastHit): BlockState? {
|
override fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? {
|
||||||
val below = connection.world[hit.blockPosition + hit.hitDirection + Directions.DOWN] ?: return null
|
val below = connection.world[target.blockPosition + target.direction + Directions.DOWN] ?: return null
|
||||||
if (!canPlaceOn(below)) {
|
if (!canPlaceOn(below)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return super.getPlacementState(connection, hit)
|
return super.getPlacementState(connection, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : BlockFactory<PlantBlock> {
|
companion object : BlockFactory<PlantBlock> {
|
||||||
|
@ -20,18 +20,18 @@ import de.bixilon.minosoft.data.registries.blocks.BlockFactory
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
open class ComparatorBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : RedstoneGateBlock(resourceLocation, registries, data) {
|
open class ComparatorBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : RedstoneGateBlock(resourceLocation, registries, data) {
|
||||||
|
|
||||||
override fun getPlacementState(connection: PlayConnection, hit: BlockRaycastHit): BlockState? {
|
override fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? {
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
connection.world[hit.blockPosition] = hit.blockState.cycle(BlockProperties.STRUCTURE_BLOCK_MODE)
|
connection.world[target.blockPosition] = target.blockState.cycle(BlockProperties.STRUCTURE_BLOCK_MODE)
|
||||||
|
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -20,18 +20,18 @@ import de.bixilon.minosoft.data.registries.blocks.BlockFactory
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
open class RepeaterBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : RedstoneGateBlock(resourceLocation, registries, data) {
|
open class RepeaterBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : RedstoneGateBlock(resourceLocation, registries, data) {
|
||||||
|
|
||||||
override fun getPlacementState(connection: PlayConnection, hit: BlockRaycastHit): BlockState? {
|
override fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? {
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
connection.world[hit.blockPosition] = hit.blockState.cycle(BlockProperties.REPEATER_DELAY)
|
connection.world[target.blockPosition] = target.blockState.cycle(BlockProperties.REPEATER_DELAY)
|
||||||
|
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,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.particle.data.DustParticleData
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.data.text.Colors
|
import de.bixilon.minosoft.data.text.Colors
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.dust.DustParticle
|
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.dust.DustParticle
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
||||||
@ -55,14 +55,14 @@ open class LeverBlock(resourceLocation: ResourceLocation, registries: Registries
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlacementState(connection: PlayConnection, hit: BlockRaycastHit): BlockState? {
|
override fun getPlacementState(connection: PlayConnection, target: BlockTarget): BlockState? {
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUse(connection: PlayConnection, hit: BlockRaycastHit, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
override fun onUse(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack?): InteractionResults {
|
||||||
val nextState = hit.blockState.cycle(BlockProperties.POWERED)
|
val nextState = target.blockState.cycle(BlockProperties.POWERED)
|
||||||
connection.world[hit.blockPosition] = nextState
|
connection.world[target.blockPosition] = nextState
|
||||||
spawnParticles(connection, nextState, hit.blockPosition, 1.0f)
|
spawnParticles(connection, nextState, target.blockPosition, 1.0f)
|
||||||
|
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,8 @@ import de.bixilon.minosoft.data.registries.registries.Registries
|
|||||||
import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem
|
import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem
|
||||||
import de.bixilon.minosoft.data.registries.registries.registry.ResourceLocationDeserializer
|
import de.bixilon.minosoft.data.registries.registries.registry.ResourceLocationDeserializer
|
||||||
import de.bixilon.minosoft.data.registries.registries.registry.Translatable
|
import de.bixilon.minosoft.data.registries.registries.registry.Translatable
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.toBoolean
|
import de.bixilon.minosoft.util.KUtil.toBoolean
|
||||||
@ -69,15 +69,15 @@ open class Item(
|
|||||||
return 1.0f
|
return 1.0f
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun interactBlock(connection: PlayConnection, raycastHit: BlockRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
open fun interactBlock(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun interactEntity(connection: PlayConnection, raycastHit: EntityRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
open fun interactEntity(connection: PlayConnection, target: EntityTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun interactEntityAt(connection: PlayConnection, raycastHit: EntityRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
open fun interactEntityAt(connection: PlayConnection, target: EntityTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
|
|||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.items.Item
|
import de.bixilon.minosoft.data.registries.items.Item
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plusAssign
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
@ -37,14 +37,14 @@ open class BlockItem(
|
|||||||
this::block.inject(data["block"])
|
this::block.inject(data["block"])
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun interactBlock(connection: PlayConnection, raycastHit: BlockRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
override fun interactBlock(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
if (!connection.player.gamemode.canBuild) {
|
if (!connection.player.gamemode.canBuild) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
val placePosition = raycastHit.blockPosition
|
val placePosition = target.blockPosition
|
||||||
if (!raycastHit.blockState.material.replaceable) {
|
if (!target.blockState.material.replaceable) {
|
||||||
placePosition += raycastHit.hitDirection
|
placePosition += target.direction
|
||||||
|
|
||||||
if (connection.world[placePosition]?.material?.replaceable == false) {
|
if (connection.world[placePosition]?.material?.replaceable == false) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
@ -62,7 +62,7 @@ open class BlockItem(
|
|||||||
|
|
||||||
var placeBlockState: BlockState = block!!.defaultState
|
var placeBlockState: BlockState = block!!.defaultState
|
||||||
try {
|
try {
|
||||||
placeBlockState = block.getPlacementState(connection, raycastHit) ?: return InteractionResults.PASS
|
placeBlockState = block.getPlacementState(connection, target) ?: return InteractionResults.PASS
|
||||||
} catch (exception: Throwable) {
|
} catch (exception: Throwable) {
|
||||||
exception.printStackTrace()
|
exception.printStackTrace()
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import de.bixilon.minosoft.data.player.Hands
|
|||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.util.KUtil.mapCast
|
import de.bixilon.minosoft.util.KUtil.mapCast
|
||||||
@ -39,12 +39,12 @@ open class AxeItem(
|
|||||||
entries.toMap()
|
entries.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun interactBlock(connection: PlayConnection, raycastHit: BlockRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
override fun interactBlock(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
if (!connection.profiles.controls.interaction.stripping) {
|
if (!connection.profiles.controls.interaction.stripping) {
|
||||||
return InteractionResults.CONSUME
|
return InteractionResults.CONSUME
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.interactWithTool(connection, raycastHit.blockPosition, strippableBlocks?.get(raycastHit.blockState.block)?.withProperties(raycastHit.blockState.properties))
|
return super.interactWithTool(connection, target.blockPosition, strippableBlocks?.get(target.blockState.block)?.withProperties(target.blockState.properties))
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -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.BlockState
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
@ -42,16 +42,16 @@ open class HoeItem(
|
|||||||
entries.toMap()
|
entries.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun interactBlock(connection: PlayConnection, raycastHit: BlockRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
override fun interactBlock(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
if (!connection.profiles.controls.interaction.tilling) {
|
if (!connection.profiles.controls.interaction.tilling) {
|
||||||
return InteractionResults.CONSUME
|
return InteractionResults.CONSUME
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.world[raycastHit.blockPosition + Directions.UP] != null) {
|
if (connection.world[target.blockPosition + Directions.UP] != null) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.interactWithTool(connection, raycastHit.blockPosition, tillableBlockStates?.get(raycastHit.blockState.block))
|
return super.interactWithTool(connection, target.blockPosition, tillableBlockStates?.get(target.blockState.block))
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -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.BlockState
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.registries.Registries
|
import de.bixilon.minosoft.data.registries.registries.Registries
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionResults
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
@ -43,16 +43,16 @@ open class ShovelItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun interactBlock(connection: PlayConnection, raycastHit: BlockRaycastHit, hand: Hands, itemStack: ItemStack): InteractionResults {
|
override fun interactBlock(connection: PlayConnection, target: BlockTarget, hand: Hands, itemStack: ItemStack): InteractionResults {
|
||||||
if (!connection.profiles.controls.interaction.flattening) {
|
if (!connection.profiles.controls.interaction.flattening) {
|
||||||
return InteractionResults.CONSUME
|
return InteractionResults.CONSUME
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection.world[raycastHit.blockPosition + Directions.UP] != null) {
|
if (connection.world[target.blockPosition + Directions.UP] != null) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.interactWithTool(connection, raycastHit.blockPosition, flattenableBlockStates?.get(raycastHit.blockState.block))
|
return super.interactWithTool(connection, target.blockPosition, flattenableBlockStates?.get(target.blockState.block))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,6 @@ object RainGradientSetGameEventHandler : GameEventHandler {
|
|||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_gradient_set".toResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_gradient_set".toResourceLocation()
|
||||||
|
|
||||||
override fun handle(data: Float, connection: PlayConnection) {
|
override fun handle(data: Float, connection: PlayConnection) {
|
||||||
connection.world.rainGradient = data
|
connection.world.weather.rainGradient = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,6 @@ object ThunderGradientSetGameEventHandler : GameEventHandler {
|
|||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:thunder_gradient_set".toResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:thunder_gradient_set".toResourceLocation()
|
||||||
|
|
||||||
override fun handle(data: Float, connection: PlayConnection) {
|
override fun handle(data: Float, connection: PlayConnection) {
|
||||||
connection.world.thunderGradient = data
|
connection.world.weather.thunderGradient = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ object RainStartGameEventHandler : GameEventHandler {
|
|||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_start".toResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_start".toResourceLocation()
|
||||||
|
|
||||||
override fun handle(data: Float, connection: PlayConnection) {
|
override fun handle(data: Float, connection: PlayConnection) {
|
||||||
connection.world.raining = true
|
connection.world.weather.raining = true
|
||||||
connection.world.rainGradient = 1.0f
|
connection.world.weather.rainGradient = 1.0f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ object RainStopGameEventHandler : GameEventHandler {
|
|||||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_stop".toResourceLocation()
|
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:rain_stop".toResourceLocation()
|
||||||
|
|
||||||
override fun handle(data: Float, connection: PlayConnection) {
|
override fun handle(data: Float, connection: PlayConnection) {
|
||||||
connection.world.raining = false
|
connection.world.weather.raining = false
|
||||||
connection.world.rainGradient = 0.0f
|
connection.world.weather.rainGradient = 0.0f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,9 @@ import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
|||||||
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
|
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
|
||||||
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
|
import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
|
||||||
import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
|
import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
|
||||||
|
import de.bixilon.minosoft.data.world.time.WorldTime
|
||||||
import de.bixilon.minosoft.data.world.view.WorldView
|
import de.bixilon.minosoft.data.world.view.WorldView
|
||||||
|
import de.bixilon.minosoft.data.world.weather.WorldWeather
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.particle.types.Particle
|
import de.bixilon.minosoft.gui.rendering.particle.types.Particle
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition
|
||||||
@ -35,10 +37,8 @@ import de.bixilon.minosoft.modding.event.events.BlockSetEvent
|
|||||||
import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent
|
import de.bixilon.minosoft.modding.event.events.ChunkDataChangeEvent
|
||||||
import de.bixilon.minosoft.modding.event.events.ChunkUnloadEvent
|
import de.bixilon.minosoft.modding.event.events.ChunkUnloadEvent
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
|
||||||
import de.bixilon.minosoft.util.KUtil.lockMapOf
|
import de.bixilon.minosoft.util.KUtil.lockMapOf
|
||||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||||
import de.bixilon.minosoft.util.MMath
|
|
||||||
import de.bixilon.minosoft.util.ReadWriteLock
|
import de.bixilon.minosoft.util.ReadWriteLock
|
||||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.canBuildBiomeCache
|
import de.bixilon.minosoft.util.chunk.ChunkUtil.canBuildBiomeCache
|
||||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.getChunkNeighbourPositions
|
import de.bixilon.minosoft.util.chunk.ChunkUtil.getChunkNeighbourPositions
|
||||||
@ -46,13 +46,9 @@ import de.bixilon.minosoft.util.chunk.ChunkUtil.isInViewDistance
|
|||||||
import de.bixilon.minosoft.util.chunk.ChunkUtil.received
|
import de.bixilon.minosoft.util.chunk.ChunkUtil.received
|
||||||
import de.bixilon.minosoft.util.collections.LockMap
|
import de.bixilon.minosoft.util.collections.LockMap
|
||||||
import de.bixilon.minosoft.util.delegate.DelegateManager.delegate
|
import de.bixilon.minosoft.util.delegate.DelegateManager.delegate
|
||||||
import glm_.func.common.clamp
|
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
import kotlin.math.PI
|
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.cos
|
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,11 +66,8 @@ class World(
|
|||||||
var difficulty: Difficulties? = null
|
var difficulty: Difficulties? = null
|
||||||
var difficultyLocked = false
|
var difficultyLocked = false
|
||||||
var hashedSeed = 0L
|
var hashedSeed = 0L
|
||||||
var time = 0L
|
val time = WorldTime(this)
|
||||||
var age = 0L
|
val weather = WorldWeather()
|
||||||
var raining = false
|
|
||||||
var rainGradient = 0.0f
|
|
||||||
var thunderGradient = 0.0f
|
|
||||||
val view = WorldView(connection)
|
val view = WorldView(connection)
|
||||||
private val random = Random
|
private val random = Random
|
||||||
|
|
||||||
@ -234,25 +227,6 @@ class World(
|
|||||||
return get(blockPosition.chunkPosition)?.getLight(blockPosition.inChunkPosition) ?: 0x00
|
return get(blockPosition.chunkPosition)?.getLight(blockPosition.inChunkPosition) ?: 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
val skyAngle: Double
|
|
||||||
get() {
|
|
||||||
val fractionalPath = MMath.fractionalPart(abs(time) / ProtocolDefinition.TICKS_PER_DAYf - 0.25)
|
|
||||||
val angle = 0.5 - cos(fractionalPath * Math.PI) / 2.0
|
|
||||||
return (fractionalPath * 2.0 + angle) / 3.0
|
|
||||||
}
|
|
||||||
|
|
||||||
val lightBase: Double
|
|
||||||
get() {
|
|
||||||
var base = 1.0f - (cos(skyAngle * 2.0 * PI) * 2.0 + 0.2)
|
|
||||||
base = base.clamp(0.0, 1.0)
|
|
||||||
base = 1.0 - base
|
|
||||||
|
|
||||||
base *= 1.0 - ((rainGradient * 5.0) / 16.0)
|
|
||||||
base *= 1.0 - (((thunderGradient * rainGradient) * 5.0) / 16.0)
|
|
||||||
return base * 0.8 + 0.2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return All 8 neighbour chunks
|
* @return All 8 neighbour chunks
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package de.bixilon.minosoft.data.world.time
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.world.World
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
import de.bixilon.minosoft.util.MMath
|
||||||
|
import glm_.func.common.clamp
|
||||||
|
import kotlin.math.PI
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.cos
|
||||||
|
|
||||||
|
class WorldTime(
|
||||||
|
private val world: World,
|
||||||
|
) {
|
||||||
|
var time = 0L
|
||||||
|
var age = 0L
|
||||||
|
|
||||||
|
|
||||||
|
val skyAngle: Float
|
||||||
|
get() {
|
||||||
|
val fractionalPath = MMath.fractionalPart(abs(time) / ProtocolDefinition.TICKS_PER_DAYf - 0.25)
|
||||||
|
val angle = 0.5 - cos(fractionalPath * Math.PI) / 2.0
|
||||||
|
return ((fractionalPath * 2.0 + angle) / 3.0).toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val lightBase: Double
|
||||||
|
get() {
|
||||||
|
var base = 1.0f - (cos(skyAngle * 2.0 * PI) * 2.0 + 0.2)
|
||||||
|
base = base.clamp(0.0, 1.0)
|
||||||
|
base = 1.0 - base
|
||||||
|
|
||||||
|
base *= 1.0 - ((world.weather.rainGradient * 5.0) / 16.0)
|
||||||
|
base *= 1.0 - (((world.weather.thunderGradient * world.weather.rainGradient) * 5.0) / 16.0)
|
||||||
|
return base * 0.8 + 0.2
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package de.bixilon.minosoft.data.world.weather
|
||||||
|
|
||||||
|
class WorldWeather {
|
||||||
|
|
||||||
|
var raining = false
|
||||||
|
var rainGradient = 0.0f
|
||||||
|
var thunderGradient = 0.0f
|
||||||
|
}
|
@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
|
|||||||
import de.bixilon.minosoft.data.text.BaseComponent
|
import de.bixilon.minosoft.data.text.BaseComponent
|
||||||
import de.bixilon.minosoft.data.text.ChatColors
|
import de.bixilon.minosoft.data.text.ChatColors
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
import de.bixilon.minosoft.gui.rendering.camera.Camera
|
||||||
import de.bixilon.minosoft.gui.rendering.entity.EntityHitboxRenderer
|
import de.bixilon.minosoft.gui.rendering.entity.EntityHitboxRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.font.Font
|
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||||
import de.bixilon.minosoft.gui.rendering.font.FontLoader
|
import de.bixilon.minosoft.gui.rendering.font.FontLoader
|
||||||
@ -76,6 +77,7 @@ class RenderWindow(
|
|||||||
private val profile = connection.profiles.rendering
|
private val profile = connection.profiles.rendering
|
||||||
val window: BaseWindow = GLFWWindow(this, connection)
|
val window: BaseWindow = GLFWWindow(this, connection)
|
||||||
val renderSystem: RenderSystem = OpenGLRenderSystem(this)
|
val renderSystem: RenderSystem = OpenGLRenderSystem(this)
|
||||||
|
val camera = Camera(this)
|
||||||
var initialized = false
|
var initialized = false
|
||||||
private set
|
private set
|
||||||
private lateinit var renderThread: Thread
|
private lateinit var renderThread: Thread
|
||||||
@ -163,7 +165,7 @@ class RenderWindow(
|
|||||||
window.init(connection.profiles.rendering)
|
window.init(connection.profiles.rendering)
|
||||||
window.setDefaultIcon(connection.assetsManager)
|
window.setDefaultIcon(connection.assetsManager)
|
||||||
|
|
||||||
inputHandler.camera.init(this)
|
camera.init()
|
||||||
|
|
||||||
tintManager.init(connection.assetsManager)
|
tintManager.init(connection.assetsManager)
|
||||||
|
|
||||||
@ -360,6 +362,7 @@ class RenderWindow(
|
|||||||
window.pollEvents()
|
window.pollEvents()
|
||||||
|
|
||||||
inputHandler.draw(deltaFrameTime)
|
inputHandler.draw(deltaFrameTime)
|
||||||
|
camera.draw()
|
||||||
|
|
||||||
// handle opengl context tasks, but limit it per frame
|
// handle opengl context tasks, but limit it per frame
|
||||||
queue.timeWork(RenderConstants.MAXIMUM_QUEUE_TIME_PER_FRAME)
|
queue.timeWork(RenderConstants.MAXIMUM_QUEUE_TIME_PER_FRAME)
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.camera
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.camera.target.TargetHandler
|
||||||
|
|
||||||
|
class Camera(
|
||||||
|
renderWindow: RenderWindow,
|
||||||
|
) {
|
||||||
|
val matrixHandler = MatrixHandler(renderWindow)
|
||||||
|
val targetHandler = TargetHandler(renderWindow, this)
|
||||||
|
val fogManager = FogManager(renderWindow)
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
matrixHandler.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw() {
|
||||||
|
matrixHandler.entity.tick()
|
||||||
|
matrixHandler.draw()
|
||||||
|
targetHandler.raycast()
|
||||||
|
fogManager.draw()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.camera
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.text.ChatColors
|
||||||
|
import de.bixilon.minosoft.data.text.RGBColor
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||||
|
import de.bixilon.minosoft.util.delegate.watcher.SimpleDelegateWatcher.Companion.watchRendering
|
||||||
|
|
||||||
|
@Deprecated("Needs some refactoring and improvements")
|
||||||
|
class FogManager(
|
||||||
|
private val renderWindow: RenderWindow,
|
||||||
|
) {
|
||||||
|
private var upToDate = false
|
||||||
|
|
||||||
|
var fogColor: RGBColor = ChatColors.GREEN
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
upToDate = false
|
||||||
|
}
|
||||||
|
private var fogStart = 0.0f
|
||||||
|
private var fogEnd = 0.0f
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
renderWindow.connection.world.view::viewDistance.watchRendering(this, true) { calculateFog() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw() {
|
||||||
|
if (upToDate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
calculateFog()
|
||||||
|
updateShaders()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateFog() {
|
||||||
|
if (!renderWindow.connection.profiles.rendering.fog.enabled) {
|
||||||
|
// ToDo: This is not improving performance
|
||||||
|
fogStart = Float.MAX_VALUE
|
||||||
|
fogEnd = Float.MAX_VALUE
|
||||||
|
} else {
|
||||||
|
fogStart = renderWindow.connection.world.view.viewDistance * 16.0f - 8.0f // ToDo
|
||||||
|
fogEnd = fogStart + 10.0f
|
||||||
|
}
|
||||||
|
renderWindow[SkyRenderer]?.let { fogColor = it.baseColor }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun updateShaders() {
|
||||||
|
for (shader in renderWindow.renderSystem.shaders) {
|
||||||
|
if (!shader.uniforms.contains("uFogColor")) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
shader.use()
|
||||||
|
|
||||||
|
shader.setFloat("uFogStart", fogStart)
|
||||||
|
shader.setFloat("uFogEnd", fogEnd)
|
||||||
|
shader["uFogColor"] = fogColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.camera
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||||
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.camera.frustum.Frustum
|
||||||
|
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
|
||||||
|
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||||
|
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||||
|
import glm_.func.rad
|
||||||
|
import glm_.glm
|
||||||
|
import glm_.mat4x4.Mat4
|
||||||
|
import glm_.vec2.Vec2
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
|
class MatrixHandler(
|
||||||
|
private val renderWindow: RenderWindow,
|
||||||
|
) {
|
||||||
|
private val connection = renderWindow.connection
|
||||||
|
private val profile = renderWindow.connection.profiles.rendering.camera
|
||||||
|
val frustum = Frustum(this)
|
||||||
|
var entity: Entity = renderWindow.connection.player
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
upToDate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var eyePosition = Vec3.EMPTY
|
||||||
|
private set
|
||||||
|
var rotation = EntityRotation(0.0, 0.0)
|
||||||
|
private set
|
||||||
|
private var previousFOV = 0.0
|
||||||
|
|
||||||
|
var cameraFront = Vec3(0.0, 0.0, -1.0)
|
||||||
|
private set
|
||||||
|
var cameraRight = Vec3(0.0, 0.0, -1.0)
|
||||||
|
private set
|
||||||
|
var cameraUp = Vec3(0.0, 1.0, 0.0)
|
||||||
|
private set
|
||||||
|
|
||||||
|
|
||||||
|
var zoom = 0.0f
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
upToDate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private var upToDate = false
|
||||||
|
|
||||||
|
var viewMatrix = calculateViewMatrix()
|
||||||
|
private set
|
||||||
|
var projectionMatrix = calculateProjectionMatrix(renderWindow.window.sizef)
|
||||||
|
private set
|
||||||
|
var viewProjectionMatrix = projectionMatrix * viewMatrix
|
||||||
|
private set
|
||||||
|
|
||||||
|
|
||||||
|
private val fov: Double
|
||||||
|
get() {
|
||||||
|
val fov = profile.fov / (zoom + 1.0)
|
||||||
|
|
||||||
|
if (!profile.dynamicFOV) {
|
||||||
|
return fov
|
||||||
|
}
|
||||||
|
return fov * connection.player.fovMultiplier.interpolate()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun calculateViewMatrix(eyePosition: Vec3 = entity.eyePosition): Mat4 {
|
||||||
|
return glm.lookAt(eyePosition, eyePosition + cameraFront, CAMERA_UP_VEC3)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateProjectionMatrix(screenDimensions: Vec2): Mat4 {
|
||||||
|
return glm.perspective(fov.rad.toFloat(), screenDimensions.x / screenDimensions.y, 0.01f, 10000.0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
|
||||||
|
projectionMatrix = calculateProjectionMatrix(Vec2(it.size))
|
||||||
|
upToDate = false
|
||||||
|
})
|
||||||
|
draw() // set initial values
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw() {
|
||||||
|
val fov = fov
|
||||||
|
val eyePosition = entity.eyePosition
|
||||||
|
val rotation = entity.rotation
|
||||||
|
if (upToDate && eyePosition == this.eyePosition && rotation == this.rotation && fov == previousFOV) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.eyePosition = eyePosition
|
||||||
|
this.rotation = rotation
|
||||||
|
previousFOV = fov
|
||||||
|
|
||||||
|
updateRotation(rotation)
|
||||||
|
updateViewMatrix(eyePosition)
|
||||||
|
updateFrustum()
|
||||||
|
|
||||||
|
connection.fireEvent(CameraPositionChangeEvent(renderWindow, eyePosition))
|
||||||
|
|
||||||
|
connection.fireEvent(CameraMatrixChangeEvent(
|
||||||
|
renderWindow = renderWindow,
|
||||||
|
viewMatrix = viewMatrix,
|
||||||
|
projectionMatrix = projectionMatrix,
|
||||||
|
viewProjectionMatrix = viewProjectionMatrix,
|
||||||
|
))
|
||||||
|
|
||||||
|
updateShaders()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateViewMatrix(eyePosition: Vec3) {
|
||||||
|
viewMatrix = calculateViewMatrix(eyePosition)
|
||||||
|
viewProjectionMatrix = projectionMatrix * viewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateFrustum() {
|
||||||
|
frustum.recalculate()
|
||||||
|
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateRotation(rotation: EntityRotation = entity.rotation) {
|
||||||
|
cameraFront = rotation.front
|
||||||
|
|
||||||
|
cameraRight = (cameraFront cross CAMERA_UP_VEC3).normalize()
|
||||||
|
cameraUp = (cameraRight cross cameraFront).normalize()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateShaders() {
|
||||||
|
for (shader in renderWindow.renderSystem.shaders) {
|
||||||
|
if (shader.uniforms.contains("uViewProjectionMatrix")) {
|
||||||
|
shader.use().setMat4("uViewProjectionMatrix", viewProjectionMatrix)
|
||||||
|
}
|
||||||
|
if (shader.uniforms.contains("uCameraPosition")) {
|
||||||
|
shader.use().setVec3("uCameraPosition", connection.player.cameraPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val CAMERA_UP_VEC3 = Vec3(0.0, 1.0, 0.0)
|
||||||
|
}
|
||||||
|
}
|
@ -11,34 +11,31 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.input.camera.frustum
|
package de.bixilon.minosoft.gui.rendering.camera.frustum
|
||||||
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.registries.AABB
|
import de.bixilon.minosoft.data.registries.AABB
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.Camera
|
import de.bixilon.minosoft.gui.rendering.camera.MatrixHandler
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4Util.dot
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4Util.dot
|
||||||
import de.bixilon.minosoft.util.KUtil
|
import de.bixilon.minosoft.util.KUtil
|
||||||
import de.bixilon.minosoft.util.KUtil.get
|
import de.bixilon.minosoft.util.KUtil.get
|
||||||
import de.bixilon.minosoft.util.enum.ValuesEnum
|
import de.bixilon.minosoft.util.enum.ValuesEnum
|
||||||
import glm_.mat3x3.Mat3
|
import glm_.mat3x3.Mat3
|
||||||
import glm_.mat4x4.Mat4
|
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
import glm_.vec4.Vec4
|
import glm_.vec4.Vec4
|
||||||
|
|
||||||
// Big thanks to: https://gist.github.com/podgorskiy/e698d18879588ada9014768e3e82a644
|
// Big thanks to: https://gist.github.com/podgorskiy/e698d18879588ada9014768e3e82a644
|
||||||
class Frustum(private val camera: Camera) {
|
class Frustum(
|
||||||
|
private val matrixHandler: MatrixHandler,
|
||||||
|
) {
|
||||||
private lateinit var data: FrustumData
|
private lateinit var data: FrustumData
|
||||||
|
|
||||||
init {
|
|
||||||
recalculate()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun recalculate() {
|
fun recalculate() {
|
||||||
val matrix = Mat4(camera.viewProjectionMatrix).transpose()
|
val matrix = matrixHandler.viewProjectionMatrix.transpose()
|
||||||
val planes = arrayOf(
|
val planes = arrayOf(
|
||||||
matrix[3] + matrix[0],
|
matrix[3] + matrix[0],
|
||||||
matrix[3] - matrix[0],
|
matrix[3] - matrix[0],
|
@ -0,0 +1,138 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.camera.target
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.player.LocalPlayerEntity
|
||||||
|
import de.bixilon.minosoft.data.registries.VoxelShape
|
||||||
|
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.camera.Camera
|
||||||
|
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.camera.target.targets.FluidTarget
|
||||||
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.GenericTarget
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3d
|
||||||
|
import de.bixilon.minosoft.util.KUtil.decide
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
import glm_.vec3.Vec3d
|
||||||
|
|
||||||
|
class TargetHandler(
|
||||||
|
private val renderWindow: RenderWindow,
|
||||||
|
private var camera: Camera,
|
||||||
|
) {
|
||||||
|
private val connection = renderWindow.connection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can ba a BlockTarget or an EntityTarget. Not a FluidTarget
|
||||||
|
*/
|
||||||
|
var target: GenericTarget? = null
|
||||||
|
private set
|
||||||
|
var fluidTarget: FluidTarget? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
|
||||||
|
fun raycast() {
|
||||||
|
val eyePosition = camera.matrixHandler.eyePosition.toVec3d
|
||||||
|
val cameraFront = camera.matrixHandler.cameraFront.toVec3d
|
||||||
|
|
||||||
|
target = raycast(eyePosition, cameraFront, blocks = true, fluids = false, entities = true)
|
||||||
|
fluidTarget = raycast(eyePosition, cameraFront, blocks = false, fluids = true, entities = false) as FluidTarget?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun raycastEntity(origin: Vec3d, direction: Vec3d): EntityTarget? {
|
||||||
|
var currentHit: EntityTarget? = null
|
||||||
|
|
||||||
|
val originF = Vec3(origin)
|
||||||
|
for (entity in connection.world.entities) {
|
||||||
|
if (entity is LocalPlayerEntity) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ((entity.cameraPosition - originF).length2() > MAX_ENTITY_DISTANCE) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val target = VoxelShape(entity.cameraAABB).raycast(origin, direction)
|
||||||
|
if (!target.hit) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ((currentHit?.distance ?: Double.MAX_VALUE) < target.distance) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
currentHit = EntityTarget(origin + direction * target.distance, target.distance, target.direction, entity)
|
||||||
|
|
||||||
|
}
|
||||||
|
return currentHit
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun raycast(origin: Vec3d, direction: Vec3d, blocks: Boolean, fluids: Boolean, entities: Boolean): GenericTarget? {
|
||||||
|
if (!blocks && !fluids && entities) {
|
||||||
|
// only raycast entities
|
||||||
|
return raycastEntity(origin, direction)
|
||||||
|
}
|
||||||
|
val currentPosition = Vec3d(origin)
|
||||||
|
|
||||||
|
fun getTotalDistance(): Double {
|
||||||
|
return (origin - currentPosition).length()
|
||||||
|
}
|
||||||
|
|
||||||
|
var target: GenericTarget? = null
|
||||||
|
for (i in 0..RAYCAST_MAX_STEPS) {
|
||||||
|
val blockPosition = currentPosition.floor
|
||||||
|
val blockState = connection.world[blockPosition]
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
target = FluidTarget(
|
||||||
|
currentPosition,
|
||||||
|
distance,
|
||||||
|
voxelShapeRaycastResult.direction,
|
||||||
|
blockState,
|
||||||
|
blockPosition,
|
||||||
|
blockState.block.fluid,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blocks) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
target = BlockTarget(
|
||||||
|
currentPosition,
|
||||||
|
distance,
|
||||||
|
voxelShapeRaycastResult.direction,
|
||||||
|
blockState,
|
||||||
|
blockPosition,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entities) {
|
||||||
|
val entityRaycastHit = raycastEntity(origin, direction) ?: return target
|
||||||
|
target ?: return null
|
||||||
|
return (entityRaycastHit.distance < target.distance).decide(entityRaycastHit, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val RAYCAST_MAX_STEPS = 100
|
||||||
|
private const val MAX_ENTITY_DISTANCE = 20.0f * 20.0f // length2 does not get the square root
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.input.camera.hit
|
package de.bixilon.minosoft.gui.rendering.camera.target.targets
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||||
@ -21,13 +21,13 @@ import de.bixilon.minosoft.data.text.TextFormattable
|
|||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
|
|
||||||
open class BlockRaycastHit(
|
open class BlockTarget(
|
||||||
position: Vec3d,
|
position: Vec3d,
|
||||||
distance: Double,
|
distance: Double,
|
||||||
hitDirection: Directions,
|
direction: Directions,
|
||||||
val blockState: BlockState,
|
val blockState: BlockState,
|
||||||
val blockPosition: Vec3i,
|
val blockPosition: Vec3i,
|
||||||
) : RaycastHit(position, distance, hitDirection), TextFormattable {
|
) : GenericTarget(position, distance, direction), TextFormattable {
|
||||||
val hitPosition = position - blockPosition
|
val hitPosition = position - blockPosition
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.input.camera.hit
|
package de.bixilon.minosoft.gui.rendering.camera.target.targets
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.entities.entities.Entity
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
@ -20,12 +20,12 @@ import de.bixilon.minosoft.data.text.ChatComponent
|
|||||||
import de.bixilon.minosoft.data.text.TextFormattable
|
import de.bixilon.minosoft.data.text.TextFormattable
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
|
|
||||||
class EntityRaycastHit(
|
class EntityTarget(
|
||||||
position: Vec3d,
|
position: Vec3d,
|
||||||
distance: Double,
|
distance: Double,
|
||||||
hitDirection: Directions,
|
direction: Directions,
|
||||||
val entity: Entity,
|
val entity: Entity,
|
||||||
) : RaycastHit(position, distance, hitDirection), TextFormattable {
|
) : GenericTarget(position, distance, direction), TextFormattable {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return toText().legacyText
|
return toText().legacyText
|
@ -11,7 +11,7 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.input.camera.hit
|
package de.bixilon.minosoft.gui.rendering.camera.target.targets
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||||
@ -22,14 +22,14 @@ import de.bixilon.minosoft.data.text.TextFormattable
|
|||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
|
|
||||||
class FluidRaycastHit(
|
class FluidTarget(
|
||||||
position: Vec3d,
|
position: Vec3d,
|
||||||
distance: Double,
|
distance: Double,
|
||||||
hitDirection: Directions,
|
direction: Directions,
|
||||||
val blockState: BlockState,
|
val blockState: BlockState,
|
||||||
val blockPosition: Vec3i,
|
val blockPosition: Vec3i,
|
||||||
val fluid: Fluid,
|
val fluid: Fluid,
|
||||||
) : RaycastHit(position, distance, hitDirection), TextFormattable {
|
) : GenericTarget(position, distance, direction), TextFormattable {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return toText().legacyText
|
return toText().legacyText
|
@ -11,13 +11,13 @@
|
|||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.input.camera.hit
|
package de.bixilon.minosoft.gui.rendering.camera.target.targets
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
|
|
||||||
abstract class RaycastHit(
|
abstract class GenericTarget(
|
||||||
val position: Vec3d,
|
val position: Vec3d,
|
||||||
val distance: Double,
|
val distance: Double,
|
||||||
val hitDirection: Directions,
|
val direction: Directions,
|
||||||
)
|
)
|
@ -18,7 +18,7 @@ import de.bixilon.minosoft.data.entities.entities.Entity
|
|||||||
import de.bixilon.minosoft.data.registries.AABB
|
import de.bixilon.minosoft.data.registries.AABB
|
||||||
import de.bixilon.minosoft.data.text.ChatColors
|
import de.bixilon.minosoft.data.text.ChatColors
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.frustum.Frustum
|
import de.bixilon.minosoft.gui.rendering.camera.frustum.Frustum
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
import de.bixilon.minosoft.gui.rendering.util.mesh.LineMesh
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||||
|
@ -45,7 +45,7 @@ class EntityHitboxRenderer(
|
|||||||
) : Renderer, OpaqueDrawable, SkipAll {
|
) : Renderer, OpaqueDrawable, SkipAll {
|
||||||
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
||||||
val profile = connection.profiles.entity.hitbox
|
val profile = connection.profiles.entity.hitbox
|
||||||
private val frustum = renderWindow.inputHandler.camera.frustum
|
private val frustum = renderWindow.camera.matrixHandler.frustum
|
||||||
private val meshes: LockMap<Entity, EntityHitbox> = lockMapOf()
|
private val meshes: LockMap<Entity, EntityHitbox> = lockMapOf()
|
||||||
private val toUnload: MutableSet<EntityHitbox> = synchronizedSetOf()
|
private val toUnload: MutableSet<EntityHitbox> = synchronizedSetOf()
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.other
|
|||||||
import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegateWatcher.Companion.profileWatch
|
import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegateWatcher.Companion.profileWatch
|
||||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
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.hud.HUDRenderer
|
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.HUDAtlasElement
|
import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.HUDAtlasElement
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.CustomHUDElement
|
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.CustomHUDElement
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
|
import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
|
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
|
||||||
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.system.base.BlendingFunctions
|
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList
|
||||||
@ -69,8 +69,8 @@ class CrosshairHUDElement(hudRenderer: HUDRenderer) : CustomHUDElement(hudRender
|
|||||||
|
|
||||||
// Custom draw to make the crosshair inverted
|
// Custom draw to make the crosshair inverted
|
||||||
if (renderWindow.connection.player.gamemode == Gamemodes.SPECTATOR) {
|
if (renderWindow.connection.player.gamemode == Gamemodes.SPECTATOR) {
|
||||||
val hitResult = renderWindow.inputHandler.camera.target ?: return
|
val hitResult = renderWindow.camera.targetHandler.target ?: return
|
||||||
if (hitResult !is EntityRaycastHit && (hitResult !is BlockRaycastHit || renderWindow.connection.world.getBlockEntity(hitResult.blockPosition) == null)) {
|
if (hitResult !is EntityTarget && (hitResult !is BlockTarget || renderWindow.connection.world.getBlockEntity(hitResult.blockPosition) == null)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ class DebugHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<GridLayout>
|
|||||||
layout += AutoTextElement(hudRenderer, 1) {
|
layout += AutoTextElement(hudRenderer, 1) {
|
||||||
val text = BaseComponent("Facing ")
|
val text = BaseComponent("Facing ")
|
||||||
|
|
||||||
Directions.byDirection(hudRenderer.renderWindow.inputHandler.camera.cameraFront).apply {
|
Directions.byDirection(hudRenderer.renderWindow.camera.matrixHandler.cameraFront).apply {
|
||||||
text += this
|
text += this
|
||||||
text += " "
|
text += " "
|
||||||
text += vector
|
text += vector
|
||||||
@ -227,7 +227,7 @@ class DebugHUDElement(hudRenderer: HUDRenderer) : LayoutedHUDElement<GridLayout>
|
|||||||
|
|
||||||
layout += LineSpacerElement(hudRenderer)
|
layout += LineSpacerElement(hudRenderer)
|
||||||
|
|
||||||
renderWindow.inputHandler.camera.apply {
|
renderWindow.camera.targetHandler.apply {
|
||||||
layout += AutoTextElement(hudRenderer, 1, HorizontalAlignments.RIGHT) {
|
layout += AutoTextElement(hudRenderer, 1, HorizontalAlignments.RIGHT) {
|
||||||
// ToDo: Tags
|
// ToDo: Tags
|
||||||
target ?: "No target"
|
target ?: "No target"
|
||||||
|
@ -0,0 +1,148 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.input
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.key.KeyAction
|
||||||
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.gui.rendering.camera.MatrixHandler
|
||||||
|
import de.bixilon.minosoft.gui.rendering.input.camera.MovementInput
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
import glm_.glm
|
||||||
|
import glm_.vec2.Vec2d
|
||||||
|
|
||||||
|
class CameraInput(
|
||||||
|
private val renderWindow: RenderWindow,
|
||||||
|
val matrixHandler: MatrixHandler,
|
||||||
|
) {
|
||||||
|
private val connection = renderWindow.connection
|
||||||
|
private val player = connection.player
|
||||||
|
private val controlsProfile = connection.profiles.controls
|
||||||
|
|
||||||
|
private val ignoreInput: Boolean
|
||||||
|
get() {
|
||||||
|
val entity = matrixHandler.entity
|
||||||
|
if (entity != player) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerKeyBindings() {
|
||||||
|
renderWindow.inputHandler.registerCheckCallback(
|
||||||
|
MOVE_SPRINT_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_LEFT_CONTROL),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MOVE_FORWARDS_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_W),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MOVE_BACKWARDS_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_S),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MOVE_LEFT_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_A),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
MOVE_RIGHT_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_D),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FLY_UP_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_SPACE),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FLY_DOWN_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
JUMP_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_SPACE),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SNEAK_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TOGGLE_FLY_KEYBINDING to KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.DOUBLE_PRESS to setOf(KeyCodes.KEY_SPACE),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
renderWindow.inputHandler.registerKeyCallback(ZOOM_KEYBINDING, KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.CHANGE to setOf(KeyCodes.KEY_C),
|
||||||
|
),
|
||||||
|
)) { matrixHandler.zoom = if (it) 2.0f else 0.0f }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
registerKeyBindings()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update() {
|
||||||
|
val input = if (ignoreInput) {
|
||||||
|
MovementInput()
|
||||||
|
} else {
|
||||||
|
MovementInput(
|
||||||
|
pressingForward = renderWindow.inputHandler.isKeyBindingDown(MOVE_FORWARDS_KEYBINDING),
|
||||||
|
pressingBack = renderWindow.inputHandler.isKeyBindingDown(MOVE_BACKWARDS_KEYBINDING),
|
||||||
|
pressingLeft = renderWindow.inputHandler.isKeyBindingDown(MOVE_LEFT_KEYBINDING),
|
||||||
|
pressingRight = renderWindow.inputHandler.isKeyBindingDown(MOVE_RIGHT_KEYBINDING),
|
||||||
|
jumping = renderWindow.inputHandler.isKeyBindingDown(JUMP_KEYBINDING),
|
||||||
|
sneaking = renderWindow.inputHandler.isKeyBindingDown(SNEAK_KEYBINDING),
|
||||||
|
sprinting = renderWindow.inputHandler.isKeyBindingDown(MOVE_SPRINT_KEYBINDING),
|
||||||
|
flyDown = renderWindow.inputHandler.isKeyBindingDown(FLY_DOWN_KEYBINDING),
|
||||||
|
flyUp = renderWindow.inputHandler.isKeyBindingDown(FLY_UP_KEYBINDING),
|
||||||
|
toggleFlyDown = renderWindow.inputHandler.isKeyBindingDown(TOGGLE_FLY_KEYBINDING),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
connection.player.input = input
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mouseCallback(delta: Vec2d) {
|
||||||
|
delta *= 0.1f * controlsProfile.mouse.sensitivity
|
||||||
|
var yaw = delta.x + player.rotation.yaw
|
||||||
|
if (yaw > 180) {
|
||||||
|
yaw -= 360
|
||||||
|
} else if (yaw < -180) {
|
||||||
|
yaw += 360
|
||||||
|
}
|
||||||
|
yaw %= 180
|
||||||
|
val pitch = glm.clamp(delta.y + player.rotation.pitch, -89.9, 89.9)
|
||||||
|
val rotation = EntityRotation(yaw, pitch)
|
||||||
|
player.rotation = rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private val MOVE_SPRINT_KEYBINDING = "minosoft:move_sprint".toResourceLocation()
|
||||||
|
private val MOVE_FORWARDS_KEYBINDING = "minosoft:move_forward".toResourceLocation()
|
||||||
|
private val MOVE_BACKWARDS_KEYBINDING = "minosoft:move_backwards".toResourceLocation()
|
||||||
|
private val MOVE_LEFT_KEYBINDING = "minosoft:move_left".toResourceLocation()
|
||||||
|
private val MOVE_RIGHT_KEYBINDING = "minosoft:move_right".toResourceLocation()
|
||||||
|
|
||||||
|
private val SNEAK_KEYBINDING = "minosoft:move_sneak".toResourceLocation()
|
||||||
|
private val JUMP_KEYBINDING = "minosoft:move_jump".toResourceLocation()
|
||||||
|
|
||||||
|
private val TOGGLE_FLY_KEYBINDING = "minosoft:move_toggle_fly".toResourceLocation()
|
||||||
|
private val FLY_UP_KEYBINDING = "minosoft:move_fly_up".toResourceLocation()
|
||||||
|
private val FLY_DOWN_KEYBINDING = "minosoft:move_fly_down".toResourceLocation()
|
||||||
|
|
||||||
|
private val ZOOM_KEYBINDING = "minosoft:zoom".toResourceLocation()
|
||||||
|
}
|
||||||
|
}
|
@ -1,477 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minosoft
|
|
||||||
* Copyright (C) 2021 Moritz Zwerger, Lukas Eisenhauer
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.config.key.KeyAction
|
|
||||||
import de.bixilon.minosoft.config.key.KeyBinding
|
|
||||||
import de.bixilon.minosoft.config.key.KeyCodes
|
|
||||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
|
||||||
import de.bixilon.minosoft.data.player.LocalPlayerEntity
|
|
||||||
import de.bixilon.minosoft.data.registries.VoxelShape
|
|
||||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock
|
|
||||||
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
|
|
||||||
import de.bixilon.minosoft.data.text.ChatColors
|
|
||||||
import de.bixilon.minosoft.data.world.view.ViewDistanceChangeEvent
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.frustum.Frustum
|
|
||||||
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
|
|
||||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
|
||||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
|
|
||||||
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.PlayerActionC2SP
|
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
|
||||||
import de.bixilon.minosoft.util.KUtil
|
|
||||||
import de.bixilon.minosoft.util.KUtil.decide
|
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
|
||||||
import de.bixilon.minosoft.util.Previous
|
|
||||||
import glm_.func.rad
|
|
||||||
import glm_.glm
|
|
||||||
import glm_.mat4x4.Mat4
|
|
||||||
import glm_.mat4x4.Mat4d
|
|
||||||
import glm_.vec2.Vec2
|
|
||||||
import glm_.vec2.Vec2d
|
|
||||||
import glm_.vec3.Vec3d
|
|
||||||
|
|
||||||
class Camera(
|
|
||||||
val connection: PlayConnection,
|
|
||||||
val renderWindow: RenderWindow,
|
|
||||||
) {
|
|
||||||
private val profile = connection.profiles.rendering.camera
|
|
||||||
private val controlsProfile = connection.profiles.controls
|
|
||||||
var fogColor = Previous(ChatColors.GREEN)
|
|
||||||
var fogStart = connection.world.view.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDo
|
|
||||||
|
|
||||||
private var zoom = 0.0f
|
|
||||||
|
|
||||||
var cameraFront = Vec3d(0.0, 0.0, -1.0)
|
|
||||||
var cameraRight = Vec3d(0.0, 0.0, -1.0)
|
|
||||||
private var cameraUp = Vec3d(0.0, 1.0, 0.0)
|
|
||||||
|
|
||||||
// ToDo: They should also be available in headless mode
|
|
||||||
var nonFluidTarget: RaycastHit? = null
|
|
||||||
private set
|
|
||||||
var target: RaycastHit? = null
|
|
||||||
private set
|
|
||||||
var blockTarget: BlockRaycastHit? = null // Block target or if blocked by entity null
|
|
||||||
private set
|
|
||||||
var fluidTarget: FluidRaycastHit? = null
|
|
||||||
private set
|
|
||||||
var entityTarget: EntityRaycastHit? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
private val fov: Double
|
|
||||||
get() {
|
|
||||||
val fov = profile.fov / (zoom + 1.0)
|
|
||||||
|
|
||||||
if (!profile.dynamicFOV) {
|
|
||||||
return fov
|
|
||||||
}
|
|
||||||
return fov * connection.player.fovMultiplier.interpolate()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var viewMatrix = calculateViewMatrix()
|
|
||||||
private set
|
|
||||||
var projectionMatrix = calculateProjectionMatrix(renderWindow.window.sizef)
|
|
||||||
private set
|
|
||||||
var viewProjectionMatrix = projectionMatrix * viewMatrix
|
|
||||||
private set
|
|
||||||
|
|
||||||
|
|
||||||
var previousEyePosition = Vec3d(connection.player.position)
|
|
||||||
var previousRotation = connection.player.rotation.copy()
|
|
||||||
var previousZoom = zoom
|
|
||||||
|
|
||||||
private var lastDropPacketSent = -1L
|
|
||||||
|
|
||||||
val frustum: Frustum = Frustum(this)
|
|
||||||
|
|
||||||
|
|
||||||
fun mouseCallback(delta: Vec2d) {
|
|
||||||
delta *= 0.1f * controlsProfile.mouse.sensitivity
|
|
||||||
var yaw = delta.x + connection.player.rotation.yaw
|
|
||||||
if (yaw > 180) {
|
|
||||||
yaw -= 360
|
|
||||||
} else if (yaw < -180) {
|
|
||||||
yaw += 360
|
|
||||||
}
|
|
||||||
yaw %= 180
|
|
||||||
val pitch = glm.clamp(delta.y + connection.player.rotation.pitch, -89.9, 89.9)
|
|
||||||
val rotation = EntityRotation(yaw, pitch)
|
|
||||||
connection.player.rotation = rotation
|
|
||||||
setRotation(rotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateFogDistance() {
|
|
||||||
if (!connection.profiles.rendering.fog.enabled) {
|
|
||||||
fogStart = Float.MAX_VALUE
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fogStart = if (connection.player.submergedFluid?.resourceLocation == DefaultFluids.WATER) {
|
|
||||||
10.0f
|
|
||||||
} else {
|
|
||||||
connection.world.view.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() // ToDo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyFog() {
|
|
||||||
for (shader in renderWindow.renderSystem.shaders) {
|
|
||||||
if (!shader.uniforms.contains("uFogColor")) {
|
|
||||||
continue
|
|
||||||
|
|
||||||
}
|
|
||||||
shader.use()
|
|
||||||
|
|
||||||
shader.setFloat("uFogStart", fogStart)
|
|
||||||
shader.setFloat("uFogEnd", fogStart + 10.0f)
|
|
||||||
shader["uFogColor"] = fogColor
|
|
||||||
}
|
|
||||||
fogColor.assign()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun init(renderWindow: RenderWindow) {
|
|
||||||
renderWindow.inputHandler.registerCheckCallback(
|
|
||||||
MOVE_SPRINT_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_LEFT_CONTROL),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MOVE_FORWARDS_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_W),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MOVE_BACKWARDS_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_S),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MOVE_LEFT_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_A),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MOVE_RIGHT_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_D),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FLY_UP_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_SPACE),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FLY_DOWN_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ZOOM_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_C),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
JUMP_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_SPACE),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SNEAK_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.CHANGE to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TOGGLE_FLY_KEYBINDING to KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.DOUBLE_PRESS to setOf(KeyCodes.KEY_SPACE),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> { recalculateViewProjectionMatrix() })
|
|
||||||
|
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ViewDistanceChangeEvent> { it.viewDistance * ProtocolDefinition.SECTION_WIDTH_X.toFloat() }) // ToDo
|
|
||||||
|
|
||||||
fun dropItem(stack: Boolean) {
|
|
||||||
val time = KUtil.time
|
|
||||||
if (time - lastDropPacketSent < ProtocolDefinition.TICK_TIME) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val type = if (stack) {
|
|
||||||
connection.player.inventory.getHotbarSlot()?.count = 0
|
|
||||||
PlayerActionC2SP.Actions.DROP_ITEM_STACK
|
|
||||||
} else {
|
|
||||||
connection.player.inventory.getHotbarSlot()?.let {
|
|
||||||
it.count--
|
|
||||||
}
|
|
||||||
PlayerActionC2SP.Actions.DROP_ITEM
|
|
||||||
}
|
|
||||||
connection.sendPacket(PlayerActionC2SP(type))
|
|
||||||
lastDropPacketSent = time
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToDo: This has nothing todo with the camera, should be in the interaction manager
|
|
||||||
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_STACK_KEYBINDING, KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.PRESS to setOf(KeyCodes.KEY_Q),
|
|
||||||
KeyAction.MODIFIER to setOf(KeyCodes.KEY_LEFT_CONTROL)
|
|
||||||
),
|
|
||||||
)) { dropItem(true) }
|
|
||||||
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_KEYBINDING, KeyBinding(
|
|
||||||
mapOf(
|
|
||||||
KeyAction.PRESS to setOf(KeyCodes.KEY_Q),
|
|
||||||
),
|
|
||||||
)) { dropItem(false) }
|
|
||||||
frustum.recalculate()
|
|
||||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun recalculateViewProjectionMatrix() {
|
|
||||||
viewMatrix = calculateViewMatrix()
|
|
||||||
projectionMatrix = calculateProjectionMatrix(renderWindow.window.sizef)
|
|
||||||
viewProjectionMatrix = projectionMatrix * viewMatrix
|
|
||||||
connection.fireEvent(CameraMatrixChangeEvent(
|
|
||||||
renderWindow = renderWindow,
|
|
||||||
viewMatrix = viewMatrix,
|
|
||||||
projectionMatrix = projectionMatrix,
|
|
||||||
viewProjectionMatrix = viewProjectionMatrix,
|
|
||||||
))
|
|
||||||
|
|
||||||
for (shader in renderWindow.renderSystem.shaders) {
|
|
||||||
shader.use()
|
|
||||||
if (shader.uniforms.contains("uViewProjectionMatrix")) {
|
|
||||||
shader.setMat4("uViewProjectionMatrix", Mat4(viewProjectionMatrix))
|
|
||||||
}
|
|
||||||
if (shader.uniforms.contains("uCameraPosition")) {
|
|
||||||
shader.setVec3("uCameraPosition", connection.player.cameraPosition)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onPositionChange() {
|
|
||||||
setRotation(connection.player.rotation)
|
|
||||||
recalculateViewProjectionMatrix()
|
|
||||||
frustum.recalculate()
|
|
||||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
|
||||||
connection.fireEvent(CameraPositionChangeEvent(renderWindow, connection.player.eyePosition))
|
|
||||||
|
|
||||||
previousEyePosition = Vec3d(connection.player.eyePosition)
|
|
||||||
previousRotation = connection.player.rotation.copy()
|
|
||||||
previousZoom = zoom
|
|
||||||
|
|
||||||
setSkyColor()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setSkyColor() {
|
|
||||||
renderWindow[SkyRenderer]?.let { skyRenderer ->
|
|
||||||
skyRenderer.baseColor = connection.world.getBiome(connection.player.positionInfo.blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR
|
|
||||||
|
|
||||||
|
|
||||||
connection.world.dimension?.hasSkyLight?.let {
|
|
||||||
if (it) {
|
|
||||||
skyRenderer.baseColor = connection.player.positionInfo.biome?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR
|
|
||||||
} else {
|
|
||||||
skyRenderer.baseColor = RenderConstants.BLACK_COLOR
|
|
||||||
}
|
|
||||||
} ?: let { skyRenderer.baseColor = RenderConstants.DEFAULT_SKY_COLOR }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateProjectionMatrix(screenDimensions: Vec2): Mat4d {
|
|
||||||
return glm.perspective(fov.rad, screenDimensions.x.toDouble() / screenDimensions.y, 0.01, 10000.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateViewMatrix(): Mat4d {
|
|
||||||
val eyePosition = connection.player.eyePosition
|
|
||||||
return glm.lookAt(eyePosition, eyePosition + cameraFront, CAMERA_UP_VEC3)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setRotation(rotation: EntityRotation) {
|
|
||||||
cameraFront = rotation.front
|
|
||||||
|
|
||||||
cameraRight = (cameraFront cross CAMERA_UP_VEC3).normalize()
|
|
||||||
cameraUp = (cameraRight cross cameraFront).normalize()
|
|
||||||
recalculateViewProjectionMatrix()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun draw() {
|
|
||||||
calculateFogDistance()
|
|
||||||
if (!fogColor.equals()) {
|
|
||||||
applyFog()
|
|
||||||
}
|
|
||||||
//val input = if (renderWindow.inputHandler.currentKeyConsumer == null) {
|
|
||||||
val input = MovementInput(
|
|
||||||
pressingForward = renderWindow.inputHandler.isKeyBindingDown(MOVE_FORWARDS_KEYBINDING),
|
|
||||||
pressingBack = renderWindow.inputHandler.isKeyBindingDown(MOVE_BACKWARDS_KEYBINDING),
|
|
||||||
pressingLeft = renderWindow.inputHandler.isKeyBindingDown(MOVE_LEFT_KEYBINDING),
|
|
||||||
pressingRight = renderWindow.inputHandler.isKeyBindingDown(MOVE_RIGHT_KEYBINDING),
|
|
||||||
jumping = renderWindow.inputHandler.isKeyBindingDown(JUMP_KEYBINDING),
|
|
||||||
sneaking = renderWindow.inputHandler.isKeyBindingDown(SNEAK_KEYBINDING),
|
|
||||||
sprinting = renderWindow.inputHandler.isKeyBindingDown(MOVE_SPRINT_KEYBINDING),
|
|
||||||
flyDown = renderWindow.inputHandler.isKeyBindingDown(FLY_DOWN_KEYBINDING),
|
|
||||||
flyUp = renderWindow.inputHandler.isKeyBindingDown(FLY_UP_KEYBINDING),
|
|
||||||
toggleFlyDown = renderWindow.inputHandler.isKeyBindingDown(TOGGLE_FLY_KEYBINDING),
|
|
||||||
)
|
|
||||||
//} else {
|
|
||||||
// MovementInput()
|
|
||||||
// }
|
|
||||||
connection.player.input = input
|
|
||||||
connection.player.tick() // The thread pool might be busy, we force a tick here to avoid lagging
|
|
||||||
|
|
||||||
zoom = if (renderWindow.inputHandler.isKeyBindingDown(ZOOM_KEYBINDING)) {
|
|
||||||
2f
|
|
||||||
} else {
|
|
||||||
0.0f
|
|
||||||
}
|
|
||||||
|
|
||||||
val eyePosition = connection.player.eyePosition
|
|
||||||
|
|
||||||
if (previousEyePosition != eyePosition || previousRotation != connection.player.rotation || zoom != previousZoom) {
|
|
||||||
onPositionChange()
|
|
||||||
} else {
|
|
||||||
setSkyColor()
|
|
||||||
}
|
|
||||||
|
|
||||||
val cameraFront = cameraFront
|
|
||||||
|
|
||||||
target = raycast(eyePosition, cameraFront, blocks = true, fluids = true, entities = true)
|
|
||||||
nonFluidTarget = raycast(eyePosition, cameraFront, blocks = true, fluids = false, 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?
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun raycastEntity(origin: Vec3d, direction: Vec3d): EntityRaycastHit? {
|
|
||||||
var currentHit: EntityRaycastHit? = null
|
|
||||||
|
|
||||||
for (entity in connection.world.entities) {
|
|
||||||
if (entity is LocalPlayerEntity) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val hit = VoxelShape(entity.cameraAABB).raycast(origin, direction)
|
|
||||||
if (!hit.hit) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ((currentHit?.distance ?: Double.MAX_VALUE) < hit.distance) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
currentHit = EntityRaycastHit(origin + direction * hit.distance, hit.distance, hit.direction, entity)
|
|
||||||
|
|
||||||
}
|
|
||||||
return currentHit
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun raycast(origin: Vec3d, direction: Vec3d, blocks: Boolean, fluids: Boolean, entities: Boolean): RaycastHit? {
|
|
||||||
if (!blocks && !fluids && entities) {
|
|
||||||
// only raycast entities
|
|
||||||
return raycastEntity(origin, direction)
|
|
||||||
}
|
|
||||||
val currentPosition = Vec3d(origin)
|
|
||||||
|
|
||||||
fun getTotalDistance(): Double {
|
|
||||||
return (origin - currentPosition).length()
|
|
||||||
}
|
|
||||||
|
|
||||||
var hit: RaycastHit? = null
|
|
||||||
for (i in 0..RAYCAST_MAX_STEPS) {
|
|
||||||
val blockPosition = currentPosition.floor
|
|
||||||
val blockState = connection.world[blockPosition]
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
hit = FluidRaycastHit(
|
|
||||||
currentPosition,
|
|
||||||
distance,
|
|
||||||
voxelShapeRaycastResult.direction,
|
|
||||||
blockState,
|
|
||||||
blockPosition,
|
|
||||||
blockState.block.fluid,
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blocks) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
hit = BlockRaycastHit(
|
|
||||||
currentPosition,
|
|
||||||
distance,
|
|
||||||
voxelShapeRaycastResult.direction,
|
|
||||||
blockState,
|
|
||||||
blockPosition,
|
|
||||||
)
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
currentPosition += direction * (VecUtil.getDistanceToNextIntegerAxisInDirection(currentPosition, direction) + 0.001)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entities) {
|
|
||||||
val entityRaycastHit = raycastEntity(origin, direction) ?: return hit
|
|
||||||
hit ?: return null
|
|
||||||
return (entityRaycastHit.distance < hit.distance).decide(entityRaycastHit, hit)
|
|
||||||
}
|
|
||||||
|
|
||||||
return hit
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val CAMERA_UP_VEC3 = Vec3d(0.0, 1.0, 0.0)
|
|
||||||
|
|
||||||
private const val RAYCAST_MAX_STEPS = 100
|
|
||||||
|
|
||||||
private val MOVE_SPRINT_KEYBINDING = "minosoft:move_sprint".toResourceLocation()
|
|
||||||
private val MOVE_FORWARDS_KEYBINDING = "minosoft:move_forward".toResourceLocation()
|
|
||||||
private val MOVE_BACKWARDS_KEYBINDING = "minosoft:move_backwards".toResourceLocation()
|
|
||||||
private val MOVE_LEFT_KEYBINDING = "minosoft:move_left".toResourceLocation()
|
|
||||||
private val MOVE_RIGHT_KEYBINDING = "minosoft:move_right".toResourceLocation()
|
|
||||||
|
|
||||||
private val SNEAK_KEYBINDING = "minosoft:move_sneak".toResourceLocation()
|
|
||||||
private val JUMP_KEYBINDING = "minosoft:move_jump".toResourceLocation()
|
|
||||||
|
|
||||||
private val TOGGLE_FLY_KEYBINDING = "minosoft:move_toggle_fly".toResourceLocation()
|
|
||||||
private val FLY_UP_KEYBINDING = "minosoft:move_fly_up".toResourceLocation()
|
|
||||||
private val FLY_DOWN_KEYBINDING = "minosoft:move_fly_down".toResourceLocation()
|
|
||||||
|
|
||||||
private val ZOOM_KEYBINDING = "minosoft:zoom".toResourceLocation()
|
|
||||||
|
|
||||||
|
|
||||||
private val DROP_ITEM_KEYBINDING = "minosoft:drop_item".toResourceLocation()
|
|
||||||
private val DROP_ITEM_STACK_KEYBINDING = "minosoft:drop_item_stack".toResourceLocation()
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,7 @@ import de.bixilon.minosoft.data.registries.enchantment.DefaultEnchantments
|
|||||||
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
|
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
|
||||||
import de.bixilon.minosoft.data.registries.items.tools.MiningToolItem
|
import de.bixilon.minosoft.data.registries.items.tools.MiningToolItem
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.modding.event.events.BlockBreakAckEvent
|
import de.bixilon.minosoft.modding.event.events.BlockBreakAckEvent
|
||||||
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
|
import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
|
||||||
@ -98,9 +98,9 @@ class BreakInteractionHandler(
|
|||||||
cancelDigging()
|
cancelDigging()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val raycastHit = renderWindow.inputHandler.camera.nonFluidTarget
|
val raycastHit = renderWindow.camera.targetHandler.target
|
||||||
|
|
||||||
if (raycastHit !is BlockRaycastHit) {
|
if (raycastHit !is BlockTarget) {
|
||||||
cancelDigging()
|
cancelDigging()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ class BreakInteractionHandler(
|
|||||||
if (breakPosition != null) {
|
if (breakPosition != null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
connection.sendPacket(PlayerActionC2SP(PlayerActionC2SP.Actions.START_DIGGING, raycastHit.blockPosition, raycastHit.hitDirection))
|
connection.sendPacket(PlayerActionC2SP(PlayerActionC2SP.Actions.START_DIGGING, raycastHit.blockPosition, raycastHit.direction))
|
||||||
|
|
||||||
breakPosition = raycastHit.blockPosition
|
breakPosition = raycastHit.blockPosition
|
||||||
breakBlockState = raycastHit.blockState
|
breakBlockState = raycastHit.blockState
|
||||||
@ -130,7 +130,7 @@ class BreakInteractionHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun finishDigging() {
|
fun finishDigging() {
|
||||||
connection.sendPacket(PlayerActionC2SP(PlayerActionC2SP.Actions.FINISHED_DIGGING, raycastHit.blockPosition, raycastHit.hitDirection))
|
connection.sendPacket(PlayerActionC2SP(PlayerActionC2SP.Actions.FINISHED_DIGGING, raycastHit.blockPosition, raycastHit.direction))
|
||||||
clearDigging()
|
clearDigging()
|
||||||
connection.world.setBlockState(raycastHit.blockPosition, null)
|
connection.world.setBlockState(raycastHit.blockPosition, null)
|
||||||
|
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.input.interaction
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.key.KeyAction
|
||||||
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.protocol.RateLimiter
|
||||||
|
import de.bixilon.minosoft.protocol.packets.c2s.play.PlayerActionC2SP
|
||||||
|
import de.bixilon.minosoft.util.KUtil
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
|
||||||
|
class DropInteractionManager(
|
||||||
|
private val renderWindow: RenderWindow,
|
||||||
|
) {
|
||||||
|
private val connection = renderWindow.connection
|
||||||
|
private val rateLimiter = RateLimiter()
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
// ToDo: This creates a weird condition, because we first drop the stack and then the single item
|
||||||
|
// ToDo: Does this swing the arm?
|
||||||
|
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_STACK_KEYBINDING, KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.PRESS to setOf(KeyCodes.KEY_Q),
|
||||||
|
KeyAction.MODIFIER to setOf(KeyCodes.KEY_LEFT_CONTROL)
|
||||||
|
),
|
||||||
|
)) { dropItem(true) }
|
||||||
|
renderWindow.inputHandler.registerKeyCallback(DROP_ITEM_KEYBINDING, KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.PRESS to setOf(KeyCodes.KEY_Q),
|
||||||
|
),
|
||||||
|
)) { dropItem(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun dropItem(stack: Boolean) {
|
||||||
|
val time = KUtil.time
|
||||||
|
val type = if (stack) {
|
||||||
|
connection.player.inventory.getHotbarSlot()?.count = 0
|
||||||
|
PlayerActionC2SP.Actions.DROP_ITEM_STACK
|
||||||
|
} else {
|
||||||
|
connection.player.inventory.getHotbarSlot()?.let {
|
||||||
|
it.count--
|
||||||
|
}
|
||||||
|
PlayerActionC2SP.Actions.DROP_ITEM
|
||||||
|
}
|
||||||
|
rateLimiter += { connection.sendPacket(PlayerActionC2SP(type)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(delta: Double) {
|
||||||
|
rateLimiter.work()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val DROP_ITEM_KEYBINDING = "minosoft:drop_item".toResourceLocation()
|
||||||
|
private val DROP_ITEM_STACK_KEYBINDING = "minosoft:drop_item_stack".toResourceLocation()
|
||||||
|
}
|
||||||
|
}
|
@ -21,8 +21,8 @@ import de.bixilon.minosoft.data.inventory.ItemStack
|
|||||||
import de.bixilon.minosoft.data.player.Hands
|
import de.bixilon.minosoft.data.player.Hands
|
||||||
import de.bixilon.minosoft.data.registries.items.UsableItem
|
import de.bixilon.minosoft.data.registries.items.UsableItem
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockInteractC2SP
|
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockInteractC2SP
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.ItemUseC2SP
|
import de.bixilon.minosoft.protocol.packets.c2s.play.ItemUseC2SP
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.PlayerActionC2SP
|
import de.bixilon.minosoft.protocol.packets.c2s.play.PlayerActionC2SP
|
||||||
@ -71,16 +71,16 @@ class InteractInteractionHandler(
|
|||||||
interactingTicksLeft = 0
|
interactingTicksLeft = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun interactBlock(hit: BlockRaycastHit, item: ItemStack?, hand: Hands): InteractionResults {
|
fun interactBlock(target: BlockTarget, item: ItemStack?, hand: Hands): InteractionResults {
|
||||||
if (hit.distance >= connection.player.reachDistance) {
|
if (target.distance >= connection.player.reachDistance) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
// if out of world (border): return CONSUME
|
// if out of world (border): return CONSUME
|
||||||
|
|
||||||
connection.sendPacket(BlockInteractC2SP(
|
connection.sendPacket(BlockInteractC2SP(
|
||||||
position = hit.blockPosition,
|
position = target.blockPosition,
|
||||||
direction = hit.hitDirection,
|
direction = target.direction,
|
||||||
cursorPosition = Vec3(hit.hitPosition),
|
cursorPosition = Vec3(target.hitPosition),
|
||||||
item = item,
|
item = item,
|
||||||
hand = hand,
|
hand = hand,
|
||||||
insideBlock = false, // ToDo: insideBlock
|
insideBlock = false, // ToDo: insideBlock
|
||||||
@ -90,7 +90,7 @@ class InteractInteractionHandler(
|
|||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = hit.blockState.block.onUse(connection, hit, hand, item)
|
val result = target.blockState.block.onUse(connection, target, hand, item)
|
||||||
if (result == InteractionResults.SUCCESS) {
|
if (result == InteractionResults.SUCCESS) {
|
||||||
return InteractionResults.SUCCESS
|
return InteractionResults.SUCCESS
|
||||||
}
|
}
|
||||||
@ -102,13 +102,13 @@ class InteractInteractionHandler(
|
|||||||
return InteractionResults.PASS // ToDo: Check
|
return InteractionResults.PASS // ToDo: Check
|
||||||
}
|
}
|
||||||
|
|
||||||
return item.item.interactBlock(connection, hit, hand, item)
|
return item.item.interactBlock(connection, target, hand, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun interactEntityAt(hit: EntityRaycastHit, hand: Hands): InteractionResults {
|
fun interactEntityAt(target: EntityTarget, hand: Hands): InteractionResults {
|
||||||
// used in armor stands
|
// used in armor stands
|
||||||
val player = connection.player
|
val player = connection.player
|
||||||
connection.sendPacket(EntityInteractAtC2SP(connection, hit.entity, Vec3(hit.position), hand, player.isSneaking))
|
connection.sendPacket(EntityInteractAtC2SP(connection, target.entity, Vec3(target.position), hand, player.isSneaking))
|
||||||
|
|
||||||
if (player.gamemode == Gamemodes.SPECTATOR) {
|
if (player.gamemode == Gamemodes.SPECTATOR) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
@ -117,9 +117,9 @@ class InteractInteractionHandler(
|
|||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
fun interactEntity(hit: EntityRaycastHit, hand: Hands): InteractionResults {
|
fun interactEntity(target: EntityTarget, hand: Hands): InteractionResults {
|
||||||
val player = connection.player
|
val player = connection.player
|
||||||
connection.sendPacket(EntityInteractC2SP(connection, hit.entity, hand, player.isSneaking))
|
connection.sendPacket(EntityInteractC2SP(connection, target.entity, hand, player.isSneaking))
|
||||||
|
|
||||||
if (player.gamemode == Gamemodes.SPECTATOR) {
|
if (player.gamemode == Gamemodes.SPECTATOR) {
|
||||||
return InteractionResults.PASS
|
return InteractionResults.PASS
|
||||||
@ -155,12 +155,12 @@ class InteractInteractionHandler(
|
|||||||
// if riding: return
|
// if riding: return
|
||||||
|
|
||||||
val selectedSlot = connection.player.selectedHotbarSlot
|
val selectedSlot = connection.player.selectedHotbarSlot
|
||||||
val target = renderWindow.inputHandler.camera.nonFluidTarget
|
val target = renderWindow.camera.targetHandler.target
|
||||||
|
|
||||||
for (hand in Hands.VALUES) {
|
for (hand in Hands.VALUES) {
|
||||||
val item = connection.player.inventory[hand]
|
val item = connection.player.inventory[hand]
|
||||||
when (target) {
|
when (target) {
|
||||||
is EntityRaycastHit -> {
|
is EntityTarget -> {
|
||||||
var result = interactEntityAt(target, hand)
|
var result = interactEntityAt(target, hand)
|
||||||
|
|
||||||
if (result == InteractionResults.PASS) {
|
if (result == InteractionResults.PASS) {
|
||||||
@ -175,7 +175,7 @@ class InteractInteractionHandler(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is BlockRaycastHit -> {
|
is BlockTarget -> {
|
||||||
val result = interactBlock(target, item, hand)
|
val result = interactBlock(target, item, hand)
|
||||||
if (result == InteractionResults.SUCCESS) {
|
if (result == InteractionResults.SUCCESS) {
|
||||||
interactionManager.swingHand(hand)
|
interactionManager.swingHand(hand)
|
||||||
|
@ -28,6 +28,8 @@ class InteractionManager(
|
|||||||
val attack = AttackInteractionHandler(renderWindow)
|
val attack = AttackInteractionHandler(renderWindow)
|
||||||
val `break` = BreakInteractionHandler(renderWindow)
|
val `break` = BreakInteractionHandler(renderWindow)
|
||||||
val use = InteractInteractionHandler(renderWindow, this)
|
val use = InteractInteractionHandler(renderWindow, this)
|
||||||
|
val drop = DropInteractionManager(renderWindow)
|
||||||
|
val spectate = SpectateInteractionManager(renderWindow)
|
||||||
|
|
||||||
private val swingArmRateLimiter = RateLimiter()
|
private val swingArmRateLimiter = RateLimiter()
|
||||||
|
|
||||||
@ -38,6 +40,8 @@ class InteractionManager(
|
|||||||
pick.init()
|
pick.init()
|
||||||
`break`.init()
|
`break`.init()
|
||||||
use.init()
|
use.init()
|
||||||
|
drop.init()
|
||||||
|
spectate.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun draw(delta: Double) {
|
fun draw(delta: Double) {
|
||||||
@ -46,6 +50,8 @@ class InteractionManager(
|
|||||||
// attack.draw(delta)
|
// attack.draw(delta)
|
||||||
`break`.draw(delta)
|
`break`.draw(delta)
|
||||||
use.draw(delta)
|
use.draw(delta)
|
||||||
|
drop.draw(delta)
|
||||||
|
spectate.draw(delta)
|
||||||
|
|
||||||
swingArmRateLimiter.work()
|
swingArmRateLimiter.work()
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ import de.bixilon.minosoft.data.inventory.InventorySlots
|
|||||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||||
import de.bixilon.minosoft.data.registries.other.containers.PlayerInventory
|
import de.bixilon.minosoft.data.registries.other.containers.PlayerInventory
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.EntityRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.EntityTarget
|
||||||
import de.bixilon.minosoft.protocol.RateLimiter
|
import de.bixilon.minosoft.protocol.RateLimiter
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.ItemStackCreateC2SP
|
import de.bixilon.minosoft.protocol.packets.c2s.play.ItemStackCreateC2SP
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
@ -48,25 +48,25 @@ class ItemPickInteractionHandler(
|
|||||||
if (!connection.player.baseAbilities.creative) {
|
if (!connection.player.baseAbilities.creative) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val raycast = renderWindow.inputHandler.camera.nonFluidTarget ?: return
|
val target = renderWindow.camera.targetHandler.target ?: return
|
||||||
|
|
||||||
if (raycast.distance > connection.player.reachDistance) {
|
if (target.distance > connection.player.reachDistance) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val itemStack: ItemStack?
|
val itemStack: ItemStack?
|
||||||
|
|
||||||
when (raycast) {
|
when (target) {
|
||||||
is BlockRaycastHit -> {
|
is BlockTarget -> {
|
||||||
itemStack = ItemStack(raycast.blockState.block.item!!, connection, 1)
|
itemStack = ItemStack(target.blockState.block.item!!, connection, 1)
|
||||||
|
|
||||||
if (copyNBT) {
|
if (copyNBT) {
|
||||||
val blockEntity = connection.world.getBlockEntity(raycast.blockPosition)
|
val blockEntity = connection.world.getBlockEntity(target.blockPosition)
|
||||||
blockEntity?.nbt?.let { itemStack.nbt.putAll(it) }
|
blockEntity?.nbt?.let { itemStack.nbt.putAll(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is EntityRaycastHit -> {
|
is EntityTarget -> {
|
||||||
val entity = raycast.entity
|
val entity = target.entity
|
||||||
itemStack = entity.entityType.spawnEgg?.let { ItemStack(it, connection) } ?: let {
|
itemStack = entity.entityType.spawnEgg?.let { ItemStack(it, connection) } ?: let {
|
||||||
entity.equipment[InventorySlots.EquipmentSlots.MAIN_HAND]?.copy()
|
entity.equipment[InventorySlots.EquipmentSlots.MAIN_HAND]?.copy()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.input.interaction
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.key.KeyAction
|
||||||
|
import de.bixilon.minosoft.config.key.KeyBinding
|
||||||
|
import de.bixilon.minosoft.config.key.KeyCodes
|
||||||
|
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||||
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
|
import de.bixilon.minosoft.data.registries.other.game.event.handlers.gamemode.GamemodeChangeEvent
|
||||||
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
|
import de.bixilon.minosoft.modding.event.events.CameraSetEvent
|
||||||
|
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||||
|
import de.bixilon.minosoft.protocol.RateLimiter
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
|
||||||
|
class SpectateInteractionManager(
|
||||||
|
private val renderWindow: RenderWindow,
|
||||||
|
) {
|
||||||
|
private val connection = renderWindow.connection
|
||||||
|
private val rateLimiter = RateLimiter()
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
renderWindow.inputHandler.registerKeyCallback(STOP_SPECTATING, KeyBinding(
|
||||||
|
mapOf(
|
||||||
|
KeyAction.PRESS to setOf(KeyCodes.KEY_LEFT_SHIFT),
|
||||||
|
),
|
||||||
|
)) { spectate(null) }
|
||||||
|
|
||||||
|
renderWindow.connection.registerEvent(CallbackEventInvoker.of<GamemodeChangeEvent> { spectate(null) })
|
||||||
|
renderWindow.connection.registerEvent(CallbackEventInvoker.of<CameraSetEvent> { spectate(it.entity) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun spectate(entity: Entity?) {
|
||||||
|
var entity = entity ?: connection.player
|
||||||
|
if (connection.player.gamemode != Gamemodes.SPECTATOR) {
|
||||||
|
entity = connection.player
|
||||||
|
}
|
||||||
|
renderWindow.camera.matrixHandler.entity = entity
|
||||||
|
}
|
||||||
|
|
||||||
|
fun draw(delta: Double) {
|
||||||
|
rateLimiter.work()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val STOP_SPECTATING = "minosoft:stop_spectating".toResourceLocation()
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.config.profile.delegate.watcher.entry.MapProfileDeleg
|
|||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.Camera
|
import de.bixilon.minosoft.gui.rendering.input.CameraInput
|
||||||
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionManager
|
import de.bixilon.minosoft.gui.rendering.input.interaction.InteractionManager
|
||||||
import de.bixilon.minosoft.gui.rendering.modding.events.input.MouseMoveEvent
|
import de.bixilon.minosoft.gui.rendering.modding.events.input.MouseMoveEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.modding.events.input.RawCharInputEvent
|
import de.bixilon.minosoft.gui.rendering.modding.events.input.RawCharInputEvent
|
||||||
@ -38,7 +38,7 @@ class RenderWindowInputHandler(
|
|||||||
val renderWindow: RenderWindow,
|
val renderWindow: RenderWindow,
|
||||||
) {
|
) {
|
||||||
val connection: PlayConnection = renderWindow.connection
|
val connection: PlayConnection = renderWindow.connection
|
||||||
val camera: Camera = Camera(connection, renderWindow)
|
val cameraInput = CameraInput(renderWindow, renderWindow.camera.matrixHandler)
|
||||||
private val profile = connection.profiles.controls
|
private val profile = connection.profiles.controls
|
||||||
|
|
||||||
private val keyBindingCallbacks: MutableMap<ResourceLocation, KeyBindingCallbackPair> = mutableMapOf()
|
private val keyBindingCallbacks: MutableMap<ResourceLocation, KeyBindingCallbackPair> = mutableMapOf()
|
||||||
@ -80,7 +80,8 @@ class RenderWindowInputHandler(
|
|||||||
//if (renderWindow.inputHandler.currentKeyConsumer != null) {
|
//if (renderWindow.inputHandler.currentKeyConsumer != null) {
|
||||||
// return
|
// return
|
||||||
//}
|
//}
|
||||||
camera.mouseCallback(it.delta)
|
|
||||||
|
cameraInput.mouseCallback(it.delta)
|
||||||
})
|
})
|
||||||
|
|
||||||
profile::keyBindings.profileWatchMap(this, profile = profile) {
|
profile::keyBindings.profileWatchMap(this, profile = profile) {
|
||||||
@ -93,6 +94,7 @@ class RenderWindowInputHandler(
|
|||||||
keyBinding.keyBinding = it.valueAdded
|
keyBinding.keyBinding = it.valueAdded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cameraInput.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -275,8 +277,7 @@ class RenderWindowInputHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun draw(delta: Double) {
|
fun draw(delta: Double) {
|
||||||
camera.draw()
|
cameraInput.update()
|
||||||
|
|
||||||
interactionManager.draw(delta)
|
interactionManager.draw(delta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,20 +15,20 @@ package de.bixilon.minosoft.gui.rendering.modding.events
|
|||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||||
import glm_.mat4x4.Mat4d
|
import glm_.mat4x4.Mat4
|
||||||
|
|
||||||
class CameraMatrixChangeEvent(
|
class CameraMatrixChangeEvent(
|
||||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||||
viewMatrix: Mat4d,
|
viewMatrix: Mat4,
|
||||||
projectionMatrix: Mat4d,
|
projectionMatrix: Mat4,
|
||||||
viewProjectionMatrix: Mat4d,
|
viewProjectionMatrix: Mat4,
|
||||||
) : RenderEvent(renderWindow) {
|
) : RenderEvent(renderWindow) {
|
||||||
val viewMatrix: Mat4d = viewMatrix
|
val viewMatrix: Mat4 = viewMatrix
|
||||||
get() = Mat4d(field)
|
get() = Mat4(field)
|
||||||
|
|
||||||
val projectionMatrix: Mat4d = projectionMatrix
|
val projectionMatrix: Mat4 = projectionMatrix
|
||||||
get() = Mat4d(field)
|
get() = Mat4(field)
|
||||||
|
|
||||||
val viewProjectionMatrix: Mat4d = viewProjectionMatrix
|
val viewProjectionMatrix: Mat4 = viewProjectionMatrix
|
||||||
get() = Mat4d(field)
|
get() = Mat4(field)
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,12 @@ package de.bixilon.minosoft.gui.rendering.modding.events
|
|||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
class CameraPositionChangeEvent(
|
class CameraPositionChangeEvent(
|
||||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||||
newPosition: Vec3d,
|
newPosition: Vec3,
|
||||||
) : RenderEvent(renderWindow) {
|
) : RenderEvent(renderWindow) {
|
||||||
val newPosition: Vec3d = newPosition
|
val newPosition: Vec3 = newPosition
|
||||||
get() = Vec3d(field)
|
get() = Vec3(field)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.rendering.modding.events
|
|||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.frustum.Frustum
|
import de.bixilon.minosoft.gui.rendering.camera.frustum.Frustum
|
||||||
|
|
||||||
class FrustumChangeEvent(
|
class FrustumChangeEvent(
|
||||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.sky
|
package de.bixilon.minosoft.gui.rendering.sky
|
||||||
|
|
||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
|
|
||||||
import de.bixilon.minosoft.data.text.ChatColors
|
import de.bixilon.minosoft.data.text.ChatColors
|
||||||
import de.bixilon.minosoft.data.text.RGBColor
|
import de.bixilon.minosoft.data.text.RGBColor
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
@ -35,9 +34,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
|||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import glm_.func.rad
|
import glm_.func.rad
|
||||||
import glm_.mat4x4.Mat4
|
import glm_.mat4x4.Mat4
|
||||||
import glm_.mat4x4.Mat4d
|
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3d
|
|
||||||
|
|
||||||
class SkyRenderer(
|
class SkyRenderer(
|
||||||
private val connection: PlayConnection,
|
private val connection: PlayConnection,
|
||||||
@ -49,7 +46,7 @@ class SkyRenderer(
|
|||||||
private val skyboxMesh = SkyboxMesh(renderWindow)
|
private val skyboxMesh = SkyboxMesh(renderWindow)
|
||||||
private var skySunMesh = SimpleTextureMesh(renderWindow)
|
private var skySunMesh = SimpleTextureMesh(renderWindow)
|
||||||
private lateinit var sunTexture: AbstractTexture
|
private lateinit var sunTexture: AbstractTexture
|
||||||
private var sunMatrixUpToDate: Boolean = true
|
private var updateSun: Boolean = true
|
||||||
var baseColor = RenderConstants.DEFAULT_SKY_COLOR
|
var baseColor = RenderConstants.DEFAULT_SKY_COLOR
|
||||||
|
|
||||||
|
|
||||||
@ -69,22 +66,21 @@ class SkyRenderer(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
connection.registerEvent(CallbackEventInvoker.of<TimeChangeEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<TimeChangeEvent> {
|
||||||
if (connection.world.time != it.time) {
|
if (connection.world.time.time != it.time) {
|
||||||
sunMatrixUpToDate = true
|
updateSun = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
sunTexture = renderWindow.textureManager.staticTextures.createTexture(SUN_TEXTURE_RESOURCE_LOCATION)
|
sunTexture = renderWindow.textureManager.staticTextures.createTexture(SUN_TEXTURE_RESOURCE_LOCATION)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setSunMatrix(projectionViewMatrix: Mat4d) {
|
private fun setSunMatrix(projectionViewMatrix: Mat4) {
|
||||||
val timeAngle = (connection.world.skyAngle * 360.0).rad
|
val timeAngle = (connection.world.time.skyAngle * 360.0f).rad
|
||||||
val rotatedMatrix = if (timeAngle == 0.0) {
|
val rotatedMatrix = if (timeAngle == 0.0f) {
|
||||||
projectionViewMatrix
|
projectionViewMatrix
|
||||||
} else {
|
} else {
|
||||||
projectionViewMatrix.rotate(timeAngle, Vec3d(0.0f, 0.0f, 1.0f))
|
projectionViewMatrix.rotate(timeAngle, Vec3(0.0f, 0.0f, 1.0f))
|
||||||
}
|
}
|
||||||
skySunShader.use().setMat4("uSkyViewProjectionMatrix", Mat4(rotatedMatrix))
|
skySunShader.use().setMat4("uSkyViewProjectionMatrix", rotatedMatrix)
|
||||||
sunMatrixUpToDate = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun postInit() {
|
override fun postInit() {
|
||||||
@ -92,8 +88,8 @@ class SkyRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun drawSun() {
|
private fun drawSun() {
|
||||||
if (sunMatrixUpToDate) {
|
if (updateSun) {
|
||||||
setSunMatrix(renderWindow.inputHandler.camera.projectionMatrix * renderWindow.inputHandler.camera.viewMatrix.toMat3().toMat4())
|
setSunMatrix(renderWindow.camera.matrixHandler.projectionMatrix * renderWindow.camera.matrixHandler.viewMatrix.toMat3().toMat4())
|
||||||
skySunMesh.unload()
|
skySunMesh.unload()
|
||||||
|
|
||||||
skySunMesh = SimpleTextureMesh(renderWindow)
|
skySunMesh = SimpleTextureMesh(renderWindow)
|
||||||
@ -105,11 +101,12 @@ class SkyRenderer(
|
|||||||
position = position,
|
position = position,
|
||||||
texture = sunTexture,
|
texture = sunTexture,
|
||||||
uv = uv,
|
uv = uv,
|
||||||
tintColor = ChatColors.WHITE.with(alpha = 1.0f - connection.world.rainGradient), // ToDo: Depends on time
|
tintColor = ChatColors.WHITE.with(alpha = 1.0f - connection.world.weather.rainGradient), // ToDo: Depends on time
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
skySunMesh.load()
|
skySunMesh.load()
|
||||||
|
updateSun = false
|
||||||
|
|
||||||
}
|
}
|
||||||
renderSystem.enable(RenderingCapabilities.BLENDING)
|
renderSystem.enable(RenderingCapabilities.BLENDING)
|
||||||
@ -123,18 +120,18 @@ class SkyRenderer(
|
|||||||
val brightness = 1.0f
|
val brightness = 1.0f
|
||||||
val skyColor = RGBColor((baseColor.red * brightness).toInt(), (baseColor.green * brightness).toInt(), (baseColor.blue * brightness).toInt())
|
val skyColor = RGBColor((baseColor.red * brightness).toInt(), (baseColor.green * brightness).toInt(), (baseColor.blue * brightness).toInt())
|
||||||
|
|
||||||
renderWindow.inputHandler.camera.fogColor.value = if (connection.player.submergedFluid?.resourceLocation == DefaultFluids.WATER) {
|
baseColor = connection.world.getBiome(connection.player.positionInfo.blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR
|
||||||
connection.player.positionInfo.biome?.waterFogColor ?: skyColor
|
|
||||||
|
connection.world.dimension?.hasSkyLight?.let {
|
||||||
|
baseColor = if (it) {
|
||||||
|
connection.player.positionInfo.biome?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR
|
||||||
} else {
|
} else {
|
||||||
skyColor
|
RenderConstants.BLACK_COLOR
|
||||||
}
|
}
|
||||||
|
} ?: let { baseColor = RenderConstants.DEFAULT_SKY_COLOR }
|
||||||
|
|
||||||
|
|
||||||
for (shader in renderWindow.renderSystem.shaders) {
|
skyboxShader.use().setRGBColor("uSkyColor", skyColor)
|
||||||
if (shader.uniforms.contains("uSkyColor")) {
|
|
||||||
shader.use().setRGBColor("uSkyColor", skyColor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawSkybox() {
|
private fun drawSkybox() {
|
||||||
|
@ -17,7 +17,7 @@ import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegate
|
|||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
import de.bixilon.minosoft.data.world.AbstractAudioPlayer
|
import de.bixilon.minosoft.data.world.AbstractAudioPlayer
|
||||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.Camera
|
import de.bixilon.minosoft.gui.rendering.camera.MatrixHandler
|
||||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraPositionChangeEvent
|
import de.bixilon.minosoft.gui.rendering.modding.events.CameraPositionChangeEvent
|
||||||
import de.bixilon.minosoft.gui.rendering.sound.sounds.Sound
|
import de.bixilon.minosoft.gui.rendering.sound.sounds.Sound
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||||
@ -96,7 +96,7 @@ class AudioPlayer(
|
|||||||
connection.registerEvent(CallbackEventInvoker.of<CameraPositionChangeEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<CameraPositionChangeEvent> {
|
||||||
queue += {
|
queue += {
|
||||||
listener.position = Vec3(it.newPosition)
|
listener.position = Vec3(it.newPosition)
|
||||||
listener.setOrientation(it.renderWindow.inputHandler.camera.cameraFront, Camera.CAMERA_UP_VEC3)
|
listener.setOrientation(it.renderWindow.camera.matrixHandler.cameraFront, MatrixHandler.CAMERA_UP_VEC3)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -14,9 +14,7 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.sound
|
package de.bixilon.minosoft.gui.rendering.sound
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3d
|
|
||||||
import org.lwjgl.openal.AL10.*
|
import org.lwjgl.openal.AL10.*
|
||||||
|
|
||||||
class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
||||||
@ -36,13 +34,13 @@ class SoundListener(position: Vec3 = Vec3.EMPTY) {
|
|||||||
get() = alGetListenerf(AL_MAX_GAIN)
|
get() = alGetListenerf(AL_MAX_GAIN)
|
||||||
set(value) = alListenerf(AL_MAX_GAIN, value)
|
set(value) = alListenerf(AL_MAX_GAIN, value)
|
||||||
|
|
||||||
fun setOrientation(look: Vec3d, up: Vec3d) {
|
fun setOrientation(look: Vec3, up: Vec3) {
|
||||||
alListenerfv(AL_ORIENTATION, floatArrayOf(look.x.toFloat(), look.y.toFloat(), look.z.toFloat(), up.x.toFloat(), up.y.toFloat(), up.z.toFloat()))
|
alListenerfv(AL_ORIENTATION, floatArrayOf(look.x, look.y, look.z, up.x, up.y, up.z))
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.position = position
|
this.position = position
|
||||||
this.velocity = Vec3.EMPTY
|
this.velocity = Vec3.EMPTY
|
||||||
setOrientation(Vec3d.EMPTY, Vec3d(0.0, 1.0, 0.0))
|
setOrientation(Vec3.EMPTY, Vec3(0.0, 1.0, 0.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import kotlin.math.max
|
|||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
@Deprecated("Needs refactoring")
|
||||||
class LightMap(private val connection: PlayConnection) {
|
class LightMap(private val connection: PlayConnection) {
|
||||||
private val profile = connection.profiles.rendering.light
|
private val profile = connection.profiles.rendering.light
|
||||||
private val nightVisionStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.NIGHT_VISION]
|
private val nightVisionStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.NIGHT_VISION]
|
||||||
@ -50,7 +50,7 @@ class LightMap(private val connection: PlayConnection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
val skyGradient = connection.world.lightBase.toFloat()
|
val skyGradient = connection.world.time.lightBase.toFloat()
|
||||||
|
|
||||||
// ToDo: Lightning
|
// ToDo: Lightning
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
|
|||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.toVec3
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3
|
||||||
import de.bixilon.minosoft.gui.rendering.world.mesh.VisibleMeshes
|
import de.bixilon.minosoft.gui.rendering.world.mesh.VisibleMeshes
|
||||||
@ -87,7 +86,7 @@ class WorldRenderer(
|
|||||||
) : Renderer, OpaqueDrawable, TranslucentDrawable, TransparentDrawable {
|
) : Renderer, OpaqueDrawable, TranslucentDrawable, TransparentDrawable {
|
||||||
private val profile = connection.profiles.block
|
private val profile = connection.profiles.block
|
||||||
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
override val renderSystem: RenderSystem = renderWindow.renderSystem
|
||||||
private val frustum = renderWindow.inputHandler.camera.frustum
|
private val frustum = renderWindow.camera.matrixHandler.frustum
|
||||||
private val shader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
private val shader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
||||||
private val transparentShader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
private val transparentShader = renderSystem.createShader("minosoft:world".toResourceLocation())
|
||||||
private val world: World = connection.world
|
private val world: World = connection.world
|
||||||
@ -660,7 +659,7 @@ class WorldRenderer(
|
|||||||
|
|
||||||
private fun onFrustumChange() {
|
private fun onFrustumChange() {
|
||||||
var sortQueue = false
|
var sortQueue = false
|
||||||
val cameraPosition = connection.player.cameraPosition.toVec3()
|
val cameraPosition = connection.player.cameraPosition
|
||||||
if (this.cameraPosition != cameraPosition) {
|
if (this.cameraPosition != cameraPosition) {
|
||||||
this.cameraPosition = cameraPosition
|
this.cameraPosition = cameraPosition
|
||||||
this.cameraChunkPosition = connection.player.positionInfo.chunkPosition
|
this.cameraChunkPosition = connection.player.positionInfo.chunkPosition
|
||||||
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.gui.rendering.RenderConstants
|
|||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.Renderer
|
import de.bixilon.minosoft.gui.rendering.Renderer
|
||||||
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
||||||
import de.bixilon.minosoft.gui.rendering.input.camera.hit.BlockRaycastHit
|
import de.bixilon.minosoft.gui.rendering.camera.target.targets.BlockTarget
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
|
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.phases.OtherDrawable
|
import de.bixilon.minosoft.gui.rendering.system.base.phases.OtherDrawable
|
||||||
@ -82,7 +82,7 @@ class BlockOutlineRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun prepareDraw() {
|
override fun prepareDraw() {
|
||||||
val raycastHit = renderWindow.inputHandler.camera.target.nullCast<BlockRaycastHit>()
|
val raycastHit = renderWindow.camera.targetHandler.target.nullCast<BlockTarget>()
|
||||||
|
|
||||||
var currentMesh = currentMesh
|
var currentMesh = currentMesh
|
||||||
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package de.bixilon.minosoft.modding.event.events
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.entities.entities.Entity
|
||||||
|
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
|
class CameraSetEvent(
|
||||||
|
connection: PlayConnection,
|
||||||
|
val entity: Entity,
|
||||||
|
) : PlayConnectionEvent(connection)
|
@ -16,6 +16,7 @@ import de.bixilon.minosoft.modding.event.EventInitiators
|
|||||||
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.play.WorldTimeSetS2CP
|
import de.bixilon.minosoft.protocol.packets.s2c.play.WorldTimeSetS2CP
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
|
||||||
class TimeChangeEvent(
|
class TimeChangeEvent(
|
||||||
connection: PlayConnection,
|
connection: PlayConnection,
|
||||||
@ -25,5 +26,5 @@ class TimeChangeEvent(
|
|||||||
) : PlayConnectionEvent(connection, initiator) {
|
) : PlayConnectionEvent(connection, initiator) {
|
||||||
|
|
||||||
|
|
||||||
constructor(connection: PlayConnection, packet: WorldTimeSetS2CP) : this(connection, EventInitiators.SERVER, packet.age, packet.time)
|
constructor(connection: PlayConnection, packet: WorldTimeSetS2CP) : this(connection, EventInitiators.SERVER, packet.age, packet.time % ProtocolDefinition.TICKS_PER_DAY)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,9 @@ import de.bixilon.minosoft.util.logging.LogLevels
|
|||||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teleports our self in spectator mode to an entity
|
||||||
|
*/
|
||||||
class EntitySpectateC2SP(
|
class EntitySpectateC2SP(
|
||||||
val entityUUID: UUID,
|
val entityUUID: UUID,
|
||||||
) : PlayC2SPacket {
|
) : PlayC2SPacket {
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.protocol.packets.s2c.play
|
package de.bixilon.minosoft.protocol.packets.s2c.play
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.modding.event.events.CameraSetEvent
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
||||||
import de.bixilon.minosoft.util.logging.Log
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
@ -21,6 +23,11 @@ import de.bixilon.minosoft.util.logging.LogMessageType
|
|||||||
class CameraS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
class CameraS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||||
val entityId: Int = buffer.readVarInt()
|
val entityId: Int = buffer.readVarInt()
|
||||||
|
|
||||||
|
override fun handle(connection: PlayConnection) {
|
||||||
|
val entity = connection.world.entities[entityId] ?: return
|
||||||
|
connection.fireEvent(CameraSetEvent(connection, entity))
|
||||||
|
}
|
||||||
|
|
||||||
override fun log(reducedLog: Boolean) {
|
override fun log(reducedLog: Boolean) {
|
||||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Camera (entityId=$entityId)" }
|
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Camera (entityId=$entityId)" }
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import de.bixilon.minosoft.modding.event.events.TimeChangeEvent
|
|||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
import de.bixilon.minosoft.util.logging.Log
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
import de.bixilon.minosoft.util.logging.LogLevels
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
@ -25,8 +26,8 @@ class WorldTimeSetS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
|||||||
val time = buffer.readLong()
|
val time = buffer.readLong()
|
||||||
|
|
||||||
override fun handle(connection: PlayConnection) {
|
override fun handle(connection: PlayConnection) {
|
||||||
connection.world.age = age
|
connection.world.time.age = age
|
||||||
connection.world.time = time
|
connection.world.time.time = time % ProtocolDefinition.TICKS_PER_DAY
|
||||||
|
|
||||||
connection.fireEvent(TimeChangeEvent(connection, this))
|
connection.fireEvent(TimeChangeEvent(connection, this))
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ import de.bixilon.minosoft.data.text.ChatComponent
|
|||||||
import de.bixilon.minosoft.protocol.network.connection.Connection
|
import de.bixilon.minosoft.protocol.network.connection.Connection
|
||||||
import de.bixilon.minosoft.util.Util
|
import de.bixilon.minosoft.util.Util
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTTagTypes
|
import de.bixilon.minosoft.util.nbt.tag.NBTTagTypes
|
||||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.type
|
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.nbtType
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
@ -178,7 +178,7 @@ open class OutByteBuffer(open val connection: Connection? = null) {
|
|||||||
this.writeNBTTagType(type)
|
this.writeNBTTagType(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
val type = tag.type
|
val type = tag.nbtType
|
||||||
writeNBTTagType(type)
|
writeNBTTagType(type)
|
||||||
if (type == NBTTagTypes.END) {
|
if (type == NBTTagTypes.END) {
|
||||||
return
|
return
|
||||||
@ -206,7 +206,7 @@ open class OutByteBuffer(open val connection: Connection? = null) {
|
|||||||
this.writeNBTTagType(if (tag.isEmpty()) {
|
this.writeNBTTagType(if (tag.isEmpty()) {
|
||||||
NBTTagTypes.END
|
NBTTagTypes.END
|
||||||
} else {
|
} else {
|
||||||
tag.iterator().next().type
|
tag.iterator().next().nbtType
|
||||||
})
|
})
|
||||||
|
|
||||||
writeInt(tag.size)
|
writeInt(tag.size)
|
||||||
@ -217,7 +217,7 @@ open class OutByteBuffer(open val connection: Connection? = null) {
|
|||||||
}
|
}
|
||||||
is Map<*, *> -> {
|
is Map<*, *> -> {
|
||||||
for ((key, value) in tag) {
|
for ((key, value) in tag) {
|
||||||
val valueType = value.type
|
val valueType = value.nbtType
|
||||||
if (valueType == NBTTagTypes.END) {
|
if (valueType == NBTTagTypes.END) {
|
||||||
error("NBT does not support null as value in a compound tag!")
|
error("NBT does not support null as value in a compound tag!")
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ object NBTUtil {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val Any?.type: NBTTagTypes
|
val Any?.nbtType: NBTTagTypes
|
||||||
get() {
|
get() {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
null -> NBTTagTypes.END
|
null -> NBTTagTypes.END
|
||||||
@ -76,7 +76,7 @@ object NBTUtil {
|
|||||||
is Map<*, *> -> NBTTagTypes.COMPOUND
|
is Map<*, *> -> NBTTagTypes.COMPOUND
|
||||||
is IntArray -> NBTTagTypes.INT_ARRAY
|
is IntArray -> NBTTagTypes.INT_ARRAY
|
||||||
is LongArray -> NBTTagTypes.LONG_ARRAY
|
is LongArray -> NBTTagTypes.LONG_ARRAY
|
||||||
else -> throw IllegalArgumentException("NBT does not support ${type::class.java.name}")
|
else -> throw IllegalArgumentException("NBT does not support ${this::class.java.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user