From 79f3ae1d4f5ce9955c3be022b0be34f661dbef3e Mon Sep 17 00:00:00 2001 From: Holly Date: Tue, 7 Nov 2023 01:50:51 +0000 Subject: [PATCH] handle block breaking better --- server/MPClient.ts | 21 +++++++---- server/blocks/Block.ts | 65 ++++++++++++++++++++++++--------- server/inventories/Inventory.ts | 9 +++++ 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/server/MPClient.ts b/server/MPClient.ts index 1006caf..4d84371 100644 --- a/server/MPClient.ts +++ b/server/MPClient.ts @@ -155,8 +155,15 @@ export class MPClient { this.entity.rotation.set(packet.yaw, packet.pitch); } + private breakBlock(brokenBlockId:number, x:number, y:number, z:number) { + const metadata = this.entity.world.getBlockMetadata(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z); + this.entity.world.setBlockWithNotify(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z, 0); + this.inventory.addItemStack(new ItemStack(Block.blockBehaviours[brokenBlockId].droppedItem(brokenBlockId), 1, metadata)); + this.send(new PacketWindowItems(0, this.inventory.getInventorySize(), this.inventory.constructInventoryPayload()).writeData()); + } + + // TODO: Cap how far away a player is able to break blocks private handlePacketPlayerDigging(packet:PacketPlayerDigging) { - console.log(packet.status); // Special drop item case if (packet.status === 4) { @@ -165,17 +172,16 @@ export class MPClient { } this.diggingAt.set(packet.x, packet.y, packet.z); - //this.mapCoordsToFace(this.diggingAt, packet.face); + let brokenBlockId:number; if (packet.status === 0) { // Started digging + if ((brokenBlockId = this.entity.world.getBlockId(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z)) != 0 && Block.blocks[brokenBlockId].blockStrength() >= 1) { + this.breakBlock(brokenBlockId, this.diggingAt.x, this.diggingAt.y, this.diggingAt.z); + } } else if (packet.status === 2) { - let brokenBlockId:number; if ((brokenBlockId = this.entity.world.getBlockId(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z)) != 0) { - const metadata = this.entity.world.getBlockMetadata(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z); - this.entity.world.setBlockWithNotify(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z, 0); - this.inventory.addItemStack(new ItemStack(Block.blockBehaviours[brokenBlockId].droppedItem(brokenBlockId), 1, metadata)); - this.send(new PacketWindowItems(0, this.inventory.getInventorySize(), this.inventory.constructInventoryPayload()).writeData()); + this.breakBlock(brokenBlockId, this.diggingAt.x, this.diggingAt.y, this.diggingAt.z); } } } @@ -197,6 +203,7 @@ export class MPClient { if (this.entity.world.getBlockId(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z) === 0) { itemStack.size--; this.entity.world.setBlockAndMetadataWithNotify(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z, itemStack.itemID, itemStack.damage); + this.inventory.dropEmptyItemStacks(); } } else { // TODO: Handle item usage diff --git a/server/blocks/Block.ts b/server/blocks/Block.ts index ff67f02..1682ac9 100644 --- a/server/blocks/Block.ts +++ b/server/blocks/Block.ts @@ -19,6 +19,7 @@ export class Block { public static readonly blocks:Array = new Array(); public static readonly lightPassage:Array = new Array(); + public static readonly hardness:Array = new Array(); public static readonly blockBehaviours:Array = new Array(); public static readonly blockNames:Array = new Array(); @@ -38,6 +39,14 @@ export class Block { Block.lightPassage[this.blockId] = value; } + public get hardness() { + return Block.hardness[this.blockId]; + } + + public set hardness(value:number) { + Block.hardness[this.blockId] = value; + } + public get blockName() { return Block.blockNames[this.blockId]; } @@ -77,32 +86,54 @@ export class Block { this.behaviour.droppedItem(blockId); } + public getHardness() { + return this.hardness; + } + + public setHardness(value:number) { + this.hardness = value; + return this; + } + + public setUnbreakable() { + return this.setHardness(-1); + } + + public blockStrength() { + if (this.hardness < 0) { + return 0; + } + // TODO: Check if we can actually harvest a block with current tool + // TODO: Have the 1 be based on current tool ig + return 1 / this.hardness / 100; + } + // Define statics here - static readonly stone = new Block(1).setBehaviour(Behaviour.stone).setBlockName("Stone"); - static readonly grass = new Block(2).setBehaviour(Behaviour.grass).setBlockName("Grass"); - static readonly dirt = new Block(3).setBlockName("Dirt"); - static readonly cobblestone = new Block(4).setBlockName("Cobblestone"); + static readonly stone = new Block(1).setHardness(1.5).setBehaviour(Behaviour.stone).setBlockName("Stone"); + static readonly grass = new Block(2).setHardness(0.6).setBehaviour(Behaviour.grass).setBlockName("Grass"); + static readonly dirt = new Block(3).setHardness(0.5).setBlockName("Dirt"); + static readonly cobblestone = new Block(4).setHardness(2).setBlockName("Cobblestone"); - static readonly bedrock = new Block(7).setBlockName("Bedrock"); + static readonly bedrock = new Block(7).setUnbreakable().setBlockName("Bedrock"); - static readonly waterStill = new Block(9).setLightPassage(128).setBlockName("Still Water"); + static readonly waterStill = new Block(9).setHardness(100).setLightPassage(128).setBlockName("Still Water"); - static readonly lavaStill = new Block(11).setBlockName("Still Lava"); + static readonly lavaStill = new Block(11).setHardness(100).setBlockName("Still Lava"); - static readonly sand = new Block(12).setBlockName("Sand"); - static readonly gravel = new Block(13).setBlockName("Gravel"); + static readonly sand = new Block(12).setHardness(0.5).setBlockName("Sand"); + static readonly gravel = new Block(13).setHardness(0.6).setBlockName("Gravel"); - static readonly wood = new Block(17).setBlockName("Wood"); - static readonly leaves = new Block(18).setLightPassage(240).setBlockName("Leaves"); + static readonly wood = new Block(17).setHardness(2).setBlockName("Wood"); + static readonly leaves = new Block(18).setHardness(0.2).setLightPassage(240).setBlockName("Leaves"); - static readonly glass = new Block(20).setLightPassage(255).setBlockName("Glass"); + static readonly glass = new Block(20).setHardness(0.3).setLightPassage(255).setBlockName("Glass"); - static readonly tallGrass = new Block(31).setLightPassage(255).setBehaviour(Behaviour.flower).setBlockName("Tall Grass"); + static readonly tallGrass = new Block(31).setHardness(0).setLightPassage(255).setBehaviour(Behaviour.flower).setBlockName("Tall Grass"); - static readonly flowerDandelion = new Block(37).setLightPassage(255).setBlockName("Dandelion"); - static readonly flowerRose = new Block(38).setLightPassage(255).setBlockName("Rose"); + static readonly flowerDandelion = new Block(37).setHardness(0).setLightPassage(255).setBlockName("Dandelion"); + static readonly flowerRose = new Block(38).setHardness(0).setLightPassage(255).setBlockName("Rose"); - static readonly clay = new Block(82).setBlockName("Clay"); + static readonly clay = new Block(82).setHardness(0.6).setBlockName("Clay"); - static readonly netherrack = new Block(87).setBlockName("Netherrack"); + static readonly netherrack = new Block(87).setHardness(0.4).setBlockName("Netherrack"); } \ No newline at end of file diff --git a/server/inventories/Inventory.ts b/server/inventories/Inventory.ts index 5dabc42..0f1a1dd 100644 --- a/server/inventories/Inventory.ts +++ b/server/inventories/Inventory.ts @@ -44,6 +44,15 @@ export class Inventory implements IInventory { return this.itemStacks[slotId]; } + dropEmptyItemStacks() { + for (let i = 0; i < this.itemStacks.length; i++) { + const itemStack = this.itemStacks[i]; + if (itemStack?.size === 0) { + this.itemStacks[i] = null; + } + } + } + setSlotItemStack(slotId:number, itemStack: ItemStack | null) { if (slotId < 0 || slotId > this.size - 1) { throw new Error(`Tried to set an Inventory ItemStack out of bounds! Requested slot: ${slotId}, Inventory Size: ${this.size}`);