import { world, system, Vector3, MolangVariableMap, ChatSendAfterEvent, Dimension, TicksPerSecond, BlockVolume, ScriptEventCommandMessageAfterEvent, } from "@minecraft/server"; import { Mindkeeper, StoreType } from "./Commandeer/mindKeeper"; import Pupeteer from "./Commandeer/pupeteer"; import { Vector3ToCommandString, Vector3ToFancyString, vector3 } from "./Commandeer/utils/vectorUtils"; import { delay } from "./Commandeer/utils/waitUtil"; import { spawnParticle } from "./Commandeer/utils/particleUtils"; import { TrailMaker } from "./Commandeer/trail/trailMaker"; import * as CCTrigger from "./Commandeer/Trigger/CCTrigger"; import { Commands } from "./Commandeer/command/command"; import { Trail } from "./Commandeer/trail/trailEngine"; import { levelStartTrail } from "./trails/startTrail"; import level1 from "./levels/level1/mission1"; import level2 from "./levels/level2/mission1"; import level3 from "./levels/level2/mission2"; import level4 from "./levels/level2/mission3"; import level5 from "./levels/level3/mission1"; import { MinecraftBlockTypes } from "./vanilla-data/mojang-block"; import { TransitionTrailToLevel2 } from "./trails/TransitionTrailToLevel2"; import { TransitionTrailBeforeLevel3 } from "./trails/TransitionTrailBeforeLevel3"; import { TransitionTrailToLevel5 } from "./trails/TransitionTrailToLevel5"; import { TransitionTrailToTheEnd } from "./trails/TransitionTrailToTheEnd"; import { setNPCDialog } from "./Commandeer/utils/entityUtils"; import { drawArrow } from "./Commandeer/utils/arrow"; import { TransitionTrailBeforeLevel5 } from "./trails/TransitionTrailBeforeLevel5"; import { TransitionTrailBeforeLevel4 } from "./trails/TransitionTrailBeforeLevel4"; import { drawSmallArrow } from "./Commandeer/utils/smallArrow"; const mindKeeper = new Mindkeeper(world); const trailMaker: TrailMaker.Maker = new TrailMaker.Maker(); const triggerManager = new CCTrigger.Manager(mindKeeper); const CURRENT_LEVEL = "currentLevel"; const AGENT_ID = "agentid"; const PREFIX = "!"; const frameDuration = 7; const DEVELOPER_MODE = true; export { mindKeeper, CURRENT_LEVEL, triggerManager }; let startTrail: Trail = new Trail("startTrail", 4, 4); startTrail.fromTrail(levelStartTrail); let transitionTrail1 = new Trail("transitionTrail1", 2, 2); transitionTrail1.fromTrail(TransitionTrailToLevel2); let transitionTrail2 = new Trail("transitionTrail2", 2, 2); transitionTrail2.fromTrail(TransitionTrailBeforeLevel3); let transitionTrail3 = new Trail("transitionTrail3", 2, 2); transitionTrail3.fromTrail(TransitionTrailBeforeLevel4); let transitionTrail4 = new Trail("transitionTrail4", 2, 2); transitionTrail4.fromTrail(TransitionTrailBeforeLevel5); let transitionTrail5 = new Trail("transitionTrail5", 2, 2); transitionTrail5.fromTrail(TransitionTrailToLevel5); let transitionTrail6 = new Trail("transitionTrail6", 2, 2); transitionTrail6.fromTrail(TransitionTrailToTheEnd); let animationPlaying = false; let tickCounter = 0; let gateRoot = vector3(-226, 68, 223); enum GateState { open, closed, } let gateState = GateState.closed; system.runInterval(async () => { tickCounter++; if (mindKeeper.initialised) { trailMaker.Update(); if (tickCounter % 2 == 0) { triggerManager.Update(); } const currentLevel = mindKeeper.get(CURRENT_LEVEL); switch (currentLevel) { case 0: Pupeteer.setActionBar("%message.intro"); setNPCDialog("bilal1", "bilal_beforelevel_1_1"); startTrail.spawnNext(); break; case 1: Pupeteer.setActionBar("%message.talkto.bilal"); break; case 2: break; case 3: level1.update(); break; case 4: setNPCDialog("bilal1", "bilal_afterlevel_1_1"); Pupeteer.setActionBar("%message.talkto.bilal"); break; case 5: transitionTrail1.spawnNext(); setNPCDialog("chanel1", "chanel_beforelevel_2_1"); Pupeteer.setActionBar("%message.talkto.chanel"); break; case 6: drawArrow(vector3(-118.5, 78, 265.5)); level2.update(); break; case 7: setNPCDialog("chanel1", "chanel_afterlevel_2_1"); transitionTrail2.spawnNext(); Pupeteer.setActionBar("%message.talkto.chanel"); break; case 8: drawArrow(vector3(-141.5, 78, 265.5)); level3.update(); break; case 9: setNPCDialog("chanel1", "chanel_afterlevel_3_1"); transitionTrail3.spawnNext(); Pupeteer.setActionBar("%message.talkto.chanel"); break; case 10: drawArrow(vector3(-167.5, 78, 265.5)); drawSmallArrow(vector3(-161.5, 76, 276.5)); level4.update(); break; case 11: setNPCDialog("chanel1", "chanel_afterlevel_4_1"); transitionTrail4.spawnNext(); Pupeteer.setActionBar("%message.talkto.chanel"); break; case 12: Pupeteer.setActionBar("Follow the trail to the next level."); transitionTrail5.spawnNext(); break; case 13: setNPCDialog("farah1", "farah_beforelevel_5_1"); Pupeteer.setActionBar("%message.talkto.farah"); break; case 14: level5.update(); break; case 15: transitionTrail6.spawnNext(); if (gateState == GateState.closed) { gateState = GateState.open; PlayGateOpenAnimation(); } break; case 16: Pupeteer.setActionBar("%message.end"); break; } } }); class ClonePos { point1: Vector3; point2: Vector3; constructor(point1: Vector3, point2: Vector3) { this.point1 = point1; this.point2 = point2; } } const gateFrames: ClonePos[] = [ { point1: vector3(-226, 66, 223), point2: vector3(-219, 62, 223), }, { point1: vector3(-226, 61, 223), point2: vector3(-219, 57, 223), }, { point1: vector3(-226, 56, 223), point2: vector3(-219, 52, 223), }, { point1: vector3(-226, 51, 223), point2: vector3(-219, 47, 223), }, { point1: vector3(-226, 46, 223), point2: vector3(-219, 42, 223), }, ]; let PlayGateOpenAnimation = async () => { playAnimation(gateFrames, frameDuration, false, gateRoot); }; let ResetGate = () => SetFrame(gateFrames[0], gateRoot); async function SetFrame(frame: ClonePos, destination: Vector3) { await world .getDimension("overworld") .runCommandAsync( `/clone ${Vector3ToCommandString(frame.point1)} ${Vector3ToCommandString(frame.point2)} ${Vector3ToCommandString( destination )}` ); } async function playAnimation( frames: ClonePos[], delayTime: number, reverse: boolean, destination: Vector3, force: boolean = false ) { if (animationPlaying && !force) { world.sendMessage("Animation already playing"); return; } let frameCount = frames.length; if (!force) { animationPlaying = true; } for (let i = 0; i < frameCount; i++) { let frame = reverse ? frames[frameCount - i - 1] : frames[i]; await world .getDimension("overworld") .runCommandAsync( `/clone ${Vector3ToCommandString(frame.point1)} ${Vector3ToCommandString( frame.point2 )} ${Vector3ToCommandString(destination)}` ); await delay(delayTime); } if (!force) { animationPlaying = false; } } triggerManager.RegisterFunctionTrigger("BottomTreehouse", async (event) => { if (mindKeeper.get(CURRENT_LEVEL) == 0) { mindKeeper.increment(CURRENT_LEVEL); } }); triggerManager.RegisterFunctionTrigger("level1", async (event) => { if (mindKeeper.get(CURRENT_LEVEL) == 2) { mindKeeper.increment(CURRENT_LEVEL); } }); triggerManager.RegisterFunctionTrigger("level5", async (event) => { if (mindKeeper.get(CURRENT_LEVEL) == 12) { mindKeeper.increment(CURRENT_LEVEL); } }); triggerManager.RegisterFunctionTrigger("CompletedTheMission", async (event) => { if (mindKeeper.get(CURRENT_LEVEL) == 15) { mindKeeper.increment(CURRENT_LEVEL); } }); Commands.register(PREFIX, "info", (arg) => { world.sendMessage("-----------------"); world.sendMessage("Current level: " + mindKeeper.get(CURRENT_LEVEL)); world.sendMessage("Agent ID: " + mindKeeper.get(AGENT_ID)); world.sendMessage("Engine Version: 1.0.2"); world.sendMessage("Engine is running"); world.sendMessage("Active players: " + world.getPlayers().length); world.sendMessage("Current dimension: " + arg.player.dimension.id); world.sendMessage("Current position: " + Vector3ToFancyString(arg.player.location)); world.sendMessage("-----------------"); }); system.afterEvents.scriptEventReceive.subscribe((event) => { if (event.id == "cc:getId") { let id = event.message; world.sendMessage("Script got the id " + id); mindKeeper.set(AGENT_ID, id); } checkNpcResponse(event, "cc:startLevel1", 1); checkNpcResponse(event, "cc:afterLevel1", 4); checkNpcResponse(event, "cc:startLevel2", 5); checkNpcResponse(event, "cc:afterLevel2", 7); checkNpcResponse(event, "cc:afterLevel3", 9); checkNpcResponse(event, "cc:afterLevel4", 11); checkNpcResponse(event, "cc:startLevel5", 13); }); function checkNpcResponse(event: ScriptEventCommandMessageAfterEvent, id: string, level: number) { if (event.id == id) { if (mindKeeper.get(CURRENT_LEVEL) == level) { mindKeeper.increment(CURRENT_LEVEL); } } } world.afterEvents.worldInitialize.subscribe(() => { mindKeeper.registerStore(CURRENT_LEVEL, StoreType.number); mindKeeper.registerStore(AGENT_ID, StoreType.string); triggerManager.RegisterStores(); mindKeeper.registerToWorld(); triggerManager.Load(); }); world.beforeEvents.itemUseOn.subscribe((event) => { trailMaker.OnItemUse(event); triggerManager.OnItemUse(event); }); world.afterEvents.chatSend.subscribe(async (event: ChatSendAfterEvent) => { const command = event.message.split(" ")[0]; trailMaker.OnChat(event); mindKeeper.chatCommands(event); triggerManager.OnChat(event); if (command === "!reset") { mindKeeper.set(CURRENT_LEVEL, 0); world.sendMessage("currentlevel = " + mindKeeper.get(CURRENT_LEVEL)); world.sendMessage("Resetting"); level1.reset(); level2.reset(); level3.reset(); level4.reset(); level5.reset(); ResetGate(); world.getDimension("Overworld").runCommand("/fill -86 71 253 -86 75 275 barrier replace air"); world.getDimension("Overworld").runCommand("/fill -182 69 255 -182 74 276 barrier replace air"); setNPCDialog("bilal1", "bilal_beforelevel_1_1"); setNPCDialog("chanel1", "chanel_beforelevel_2_1"); setNPCDialog("farah1", "farah_beforelevel_5_1"); } });