import { Identifier, Hand, ActionResult, Pos, Direction, SimpleRegistry } from './core'; import { World } from './world'; import { PlayerEntity, LivingEntity } from './entity'; import { CompoundTag } from './tag'; import { useBridge, addBridge } from 'scriptcraft-core'; /** * Item Stack */ export class ItemStack { /** * @internal */ readonly javaObject: JavaObject; /** * @internal */ constructor(obj: JavaObject) { this.javaObject = obj; } /** * Create Item Stack * @param item Item ID * @param count Item Count */ static create(item: Identifier, count?: number): ItemStack { const obj = useBridge('ItemStack.create', item.toString(), count ? count : 1) as JavaObject; if (obj !== null) { return new ItemStack(obj); } else { return null; } } /** * Get Item ID * @returns Item ID */ getItem(): Identifier { const obj = useBridge('ItemStack.getItem', this.javaObject) as string; if (obj !== null) { return new Identifier(obj); } else { return null; } } /** * Get Custom Item * @returns Custom Item */ getCustomItem(): CustomItem { return ItemRegistry.INSTANCE.get(this.getItem()); } /** * Get Item Count * @returns Item Count */ getCount(): number { return useBridge('ItemStack.getCount', this.javaObject) as number; } /** * Set Item Count * @param count New Count */ setCount(count: number): void { useBridge('ItemStack.setCount', this.javaObject, count); } /** * Get Item Damage * @returns Item Damage */ getDamage(): number { return useBridge('ItemStack.getDamage', this.javaObject) as number; } /** * Set Item Damage * @param count New Damage */ setDamage(damage: number): void { useBridge('ItemStack.setDamage', this.javaObject, damage); } /** * Is Item Damageable * @returns TRUE If Item Is Damageable, Otherwise FALSE */ isDamageable(): boolean { return useBridge('ItemStack.isDamageable', this.javaObject) as boolean; } /** * Get Item Tag * @returns Item Tag */ getTag(): CompoundTag { const obj = useBridge('ItemStack.getTag', this.javaObject) as JavaObject; if (obj !== null) { return new CompoundTag(obj); } else { return null; } } /** * Set Item Tag * @param tag New Item Tag */ setTag(tag: CompoundTag): void { useBridge('ItemStack.setTag', this.javaObject, tag.javaObject); } /** * Convert To Tag * @returns Item Tag */ toTag(): CompoundTag { const obj = useBridge('ItemStack.toTag', this.javaObject) as JavaObject; if (obj !== null) { return new CompoundTag(obj); } else { return null; } } /** * Create From Tag * @param tag Item Tag * @returns Item Stack */ static fromTag(tag: CompoundTag): ItemStack { const obj = useBridge('ItemStack.fromTag', tag.javaObject) as JavaObject; if (obj !== null) { return new ItemStack(obj); } else { return null; } } /** * Split Item Stack * @param amount Amount * @returns New Item Stack */ split(amount: number): ItemStack { const obj = useBridge('ItemStack.split', this.javaObject, amount) as JavaObject; if (obj !== null) { return new ItemStack(obj); } else { return null; } } } /** * Item Rarity */ export enum ItemRarity { COMMON = 'COMMON', UNCOMMON = 'UNCOMMON', RARE = 'RARE', EPIC = 'EPIC' } /** * Settings for {@link CustomItem} and {@link BlockItem} */ export class ItemSettings { #maxCount: number; #itemGroup: string; #rarity: ItemRarity; /** * Create Item Settings */ constructor() { this.#maxCount = 64; this.#rarity = ItemRarity.COMMON; } /** * Set Max Count * @param maxCount Max Count */ setMaxCount(maxCount: number): ItemSettings { this.#maxCount = maxCount; return this; } /** * Set Item Group * @param itemGroup Item Group */ setItemGroup(itemGroup: string | Identifier): ItemSettings { this.#itemGroup = itemGroup.toString(); return this; } /** * Set Item Rarity * @param rarity Item Rarity */ setRarity(rarity: ItemRarity): ItemSettings { this.#rarity = rarity; return this; } /** * @internal */ createJavaObject(): JavaObject { return useBridge('ItemSettings.create', this.#maxCount, this.#rarity, this.#itemGroup) as JavaObject; } } /** * Custom Item */ export class CustomItem { /** * @internal */ readonly settings: ItemSettings; /** * Create Custom Item * @param settings Item Settings */ constructor(settings: ItemSettings) { this.settings = settings; } /** * Called When The Item Is Used * @param world World * @param player Player * @param hand Hand * @returns Action Result */ onUse(world: World, player: PlayerEntity, hand: Hand): ActionResult { return ActionResult.PASS; } /** * Called When The Item Is Used On A Block * @param world World * @param pos Block Position * @param side Side Of The Block Used * @param player Player * @param hand Hand * @returns Action Result */ onUseOnBlock(world: World, pos: Pos, side: Direction, player: PlayerEntity, hand: Hand): ActionResult { return ActionResult.PASS; } /** * Called When The Item Is Used On An Entity * @param player Player * @param target Target Entity * @param hand Hand * @returns Action Result */ onUseOnEntity(player: PlayerEntity, target: LivingEntity, hand: Hand): ActionResult { return ActionResult.PASS; } } /** * Block Item */ export class BlockItem { /** * @internal */ readonly settings: ItemSettings; /** * @internal */ readonly block: Identifier; /** * Create Block Item * @param block Block ID * @param settings Item Settings */ constructor(block: Identifier, settings: ItemSettings) { this.settings = settings; this.block = block; } } /** * @internal */ export class ItemRegistry implements SimpleRegistry { static readonly INSTANCE = new ItemRegistry(); readonly #items: Map; private constructor() { this.#items = new Map(); } register(id: Identifier, obj: CustomItem | BlockItem): void { if (obj instanceof CustomItem) { this.#items.set(id.toString(), obj); useBridge('Registry.registerItem', id.toString(), obj.settings.createJavaObject()); } else { useBridge('Registry.registerBlockItem', id.toString(), obj.settings.createJavaObject(), obj.block.toString()); } } get(id: Identifier): CustomItem { return this.#items.get(id.toString()); } getID(obj: CustomItem): Identifier { for (const item of this.#items) { if (item[1] === obj) { return new Identifier(item[0]); } } return null; } } addBridge('CustomItem.onUse', (id: string, world: JavaObject, player: JavaObject, hand: keyof typeof Hand): string => { return ItemRegistry.INSTANCE.get(new Identifier(id)).onUse(new World(world), new PlayerEntity(player), Hand[hand]); }); addBridge('CustomItem.onUseOnBlock', (id: string, world: JavaObject, x: number, y: number, z: number, side: keyof typeof Direction, player: JavaObject, hand: keyof typeof Hand): string => { return ItemRegistry.INSTANCE.get(new Identifier(id)).onUseOnBlock(new World(world), new Pos(x, y, z), Direction[side], new PlayerEntity(player), Hand[hand]); }); addBridge('CustomItem.onUseOnEntity', (id: string, player: JavaObject, target: JavaObject, hand: keyof typeof Hand): boolean => { return ItemRegistry.INSTANCE.get(new Identifier(id)).onUseOnEntity(new PlayerEntity(player), new LivingEntity(target), Hand[hand]) === ActionResult.SUCCESS; });