2023-11-09 17:04:11 +00:00
|
|
|
import { IReader, IWriter } from "bufferstuff";
|
2023-10-29 05:08:26 +00:00
|
|
|
import { Block } from "../blocks/Block";
|
2023-11-05 00:55:23 +00:00
|
|
|
import { IEntity } from "../entities/IEntity";
|
|
|
|
import { Player } from "../entities/Player";
|
2023-10-29 05:08:26 +00:00
|
|
|
import { Item } from "../items/Item";
|
|
|
|
|
|
|
|
export class ItemStack {
|
2023-11-05 10:55:15 +00:00
|
|
|
private static ITEMSTACK_ID_ADDER = 0;
|
|
|
|
private readonly itemStackId:number;
|
|
|
|
|
2023-10-29 05:08:26 +00:00
|
|
|
public readonly itemID:number;
|
2023-11-02 08:31:43 +00:00
|
|
|
public readonly isBlock:boolean;
|
2023-10-29 05:08:26 +00:00
|
|
|
public size:number;
|
|
|
|
public damage:number;
|
|
|
|
|
2023-11-05 00:55:23 +00:00
|
|
|
private readonly maxSize:number;
|
|
|
|
private readonly maxDamage:number;
|
|
|
|
private readonly canBeDamaged:boolean;
|
|
|
|
|
2023-10-29 05:08:26 +00:00
|
|
|
public constructor(blockOrItemOrItemID:Block|Item|number, size?:number, damage?:number) {
|
|
|
|
if (blockOrItemOrItemID instanceof Block && size === undefined && damage === undefined) {
|
|
|
|
this.itemID = blockOrItemOrItemID.blockId;
|
2023-11-02 08:31:43 +00:00
|
|
|
this.size = 0;
|
2023-10-29 05:08:26 +00:00
|
|
|
this.damage = 0;
|
|
|
|
} else if (blockOrItemOrItemID instanceof Block && typeof(size) === "number" && damage === undefined) {
|
|
|
|
this.itemID = blockOrItemOrItemID.blockId;
|
|
|
|
this.size = size;
|
|
|
|
this.damage = 0;
|
|
|
|
} else if (blockOrItemOrItemID instanceof Block && typeof(size) === "number" && typeof(damage) === "number") {
|
|
|
|
this.itemID = blockOrItemOrItemID.blockId;
|
|
|
|
this.size = size;
|
|
|
|
this.damage = damage;
|
|
|
|
} else if (blockOrItemOrItemID instanceof Item && size === undefined && damage === undefined) {
|
|
|
|
this.itemID = blockOrItemOrItemID.shiftedItemID;
|
2023-11-02 08:31:43 +00:00
|
|
|
this.size = 0;
|
2023-10-29 05:08:26 +00:00
|
|
|
this.damage = 0;
|
|
|
|
} else if (blockOrItemOrItemID instanceof Item && typeof(size) === "number" && damage === undefined) {
|
|
|
|
this.itemID = blockOrItemOrItemID.shiftedItemID;
|
|
|
|
this.size = size;
|
|
|
|
this.damage = 0;
|
|
|
|
} else if (blockOrItemOrItemID instanceof Item && typeof(size) === "number" && typeof(damage) === "number") {
|
|
|
|
this.itemID = blockOrItemOrItemID.shiftedItemID;
|
|
|
|
this.size = size;
|
|
|
|
this.damage = damage;
|
|
|
|
} else if (typeof(blockOrItemOrItemID) === "number" && typeof(size) === "number" && typeof(damage) === "number") {
|
|
|
|
this.itemID = blockOrItemOrItemID;
|
|
|
|
this.size = size;
|
|
|
|
this.damage = damage;
|
2023-11-02 08:31:43 +00:00
|
|
|
} else if (typeof(blockOrItemOrItemID) === "number" && typeof(size) === "number" && damage === undefined) {
|
|
|
|
this.itemID = blockOrItemOrItemID;
|
|
|
|
this.size = size;
|
|
|
|
this.damage = 0;
|
|
|
|
} else if (typeof(blockOrItemOrItemID) === "number" && size === undefined && damage === undefined) {
|
|
|
|
this.itemID = blockOrItemOrItemID;
|
|
|
|
this.size = 0;
|
|
|
|
this.damage = 0;
|
2023-10-29 05:08:26 +00:00
|
|
|
} else {
|
|
|
|
throw new Error(`ItemStack created with invalid properties (${typeof(blockOrItemOrItemID)}, ${typeof(size)}, ${typeof(damage)})`);
|
|
|
|
}
|
2023-11-02 08:31:43 +00:00
|
|
|
|
|
|
|
this.isBlock = this.itemID < 256;
|
2023-11-05 00:55:23 +00:00
|
|
|
this.maxSize = this.isBlock ? 64 : Item.getByShiftedItemId(this.itemID).maxStackSize;
|
|
|
|
this.maxDamage = this.isBlock ? 0 : Item.getByShiftedItemId(this.itemID).maxDamage;
|
|
|
|
this.canBeDamaged = this.maxDamage > 0;
|
2023-11-05 10:55:15 +00:00
|
|
|
|
|
|
|
this.itemStackId = ItemStack.ITEMSTACK_ID_ADDER++;
|
|
|
|
}
|
|
|
|
|
2023-11-09 17:04:11 +00:00
|
|
|
public static FromSave(reader:IReader) {
|
|
|
|
const itemId = reader.readShort();
|
|
|
|
if (itemId === -1) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new ItemStack(itemId, reader.readByte(), reader.readShort());
|
|
|
|
}
|
|
|
|
|
|
|
|
public toSave(writer:IWriter) {
|
|
|
|
writer.writeShort(this.itemID)
|
|
|
|
.writeByte(this.size)
|
|
|
|
.writeShort(this.damage);
|
|
|
|
}
|
|
|
|
|
2023-11-05 10:55:15 +00:00
|
|
|
public static Compare(itemStack1:ItemStack, itemStack2:ItemStack) {
|
|
|
|
return itemStack1.itemStackId === itemStack2.itemStackId;
|
|
|
|
}
|
|
|
|
|
|
|
|
public compare(itemStack:ItemStack) {
|
|
|
|
return this.itemStackId === itemStack.itemStackId;
|
2023-11-02 08:31:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public insert(itemStack:ItemStack) {
|
|
|
|
const remainingSpace = this.spaceAvaliable;
|
|
|
|
if (remainingSpace === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remainingSpace >= itemStack.size) {
|
|
|
|
this.size += itemStack.size;
|
|
|
|
itemStack.size = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remainingSpace < itemStack.size) {
|
|
|
|
this.size += remainingSpace;
|
|
|
|
itemStack.size -= remainingSpace;
|
|
|
|
}
|
2023-11-05 00:55:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public damageItem(damageAmount:number, entity:IEntity) {
|
|
|
|
if (!this.canBeDamaged) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.damage += damageAmount;
|
|
|
|
if (this.damage > this.maxDamage) {
|
|
|
|
this.size--;
|
|
|
|
if (this.size < 0) {
|
|
|
|
this.size = 0;
|
|
|
|
}
|
|
|
|
this.damage = 0;
|
|
|
|
}
|
|
|
|
}
|
2023-11-02 08:31:43 +00:00
|
|
|
|
|
|
|
public get spaceAvaliable() {
|
|
|
|
// Stack size check for Item(s) and Block(s).
|
|
|
|
return Math.max(this.maxSize - this.size, 0);
|
2023-10-29 05:08:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
split(amount:number) {
|
|
|
|
this.size -= amount;
|
|
|
|
return new ItemStack(this.itemID, amount, this.damage);
|
|
|
|
}
|
|
|
|
}
|