option to disable tool interaction, almost finished mining math

This commit is contained in:
Bixilon 2021-05-22 23:43:23 +02:00
parent bf66039ca0
commit 9edda894fd
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
18 changed files with 210 additions and 130 deletions

View File

@ -17,4 +17,7 @@ import com.squareup.moshi.Json
data class ControlsGameConfig( data class ControlsGameConfig(
@Json(name = "key_bindings") var keyBindings: KeyBindingsGameConfig = KeyBindingsGameConfig(), @Json(name = "key_bindings") var keyBindings: KeyBindingsGameConfig = KeyBindingsGameConfig(),
@Json(name = "enable_flattening") var enableFlattening: Boolean = true,
@Json(name = "enable_stripping") var enableStripping: Boolean = true,
@Json(name = "enable_tilling") var enableTilling: Boolean = true,
) )

View File

@ -18,26 +18,31 @@ import de.bixilon.minosoft.util.enum.ValuesEnum
enum class Gamemodes( enum class Gamemodes(
val canBuild: Boolean, val canBuild: Boolean,
val canBreak: Boolean, val canBreak: Boolean,
val useTools: Boolean,
val canInteract: InteractionAbilities, val canInteract: InteractionAbilities,
) { ) {
SURVIVAL( SURVIVAL(
canBuild = true, canBuild = true,
canBreak = true, canBreak = true,
useTools = true,
canInteract = InteractionAbilities.EVERYTHING, canInteract = InteractionAbilities.EVERYTHING,
), ),
CREATIVE( CREATIVE(
canBuild = true, canBuild = true,
canBreak = true, canBreak = true,
useTools = true,
canInteract = InteractionAbilities.EVERYTHING, canInteract = InteractionAbilities.EVERYTHING,
), ),
ADVENTURE( ADVENTURE(
canBuild = false, canBuild = false,
canBreak = false, canBreak = false,
useTools = false,
canInteract = InteractionAbilities.ONLY_ENTITIES, canInteract = InteractionAbilities.ONLY_ENTITIES,
), ),
SPECTATOR( SPECTATOR(
canBuild = false, canBuild = false,
canBreak = false, canBreak = false,
useTools = false,
canInteract = InteractionAbilities.ONLY_ENTITIES, canInteract = InteractionAbilities.ONLY_ENTITIES,
), ),
; ;

View File

@ -1,67 +0,0 @@
/*
* Minosoft
* Copyright (C) 2020 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.inventory;
import java.util.HashMap;
public class Inventory {
private final InventoryProperties properties;
private final HashMap<Integer, ItemStack> slots;
public Inventory(InventoryProperties properties, HashMap<Integer, ItemStack> slots) {
this.properties = properties;
this.slots = slots;
}
public Inventory(InventoryProperties properties) {
this.properties = properties;
this.slots = new HashMap<>();
}
public Inventory(InventoryProperties properties, ItemStack[] itemStacks) {
this.properties = properties;
this.slots = new HashMap<>();
for (int i = 0; i < itemStacks.length; i++) {
this.slots.put(i, itemStacks[i]);
}
}
public ItemStack getSlot(int slotId, int versionId) {
return getSlot(slotId);
}
public ItemStack getSlot(int slot) {
return this.slots.get(slot);
}
public void setSlot(int slot, ItemStack data) {
this.slots.put(slot, data);
}
public void setSlot(int slotId, int versionId, ItemStack data) {
this.slots.put(slotId, data);
}
public void clear() {
this.slots.clear();
}
public HashMap<Integer, ItemStack> getSlots() {
return this.slots;
}
public InventoryProperties getProperties() {
return this.properties;
}
}

View File

@ -23,8 +23,8 @@ import de.bixilon.minosoft.data.inventory.ItemNBTValues.ENCHANTMENT_PRE_FLATTENI
import de.bixilon.minosoft.data.inventory.ItemNBTValues.HIDE_FLAGS_TAG import de.bixilon.minosoft.data.inventory.ItemNBTValues.HIDE_FLAGS_TAG
import de.bixilon.minosoft.data.inventory.ItemNBTValues.REPAIR_COST_TAG import de.bixilon.minosoft.data.inventory.ItemNBTValues.REPAIR_COST_TAG
import de.bixilon.minosoft.data.inventory.ItemNBTValues.UNBREAKABLE_TAG import de.bixilon.minosoft.data.inventory.ItemNBTValues.UNBREAKABLE_TAG
import de.bixilon.minosoft.data.mappings.Enchantment
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.enchantment.Enchantment
import de.bixilon.minosoft.data.mappings.items.Item import de.bixilon.minosoft.data.mappings.items.Item
import de.bixilon.minosoft.data.mappings.versions.Version import de.bixilon.minosoft.data.mappings.versions.Version
import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.ChatComponent

View File

@ -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.blocks
import de.bixilon.minosoft.util.KUtil.asResourceLocation
object DefaultBlocks {
val COBWEB = "minecraft:cobweb".asResourceLocation()
}

View File

@ -0,0 +1,21 @@
/*
* 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.effects
import de.bixilon.minosoft.util.KUtil.asResourceLocation
object DefaultStatusEffects {
val HASTE = "minecraft:haste".asResourceLocation()
val MINING_FATIGUE = "minecraft:mining_fatigue".asResourceLocation()
}

View File

@ -11,17 +11,10 @@
* 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.data.player package de.bixilon.minosoft.data.mappings.enchantment
import de.bixilon.minosoft.data.inventory.Inventory import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
class PlayerInventoryManager { object DefaultEnchantments {
val inventories: MutableMap<Int, Inventory> = mutableMapOf() val EFFICIENCY = "minecraft:efficiency".asResourceLocation()
var selectedHotbarSlot: Int = 0
init {
// create our own inventory without any properties
inventories[ProtocolDefinition.PLAYER_INVENTORY_ID] = Inventory(null)
}
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020 Moritz Zwerger * 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 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.
* *
@ -10,9 +10,10 @@
* *
* 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.data.mappings package de.bixilon.minosoft.data.mappings.enchantment
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.registry.RegistryItem import de.bixilon.minosoft.data.mappings.registry.RegistryItem
import de.bixilon.minosoft.data.mappings.registry.ResourceLocationDeserializer import de.bixilon.minosoft.data.mappings.registry.ResourceLocationDeserializer
import de.bixilon.minosoft.data.mappings.versions.Registries import de.bixilon.minosoft.data.mappings.versions.Registries

View File

@ -47,7 +47,7 @@ open class Item(
return resourceLocation.toString() return resourceLocation.toString()
} }
open fun getMiningSpeedMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, itemStack: ItemStack): Float { open fun getMiningSpeedMultiplier(connection: PlayConnection, blockState: BlockState, itemStack: ItemStack): Float {
return 1.0f return 1.0f
} }
@ -73,6 +73,7 @@ open class Item(
"SpawnEggItem" -> SpawnEggItem(resourceLocation, mappings, data) "SpawnEggItem" -> SpawnEggItem(resourceLocation, mappings, data)
"MusicDiscItem" -> MusicDiscItem(resourceLocation, mappings, data) "MusicDiscItem" -> MusicDiscItem(resourceLocation, mappings, data)
"ShovelItem" -> ShovelItem(resourceLocation, mappings, data) "ShovelItem" -> ShovelItem(resourceLocation, mappings, data)
"PickaxeItem" -> PickaxeItem(resourceLocation, mappings, data)
"HoeItem" -> HoeItem(resourceLocation, mappings, data) "HoeItem" -> HoeItem(resourceLocation, mappings, data)
// "Item" -> Item(resourceLocation, data) // "Item" -> Item(resourceLocation, data)
// else -> TODO("Can not find item class: ${data["class"].asString}") // else -> TODO("Can not find item class: ${data["class"].asString}")

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.data.mappings.items.tools package de.bixilon.minosoft.data.mappings.items.tools
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.inventory.ItemStack import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.mappings.blocks.BlockState
@ -23,7 +23,6 @@ import de.bixilon.minosoft.data.mappings.blocks.types.Block
import de.bixilon.minosoft.data.mappings.versions.Registries import de.bixilon.minosoft.data.mappings.versions.Registries
import de.bixilon.minosoft.data.player.Hands import de.bixilon.minosoft.data.player.Hands
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit 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 de.bixilon.minosoft.protocol.network.connection.PlayConnection
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
@ -33,23 +32,20 @@ open class AxeItem(
data: JsonObject, data: JsonObject,
) : MiningToolItem(resourceLocation, registries, data) { ) : MiningToolItem(resourceLocation, registries, data) {
val strippableBlocks: Map<Block, Block>? = data["strippables_blocks"]?.asJsonObject?.let { val strippableBlocks: Map<Block, Block>? = data["strippables_blocks"]?.asJsonObject?.let {
val items: MutableMap<Block, Block> = mutableMapOf() val entries: MutableMap<Block, Block> = mutableMapOf()
for ((origin, target) in it.entrySet()) { for ((origin, target) in it.entrySet()) {
items[registries.blockRegistry[origin.toInt()]] = registries.blockRegistry[target.asInt] entries[registries.blockRegistry[origin.toInt()]] = registries.blockRegistry[target]
} }
items.toMap() entries.toMap()
} }
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages { override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
// ToDo: Check tags (21w19a+) // ToDo: Check tags (21w19a+)
val target = strippableBlocks?.get(blockState.block) ?: return BlockUsages.PASS if (!Minosoft.config.config.game.controls.enableStripping) {
return BlockUsages.CONSUME
if (connection.world[blockPosition + Directions.UP] != null) {
return BlockUsages.PASS
} }
connection.world[blockPosition] = target.withProperties(blockState.properties) return super.interactWithTool(connection, blockPosition, strippableBlocks?.get(blockState.block)?.withProperties(blockState.properties))
return BlockUsages.SUCCESS
} }
} }

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.data.mappings.items.tools package de.bixilon.minosoft.data.mappings.items.tools
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.inventory.ItemStack import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
@ -33,23 +34,24 @@ open class HoeItem(
data: JsonObject, data: JsonObject,
) : MiningToolItem(resourceLocation, registries, data) { ) : MiningToolItem(resourceLocation, registries, data) {
val tillableBlockStates: Map<Block, BlockState>? = data["tillables_block_states"]?.asJsonObject?.let { val tillableBlockStates: Map<Block, BlockState>? = data["tillables_block_states"]?.asJsonObject?.let {
val items: MutableMap<Block, BlockState> = mutableMapOf() val entries: MutableMap<Block, BlockState> = mutableMapOf()
for ((origin, target) in it.entrySet()) { for ((origin, target) in it.entrySet()) {
items[registries.blockRegistry[origin.toInt()]] = registries.getBlockState(target.asInt)!! entries[registries.blockRegistry[origin.toInt()]] = registries.getBlockState(target.asInt)!!
} }
items.toMap() entries.toMap()
} }
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages { override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
// ToDo: Check tags (21w19a+) // ToDo: Check tags (21w19a+)
val nextState = tillableBlockStates?.get(blockState.block) ?: return BlockUsages.PASS if (!Minosoft.config.config.game.controls.enableTilling) {
return BlockUsages.CONSUME
}
if (connection.world[blockPosition + Directions.UP] != null) { if (connection.world[blockPosition + Directions.UP] != null) {
return BlockUsages.PASS return BlockUsages.PASS
} }
connection.world[blockPosition] = nextState return super.interactWithTool(connection, blockPosition, tillableBlockStates?.get(blockState.block))
return BlockUsages.SUCCESS
} }
} }

View File

@ -17,6 +17,7 @@ import com.google.gson.JsonObject
import de.bixilon.minosoft.data.inventory.ItemStack import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.blocks.BlockUsages
import de.bixilon.minosoft.data.mappings.blocks.types.Block import de.bixilon.minosoft.data.mappings.blocks.types.Block
import de.bixilon.minosoft.data.mappings.versions.Registries import de.bixilon.minosoft.data.mappings.versions.Registries
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
@ -27,23 +28,38 @@ open class MiningToolItem(
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : ToolItem(resourceLocation, registries, data) { ) : ToolItem(resourceLocation, registries, data) {
val diggableBlocks: List<Block>? = data["diggable_blocks"]?.asJsonArray?.let { val diggableBlocks: Set<Block>? = data["diggable_blocks"]?.asJsonArray?.let {
val diggableBlocks: MutableList<Block> = mutableListOf() val entries: MutableList<Block> = mutableListOf()
for (id in it) { for (id in it) {
diggableBlocks += registries.blockRegistry[id.asInt] entries += registries.blockRegistry[id]
} }
diggableBlocks.toList() entries.toSet()
} }
override val attackDamage: Float = data["attack_damage"]?.asFloat ?: 1.0f override val attackDamage: Float = data["attack_damage"]?.asFloat ?: 1.0f
val miningSpeed: Float = data["mining_speed"]?.asFloat ?: 1.0f
override fun getMiningSpeedMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, itemStack: ItemStack): Float { open fun isEffectiveOn(blockState: BlockState): Boolean {
// ToDo: Calculate correct, Tags (21w19a) return diggableBlocks?.contains(blockState.block) == true
if (diggableBlocks?.contains(blockState.block) == true) { }
return 10.0f * miningSpeed
protected fun interactWithTool(connection: PlayConnection, blockPosition: Vec3i, replace: BlockState?): BlockUsages {
if (!connection.player.entity.gamemode.useTools) {
return BlockUsages.PASS
} }
return super.getMiningSpeedMultiplier(connection, blockState, blockPosition, itemStack)
replace ?: return BlockUsages.PASS
connection.world[blockPosition] = replace
return BlockUsages.SUCCESS
}
override fun getMiningSpeedMultiplier(connection: PlayConnection, blockState: BlockState, itemStack: ItemStack): Float {
// ToDo: Calculate correct, Tags (21w19a)
if (isEffectiveOn(blockState)) {
return speed
}
return super.getMiningSpeedMultiplier(connection, blockState, itemStack)
} }
} }

View File

@ -0,0 +1,24 @@
/*
* 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.items.tools
import com.google.gson.JsonObject
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.versions.Registries
open class PickaxeItem(
resourceLocation: ResourceLocation,
registries: Registries,
data: JsonObject,
) : MiningToolItem(resourceLocation, registries, data)

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.data.mappings.items.tools package de.bixilon.minosoft.data.mappings.items.tools
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.inventory.ItemStack import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
@ -33,24 +34,26 @@ open class ShovelItem(
data: JsonObject, data: JsonObject,
) : MiningToolItem(resourceLocation, registries, data) { ) : MiningToolItem(resourceLocation, registries, data) {
val flattenableBlockStates: Map<Block, BlockState>? = data["flattenables_block_states"]?.asJsonObject?.let { val flattenableBlockStates: Map<Block, BlockState>? = data["flattenables_block_states"]?.asJsonObject?.let {
val items: MutableMap<Block, BlockState> = mutableMapOf() val entries: MutableMap<Block, BlockState> = mutableMapOf()
for ((origin, target) in it.entrySet()) { for ((origin, target) in it.entrySet()) {
items[registries.blockRegistry[origin.toInt()]] = registries.getBlockState(target.asInt)!! entries[registries.blockRegistry[origin.toInt()]] = registries.getBlockState(target.asInt)!!
} }
items.toMap() entries.toMap()
} }
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages { override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
// ToDo: Check tags (21w19a+) // ToDo: Check tags (21w19a+)
val nextState = flattenableBlockStates?.get(blockState.block) ?: return BlockUsages.PASS
if (!Minosoft.config.config.game.controls.enableFlattening) {
return BlockUsages.CONSUME
}
if (connection.world[blockPosition + Directions.UP] != null) { if (connection.world[blockPosition + Directions.UP] != null) {
return BlockUsages.PASS return BlockUsages.PASS
} }
connection.world[blockPosition] = nextState return super.interactWithTool(connection, blockPosition, flattenableBlockStates?.get(blockState.block))
return BlockUsages.SUCCESS
} }
} }

View File

@ -17,10 +17,9 @@ import com.google.gson.JsonObject
import de.bixilon.minosoft.data.inventory.ItemStack import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.blocks.DefaultBlocks
import de.bixilon.minosoft.data.mappings.versions.Registries import de.bixilon.minosoft.data.mappings.versions.Registries
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import glm_.vec3.Vec3i
open class SwordItem( open class SwordItem(
@ -30,15 +29,10 @@ open class SwordItem(
) : ToolItem(resourceLocation, registries, data) { ) : ToolItem(resourceLocation, registries, data) {
override val attackDamage = data["attack_damage"]?.asFloat ?: -1.0f override val attackDamage = data["attack_damage"]?.asFloat ?: -1.0f
override fun getMiningSpeedMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, itemStack: ItemStack): Float { override fun getMiningSpeedMultiplier(connection: PlayConnection, blockState: BlockState, itemStack: ItemStack): Float {
if (blockState.block.resourceLocation == COBWEB_BLOCK) { if (blockState.block.resourceLocation == DefaultBlocks.COBWEB) {
return 15.0f return 15.0f
} }
return super.getMiningSpeedMultiplier(connection, blockState, blockPosition, itemStack) return super.getMiningSpeedMultiplier(connection, blockState, itemStack)
}
companion object {
val COBWEB_BLOCK = "minecraft:cobweb".asResourceLocation()
} }
} }

View File

@ -13,9 +13,12 @@
package de.bixilon.minosoft.data.mappings.registry package de.bixilon.minosoft.data.mappings.registry
import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.versions.Registries import de.bixilon.minosoft.data.mappings.versions.Registries
import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.collections.Clearable import de.bixilon.minosoft.util.collections.Clearable
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
@ -27,6 +30,18 @@ open class Registry<T : RegistryItem>(
protected val valueIdMap: MutableMap<T, Int> = mutableMapOf() protected val valueIdMap: MutableMap<T, Int> = mutableMapOf()
protected val resourceLocationMap: MutableMap<ResourceLocation, T> = mutableMapOf() protected val resourceLocationMap: MutableMap<ResourceLocation, T> = mutableMapOf()
open operator fun get(json: JsonElement): T {
return when (json) {
is JsonPrimitive -> {
when {
json.isString -> get(json.asString.asResourceLocation())!!
json.isNumber -> get(json.asInt)
else -> TODO()
}
}
else -> TODO()
}
}
open operator fun get(resourceLocation: ResourceLocation): T? { open operator fun get(resourceLocation: ResourceLocation): T? {
return resourceLocationMap[resourceLocation] ?: parentRegistry?.get(resourceLocation) return resourceLocationMap[resourceLocation] ?: parentRegistry?.get(resourceLocation)

View File

@ -19,7 +19,10 @@ import de.bixilon.minosoft.data.entities.EntityMetaDataFields
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaType import de.bixilon.minosoft.data.entities.block.BlockEntityMetaType
import de.bixilon.minosoft.data.entities.meta.EntityMetaData import de.bixilon.minosoft.data.entities.meta.EntityMetaData
import de.bixilon.minosoft.data.inventory.InventorySlots import de.bixilon.minosoft.data.inventory.InventorySlots
import de.bixilon.minosoft.data.mappings.* import de.bixilon.minosoft.data.mappings.DefaultRegistries
import de.bixilon.minosoft.data.mappings.Dimension
import de.bixilon.minosoft.data.mappings.Motive
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.mappings.biomes.Biome
import de.bixilon.minosoft.data.mappings.biomes.BiomeCategory import de.bixilon.minosoft.data.mappings.biomes.BiomeCategory
import de.bixilon.minosoft.data.mappings.biomes.BiomePrecipitation import de.bixilon.minosoft.data.mappings.biomes.BiomePrecipitation
@ -28,6 +31,7 @@ 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.entites.BlockEntityTypeRegistry
import de.bixilon.minosoft.data.mappings.blocks.types.Block import de.bixilon.minosoft.data.mappings.blocks.types.Block
import de.bixilon.minosoft.data.mappings.effects.StatusEffect import de.bixilon.minosoft.data.mappings.effects.StatusEffect
import de.bixilon.minosoft.data.mappings.enchantment.Enchantment
import de.bixilon.minosoft.data.mappings.entities.EntityType import de.bixilon.minosoft.data.mappings.entities.EntityType
import de.bixilon.minosoft.data.mappings.entities.villagers.VillagerProfession import de.bixilon.minosoft.data.mappings.entities.villagers.VillagerProfession
import de.bixilon.minosoft.data.mappings.fluid.Fluid import de.bixilon.minosoft.data.mappings.fluid.Fluid

View File

@ -18,12 +18,16 @@ import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.inventory.ItemStack import de.bixilon.minosoft.data.inventory.ItemStack
import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.effects.DefaultStatusEffects
import de.bixilon.minosoft.data.mappings.enchantment.DefaultEnchantments
import de.bixilon.minosoft.data.mappings.items.tools.MiningToolItem
import de.bixilon.minosoft.data.player.Hands import de.bixilon.minosoft.data.player.Hands
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.protocol.packets.c2s.play.ArmSwingC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.ArmSwingC2SP
import de.bixilon.minosoft.protocol.packets.c2s.play.BlockBreakC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.BlockBreakC2SP
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import glm_.pow
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
class LeftClickHandler( class LeftClickHandler(
@ -42,6 +46,10 @@ class LeftClickHandler(
private var lastSwing = 0L private var lastSwing = 0L
private var creativeLastHoldBreakTime = 0L private var creativeLastHoldBreakTime = 0L
private val efficiencyEnchantment = connection.registries.enchantmentRegistry[DefaultEnchantments.EFFICIENCY]
private val hasteStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.HASTE]
private val miningFatigueStatusEffect = connection.registries.statusEffectRegistry[DefaultStatusEffects.MINING_FATIGUE]
private fun clearDigging() { private fun clearDigging() {
breakPosition = null breakPosition = null
breakBlockState = null breakBlockState = null
@ -116,6 +124,11 @@ class LeftClickHandler(
connection.sendPacket(BlockBreakC2SP(BlockBreakC2SP.BreakType.FINISHED_DIGGING, raycastHit.blockPosition, raycastHit.hitDirection)) connection.sendPacket(BlockBreakC2SP(BlockBreakC2SP.BreakType.FINISHED_DIGGING, raycastHit.blockPosition, raycastHit.hitDirection))
clearDigging() clearDigging()
connection.world.setBlockState(raycastHit.blockPosition, null) connection.world.setBlockState(raycastHit.blockPosition, null)
if (connection.player.entity.gamemode != Gamemodes.CREATIVE) {
// decrease durability
// ToDo
}
} }
val canStartBreaking = currentTime - breakSent >= ProtocolDefinition.TICK_TIME val canStartBreaking = currentTime - breakSent >= ProtocolDefinition.TICK_TIME
@ -149,15 +162,51 @@ class LeftClickHandler(
swingArm() swingArm()
// thanks to https://minecraft.fandom.com/wiki/Breaking#Calculation
var speedMultiplier = 1.0f val breakItemInHand = breakItemInHand
val isBestTool = !raycastHit.blockState.requiresTool || breakItemInHand?.item?.let {
return@let if (it is MiningToolItem) {
it.isEffectiveOn(raycastHit.blockState)
} else {
false
}
} ?: false
var speedMultiplier = breakItemInHand?.let { it.item.getMiningSpeedMultiplier(connection, raycastHit.blockState, it) } ?: 1.0f
if (isBestTool) {
breakItemInHand?.enchantments?.get(efficiencyEnchantment)?.let {
speedMultiplier += it.pow(2) + 1.0f
}
}
connection.player.entity.activeStatusEffects[hasteStatusEffect]?.let {
speedMultiplier *= (0.2f * it.amplifier) + 1.0f
}
connection.player.entity.activeStatusEffects[miningFatigueStatusEffect]?.let {
speedMultiplier *= when (it.amplifier) {
0 -> 0.3f
1 -> 0.09f
2 -> 0.0027f
else -> 0.00081f
}
}
// ToDp: Check if is in water
if (!connection.player.entity.onGround) {
speedMultiplier /= 5.0f
}
var damage = speedMultiplier / raycastHit.blockState.hardness var damage = speedMultiplier / raycastHit.blockState.hardness
damage /= if (raycastHit.blockState.requiresTool) { damage /= if (isBestTool) {
100
} else {
30 30
} else {
100
} }
when { when {