lazuli-api
Version:
Add some useful instances for Minecraft Bedrock Edition
324 lines (317 loc) • 8.79 kB
text/typescript
import { world, Player, ItemStack, GameMode, Entity } from "@minecraft/server";
import {
axeConvertBlockIds,
hoeConvertBlockIds,
shovelConvertBlockIds,
} from "lazuli-game-data";
import {
getEquipmentItem,
consumeDurability,
setEquipmentItem,
} from "lazuli-utils";
/**
* Dispose the item when entity use it.
* @param durability The durability to reduce.
* @param item The item to be used.
* @param entity The entity that used the item.
* @param event
*/
function disposeItem(
durability: number,
item: ItemStack,
entity: Entity,
event?: (holder: Entity, item: ItemStack) => void
): void {
const newItem = consumeDurability(item, durability, entity);
setEquipmentItem(entity, newItem);
if (!newItem && event) {
event(entity, item);
}
}
/**
* Define a tool tag.
* @category Need Registry
*/
export class ToolTag {
constructor(
/**
* The tool tag.
*/
public tag: string,
/**
* Additional options of the tool.
*/
public options?: ToolOptions
) {}
/**
* Automatically consume durability for the tools.
*/
listeningDurability() {
world.afterEvents.playerBreakBlock.subscribe((event) => {
const [PLAYER, ITEM] = [event.player, getEquipmentItem(event.player)];
if (ITEM?.hasTag(this.tag)) {
if (
PLAYER.getGameMode() === GameMode.survival ||
PLAYER.getGameMode() === GameMode.adventure
) {
disposeItem(1, ITEM, PLAYER, this.options?.destroyedAfterEvents);
}
}
});
world.afterEvents.entityHitEntity.subscribe((event) => {
const [ENTITY, ITEM] = [
event.damagingEntity,
getEquipmentItem(event.damagingEntity),
];
if (ITEM?.hasTag(this.tag)) {
if (ENTITY instanceof Player) {
if (
ENTITY.getGameMode() === GameMode.survival ||
ENTITY.getGameMode() === GameMode.adventure
) {
disposeItem(2, ITEM, ENTITY, this.options?.destroyedAfterEvents);
}
} else {
disposeItem(2, ITEM, ENTITY, this.options?.destroyedAfterEvents);
}
}
});
}
/**
* Consume durability when the tool use on dirts.
*/
listeningShovelDurability() {
world.afterEvents.itemUseOn.subscribe((event) => {
const [ITEM, BLOCK, PLAYER] = [
event.itemStack,
event.block,
event.source,
];
if (
ITEM.hasTag(this.tag) &&
shovelConvertBlockIds.includes(BLOCK.typeId)
) {
/**
* 锹压地的事件
*/
const newItem = consumeDurability(ITEM, 1, PLAYER);
setEquipmentItem(PLAYER, newItem);
PLAYER.playSound("step.grass");
if (!newItem && this.options?.destroyedAfterEvents) {
this.options?.destroyedAfterEvents(PLAYER, ITEM);
}
}
});
}
listeningHoeDurability() {
world.afterEvents.itemUseOn.subscribe((event) => {
const [ITEM, BLOCK, PLAYER] = [
event.itemStack,
event.block,
event.source,
];
if (ITEM.hasTag(this.tag) && hoeConvertBlockIds.includes(BLOCK.typeId)) {
/**
* 锹压地的事件
*/
const newItem = consumeDurability(ITEM, 1, PLAYER);
setEquipmentItem(PLAYER, newItem);
PLAYER.playSound("step.gravel");
if (!newItem && this.options?.destroyedAfterEvents) {
this.options?.destroyedAfterEvents(PLAYER, ITEM);
}
}
});
}
/**
* Consume durability when the tool use on logs.
*/
listeningAxeDurability() {
world.afterEvents.itemUseOn.subscribe((event) => {
const [ITEM, BLOCK, PLAYER] = [
event.itemStack,
event.block,
event.source,
];
if (ITEM.hasTag(this.tag) && axeConvertBlockIds.includes(BLOCK.typeId)) {
/**
* 斧剥皮的事件
*/
const newItem = consumeDurability(ITEM, 1, PLAYER);
setEquipmentItem(PLAYER, newItem);
PLAYER.playSound("use.wood");
if (!newItem && this.options?.destroyedAfterEvents) {
this.options?.destroyedAfterEvents(PLAYER, ITEM);
}
}
});
}
}
/**
* Define a tool.
* @category Need Registry
*/
export class ToolItem {
constructor(
/**
* Item of the weapon.
*/
public item: ItemStack,
/**
* Additional options of the tool.
*/
public options?: ToolOptions
) {
this.listeningDurability();
if (this.options?.type === ToolType.shovel) {
this.listeningShovelDurability();
}
if (this.options?.type === ToolType.axe) {
this.listeningAxeDurability();
}
}
/**
* Automatically consume durability for the tools.
*/
listeningDurability() {
world.afterEvents.playerBreakBlock.subscribe((event) => {
const [PLAYER, ITEM] = [event.player, getEquipmentItem(event.player)];
if (ITEM?.typeId === this.item.typeId) {
if (
PLAYER.getGameMode() === GameMode.survival ||
PLAYER.getGameMode() === GameMode.adventure
) {
disposeItem(2, ITEM, PLAYER, this.options?.destroyedAfterEvents);
}
}
});
world.afterEvents.entityHitEntity.subscribe((event) => {
const [ENTITY, ITEM] = [
event.damagingEntity,
getEquipmentItem(event.damagingEntity),
];
if (ITEM?.typeId === this.item.typeId) {
if (ENTITY instanceof Player) {
if (
ENTITY.getGameMode() === GameMode.survival ||
ENTITY.getGameMode() === GameMode.adventure
) {
disposeItem(2, ITEM, ENTITY, this.options?.destroyedAfterEvents);
}
} else {
disposeItem(2, ITEM, ENTITY, this.options?.destroyedAfterEvents);
}
}
});
}
listeningHoeDurability() {
world.afterEvents.itemUseOn.subscribe((event) => {
const [ITEM, BLOCK, PLAYER] = [
event.itemStack,
event.block,
event.source,
];
if (
ITEM.typeId === this.item.typeId &&
hoeConvertBlockIds.includes(BLOCK.typeId)
) {
/**
* 锹压地的事件
*/
const newItem = consumeDurability(ITEM, 1, PLAYER);
setEquipmentItem(PLAYER, newItem);
PLAYER.playSound("step.gravel");
if (!newItem && this.options?.destroyedAfterEvents) {
this.options?.destroyedAfterEvents(PLAYER, ITEM);
}
}
});
}
/**
* Consume durability when the tool use on dirts.
*/
listeningShovelDurability() {
world.afterEvents.itemUseOn.subscribe((event) => {
const [ITEM, BLOCK, PLAYER] = [
event.itemStack,
event.block,
event.source,
];
if (
ITEM.typeId === this.item.typeId &&
shovelConvertBlockIds.includes(BLOCK.typeId)
) {
/**
* 锹压地的事件
*/
const newItem = consumeDurability(ITEM, 1, PLAYER);
setEquipmentItem(PLAYER, newItem);
PLAYER.playSound("step.grass");
if (!newItem && this.options?.destroyedAfterEvents) {
this.options?.destroyedAfterEvents(PLAYER, ITEM);
}
}
});
}
/**
* Consume durability when the tool use on logs.
*/
listeningAxeDurability() {
world.afterEvents.itemUseOn.subscribe((event) => {
const [ITEM, BLOCK, PLAYER] = [
event.itemStack,
event.block,
event.source,
];
if (
ITEM.typeId === this.item.typeId &&
axeConvertBlockIds.includes(BLOCK.typeId)
) {
/**
* 斧剥皮的事件
*/
const newItem = consumeDurability(ITEM, 1, PLAYER);
setEquipmentItem(PLAYER, newItem);
PLAYER.playSound("use.wood");
if (!newItem && this.options?.destroyedAfterEvents) {
this.options?.destroyedAfterEvents(PLAYER, ITEM);
}
}
});
}
}
/**
* Type of the tool.
*/
export enum ToolType {
/**
* Define the tool is an axe.
*/
axe,
/**
* Define the tool is a shovel.
*/
shovel,
/**
* Define the tool is a hoe.
*/
hoe,
/**
* Define the tool is a pickaxe.
*/
pickaxe,
/**
* Define a custom tool.
*/
custom,
}
export interface ToolOptions {
/**
* Type of the tool.
*/
type?: ToolType;
/**
* Trigger events when the tool has been destroyed.
*/
destroyedAfterEvents?: (holder: Entity, item: ItemStack) => void;
}