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); } } }