From 65d31be4f91874be32eb9689e71ff7adbf48393c Mon Sep 17 00:00:00 2001 From: Holly Date: Fri, 29 Nov 2024 15:00:48 +0000 Subject: [PATCH] crafting table --- server/MPClient.ts | 13 ++++++++++++- server/blocks/Block.ts | 5 ++++- server/blocks/BlockBehaviourCraftingTable.ts | 10 ++++++++++ server/entities/Player.ts | 1 + server/enums/InventoryType.ts | 2 +- server/enums/TileEntityType.ts | 3 ++- server/inventories/Inventory.ts | 17 +++++++++++++++++ server/inventories/PlayerCombinedInventory.ts | 16 ++++++++++++++++ server/packets/WindowClick.ts | 12 +++++++++--- server/windows/Window.ts | 3 +++ server/windows/WindowCrafting.ts | 10 ++++++++++ 11 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 server/blocks/BlockBehaviourCraftingTable.ts create mode 100644 server/inventories/PlayerCombinedInventory.ts create mode 100644 server/windows/WindowCrafting.ts diff --git a/server/MPClient.ts b/server/MPClient.ts index 9e4a840..9226df5 100644 --- a/server/MPClient.ts +++ b/server/MPClient.ts @@ -31,6 +31,8 @@ import FunkyArray from "funky-array"; import Window from "./windows/Window"; import WindowChest from "./windows/WindowChest"; import TileEntityChest from "./tileentities/TileEntityChest"; +import WindowCrafting from "./windows/WindowCrafting"; +import PacketWindowClick from "./packets/WindowClick"; export default class MPClient { private readonly mcServer:MinecraftServer; @@ -95,8 +97,9 @@ export default class MPClient { //case Packets.UseBed: break; case Packet.Animation: this.handlePacketAnimation(new PacketAnimation().readData(reader)); break; case Packet.EntityAction: this.handlePacketEntityAction(new PacketEntityAction().readData(reader)); break; + case Packet.WindowClick: this.handleWindowClick(new PacketWindowClick().readData(reader)); break; case Packet.DisconnectKick: this.handleDisconnectKick(); break; - default: return Console.printWarn(`UNIMPLEMENTED PACKET: ${Packet[packetId]}`); + default: return Console.printWarn(`UNIMPLEMENTED PACKET: ${Packet[packetId]} 0x${packetId < 10 ? `0${packetId.toString(16).toUpperCase()}` : packetId.toString(16).toUpperCase()}`); } if (reader.readOffset < reader.length - 1) { @@ -281,6 +284,10 @@ export default class MPClient { this.windows.set(window.windowId, window); window.openWindow(this); } + } else if (blockClicked.is(Block.craftingTable)) { + const window = new WindowCrafting(this); + this.windows.set(window.windowId, window); + window.openWindow(this); } return; @@ -350,6 +357,10 @@ export default class MPClient { this.entity.forceUpdatePlayerChunks(); } + private handleWindowClick(windowClick: PacketWindowClick) { + console.log(windowClick); + } + private handleDisconnectKick() { this.socket.end(); } diff --git a/server/blocks/Block.ts b/server/blocks/Block.ts index 2cc5ef5..24d3416 100644 --- a/server/blocks/Block.ts +++ b/server/blocks/Block.ts @@ -12,6 +12,7 @@ import BlockBehaviourTallGrass from "./BlockBehaviourTallGrass"; import IBlockBehaviour from "./IBlockBehaviour"; import World from "../World"; import BlockBehaviourChest from "./BlockBehaviourChest"; +import BlockBehaviourCraftingTable from "./BlockBehaviourCraftingTable"; abstract class Behaviour { public static base = new BlockBehaviour(); @@ -26,6 +27,8 @@ abstract class Behaviour { public static chest = new BlockBehaviourChest(); + public static craftingTable = new BlockBehaviourCraftingTable(); + public static redstoneOre = new BlockBehaviourRedstoneOre(); public static clay = new BlockBehaviourClay(); @@ -222,7 +225,7 @@ export default class Block { static readonly redstoneDust = new Block(55).setHardness(0).setBlockName("Redstone Dust"); // TODO: Behavior script static readonly diamondOre = new Block(56).setHardness(3).setBlockName("Diamond Ore"); // TODO: Behavior script static readonly diamondBlock = new Block(57).setHardness(5).setBlockName("Diamond Block"); // TODO: Behavior script - static readonly craftingTable = new Block(58).setHardness(2.5).setBlockName("Crafting Table"); // TODO: Behavior script + static readonly craftingTable = new Block(58).setHardness(2.5).setBehaviour(Behaviour.craftingTable).setBlockName("Crafting Table"); // TODO: Behavior script static readonly wheatCrop = new Block(59).setHardness(0).setBlockName("Wheet Crop"); // TODO: Behavior script static readonly farmland = new Block(60).setHardness(0.6).setBlockName("Farmland"); // TODO: Behavior script static readonly furnaceIdle = new Block(61).setHardness(3.5).setBlockName("Furnace"); // TODO: Behavior script diff --git a/server/blocks/BlockBehaviourCraftingTable.ts b/server/blocks/BlockBehaviourCraftingTable.ts new file mode 100644 index 0000000..8d8b26d --- /dev/null +++ b/server/blocks/BlockBehaviourCraftingTable.ts @@ -0,0 +1,10 @@ +import TileEntityChest from "../tileentities/TileEntityChest"; +import Vec3 from "../Vec3"; +import World from "../World"; +import BlockBehaviour from "./BlockBehaviour"; + +export default class BlockBehaviourCraftingTable extends BlockBehaviour { + public interactable() { + return true; + } +} \ No newline at end of file diff --git a/server/entities/Player.ts b/server/entities/Player.ts index ce84a20..26dc8eb 100644 --- a/server/entities/Player.ts +++ b/server/entities/Player.ts @@ -42,6 +42,7 @@ export default class Player extends EntityLiving { this.inventory.setSlotItemStack(37, new ItemStack(Item.ironPickaxe, 1)); this.inventory.setSlotItemStack(38, new ItemStack(Item.ironShovel, 1)); this.inventory.setSlotItemStack(39, new ItemStack(Item.ironAxe, 1)); + this.inventory.setSlotItemStack(41, new ItemStack(Block.craftingTable, 1)); this.inventory.setSlotItemStack(42, new ItemStack(Block.chest, 32)); this.inventory.setSlotItemStack(43, new ItemStack(Block.dirt, 32)); diff --git a/server/enums/InventoryType.ts b/server/enums/InventoryType.ts index b6d3e93..3a8bf69 100644 --- a/server/enums/InventoryType.ts +++ b/server/enums/InventoryType.ts @@ -1,6 +1,6 @@ enum InventoryType { Chest = 0, - Workbench = 1, + CraftingTable = 1, Furnace = 2, Dispenser = 3 } diff --git a/server/enums/TileEntityType.ts b/server/enums/TileEntityType.ts index 63b7484..127a854 100644 --- a/server/enums/TileEntityType.ts +++ b/server/enums/TileEntityType.ts @@ -1,6 +1,7 @@ enum TileEntityType { Unknown, - Chest + Chest, + CraftingTable } export default TileEntityType; \ No newline at end of file diff --git a/server/inventories/Inventory.ts b/server/inventories/Inventory.ts index 5a77938..2829789 100644 --- a/server/inventories/Inventory.ts +++ b/server/inventories/Inventory.ts @@ -1,14 +1,19 @@ import { Endian, IReader, IWriter, createWriter } from "bufferstuff"; +import FunkyArray from "funky-array"; import IInventory from "./IInventory"; import ItemStack from "./ItemStack"; export default class Inventory implements IInventory { + private static CHANGE_HANDLER_ROLLING_HANDLE_ID = 0; + + public changeHandlers:FunkyArray void>; public itemStacks:Array; private size:number; private name:string; public constructor(size:number, name:string) { + this.changeHandlers = new FunkyArray void>(); this.itemStacks = new Array(); for (let i = 0; i < size; i++) { this.itemStacks.push(null); @@ -18,6 +23,18 @@ export default class Inventory implements IInventory { this.name = name; } + registerChangeHandler(changeHandler: (itemStack: ItemStack) => void) { + const changeHandlerHandle = Inventory.CHANGE_HANDLER_ROLLING_HANDLE_ID++; + this.changeHandlers.set(changeHandlerHandle, changeHandler); + return changeHandlerHandle; + } + + unregisterChangeHandler(changeHandlerHandle: number) { + if (this.changeHandlers.has(changeHandlerHandle)) { + this.changeHandlers.remove(changeHandlerHandle); + } + } + public fromSave(reader:IReader) { const inventorySize = reader.readByte(); for (let i = 0; i < inventorySize; i++) { diff --git a/server/inventories/PlayerCombinedInventory.ts b/server/inventories/PlayerCombinedInventory.ts new file mode 100644 index 0000000..dfc3655 --- /dev/null +++ b/server/inventories/PlayerCombinedInventory.ts @@ -0,0 +1,16 @@ +import Inventory from "./Inventory"; +import ItemStack from "./ItemStack"; + +export default class PlayerCombinedInventory extends Inventory { + private combinedInventoryChangeHandlerHandle: number; + + public constructor(size: number, name: string) { + super(size, name); + + this.combinedInventoryChangeHandlerHandle = this.registerChangeHandler(this.onInventoryChange); + } + + private onInventoryChange(itemStack: ItemStack) { + + } +} \ No newline at end of file diff --git a/server/packets/WindowClick.ts b/server/packets/WindowClick.ts index d2fa058..e14b722 100644 --- a/server/packets/WindowClick.ts +++ b/server/packets/WindowClick.ts @@ -42,13 +42,19 @@ export default class PacketWindowClick implements IPacket { this.actionNumber = reader.readShort(); this.shift = reader.readBool(); this.itemId = reader.readShort(); - this.itemCount = reader.readByte(); - this.itemUses = reader.readShort(); + if (this.itemId !== -1) { + this.itemCount = reader.readByte(); + this.itemUses = reader.readShort(); + } return this; } public writeData() { - return createWriter(Endian.BE, 4).writeUByte(this.packetId).writeByte(this.windowId).writeShort(this.slot).writeBool(this.rightClick).writeShort(this.actionNumber).writeShort(this.itemId).writeByte(this.itemCount).writeShort(this.itemUses).toBuffer(); + const writer = createWriter(Endian.BE, 4).writeUByte(this.packetId).writeByte(this.windowId).writeShort(this.slot).writeBool(this.rightClick).writeShort(this.actionNumber).writeShort(this.itemId); + if (this.itemId !== -1) { + writer.writeByte(this.itemCount).writeShort(this.itemUses); + } + return writer.toBuffer(); } } \ No newline at end of file diff --git a/server/windows/Window.ts b/server/windows/Window.ts index 30fa5f5..29d231b 100644 --- a/server/windows/Window.ts +++ b/server/windows/Window.ts @@ -1,5 +1,6 @@ import InventoryType from "../enums/InventoryType"; import Inventory from "../inventories/Inventory"; +import ItemStack from "../inventories/ItemStack"; import MPClient from "../MPClient"; import PacketOpenWindow from "../packets/OpenWindow"; @@ -10,6 +11,8 @@ export default abstract class Window { public inventoryType: InventoryType; public inventory: Inventory; + public cursorItemStack?: ItemStack; + public constructor(inventoryType: InventoryType, inventory: Inventory) { this.inventoryType = inventoryType; this.inventory = inventory; diff --git a/server/windows/WindowCrafting.ts b/server/windows/WindowCrafting.ts new file mode 100644 index 0000000..ac3de72 --- /dev/null +++ b/server/windows/WindowCrafting.ts @@ -0,0 +1,10 @@ +import InventoryType from "../enums/InventoryType"; +import Inventory from "../inventories/Inventory"; +import MPClient from "../MPClient"; +import Window from "./Window"; + +export default class WindowCrafting extends Window { + public constructor(mpClient: MPClient) { + super(InventoryType.CraftingTable, new Inventory(45, "Crafting")); + } +} \ No newline at end of file