make the chest gui work sorta kinda, yeah.
All checks were successful
Node.js Build / build (20.x) (push) Successful in 5m16s

This commit is contained in:
Holly Stubbs 2024-11-26 19:24:08 +00:00
parent d82b86546a
commit 6492f7c363
Signed by: tgpholly
GPG key ID: B8583C4B7D18119E
12 changed files with 118 additions and 5 deletions

8
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"bufferstuff": "^1.5.1",
"bufferstuff": "^1.7.1",
"dyetty": "^1.0.1",
"funky-array": "^1.0.0",
"hsconsole": "^1.0.2"
@ -556,9 +556,9 @@
"peer": true
},
"node_modules/bufferstuff": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/bufferstuff/-/bufferstuff-1.5.1.tgz",
"integrity": "sha512-IQF03UD+569MX80y70eOrFBhAhavEIOL12WJlVCKDSjOhCVueEY/MjwJPhW4Z1mbd9HcqEeZChldRwbqJP8k1w==",
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/bufferstuff/-/bufferstuff-1.7.1.tgz",
"integrity": "sha512-CAnj456eQCXkuUfuK1up3hICxnidz0+h8CtRghrVNo1wB0Z/zySwDWcP7vzrAjoF4xmBWMpa7e/YK8Vl2p8Jjw==",
"license": "MIT"
},
"node_modules/caniuse-lite": {

View file

@ -21,7 +21,7 @@
},
"homepage": "https://github.com/tgpholly/mc-beta-server#readme",
"dependencies": {
"bufferstuff": "^1.5.1",
"bufferstuff": "^1.7.1",
"dyetty": "^1.0.1",
"funky-array": "^1.0.0",
"hsconsole": "^1.0.2"

View file

@ -27,6 +27,10 @@ import PlayerInventory from "./inventories/PlayerInventory";
import SoundEffects from "./enums/SoundEffects";
import Vec3 from "./Vec3";
import TextColorParser from "./TextColorParser";
import FunkyArray from "funky-array";
import Window from "./windows/Window";
import WindowChest from "./windows/WindowChest";
import TileEntityChest from "./tileentities/TileEntityChest";
export default class MPClient {
private readonly mcServer:MinecraftServer;
@ -38,6 +42,8 @@ export default class MPClient {
private holdingIndex:number = 36; // First hotbar slot.
private diggingAt:Vec3;
private windows: FunkyArray<number, Window>;
public constructor(mcServer:MinecraftServer, socket:Socket, entity:Player) {
this.mcServer = mcServer;
this.socket = socket;
@ -46,6 +52,7 @@ export default class MPClient {
this.dimension = 0;
this.diggingAt = new Vec3();
this.windows = new FunkyArray<number, Window>();
}
private mapCoordsFromFace(pos:Vec3, face:number) {
@ -265,6 +272,20 @@ export default class MPClient {
this.diggingAt.set(packet.x, packet.y, packet.z);
this.mapCoordsFromFace(this.diggingAt, packet.face);
const blockClicked = Block.blocks[this.entity.world.getBlockId(packet.x, packet.y, packet.z)];
if (!this.entity.crouching && blockClicked && blockClicked.behaviour.interactable()) {
if (blockClicked.is(Block.chest)) {
const tileEntity = this.entity.world.getChunk(packet.x >> 4, packet.z >> 4).getTileEntity(packet.x, packet.y, packet.z);
if (tileEntity && tileEntity instanceof TileEntityChest) {
const window = new WindowChest(tileEntity.inventory);
this.windows.set(window.windowId, window);
window.openWindow(this);
}
}
return;
}
if (this.entity.entityAABB.intersects(AABB.getAABB(this.diggingAt.x, this.diggingAt.y, this.diggingAt.z, this.diggingAt.x + 1, this.diggingAt.y + 1, this.diggingAt.z + 1))) {
return;
}

View file

@ -159,6 +159,11 @@ export default class Block {
return this.behaviour.getBoundingBox(x, y, z);
}
// Comparison
public is(otherBlock: Block) {
return this.blockId === otherBlock.blockId;
}
// Define statics here
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");

View file

@ -9,6 +9,7 @@ export default class BlockBehaviour implements IBlockBehaviour {
public placed(world:World, x:number, y:number, z:number) {}
public destroyed(world:World, x:number, y:number, z:number) {}
public interactable() { return false; }
public neighborBlockChange(world:World, x:number, y:number, z:number, blockId:number) {}
public droppedItem(blockId:number) { return blockId; }
public droppedCount(blockId:number) { return 1; }

View file

@ -13,4 +13,8 @@ export default class BlockBehaviourChest extends BlockBehaviour {
const chunk = world.getChunk(x >> 4, z >> 4);
chunk.removeTileEntity(x, y, z);
}
public interactable() {
return true;
}
}

View file

@ -8,6 +8,7 @@ export default interface IBlockBehaviour {
placed(world:World, x:number, y:number, z:number): void,
destroyed(world:World, x:number, y:number, z:number): void,
interactable(): boolean,
neighborBlockChange(world:World, x:number, y:number, z:number, blockId:number): void,
droppedItem: (blockId:number) => number,
droppedCount: (blockId:number) => number,

View file

@ -0,0 +1,8 @@
enum InventoryType {
Chest = 0,
Workbench = 1,
Furnace = 2,
Dispenser = 3
}
export default InventoryType;

View file

@ -43,6 +43,7 @@ enum Packet {
EntityLookRelativeMove = 0x21,
EntityTeleport = 0x22,
OpenWindow = 0x64,
CloseWindow = 0x65,
WindowClick = 0x66,
SetSlot = 0x67,

View file

@ -0,0 +1,39 @@
import { createWriter, Endian, IReader } from "bufferstuff";
import InventoryType from "../enums/InventoryType";
import Packet from "../enums/Packet";
import IPacket from "./IPacket";
export default class PacketOpenWindow implements IPacket {
public packetId = Packet.OpenWindow;
public windowId:number;
public inventoryType:InventoryType;
public windowTitle: string;
public numberOfSlots: number;
public constructor(windowId?: number, inventoryType?: InventoryType, windowTitle?: string, numberOfSlots?: number) {
if (typeof(windowId) === "number" && typeof(inventoryType) === "number" && typeof(windowTitle) === "string" && typeof(numberOfSlots) === "number") {
this.windowId = windowId;
this.inventoryType = inventoryType;
this.windowTitle = windowTitle;
this.numberOfSlots = numberOfSlots;
} else {
this.windowId = Number.MIN_VALUE;
this.inventoryType = Number.MIN_VALUE;
this.windowTitle = "";
this.numberOfSlots = Number.MIN_VALUE;
}
}
public readData(reader: IReader) {
this.windowId = reader.readByte();
this.inventoryType = reader.readByte();
this.windowTitle = reader.readString();
this.numberOfSlots = reader.readByte();
return this;
}
public writeData() {
return createWriter(Endian.BE).writeUByte(this.packetId).writeByte(this.windowId).writeByte(this.inventoryType).writeJavaUTF(this.windowTitle).writeByte(this.numberOfSlots).toBuffer();
}
}

24
server/windows/Window.ts Normal file
View file

@ -0,0 +1,24 @@
import InventoryType from "../enums/InventoryType";
import Inventory from "../inventories/Inventory";
import MPClient from "../MPClient";
import PacketOpenWindow from "../packets/OpenWindow";
export default abstract class Window {
public static WINDOW_GLOBAL_COUNTER = 1;
public windowId = Window.WINDOW_GLOBAL_COUNTER++;
public inventoryType: InventoryType;
public inventory: Inventory;
public constructor(inventoryType: InventoryType, inventory: Inventory) {
this.inventoryType = inventoryType;
this.inventory = inventory;
}
openWindow(mpClient: MPClient) {
const windowPacket = new PacketOpenWindow(this.windowId, this.inventoryType, this.inventory.getInventoryName(), this.inventory.getInventorySize()).writeData();
//const inventoryDataPayload = this.inventory.constructInventoryPayload();
//mpClient.send(Buffer.concat([ windowPacket, inventoryDataPayload ], windowPacket.length + inventoryDataPayload.length));
mpClient.send(windowPacket);
}
}

View file

@ -0,0 +1,9 @@
import InventoryType from "../enums/InventoryType";
import Inventory from "../inventories/Inventory";
import Window from "./Window";
export default class WindowChest extends Window {
public constructor(inventory: Inventory) {
super(InventoryType.Chest, inventory);
}
}