chests work better i suppose, but it crashes now :c
All checks were successful
Node.js Build / build (20.x) (push) Successful in 5m16s
All checks were successful
Node.js Build / build (20.x) (push) Successful in 5m16s
This commit is contained in:
parent
65d31be4f9
commit
7c59d531ae
8 changed files with 128 additions and 33 deletions
|
@ -33,6 +33,7 @@ import WindowChest from "./windows/WindowChest";
|
||||||
import TileEntityChest from "./tileentities/TileEntityChest";
|
import TileEntityChest from "./tileentities/TileEntityChest";
|
||||||
import WindowCrafting from "./windows/WindowCrafting";
|
import WindowCrafting from "./windows/WindowCrafting";
|
||||||
import PacketWindowClick from "./packets/WindowClick";
|
import PacketWindowClick from "./packets/WindowClick";
|
||||||
|
import PlayerCombinedInventory from "./inventories/PlayerCombinedInventory";
|
||||||
|
|
||||||
export default class MPClient {
|
export default class MPClient {
|
||||||
private readonly mcServer:MinecraftServer;
|
private readonly mcServer:MinecraftServer;
|
||||||
|
@ -280,12 +281,12 @@ export default class MPClient {
|
||||||
if (blockClicked.is(Block.chest)) {
|
if (blockClicked.is(Block.chest)) {
|
||||||
const tileEntity = this.entity.world.getChunk(packet.x >> 4, packet.z >> 4).getTileEntity(packet.x, packet.y, packet.z);
|
const tileEntity = this.entity.world.getChunk(packet.x >> 4, packet.z >> 4).getTileEntity(packet.x, packet.y, packet.z);
|
||||||
if (tileEntity && tileEntity instanceof TileEntityChest) {
|
if (tileEntity && tileEntity instanceof TileEntityChest) {
|
||||||
const window = new WindowChest(tileEntity.inventory);
|
const window = new WindowChest(PlayerCombinedInventory.FromExisting(this, tileEntity.inventory, tileEntity.inventory.name));
|
||||||
this.windows.set(window.windowId, window);
|
this.windows.set(window.windowId, window);
|
||||||
window.openWindow(this);
|
window.openWindow(this);
|
||||||
}
|
}
|
||||||
} else if (blockClicked.is(Block.craftingTable)) {
|
} else if (blockClicked.is(Block.craftingTable)) {
|
||||||
const window = new WindowCrafting(this);
|
const window = new WindowCrafting(new PlayerCombinedInventory(this, 10, "Crafting"));
|
||||||
this.windows.set(window.windowId, window);
|
this.windows.set(window.windowId, window);
|
||||||
window.openWindow(this);
|
window.openWindow(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,7 +248,7 @@ export default class MinecraftServer {
|
||||||
socket.write(new PacketPlayerPositionLook(clientEntity.position.x, clientEntity.position.y, clientEntity.position.y + 0.62, clientEntity.position.z, 0, 0, false).writeData());
|
socket.write(new PacketPlayerPositionLook(clientEntity.position.x, clientEntity.position.y, clientEntity.position.y + 0.62, clientEntity.position.z, 0, 0, false).writeData());
|
||||||
|
|
||||||
const playerInventory = clientEntity.inventory;
|
const playerInventory = clientEntity.inventory;
|
||||||
socket.write(new PacketWindowItems(0, playerInventory.getInventorySize(), playerInventory.constructInventoryPayload()).writeData());
|
socket.write(new PacketWindowItems(0, playerInventory.getInventorySize(), playerInventory.constructInventoryPayload(0)).writeData());
|
||||||
} else {
|
} else {
|
||||||
socket.write(new PacketDisconnectKick("Failed to find world to put player in.").writeData());
|
socket.write(new PacketDisconnectKick("Failed to find world to put player in.").writeData());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ export default class Inventory implements IInventory {
|
||||||
public changeHandlers:FunkyArray<number, (itemStack: ItemStack) => void>;
|
public changeHandlers:FunkyArray<number, (itemStack: ItemStack) => void>;
|
||||||
public itemStacks:Array<ItemStack | null>;
|
public itemStacks:Array<ItemStack | null>;
|
||||||
|
|
||||||
private size:number;
|
public readonly size:number;
|
||||||
private name:string;
|
public readonly name:string;
|
||||||
|
|
||||||
public constructor(size:number, name:string) {
|
public constructor(size:number, name:string) {
|
||||||
this.changeHandlers = new FunkyArray<number, (itemStack: ItemStack) => void>();
|
this.changeHandlers = new FunkyArray<number, (itemStack: ItemStack) => void>();
|
||||||
|
@ -55,18 +55,13 @@ export default class Inventory implements IInventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
addItemStack(itemStack:ItemStack) {
|
addItemStack(itemStack:ItemStack) {
|
||||||
throw new Error("Adding items to non player inventories is unimplemented.");
|
for (let slotId = 0; slotId < this.itemStacks.length; slotId++) {
|
||||||
// Check bottom inventory row (hotbar) first.
|
|
||||||
/*let workingItemStack:ItemStack | null;
|
|
||||||
for (let slotId = 9; slotId <= 35; slotId++) {
|
|
||||||
if (itemStack.size === 0) {
|
if (itemStack.size === 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((workingItemStack = this.itemStacks[slotId]) != null) {
|
this.itemStacks[slotId]?.insert(itemStack);
|
||||||
workingItemStack.insert(itemStack);
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getInventoryName() {
|
getInventoryName() {
|
||||||
|
@ -100,9 +95,10 @@ export default class Inventory implements IInventory {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateInventoryPayloadSize() {
|
public calculateInventoryPayloadSize(skip: number) {
|
||||||
let bufferSize = 0;
|
let bufferSize = 0;
|
||||||
for (const stack of this.itemStacks) {
|
for (let i = skip; i < this.itemStacks.length; i++) {
|
||||||
|
const stack = this.itemStacks[i];
|
||||||
if (stack) {
|
if (stack) {
|
||||||
bufferSize += 5; // short + byte + short
|
bufferSize += 5; // short + byte + short
|
||||||
} else {
|
} else {
|
||||||
|
@ -112,9 +108,10 @@ export default class Inventory implements IInventory {
|
||||||
return bufferSize;
|
return bufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructInventoryPayload() {
|
constructInventoryPayload(skip: number) {
|
||||||
const writer = createWriter(Endian.BE, this.calculateInventoryPayloadSize());
|
const writer = createWriter(Endian.BE, this.calculateInventoryPayloadSize(skip));
|
||||||
for (const stack of this.itemStacks) {
|
for (let i = skip; i < this.itemStacks.length; i++) {
|
||||||
|
const stack = this.itemStacks[i];
|
||||||
writer.writeShort(stack == null ? -1 : stack.itemID);
|
writer.writeShort(stack == null ? -1 : stack.itemID);
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
writer.writeByte(stack.size);
|
writer.writeByte(stack.size);
|
||||||
|
|
|
@ -1,16 +1,93 @@
|
||||||
|
import { createWriter, Endian } from "bufferstuff";
|
||||||
|
import MPClient from "../MPClient";
|
||||||
import Inventory from "./Inventory";
|
import Inventory from "./Inventory";
|
||||||
import ItemStack from "./ItemStack";
|
import ItemStack from "./ItemStack";
|
||||||
|
|
||||||
export default class PlayerCombinedInventory extends Inventory {
|
export default class PlayerCombinedInventory extends Inventory {
|
||||||
private combinedInventoryChangeHandlerHandle: number;
|
private static PLAYER_INVENTORY_OFFSET = 10;
|
||||||
|
|
||||||
public constructor(size: number, name: string) {
|
private mpClient: MPClient;
|
||||||
|
|
||||||
|
public constructor(mpClient:MPClient, size: number, name: string) {
|
||||||
super(size, name);
|
super(size, name);
|
||||||
|
|
||||||
this.combinedInventoryChangeHandlerHandle = this.registerChangeHandler(this.onInventoryChange);
|
this.mpClient = mpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onInventoryChange(itemStack: ItemStack) {
|
private getSlotId(slotId: number) {
|
||||||
|
if (slotId > this.size - 1) {
|
||||||
|
return slotId + PlayerCombinedInventory.PLAYER_INVENTORY_OFFSET;
|
||||||
|
} else {
|
||||||
|
return slotId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FromExisting(mpClient: MPClient, inventory: Inventory, name: string) {
|
||||||
|
const linkedInventory = new PlayerCombinedInventory(mpClient, inventory.size, name);
|
||||||
|
linkedInventory.itemStacks = inventory.itemStacks;
|
||||||
|
return linkedInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItemStack(itemStack:ItemStack) {
|
||||||
|
for (let slotId = 0; slotId < this.itemStacks.length; slotId++) {
|
||||||
|
if (itemStack.size === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.itemStacks[slotId]?.insert(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemStack.size === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let slotId = 0; slotId < this.mpClient.entity.inventory.itemStacks.length; slotId++) {
|
||||||
|
if (itemStack.size === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mpClient.entity.inventory.itemStacks[slotId]?.insert(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getInventorySize() {
|
||||||
|
// return this.itemStacks.length + this.mpClient.entity.inventory.itemStacks.length;
|
||||||
|
// }
|
||||||
|
|
||||||
|
getSlotItemStack(slotId:number) {
|
||||||
|
return this.itemStacks[slotId] ?? this.mpClient.entity.inventory.itemStacks[this.getSlotId(slotId)];
|
||||||
|
}
|
||||||
|
|
||||||
|
dropEmptyItemStacks() {
|
||||||
|
super.dropEmptyItemStacks();
|
||||||
|
this.mpClient.entity.inventory.dropEmptyItemStacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
setSlotItemStack(slotId:number, itemStack: ItemStack | null) {
|
||||||
|
if (slotId > this.size - 1) {
|
||||||
|
this.mpClient.entity.inventory.setSlotItemStack(this.getSlotId(slotId), itemStack);
|
||||||
|
} else {
|
||||||
|
super.setSlotItemStack(slotId, itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructInventoryPayload() {
|
||||||
|
const thisInventoryPayload = super.constructInventoryPayload(0);
|
||||||
|
const playerInventoryPayload = this.mpClient.entity.inventory.constructInventoryPayload(PlayerCombinedInventory.PLAYER_INVENTORY_OFFSET);
|
||||||
|
return Buffer.concat([thisInventoryPayload, playerInventoryPayload], thisInventoryPayload.length + playerInventoryPayload.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructInventorySinglePayload(slotId:number) {
|
||||||
|
const stack = this.itemStacks[slotId] ?? this.mpClient.entity.inventory.itemStacks[this.getSlotId(slotId)];
|
||||||
|
const writer = createWriter(Endian.BE, stack == null ? 2 : 5);
|
||||||
|
writer.writeShort(stack == null ? -1 : stack.itemID);
|
||||||
|
if (stack != null) {
|
||||||
|
writer.writeByte(stack.size);
|
||||||
|
writer.writeShort(stack.damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return writer.toBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ import ItemStack from "./ItemStack";
|
||||||
import PacketSetSlot from "../packets/SetSlot";
|
import PacketSetSlot from "../packets/SetSlot";
|
||||||
import PacketWindowItems from "../packets/WindowItems";
|
import PacketWindowItems from "../packets/WindowItems";
|
||||||
import Player from "../entities/Player";
|
import Player from "../entities/Player";
|
||||||
|
import { createWriter, Endian } from "bufferstuff";
|
||||||
|
|
||||||
export default class PlayerInventory extends Inventory {
|
export default class PlayerInventory extends Inventory {
|
||||||
private player:Player;
|
private player:Player;
|
||||||
|
|
|
@ -1,27 +1,44 @@
|
||||||
import InventoryType from "../enums/InventoryType";
|
import InventoryType from "../enums/InventoryType";
|
||||||
import Inventory from "../inventories/Inventory";
|
import Inventory from "../inventories/Inventory";
|
||||||
import ItemStack from "../inventories/ItemStack";
|
import ItemStack from "../inventories/ItemStack";
|
||||||
|
import PlayerCombinedInventory from "../inventories/PlayerCombinedInventory";
|
||||||
import MPClient from "../MPClient";
|
import MPClient from "../MPClient";
|
||||||
import PacketOpenWindow from "../packets/OpenWindow";
|
import PacketOpenWindow from "../packets/OpenWindow";
|
||||||
|
import PacketWindowItems from "../packets/WindowItems";
|
||||||
|
|
||||||
export default abstract class Window {
|
export default abstract class Window {
|
||||||
public static WINDOW_GLOBAL_COUNTER = 1;
|
public static WINDOW_GLOBAL_COUNTER = 1;
|
||||||
|
|
||||||
|
public readonly inventorySize: number;
|
||||||
|
|
||||||
public windowId = Window.WINDOW_GLOBAL_COUNTER++;
|
public windowId = Window.WINDOW_GLOBAL_COUNTER++;
|
||||||
public inventoryType: InventoryType;
|
public inventoryType: InventoryType;
|
||||||
public inventory: Inventory;
|
public inventory: PlayerCombinedInventory;
|
||||||
|
|
||||||
public cursorItemStack?: ItemStack;
|
public cursorItemStack: ItemStack | null;
|
||||||
|
|
||||||
|
public constructor(inventoryType: InventoryType, inventory: PlayerCombinedInventory, inventorySize: number) {
|
||||||
|
this.inventorySize = inventorySize;
|
||||||
|
|
||||||
public constructor(inventoryType: InventoryType, inventory: Inventory) {
|
|
||||||
this.inventoryType = inventoryType;
|
this.inventoryType = inventoryType;
|
||||||
this.inventory = inventory;
|
this.inventory = inventory;
|
||||||
|
|
||||||
|
this.cursorItemStack = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
openWindow(mpClient: MPClient) {
|
openWindow(mpClient: MPClient) {
|
||||||
const windowPacket = new PacketOpenWindow(this.windowId, this.inventoryType, this.inventory.getInventoryName(), this.inventory.getInventorySize()).writeData();
|
const windowPacket = new PacketOpenWindow(this.windowId, this.inventoryType, this.inventory.getInventoryName(), this.inventory.getInventorySize()).writeData();
|
||||||
//const inventoryDataPayload = this.inventory.constructInventoryPayload();
|
const windowItems = new PacketWindowItems(this.windowId, this.inventorySize, this.inventory.constructInventoryPayload()).writeData();
|
||||||
//mpClient.send(Buffer.concat([ windowPacket, inventoryDataPayload ], windowPacket.length + inventoryDataPayload.length));
|
mpClient.send(Buffer.concat([ windowPacket, windowItems ], windowPacket.length + windowItems.length));
|
||||||
mpClient.send(windowPacket);
|
//mpClient.send(windowPacket);
|
||||||
|
//mpClient.send(inventoryDataPayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
clickedWindow(slotId: number, rightClick: boolean) {
|
||||||
|
if (this.cursorItemStack) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.cursorItemStack = this.inventory.getSlotItemStack(slotId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
import InventoryType from "../enums/InventoryType";
|
import InventoryType from "../enums/InventoryType";
|
||||||
import Inventory from "../inventories/Inventory";
|
import Inventory from "../inventories/Inventory";
|
||||||
|
import PlayerCombinedInventory from "../inventories/PlayerCombinedInventory";
|
||||||
import Window from "./Window";
|
import Window from "./Window";
|
||||||
|
|
||||||
export default class WindowChest extends Window {
|
export default class WindowChest extends Window {
|
||||||
public constructor(inventory: Inventory) {
|
public constructor(inventory: PlayerCombinedInventory) {
|
||||||
super(InventoryType.Chest, inventory);
|
super(InventoryType.Chest, inventory, 62);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
import InventoryType from "../enums/InventoryType";
|
import InventoryType from "../enums/InventoryType";
|
||||||
import Inventory from "../inventories/Inventory";
|
import Inventory from "../inventories/Inventory";
|
||||||
|
import PlayerCombinedInventory from "../inventories/PlayerCombinedInventory";
|
||||||
import MPClient from "../MPClient";
|
import MPClient from "../MPClient";
|
||||||
import Window from "./Window";
|
import Window from "./Window";
|
||||||
|
|
||||||
export default class WindowCrafting extends Window {
|
export default class WindowCrafting extends Window {
|
||||||
public constructor(mpClient: MPClient) {
|
public constructor(inventory: PlayerCombinedInventory) {
|
||||||
super(InventoryType.CraftingTable, new Inventory(45, "Crafting"));
|
super(InventoryType.CraftingTable, inventory, 45);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue