lazuli-api
Version:
Add some useful instances for Minecraft Bedrock Edition
422 lines (416 loc) • 12 kB
text/typescript
import { Entity, Player, system, world } from "@minecraft/server";
import {
Article,
ArticleCollection,
Boss,
ChapterArticle,
ChapterQuestBook,
CustomBlockComponent,
CustomItemComponent,
DurabilityLimitedProp,
FoodItem,
GiftItem,
NumberLimitedProp,
PercentGiftItem,
Prop,
Quest,
QuestBoard,
QuestBook,
ToolItem,
ToolTag,
ToolType,
WeaponItem,
WeaponTag,
WeightGiftItem,
} from "../..";
import { EffectData } from "lazuli-common";
import { consumeDurability, setEquipmentItem } from "lazuli-utils";
/**
* Registried Boss
* @param boss
* @param entity
*/
function registriedBoss(boss: Boss, entity: Entity) {
// Tirgger music
if (entity.typeId === boss.typeId && boss.music) {
const MUSIC = boss.music;
const players: Player[] = [];
entity.dimension
.getEntities({
location: entity.location,
minDistance: 0,
maxDistance: MUSIC.radius,
})
.forEach((entity) => {
if (entity instanceof Player) {
entity.playMusic(MUSIC.trackId, { loop: true });
players.push(entity);
}
});
world.afterEvents.entityDie.subscribe((event) => {
if (event.deadEntity.id === entity.id) {
players.forEach((player) => {
player.stopMusic();
});
}
});
world.afterEvents.entityRemove.subscribe((event) => {
if (event.removedEntityId === entity.id) {
players.forEach((player) => {
player.stopMusic();
});
}
});
// Start skills
if (
entity.typeId === boss.typeId &&
!entity.getDynamicProperty("lazuli:start_skill")
) {
entity.setDynamicProperty("lazuli:start_skill", true);
boss.skills.forEach((skill) => {
let handle = system.runInterval(() => {
skill.unleashArray(
entity.dimension.getEntities({
location: entity.location,
minDistance: 0,
maxDistance: skill.radius,
}),
entity
);
}, skill.cooldownTime);
world.afterEvents.entityDie.subscribe((event) => {
if (event.deadEntity.id === entity.id) {
system.clearRun(handle);
}
});
world.afterEvents.entityRemove.subscribe((event) => {
if (event.removedEntityId === entity.id) {
system.clearRun(handle);
}
});
});
}
}
}
/**
* Registired Display.
* @param item
*/
function registriedDisplay(item: ArticleCollection | QuestBoard) {
if (item.displayCondition.default === true) {
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.id) item.display(event.source);
});
}
if (item.displayCondition.firstLoad === true) {
world.afterEvents.playerSpawn.subscribe((event) => {
if (event.initialSpawn) item.display(event.player);
});
}
if (item.displayCondition.itemStack) {
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.displayCondition.itemStack?.typeId)
item.display(event.source);
});
}
if (item.displayCondition.command) {
const options = item.displayCondition.command;
world.beforeEvents.chatSend.subscribe((event) => {
if (typeof options === "string") {
if (event.message === options) {
event.cancel = true;
system.runTimeout(() => {
item.display(event.sender);
}, 20);
}
} else if (options.includes(event.message)) {
event.cancel = true;
system.runTimeout(() => {
item.display(event.sender);
}, 20);
}
});
}
}
export type NeedRegistiy =
| Article
| ArticleCollection
| Boss
| ChapterArticle
| ChapterQuestBook
| CustomBlockComponent
| CustomItemComponent
| FoodItem
| GiftItem
| Prop
| Quest
| QuestBoard
| QuestBook
| ToolItem
| ToolTag
| ToolType
| WeaponItem
| WeaponTag;
/**
* Union register for api instances.
* @category Registry
*/
class BaseRegister {
private constructor() {}
/**
* Registry the food item.
* @param item
*/
static foodRegistry(item: FoodItem): void {
world.afterEvents.itemCompleteUse.subscribe((event) => {
const [PLAYER, ITEM] = [event.source, event.itemStack];
if (ITEM.typeId === item.typeId) {
item.statusEffects?.forEach((data: EffectData) => {
PLAYER.addEffect(data.effectType, data.duration, {
amplifier: data.amplifier,
showParticles: data.showParticles,
});
});
if (item.eatEvent) {
item.eatEvent(event);
}
}
});
}
/**
* Registry the gift item.
* @param item
*/
static giftRegistry(item: GiftItem | WeightGiftItem | PercentGiftItem): void {
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.typeId) {
setEquipmentItem(event.source);
item.giveReward(event.source);
}
});
}
/**
* Registry the prop item.
* @param item
*/
static propRegistry(item: Prop | DurabilityLimitedProp | NumberLimitedProp) {
if (item instanceof DurabilityLimitedProp) {
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.typeId && item.useEvent) {
item.useEvent(event);
setEquipmentItem(
event.source,
consumeDurability(
event.itemStack,
item.durabilityValue,
event.source
)
);
}
});
} else if (item instanceof NumberLimitedProp) {
let [MAX_USE, ONCE_CONS] = [
item.options.maxUse,
item.options.onceConsumed,
];
if (!ONCE_CONS) ONCE_CONS = 1;
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.typeId && item.useEvent) {
const [PLAYER, ITEM] = [event.source, event.itemStack];
const VALUE = ITEM.getDynamicProperty("lazuli:use_value") as number;
item.useEvent(event);
if (VALUE) {
ITEM.setDynamicProperty("lazuli:use_value", VALUE + ONCE_CONS);
} else {
ITEM.setDynamicProperty("lazuli:use_value", ONCE_CONS);
}
if (VALUE > MAX_USE) {
setEquipmentItem(PLAYER);
}
}
});
} else {
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.typeId && item.useEvent) {
item.useEvent(event);
setEquipmentItem(event.source);
}
});
}
}
/**
* Registry the tool tag or item.
* @param item
*/
static toolRegistry(item: ToolItem | ToolTag) {
item.listeningDurability();
if (item.options?.type === ToolType.shovel) {
item.listeningShovelDurability();
}
if (item.options?.type === ToolType.axe) {
item.listeningAxeDurability();
}
if (item.options?.type === ToolType.hoe) {
item.listeningHoeDurability();
}
}
/**
* Registry the weapon tag or item.
* @param item
*/
static weaponRegistry(item: WeaponItem | WeaponTag) {
item.listeningDurability();
}
/**
* Registry the article.
* @param item
*/
static articleRegistry(item: Article | ChapterArticle | ArticleCollection) {
if (item instanceof ArticleCollection) {
registriedDisplay(item);
} else {
world.afterEvents.itemUse.subscribe((event) => {
if (event.itemStack.typeId === item.id) item.display(event.source);
});
}
}
/**
* Registry the quest or quest book.
* @param item
*/
static questRegistry(
item: Quest | QuestBook | ChapterQuestBook | QuestBoard
) {
if (item instanceof QuestBoard) {
registriedDisplay(item);
} else if (item instanceof Quest) {
if (item.options.condition.killEntity) {
const ENTITY_DATA = item.options.condition.killEntity;
world.afterEvents.entityDie.subscribe((event) => {
if (
event.deadEntity.typeId === ENTITY_DATA.typeId &&
event.damageSource.damagingEntity instanceof Player
) {
const PLAYER = event.damageSource.damagingEntity;
if (!item.isCompleted(PLAYER)) item.complete(PLAYER);
}
});
}
} else {
world.afterEvents.itemUse.subscribe((event) => {
if (item.id === event.itemStack.typeId) {
item.display(event.source);
}
});
}
}
/**
* Registry the job.
* @param item
*/
static jobRegistry(item: any) {
throw new Error("Function not implemented.");
}
/**
* Registry the boss.
* @param item
*/
static bossRegistry(item: Boss) {
world.afterEvents.entitySpawn.subscribe((event) => {
const ENTITY = event.entity;
registriedBoss(item, ENTITY);
});
world.afterEvents.entityLoad.subscribe((event) => {
const ENTITY = event.entity;
registriedBoss(item, ENTITY);
});
}
/**
* Registry the component.
* @param item
*/
static componentRegistry(item: CustomItemComponent | CustomBlockComponent) {
world.beforeEvents.worldInitialize.subscribe((event) => {
if (item instanceof CustomItemComponent) {
event.itemComponentRegistry.registerCustomComponent(
item.typeId,
item.components
);
} else {
event.blockComponentRegistry.registerCustomComponent(
item.typeId,
item.components
);
}
});
}
}
/**
* Union register for api instances.
* @category Registry
*/
export class Register {
private constructor() {}
/**
* Registry an instance.
* @param instance The instance to registry.
* @category Registry
*/
static simpleRegistry(instance: NeedRegistiy) {
if (instance instanceof FoodItem) {
BaseRegister.foodRegistry(instance);
}
if (instance instanceof GiftItem) {
BaseRegister.giftRegistry(instance);
}
if (
instance instanceof Prop ||
instance instanceof DurabilityLimitedProp ||
instance instanceof NumberLimitedProp
) {
BaseRegister.propRegistry(instance);
}
if (instance instanceof ToolItem || instance instanceof ToolTag) {
BaseRegister.toolRegistry(instance);
}
if (instance instanceof WeaponItem || instance instanceof WeaponTag) {
BaseRegister.weaponRegistry(instance);
}
if (instance instanceof Article || instance instanceof ArticleCollection) {
BaseRegister.articleRegistry(instance);
}
if (instance instanceof Article || instance instanceof ArticleCollection) {
BaseRegister.articleRegistry(instance);
}
if (
instance instanceof Quest ||
instance instanceof QuestBook ||
instance instanceof ChapterQuestBook ||
instance instanceof QuestBoard
) {
BaseRegister.questRegistry(instance);
}
if (instance instanceof Boss) {
BaseRegister.bossRegistry(instance);
}
if (
instance instanceof CustomItemComponent ||
instance instanceof CustomBlockComponent
) {
BaseRegister.componentRegistry(instance);
}
}
/**
* Registry the instances.
* @param instance Instances to registry.
*/
static registry(instance: NeedRegistiy | NeedRegistiy[]) {
if(Array.isArray(instance)){
instance.forEach(ins=>{
Register.simpleRegistry(ins)
})
}else{
Register.simpleRegistry(instance);
}
}
}