mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 10:55:01 -04:00
wip block interactions
This commit is contained in:
parent
fc04dc9235
commit
88c38c68bb
@ -47,6 +47,9 @@ object KeyBindingsNames {
|
||||
val CLOSE = ResourceLocation("minosoft:close")
|
||||
|
||||
|
||||
val BLOCK_INTERACT = ResourceLocation("minosoft:interact_block")
|
||||
|
||||
|
||||
val SELECT_HOTBAR_SLOTS = arrayOf(
|
||||
ResourceLocation("minosoft:select_hotbar_slot_1"),
|
||||
ResourceLocation("minosoft:select_hotbar_slot_2"),
|
||||
@ -200,5 +203,10 @@ object KeyBindingsNames {
|
||||
),
|
||||
ignoreConsumer = true
|
||||
),
|
||||
BLOCK_INTERACT to KeyBinding(
|
||||
mutableMapOf(
|
||||
KeyAction.CHANGE to mutableSetOf(KeyCodes.MOUSE_BUTTON_RIGHT)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import com.google.gson.JsonPrimitive
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.mappings.materials.Material
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
@ -28,10 +29,12 @@ import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.MultipartRenderer
|
||||
import de.bixilon.minosoft.util.enum.ValuesEnum
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
import kotlin.random.Random
|
||||
import kotlin.reflect.full.companionObjectInstance
|
||||
|
||||
data class BlockState(
|
||||
val block: Block,
|
||||
@ -111,7 +114,6 @@ data class BlockState(
|
||||
return renderers[abs(random.nextLong().toInt() % renderers.size)]
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
fun deserialize(owner: Block, versionMapping: VersionMapping, data: JsonObject, models: Map<ResourceLocation, BlockModel>): BlockState {
|
||||
@ -225,10 +227,43 @@ data class BlockState(
|
||||
}
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
fun isPowered(): Boolean? {
|
||||
return properties[BlockProperties.POWERED] as Boolean?
|
||||
fun withProperties(vararg properties: Pair<BlockProperties, Any>): BlockState {
|
||||
val newProperties = this.properties.toMutableMap()
|
||||
for ((key, value) in properties) {
|
||||
newProperties[key] = value
|
||||
}
|
||||
val wannabe = WannabeBlockState(resourceLocation = this.block.resourceLocation, properties = newProperties)
|
||||
for (blockState in this.block.states) {
|
||||
if (blockState.equals(wannabe)) {
|
||||
return blockState
|
||||
}
|
||||
}
|
||||
throw IllegalArgumentException("Can not find ${this.block.resourceLocation}, with properties: $properties")
|
||||
}
|
||||
|
||||
|
||||
fun cycle(property: BlockProperties): BlockState {
|
||||
val currentValue = properties[property] ?: throw IllegalArgumentException("$this has no property $property")
|
||||
|
||||
when (currentValue) {
|
||||
is Boolean -> {
|
||||
return withProperties(property to !currentValue)
|
||||
}
|
||||
is Number -> {
|
||||
return try {
|
||||
withProperties(property to (currentValue.toInt() + 1))
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
withProperties(property to 0)
|
||||
}
|
||||
}
|
||||
is Enum<*> -> {
|
||||
val values = currentValue::class.companionObjectInstance as ValuesEnum<Enum<*>>
|
||||
return withProperties(property to values.next(currentValue))
|
||||
}
|
||||
else -> {
|
||||
return this
|
||||
}
|
||||
}
|
||||
}
|
||||
// ToDo
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.blocks
|
||||
|
||||
enum class BlockUsages {
|
||||
/**
|
||||
* Usage get consumed (like trying to open an iron door) without animation
|
||||
*/
|
||||
CONSUME,
|
||||
|
||||
/**
|
||||
* Usage get consumed (like pressing a button, opening a door, right clicking on block entities) with animation
|
||||
*/
|
||||
SUCCESS,
|
||||
|
||||
/**
|
||||
* Nothing happens from block side (e.g. right clicking on dirt). You can maybe place a block, whatever
|
||||
*/
|
||||
PASS,
|
||||
|
||||
/**
|
||||
* Nothing happens, basically `CONSUME`, but a requirement was not satisfied.
|
||||
*/
|
||||
FAIL,
|
||||
;
|
||||
}
|
@ -18,7 +18,7 @@ import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
|
||||
import de.bixilon.minosoft.data.entities.block.DefaultBlockEntityMetaDataFactory
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.mappings.registry.RegistryItem
|
||||
import de.bixilon.minosoft.data.mappings.registry.ResourceLocationDeserializer
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
|
@ -13,25 +13,20 @@
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.blocks.entites
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.mappings.registry.Registry
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
|
||||
class BlockEntityTypeRegistry(
|
||||
private val versionMapping: VersionMapping,
|
||||
private var parentRegistry: BlockEntityTypeRegistry? = null,
|
||||
) : Registry<BlockEntityType>() {
|
||||
parentRegistry: BlockEntityTypeRegistry? = null,
|
||||
) : Registry<BlockEntityType>(parentRegistry) {
|
||||
private lateinit var blockTypeMap: MutableMap<Block, BlockEntityType>
|
||||
|
||||
fun getByBlock(block: Block): BlockEntityType? {
|
||||
val parentRegistry = super.parentRegistry as BlockEntityTypeRegistry?
|
||||
return blockTypeMap[block] ?: parentRegistry?.getByBlock(block)
|
||||
}
|
||||
|
||||
fun setParent(parent: BlockEntityTypeRegistry?) {
|
||||
super.setParent(parent)
|
||||
this.parentRegistry = parent
|
||||
}
|
||||
|
||||
override fun postInit(versionMapping: VersionMapping) {
|
||||
super.postInit(versionMapping)
|
||||
blockTypeMap = mutableMapOf()
|
||||
|
@ -16,35 +16,35 @@ package de.bixilon.minosoft.data.mappings.blocks.properties
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.Directions
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BooleanBlocKPropertiesSerializer
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BooleanBlockPropertiesSerializer
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.IntBlockPropertiesSerializer
|
||||
import java.util.*
|
||||
|
||||
enum class BlockProperties {
|
||||
POWERED(BooleanBlocKPropertiesSerializer),
|
||||
TRIGGERED(BooleanBlocKPropertiesSerializer),
|
||||
INVERTED(BooleanBlocKPropertiesSerializer),
|
||||
LIT(BooleanBlocKPropertiesSerializer),
|
||||
WATERLOGGED(BooleanBlocKPropertiesSerializer),
|
||||
POWERED(BooleanBlockPropertiesSerializer),
|
||||
TRIGGERED(BooleanBlockPropertiesSerializer),
|
||||
INVERTED(BooleanBlockPropertiesSerializer),
|
||||
LIT(BooleanBlockPropertiesSerializer),
|
||||
WATERLOGGED(BooleanBlockPropertiesSerializer),
|
||||
STAIR_DIRECTIONAL("shape", Shapes),
|
||||
STAIR_HALF("half", Halves),
|
||||
SLAB_TYPE("type", Halves),
|
||||
MOISTURE_LEVEL("moisture", IntBlockPropertiesSerializer),
|
||||
FLUID_LEVEL("level", IntBlockPropertiesSerializer),
|
||||
HONEY_LEVEL("honey_level", IntBlockPropertiesSerializer),
|
||||
PISTON_EXTENDED("extended", BooleanBlocKPropertiesSerializer),
|
||||
PISTON_EXTENDED("extended", BooleanBlockPropertiesSerializer),
|
||||
PISTON_TYPE("type", PistonTypes),
|
||||
PISTON_SHORT("short", BooleanBlocKPropertiesSerializer),
|
||||
PISTON_SHORT("short", BooleanBlockPropertiesSerializer),
|
||||
RAILS_SHAPE("shape", Shapes),
|
||||
SNOWY(BooleanBlocKPropertiesSerializer),
|
||||
SNOWY(BooleanBlockPropertiesSerializer),
|
||||
STAGE(IntBlockPropertiesSerializer),
|
||||
DISTANCE(IntBlockPropertiesSerializer),
|
||||
LEAVES_PERSISTENT("persistent", BooleanBlocKPropertiesSerializer),
|
||||
LEAVES_PERSISTENT("persistent", BooleanBlockPropertiesSerializer),
|
||||
BED_PART("part", BedParts),
|
||||
BED_OCCUPIED("occupied", BooleanBlocKPropertiesSerializer),
|
||||
TNT_UNSTABLE("unstable", BooleanBlocKPropertiesSerializer),
|
||||
BED_OCCUPIED("occupied", BooleanBlockPropertiesSerializer),
|
||||
TNT_UNSTABLE("unstable", BooleanBlockPropertiesSerializer),
|
||||
DOOR_HINGE("hinge", Sides),
|
||||
DOOR_OPEN("open", BooleanBlocKPropertiesSerializer),
|
||||
DOOR_OPEN("open", BooleanBlockPropertiesSerializer),
|
||||
AGE(IntBlockPropertiesSerializer),
|
||||
INSTRUMENT(Instruments),
|
||||
NOTE(IntBlockPropertiesSerializer),
|
||||
@ -58,55 +58,55 @@ enum class BlockProperties {
|
||||
MULTIPART_DOWN("down", MultipartDirectionParser),
|
||||
|
||||
SNOW_LAYERS("layers", IntBlockPropertiesSerializer),
|
||||
FENCE_IN_WALL("in_wall", BooleanBlocKPropertiesSerializer),
|
||||
SCAFFOLDING_BOTTOM("bottom", BooleanBlocKPropertiesSerializer),
|
||||
TRIPWIRE_DISARMED("disarmed", BooleanBlocKPropertiesSerializer),
|
||||
TRIPWIRE_IN_AIR("in_air", BooleanBlocKPropertiesSerializer),
|
||||
TRIPWIRE_ATTACHED("attached", BooleanBlocKPropertiesSerializer),
|
||||
FENCE_IN_WALL("in_wall", BooleanBlockPropertiesSerializer),
|
||||
SCAFFOLDING_BOTTOM("bottom", BooleanBlockPropertiesSerializer),
|
||||
TRIPWIRE_DISARMED("disarmed", BooleanBlockPropertiesSerializer),
|
||||
TRIPWIRE_IN_AIR("in_air", BooleanBlockPropertiesSerializer),
|
||||
TRIPWIRE_ATTACHED("attached", BooleanBlockPropertiesSerializer),
|
||||
STRUCTURE_BLOCK_MODE("mode", StructureBlockModes),
|
||||
COMMAND_BLOCK_CONDITIONAL("conditional", BooleanBlocKPropertiesSerializer),
|
||||
BUBBLE_COLUMN_DRAG("drag", BooleanBlocKPropertiesSerializer),
|
||||
COMMAND_BLOCK_CONDITIONAL("conditional", BooleanBlockPropertiesSerializer),
|
||||
BUBBLE_COLUMN_DRAG("drag", BooleanBlockPropertiesSerializer),
|
||||
BELL_ATTACHMENT("attachment", Attachments),
|
||||
LANTERN_HANGING("hanging", BooleanBlocKPropertiesSerializer),
|
||||
LANTERN_HANGING("hanging", BooleanBlockPropertiesSerializer),
|
||||
SEA_PICKLE_PICKLES("pickles", IntBlockPropertiesSerializer),
|
||||
LECTERN_BOOK("has_book", BooleanBlocKPropertiesSerializer),
|
||||
LECTERN_BOOK("has_book", BooleanBlockPropertiesSerializer),
|
||||
|
||||
BREWING_STAND_BOTTLE_0("has_bottle_0", BooleanBlocKPropertiesSerializer),
|
||||
BREWING_STAND_BOTTLE_1("has_bottle_1", BooleanBlocKPropertiesSerializer),
|
||||
BREWING_STAND_BOTTLE_2("has_bottle_2", BooleanBlocKPropertiesSerializer),
|
||||
BREWING_STAND_BOTTLE_0("has_bottle_0", BooleanBlockPropertiesSerializer),
|
||||
BREWING_STAND_BOTTLE_1("has_bottle_1", BooleanBlockPropertiesSerializer),
|
||||
BREWING_STAND_BOTTLE_2("has_bottle_2", BooleanBlockPropertiesSerializer),
|
||||
|
||||
CHEST_TYPE("type", ChestTypes),
|
||||
|
||||
CAKE_BITES("bites", IntBlockPropertiesSerializer),
|
||||
BAMBOO_LEAVES("leaves", BambooLeaves),
|
||||
REPEATER_LOCKED("locked", BooleanBlocKPropertiesSerializer),
|
||||
REPEATER_LOCKED("locked", BooleanBlockPropertiesSerializer),
|
||||
REPEATER_DELAY("delay", IntBlockPropertiesSerializer),
|
||||
PORTA_FRAME_EYE("eye", BooleanBlocKPropertiesSerializer),
|
||||
JUKEBOX_HAS_RECORD("has_record", BooleanBlocKPropertiesSerializer),
|
||||
CAMPFIRE_SIGNAL_FIRE("signal_fire", BooleanBlocKPropertiesSerializer),
|
||||
PORTA_FRAME_EYE("eye", BooleanBlockPropertiesSerializer),
|
||||
JUKEBOX_HAS_RECORD("has_record", BooleanBlockPropertiesSerializer),
|
||||
CAMPFIRE_SIGNAL_FIRE("signal_fire", BooleanBlockPropertiesSerializer),
|
||||
TURTLE_EGS_EGGS("eggs", IntBlockPropertiesSerializer),
|
||||
TURTLE_EGGS_HATCH("hatch", IntBlockPropertiesSerializer),
|
||||
RESPAWN_ANCHOR_CHARGES("charges", IntBlockPropertiesSerializer),
|
||||
CANDLES(IntBlockPropertiesSerializer),
|
||||
FACE("face", Attachments),
|
||||
HOPPER_ENABLED("enabled", BooleanBlocKPropertiesSerializer),
|
||||
HOPPER_ENABLED("enabled", BooleanBlockPropertiesSerializer),
|
||||
|
||||
DRIPSTONE_THICKNESS("thickness", Thicknesses),
|
||||
|
||||
|
||||
LEGACY_BLOCK_UPDATE("block_update", BooleanBlocKPropertiesSerializer),
|
||||
LEGACY_SMOOTH("smooth", BooleanBlocKPropertiesSerializer),
|
||||
LEGACY_BLOCK_UPDATE("block_update", BooleanBlockPropertiesSerializer),
|
||||
LEGACY_SMOOTH("smooth", BooleanBlockPropertiesSerializer),
|
||||
SCULK_SENSOR_PHASE("sculk_sensor_phase", SensorPhases),
|
||||
DRIPSTONE_TILT("tilt", Tilts),
|
||||
CAVE_VINES_BERRIES("berries", BooleanBlocKPropertiesSerializer),
|
||||
CAVE_VINES_BERRIES("berries", BooleanBlockPropertiesSerializer),
|
||||
|
||||
|
||||
VERTICAL_DIRECTION("vertical_direction", VerticalDirections),
|
||||
|
||||
|
||||
LEGACY_CHECK_DECAY("check_decay", BooleanBlocKPropertiesSerializer),
|
||||
LEGAVY_DECAYABLE("decayable", BooleanBlocKPropertiesSerializer),
|
||||
LEGAVY_NODROP("nodrop", BooleanBlocKPropertiesSerializer),
|
||||
LEGACY_CHECK_DECAY("check_decay", BooleanBlockPropertiesSerializer),
|
||||
LEGAVY_DECAYABLE("decayable", BooleanBlockPropertiesSerializer),
|
||||
LEGAVY_NODROP("nodrop", BooleanBlockPropertiesSerializer),
|
||||
|
||||
AXIS("axis", Axes),
|
||||
FACING("facing", Directions),
|
||||
@ -128,6 +128,7 @@ enum class BlockProperties {
|
||||
this.serializer = serializer
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private val PROPERTIES: Map<String, List<BlockProperties>> = run {
|
||||
val map: MutableMap<String, MutableList<BlockProperties>> = mutableMapOf()
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.blocks.properties.serializer
|
||||
|
||||
object BooleanBlocKPropertiesSerializer : BlockPropertiesSerializer {
|
||||
object BooleanBlockPropertiesSerializer : BlockPropertiesSerializer {
|
||||
|
||||
override fun deserialize(value: Any): Boolean {
|
||||
if (value is Boolean) {
|
@ -10,18 +10,28 @@
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
package de.bixilon.minosoft.data.mappings.blocks
|
||||
package de.bixilon.minosoft.data.mappings.blocks.types
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockUsages
|
||||
import de.bixilon.minosoft.data.mappings.blocks.RandomOffsetTypes
|
||||
import de.bixilon.minosoft.data.mappings.blocks.entites.BlockEntityType
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.items.Item
|
||||
import de.bixilon.minosoft.data.mappings.registry.RegistryItem
|
||||
import de.bixilon.minosoft.data.mappings.registry.ResourceLocationDeserializer
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
import de.bixilon.minosoft.data.player.Hands
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.TintColorCalculator
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
open class Block(final override val resourceLocation: ResourceLocation, mappings: VersionMapping, data: JsonObject) : RegistryItem {
|
||||
open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f
|
||||
@ -50,12 +60,40 @@ open class Block(final override val resourceLocation: ResourceLocation, mappings
|
||||
return resourceLocation.full
|
||||
}
|
||||
|
||||
open fun getPlacementState(connection: PlayConnection, raycastHit: RaycastHit): BlockState {
|
||||
return defaultState
|
||||
}
|
||||
|
||||
open fun onBreak(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState, blockEntity: BlockEntity?) {
|
||||
|
||||
}
|
||||
|
||||
open fun onPlace(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState) {
|
||||
|
||||
}
|
||||
|
||||
open fun canPlaceAt(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
open fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
if (blockEntityType == null) {
|
||||
return BlockUsages.PASS
|
||||
}
|
||||
return BlockUsages.SUCCESS
|
||||
}
|
||||
|
||||
fun withProperties(vararg properties: Pair<BlockProperties, Any>): BlockState {
|
||||
return this.defaultState.withProperties(*properties)
|
||||
}
|
||||
|
||||
companion object : ResourceLocationDeserializer<Block> {
|
||||
override fun deserialize(mappings: VersionMapping?, resourceLocation: ResourceLocation, data: JsonObject): Block {
|
||||
check(mappings != null) { "VersionMapping is null!" }
|
||||
|
||||
val block = when (data["class"].asString) {
|
||||
"FluidBlock" -> FluidBlock(resourceLocation, mappings, data)
|
||||
"DoorBlock" -> DoorBlock(resourceLocation, mappings, data)
|
||||
else -> Block(resourceLocation, mappings, data)
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.blocks.types
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.Directions
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockUsages
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.Halves
|
||||
import de.bixilon.minosoft.data.mappings.materials.DefaultMaterials
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
import de.bixilon.minosoft.data.player.Hands
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
open class DoorBlock(resourceLocation: ResourceLocation, mappings: VersionMapping, data: JsonObject) : Block(resourceLocation, mappings, data) {
|
||||
|
||||
|
||||
override fun getPlacementState(connection: PlayConnection, raycastHit: RaycastHit): BlockState {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun onBreak(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState, blockEntity: BlockEntity?) {
|
||||
if (blockState.properties[BlockProperties.STAIR_HALF] == Halves.LOWER) {
|
||||
connection.world.forceSetBlock(blockPosition + Directions.UP, null)
|
||||
} else {
|
||||
connection.world.forceSetBlock(blockPosition + Directions.DOWN, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlace(connection: PlayConnection, blockPosition: Vec3i, blockState: BlockState) {
|
||||
if (blockState.properties[BlockProperties.STAIR_HALF] == Halves.LOWER) {
|
||||
connection.world.forceSetBlock(blockPosition + Directions.UP, blockState.withProperties(BlockProperties.STAIR_HALF to Halves.UPPER))
|
||||
} else {
|
||||
connection.world.forceSetBlock(blockPosition + Directions.DOWN, blockState.withProperties(BlockProperties.STAIR_HALF to Halves.LOWER))
|
||||
}
|
||||
}
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
if (blockState.material.resourceLocation == DefaultMaterials.METAL) {
|
||||
return BlockUsages.CONSUME
|
||||
}
|
||||
|
||||
val nextBlockState = blockState.cycle(BlockProperties.DOOR_OPEN)
|
||||
|
||||
connection.world.setBlock(blockPosition, nextBlockState)
|
||||
|
||||
return BlockUsages.SUCCESS
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.blocks
|
||||
package de.bixilon.minosoft.data.mappings.blocks.types
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.mappings.items
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
|
||||
open class BlockItem(
|
||||
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.materials
|
||||
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
|
||||
object DefaultMaterials {
|
||||
val METAL = "minecraft:metal".asResourceLocation()
|
||||
}
|
@ -20,7 +20,7 @@ import de.bixilon.minosoft.util.collections.Clearable
|
||||
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
|
||||
|
||||
open class Registry<T : RegistryItem>(
|
||||
private var parentRegistry: Registry<T>? = null,
|
||||
protected var parentRegistry: Registry<T>? = null,
|
||||
) : Iterable<T>, Clearable, Parentable<Registry<T>> {
|
||||
private var initialized = false
|
||||
protected val idValueMap: MutableMap<Int, T> = mutableMapOf()
|
||||
|
@ -23,10 +23,10 @@ import de.bixilon.minosoft.data.mappings.*
|
||||
import de.bixilon.minosoft.data.mappings.biomes.Biome
|
||||
import de.bixilon.minosoft.data.mappings.biomes.BiomeCategory
|
||||
import de.bixilon.minosoft.data.mappings.biomes.BiomePrecipitation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.entites.BlockEntityType
|
||||
import de.bixilon.minosoft.data.mappings.blocks.entites.BlockEntityTypeRegistry
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.mappings.effects.StatusEffect
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||
import de.bixilon.minosoft.data.mappings.entities.villagers.VillagerProfession
|
||||
@ -93,7 +93,7 @@ class VersionMapping {
|
||||
val entityMetaIndexMap: MutableMap<EntityMetaDataFields, Int> = mutableMapOf()
|
||||
val entityRegistry: Registry<EntityType> = Registry()
|
||||
|
||||
val blockEntityTypeRegistry = BlockEntityTypeRegistry(this)
|
||||
val blockEntityTypeRegistry = BlockEntityTypeRegistry()
|
||||
val blockEntityMetaDataTypeRegistry: Registry<BlockEntityMetaType> = Registry()
|
||||
|
||||
val containerTypeRegistry: Registry<ContainerType> = Registry()
|
||||
|
@ -80,6 +80,11 @@ class World(
|
||||
} else {
|
||||
VersionTweaker.transformBlock(blockState, sections, blockPosition.inChunkSectionPosition, blockPosition.sectionHeight)
|
||||
}
|
||||
val inChunkPosition = blockPosition.inChunkPosition
|
||||
it.getBlockState(inChunkPosition)?.let { oldBlockState ->
|
||||
oldBlockState.block.onBreak(connection, blockPosition, oldBlockState, it.getBlockEntity(inChunkPosition))
|
||||
}
|
||||
blockState?.block?.onPlace(connection, blockPosition, blockState)
|
||||
it.setBlockState(blockPosition.inChunkPosition, transformedBlockState)
|
||||
connection.fireEvent(BlockSetEvent(
|
||||
connection = connection,
|
||||
@ -89,6 +94,10 @@ class World(
|
||||
}
|
||||
}
|
||||
|
||||
fun forceSetBlock(blockPosition: Vec3i, blockState: BlockState?) {
|
||||
chunks[blockPosition.chunkPosition]?.setBlockState(blockPosition.inChunkPosition, blockState)
|
||||
}
|
||||
|
||||
fun unloadChunk(chunkPosition: Vec2i) {
|
||||
chunks.remove(chunkPosition)?.let {
|
||||
connection.fireEvent(ChunkUnloadEvent(connection, chunkPosition))
|
||||
|
@ -260,8 +260,10 @@ class RenderWindow(
|
||||
glfwSetCursorPosCallback(windowId, inputHandler::mouseMove)
|
||||
|
||||
|
||||
inputHandler.init()
|
||||
registerGlobalKeyCombinations()
|
||||
|
||||
|
||||
connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = Vec2i(0, 0), screenDimensions = screenDimensions))
|
||||
|
||||
|
||||
@ -327,7 +329,7 @@ class RenderWindow(
|
||||
|
||||
glfwSwapBuffers(windowId)
|
||||
glfwPollEvents()
|
||||
inputHandler.camera.draw()
|
||||
inputHandler.draw()
|
||||
inputHandler.camera.handleInput(deltaFrameTime)
|
||||
|
||||
// handle opengl context tasks, but limit it per frame
|
||||
|
@ -18,8 +18,8 @@ import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||
import de.bixilon.minosoft.data.Directions
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.FluidBlock
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.FluidBlock
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.ChunkSection
|
||||
|
@ -2,9 +2,9 @@ package de.bixilon.minosoft.gui.rendering.chunk.models.renderable
|
||||
|
||||
import de.bixilon.minosoft.data.Directions
|
||||
import de.bixilon.minosoft.data.mappings.biomes.Biome
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.data.mappings.fluid.Fluid
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.data.world.World
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.input
|
||||
|
||||
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||
import de.bixilon.minosoft.data.Directions
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockUsages
|
||||
import de.bixilon.minosoft.data.player.Hands
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockPlaceC2SP
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
class InteractionHandler(
|
||||
val renderWindow: RenderWindow,
|
||||
) {
|
||||
private var lastInteraction = 0L
|
||||
private var lastInteractionSent = 0L
|
||||
|
||||
fun init() {
|
||||
renderWindow.inputHandler.registerCheckCallback(KeyBindingsNames.BLOCK_INTERACT)
|
||||
}
|
||||
|
||||
private fun checkInteraction(isKeyDown: Boolean) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (!isKeyDown) {
|
||||
lastInteraction = 0L
|
||||
return
|
||||
}
|
||||
if (currentTime - lastInteraction < ProtocolDefinition.TICK_TIME * 5) {
|
||||
return
|
||||
}
|
||||
|
||||
val raycastHit = renderWindow.inputHandler.camera.getTargetBlock() ?: return
|
||||
|
||||
if (raycastHit.distance > RenderConstants.MAX_BLOCK_OUTLINE_RAYCAST_DISTANCE) {
|
||||
return
|
||||
}
|
||||
|
||||
val usage = raycastHit.blockState.block.use(renderWindow.connection, raycastHit.blockState, raycastHit.blockPosition, raycastHit, Hands.MAIN_HAND, null) // ToDo
|
||||
|
||||
when (usage) {
|
||||
BlockUsages.SUCCESS -> {
|
||||
if (currentTime - lastInteractionSent < ProtocolDefinition.TICK_TIME) {
|
||||
return
|
||||
}
|
||||
renderWindow.connection.sendPacket(ArmSwingC2SP(Hands.MAIN_HAND))
|
||||
|
||||
renderWindow.connection.sendPacket(BlockPlaceC2SP(
|
||||
position = raycastHit.blockPosition,
|
||||
direction = Directions.NORTH, // ToDo
|
||||
cursorPosition = raycastHit.hitPosition,
|
||||
item = null, // ToDo
|
||||
hand = Hands.MAIN_HAND,
|
||||
insideBlock = false, // ToDo
|
||||
))
|
||||
lastInteractionSent = currentTime
|
||||
lastInteraction = currentTime
|
||||
}
|
||||
BlockUsages.PASS -> {
|
||||
// use item or place block
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun draw() {
|
||||
checkInteraction(renderWindow.inputHandler.isKeyBindingDown(KeyBindingsNames.BLOCK_INTERACT))
|
||||
}
|
||||
}
|
@ -24,4 +24,5 @@ data class RaycastHit(
|
||||
val steps: Int,
|
||||
) {
|
||||
val blockPosition = position.floor
|
||||
val hitPosition = position.minus(blockPosition)
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.hud.elements.input.KeyConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.input.InteractionHandler
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.Camera
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
@ -41,6 +42,7 @@ class RenderWindowInputHandler(
|
||||
|
||||
private var skipNextCharPress = false
|
||||
|
||||
private val interactionHandler = InteractionHandler(renderWindow)
|
||||
|
||||
init {
|
||||
registerKeyCallback(KeyBindingsNames.DEBUG_MOUSE_CATCH) {
|
||||
@ -54,6 +56,10 @@ class RenderWindowInputHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun init() {
|
||||
interactionHandler.init()
|
||||
}
|
||||
|
||||
|
||||
var currentKeyConsumer: KeyConsumer? = null
|
||||
|
||||
@ -266,4 +272,9 @@ class RenderWindowInputHandler(
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun draw() {
|
||||
camera.draw()
|
||||
interactionHandler.draw()
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.Directions
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.RandomOffsetTypes
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import glm_.func.common.clamp
|
||||
|
@ -39,7 +39,7 @@ class BlockBreakC2SP(
|
||||
} else {
|
||||
buffer.writePosition(position)
|
||||
}
|
||||
buffer.writeByte(direction?.ordinal ?: 0xFF)
|
||||
buffer.writeByte(direction?.ordinal ?: 0x00)
|
||||
}
|
||||
|
||||
override fun log() {
|
||||
|
@ -27,7 +27,7 @@ class BlockPlaceC2SP(
|
||||
val position: Vec3i,
|
||||
val direction: Directions,
|
||||
val cursorPosition: Vec3,
|
||||
val item: ItemStack,
|
||||
val item: ItemStack?,
|
||||
val hand: Hands,
|
||||
val insideBlock: Boolean,
|
||||
) : PlayC2SPacket {
|
||||
|
@ -14,7 +14,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockActionEntity
|
||||
import de.bixilon.minosoft.data.entities.block.DefaultBlockEntityMetaDataFactory
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.Block
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
||||
|
@ -26,9 +26,9 @@ import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
class ContainerOpenS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
val containerId: Byte = buffer.readByte()
|
||||
val containerType: ContainerType = if (buffer.versionId < V_14W03B) {
|
||||
buffer.connection.mapping.containerTypeRegistry.get(buffer.readUnsignedByte())
|
||||
buffer.connection.mapping.containerTypeRegistry[buffer.readUnsignedByte()]
|
||||
} else {
|
||||
buffer.connection.mapping.containerTypeRegistry.get(buffer.readResourceLocation())!!
|
||||
buffer.connection.mapping.containerTypeRegistry[buffer.readResourceLocation()]!!
|
||||
}
|
||||
val title: ChatComponent = buffer.readChatComponent()
|
||||
val slotCount: Int = if (buffer.versionId < V_19W02A || buffer.versionId >= V_19W11A) {
|
||||
|
@ -24,4 +24,12 @@ interface ValuesEnum<T : Enum<*>> {
|
||||
operator fun get(name: String): T {
|
||||
return NAME_MAP[name]!!
|
||||
}
|
||||
|
||||
fun next(current: T): T {
|
||||
val ordinal = current.ordinal
|
||||
if (ordinal + 1 > VALUES.size) {
|
||||
return VALUES[0]
|
||||
}
|
||||
return VALUES[ordinal + 1]
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user