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 WindowCrafting from "./windows/WindowCrafting";
|
||||
import PacketWindowClick from "./packets/WindowClick";
|
||||
import PlayerCombinedInventory from "./inventories/PlayerCombinedInventory";
|
||||
|
||||
export default class MPClient {
|
||||
private readonly mcServer:MinecraftServer;
|
||||
|
@ -280,12 +281,12 @@ export default class MPClient {
|
|||
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);
|
||||
const window = new WindowChest(PlayerCombinedInventory.FromExisting(this, tileEntity.inventory, tileEntity.inventory.name));
|
||||
this.windows.set(window.windowId, window);
|
||||
window.openWindow(this);
|
||||
}
|
||||
} 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);
|
||||
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());
|
||||
|
||||
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 {
|
||||
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 itemStacks:Array<ItemStack | null>;
|
||||
|
||||
private size:number;
|
||||
private name:string;
|
||||
public readonly size:number;
|
||||
public readonly name:string;
|
||||
|
||||
public constructor(size:number, name:string) {
|
||||
this.changeHandlers = new FunkyArray<number, (itemStack: ItemStack) => void>();
|
||||
|
@ -55,18 +55,13 @@ export default class Inventory implements IInventory {
|
|||
}
|
||||
|
||||
addItemStack(itemStack:ItemStack) {
|
||||
throw new Error("Adding items to non player inventories is unimplemented.");
|
||||
// Check bottom inventory row (hotbar) first.
|
||||
/*let workingItemStack:ItemStack | null;
|
||||
for (let slotId = 9; slotId <= 35; slotId++) {
|
||||
for (let slotId = 0; slotId < this.itemStacks.length; slotId++) {
|
||||
if (itemStack.size === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((workingItemStack = this.itemStacks[slotId]) != null) {
|
||||
workingItemStack.insert(itemStack);
|
||||
this.itemStacks[slotId]?.insert(itemStack);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
getInventoryName() {
|
||||
|
@ -100,9 +95,10 @@ export default class Inventory implements IInventory {
|
|||
return this;
|
||||
}
|
||||
|
||||
private calculateInventoryPayloadSize() {
|
||||
public calculateInventoryPayloadSize(skip: number) {
|
||||
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) {
|
||||
bufferSize += 5; // short + byte + short
|
||||
} else {
|
||||
|
@ -112,9 +108,10 @@ export default class Inventory implements IInventory {
|
|||
return bufferSize;
|
||||
}
|
||||
|
||||
constructInventoryPayload() {
|
||||
const writer = createWriter(Endian.BE, this.calculateInventoryPayloadSize());
|
||||
for (const stack of this.itemStacks) {
|
||||
constructInventoryPayload(skip: number) {
|
||||
const writer = createWriter(Endian.BE, this.calculateInventoryPayloadSize(skip));
|
||||
for (let i = skip; i < this.itemStacks.length; i++) {
|
||||
const stack = this.itemStacks[i];
|
||||
writer.writeShort(stack == null ? -1 : stack.itemID);
|
||||
if (stack != null) {
|
||||
writer.writeByte(stack.size);
|
||||
|
|
|
@ -1,16 +1,93 @@
|
|||
import { createWriter, Endian } from "bufferstuff";
|
||||
import MPClient from "../MPClient";
|
||||
import Inventory from "./Inventory";
|
||||
import ItemStack from "./ItemStack";
|
||||
|
||||
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);
|
||||
|
||||
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 PacketWindowItems from "../packets/WindowItems";
|
||||
import Player from "../entities/Player";
|
||||
import { createWriter, Endian } from "bufferstuff";
|
||||
|
||||
export default class PlayerInventory extends Inventory {
|
||||
private player:Player;
|
||||
|
|
|
@ -1,27 +1,44 @@
|
|||
import InventoryType from "../enums/InventoryType";
|
||||
import Inventory from "../inventories/Inventory";
|
||||
import ItemStack from "../inventories/ItemStack";
|
||||
import PlayerCombinedInventory from "../inventories/PlayerCombinedInventory";
|
||||
import MPClient from "../MPClient";
|
||||
import PacketOpenWindow from "../packets/OpenWindow";
|
||||
import PacketWindowItems from "../packets/WindowItems";
|
||||
|
||||
export default abstract class Window {
|
||||
public static WINDOW_GLOBAL_COUNTER = 1;
|
||||
|
||||
public readonly inventorySize: number;
|
||||
|
||||
public windowId = Window.WINDOW_GLOBAL_COUNTER++;
|
||||
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.inventory = inventory;
|
||||
|
||||
this.cursorItemStack = null;
|
||||
}
|
||||
|
||||
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);
|
||||
const windowItems = new PacketWindowItems(this.windowId, this.inventorySize, this.inventory.constructInventoryPayload()).writeData();
|
||||
mpClient.send(Buffer.concat([ windowPacket, windowItems ], windowPacket.length + windowItems.length));
|
||||
//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 Inventory from "../inventories/Inventory";
|
||||
import PlayerCombinedInventory from "../inventories/PlayerCombinedInventory";
|
||||
import Window from "./Window";
|
||||
|
||||
export default class WindowChest extends Window {
|
||||
public constructor(inventory: Inventory) {
|
||||
super(InventoryType.Chest, inventory);
|
||||
public constructor(inventory: PlayerCombinedInventory) {
|
||||
super(InventoryType.Chest, inventory, 62);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
import InventoryType from "../enums/InventoryType";
|
||||
import Inventory from "../inventories/Inventory";
|
||||
import PlayerCombinedInventory from "../inventories/PlayerCombinedInventory";
|
||||
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"));
|
||||
public constructor(inventory: PlayerCombinedInventory) {
|
||||
super(InventoryType.CraftingTable, inventory, 45);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue