@magikcraft/mct1
Version:
Minecraft for Type 1 Diabetes
155 lines (140 loc) • 4.68 kB
text/typescript
import { Multiverse } from '@magikcraft/mct1/world/multiverse'
import * as fs from '@magikcraft/mct1/utils/fs'
import { Logger } from '@magikcraft/mct1/log'
import * as server from '@magikcraft/mct1/utils/server'
import { QuestConfig } from 'quests/Quest'
import * as utils from 'utils'
const log = Logger(__filename)
const quests = {
mct1: {
// alias for mct1-prologue
filePath: '@magikcraft/mct1/quests/mct1/prologue',
worldName: 'mct1-start',
nextQuestName: 'mct1-jail',
},
'mct1-prologue': {
filePath: '@magikcraft/mct1/quests/mct1/prologue',
worldName: 'mct1-start',
nextQuestName: 'mct1-jail',
},
'mct1-jail': {
filePath: '@magikcraft/mct1/quests/mct1/jail',
worldName: 'mct1-jail',
nextQuestName: 'mct1-sunken',
},
'mct1-sunken': {
filePath: '@magikcraft/mct1/quests/mct1/sunken',
worldName: 'mct1-sunken-v2',
nextQuestName: 'mct1-magmarun',
},
'mct1-magmarun': {
filePath: '@magikcraft/mct1/quests/mct1/magmarun',
worldName: 'mct1-magmarun',
nextQuestName: 'mct1-magmaboss',
},
'mct1-magmaboss': {
filePath: '@magikcraft/mct1/quests/mct1/magmaboss',
worldName: 'mct1-magmaboss',
nextQuestName: 'mct1-breakout',
},
'mct1-breakout': {
filePath: '@magikcraft/mct1/quests/mct1/breakout',
worldName: 'mct1-breakout',
nextQuestName: 'mct1-village',
},
'mct1-village': {
filePath: '@magikcraft/mct1/quests/mct1/village',
worldName: 'mct1-start',
nextQuestName: 'mct1-breakout2',
},
'mct1-breakout2': {
filePath: '@magikcraft/mct1/quests/mct1/breakout2',
worldName: 'mct1-breakout',
nextQuestName: 'mct1-village',
},
}
const availableQuests = Object.keys(quests)
.sort()
.reduce((prev, current) => `${prev}, ${current}`)
export function questCommand(questName, method, player, opts) {
const quest = quests[questName]
if (!questName || !quest) {
echo(player, `Usage: /quest <quest-name> <command> <player>`)
return echo(player, `Available quests: ${availableQuests}`)
}
const templateWorldName = quests[questName].worldName
const worldName =
opts.mode === 'single'
? `${templateWorldName}--${player.name}`
: `${templateWorldName}-multi`
doCommand(worldName, templateWorldName, questName, player, method, opts)
}
function importWorld(templateWorldName: string) {
server.executeCommand(`mv import ${templateWorldName} normal`)
}
async function deleteWorld(worldName: string) {
log(`Deleting ./${worldName}`)
const w = utils.world(worldName)
const worldFilePath = w
? w.getWorldFolder().getPath()
: `worlds/${worldName}`
Multiverse().deleteWorld(worldName)
if (fs.exists(worldFilePath)) {
log(`Removing file ${worldFilePath}...`)
fs.remove(worldFilePath)
}
return worldName
}
async function cloneWorld(worldName: string, templateWorldName: string) {
await deleteWorld(worldName)
log(`Cloning ${worldName}`)
server.executeCommand(`mv import ${templateWorldName} normal`)
const success = Multiverse().cloneWorld(
templateWorldName,
worldName,
'normal'
)
if (!success) {
return log(`Failed to clone world ${templateWorldName}`)
}
const world = utils.world(worldName)
log(`World clone complete for ${worldName}`)
return world
}
function createQuest({ questName, player, world, opts }) {
const QuestClass = require(quests[questName].filePath).default
const questConfig: QuestConfig = {
name: questName,
nextQuestName: quests[questName].nextQuestName,
player,
world,
options: opts,
}
const quest = new QuestClass(questConfig)
return quest
}
async function doCommand(
worldName,
templateWorldName,
questName,
player,
method,
opts
) {
switch (method) {
case 'start':
echo(player, `Starting quest ${questName}...`)
const world = await cloneWorld(worldName, templateWorldName)
createQuest({ opts, player, questName, world }).start()
break
case 'import':
importWorld(templateWorldName)
break
case 'stop':
// Deleting the world kicks the player from the world
// This triggers the playerChangedWorld event, which calls the stop() method
// of the quest object, doing quest cleanup.
await deleteWorld(worldName)
break
}
}