From c18f189ab779c7d4bdce380e683661703d4c023e Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sun, 21 Oct 2018 19:07:41 +1100 Subject: [PATCH] Rewrote ADAM --- ADAM/adam.js | 1370 ++++++++--------------------------------- ADAM/dialog.json | 82 +-- Shared/factions.js | 16 +- Shared/progression.js | 18 +- Shared/utility.js | 8 +- 5 files changed, 338 insertions(+), 1156 deletions(-) diff --git a/ADAM/adam.js b/ADAM/adam.js index 9c366d1..28c9504 100644 --- a/ADAM/adam.js +++ b/ADAM/adam.js @@ -2,1146 +2,322 @@ require('dotenv').config({path: '../.env'}); // Node Modules -const Discord = require('discord.js'); -const client = new Discord.Client(); -const cron = require('node-cron'); +let Discord = require('discord.js'); +let client = new Discord.Client(); +let cron = require('node-cron'); -// Bot Modules (stores http requests & random functions respectively) -const npcSettings = require('./npcSettings'); -const dialog = require('./dialog'); -const dataRequest = require('../modules/dataRequest'); -const calcRandom = require('../modules/calcRandom'); +// Bot Modules +let npcSettings = require('./npcSettings'); +let shared = require("../shared/shared"); +let dataRequest = require('../modules/dataRequest'); +let calcRandom = require('../modules/calcRandom'); -const commandArray = ['!checkin', '!stats', '!inventory', '!upgrade', '!heal', '!quests'] +//dialog system +let dialog = shared.GenerateDialogFunction(require("./dialog.json")); -// Creates an array that seperates 10 items into seperate arrays each -const itemDB = { - "iron_sword": { - "name": "Iron Sword", - "info": "This sturdy sword is great for slashing Ravagers.", - "type": { - "type": "Weapon", - "subtype": "Sword", - "stats": [ - { "attack": 2 } - ] - }, - "amount": 1 - }, - "steel_sword": { - "name": "Steel Sword", - "info": "A tougher form of the Iron Sword, it deals greater blows.", - "type": { - "type": "Weapon", - "subtype": "Sword", - "stats": [ - { "attack": 3 } - ] - }, - "amount": 1 - }, - "leather_armour": { - "name": "Leather Armour", - "info": "A light piece of armour made of leather.", - "type": { - "type": "Equipment", - "subtype": "Armour", - "stats": [ - {"defence": 3}, {"speed": 1} - ] - }, - "amount": 1 - }, - "leather_helm": { - "name": "Leather Helm", - "info": "A leather headpiece, designed for some protection and shade.", - "type": { - "type": "Equipment", - "subtype": "Helm", - "stats": [ - {"defence": 2}, {"speed": 1} - ] - }, - "amount": 1 - }, - "leather_boots": { - "name": "Leather Boots", - "info": "Comfy, leather boots made for long trips in New Eden's deserts.", - "type": { - "type": "Equipment", - "subtype": "Boots", - "stats": [ - {"defence": 1}, {"speed": 1} - ] - }, - "amount": 1 - }, - "iron_armour": { - "name": "Iron Armour", - "info": "Tough, iron armour. It feels solid.", - "type": { - "type": "Equipment", - "subtype": "Armour", - "stats": [ - {"defence": 4}, {"speed": -1} - ] - }, - "amount": 1 - }, - "health_potion": { - "name": "Health Potion", - "info": "A sweet-smelling potion that heals the drinker for 50 HP.", - "type": { - "type": "Potion", - "stats": [ - {"healing": 50} - ] - }, - "amount": 1 - } -} +//dialog decorator +dialog = function(baseDialog) { + return function(key, ...data) { + if ( (key === "help" || key === "lore") && typeof(data[0]) !== "undefined") { + //force the arg into camelCase + arg = data[0].toLowerCase(); + arg = arg.charAt(0).toUpperCase() + arg.substr(1); + key += arg; + } -// For development testing -var userItems = []; + let result = baseDialog(key, ...data); -addItem(undefined, itemDB["health_potion"], 10); -addItem(undefined, itemDB["iron_sword"], 1); -addItem(undefined, itemDB["leather_armour"], 1); -addItem(undefined, itemDB["leather_boots"], 1); -addItem(undefined, itemDB["leather_helm"], 1); -addItem(undefined, itemDB["steel_sword"], 1); - -// State Machine (Uncomment if needed) -/* -var BotEnumState = { - WAITING: 0, - ACTIVE: 1 -} -var botState = BotEnumState.ACTIVE; -*/ + if (result === "") { + return "No result for \"" + key + "\""; + } + return result; + } +}(dialog); -// The ready event is vital, it means that your bot will only start reacting to information -// from Discord _after_ ready is emitted +//handle errors +client.on('error', console.error); + +// The ready event is vital, it means that your bot will only start reacting to information from Discord _after_ ready is emitted client.on('ready', async () => { - // Generates invite link - try { - let link = await client.generateInvite(["ADMINISTRATOR"]); - console.log("Invite Link: " + link); - } catch(e) { - console.log(e.stack); - } + // Generates invite link + try { + let link = await client.generateInvite(["ADMINISTRATOR"]); + console.log("Invite Link: " + link); + } catch(e) { + console.log(e.stack); + } - // You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb) - if (client.user.username !== "Ghost 5.0.1") - client.user.setStatus('online'); - else - client.user.setStatus('invisible'); - - if (client.user.username == "Captain Montomery") { - const newName = "Captain Montgomery"; - console.log("Username is " + client.user.username + "! Typos are NOT(?) cannon, so better change stuff.\nAttempting rename to " + newName + "..."); + // You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb) + client.user.setStatus('online'); + + // Sets your "Playing" + if (npcSettings.activity) { + client.user.setActivity(npcSettings.activity, { type: npcSettings.type }) + //DEBUGGING + .then(presence => console.log("Activity set to " + (presence.game ? presence.game.name : 'none')) ) + .catch(console.error); + } - // Set username - client.user.setUsername(newName) - .then(user => console.log(`Success! New username is now ${user.username}.`)) - .catch(console.error); + console.log("Logged in as: " + client.user.username + " - " + client.user.id); - // Changes nickname - //client.guilds.get(process.env.SANCTUM_ID).members.get(client.user.id).setNickname(""); - } - - // Sets your "Playing" - if (npcSettings.activity) { - client.user.setActivity(npcSettings.activity, { type: npcSettings.type }) - .then(presence => console.log(`Activity set to ${presence.game ? presence.game.name : 'none'}`)) - .catch(console.error); - } + //ADAM updates stamina (1) and health by 1% every 2 min. + cron.schedule('*/2 * * * *', () => { + console.log('Updating STAMINA every 2 min.'); + dataRequest.sendServerData("updateStamina"); + }); - console.log(`Connected! \ - \nLogged in as: ${client.user.username} - (${client.user.id})`); + //ADAM prints the intros in the gate + shared.SendPublicMessage(client, client.channels.get(process.env.GATE_CHANNEL_ID), dialog("intro")); + shared.SendPublicMessage(client, client.channels.get(process.env.GATE_CHANNEL_ID), dialog("introObsidian", process.env.GROUP_A_ROLE)); + shared.SendPublicMessage(client, client.channels.get(process.env.GATE_CHANNEL_ID), dialog("introGenesis", process.env.GROUP_B_ROLE)); + shared.SendPublicMessage(client, client.channels.get(process.env.GATE_CHANNEL_ID), dialog("introHand", process.env.GROUP_C_ROLE)); + shared.SendPublicMessage(client, client.channels.get(process.env.GATE_CHANNEL_ID), dialog("introEnd")); }); // Create an event listener for messages client.on('message', async message => { - // Ignores ALL bot messages - if (message.author.bot) return; + // Ignores ALL bot messages + if (message.author.bot) { + return; + } - // Message has to be in a bot channel - //if (!channelProcessor.isBotChannel(message.channel.id)) { - if (message.channel.id !== npcSettings.botChannel) { - // If it's the gate - if (message.channel.id === process.env.GATE_CHANNEL_ID && client.user.username === "A.D.A.M") { - const args = message.content.slice(prefix.length).trim().split(/ +/g); - const command = args.shift().toLowerCase(); + //skip the statis channel + if (message.channel.id === process.env.STASIS_CHANNEL_ID) { + return; + } - // If they haven't done the right command to enter - if (!(command === "obsidian" || command === "hand" || command === "genesis")) { - console.log("User sent " + command + (command !== "obsidian")); - if (!(command !== "intro" || command !== "introgenesis" || command !== "introhand" || command !== "introobsidian" || command !== "introend")) { - message.reply("Please choose one of the factions by typing your desired faction shown above (!genesis, !obsidian, or !hand).") - .then(msg => { - msg.delete(10000) - }) - .catch(console.error); - } - } - message.delete(100); - } - } - if (message.channel.id === process.env.STASIS_CHANNEL_ID) return; - - // Has to be (prefix)command - if (message.content.indexOf(process.env.PREFIX) !== 0) return; + //ADAM only - handle the gate + if (processGateCommands(message)) { + return; + } - // "This is the best way to define args. Trust me." - // - Some tutorial dude on the internet - const args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); - const command = args.shift().toLowerCase(); + // Has to be (prefix)command + if (message.content.indexOf(process.env.PREFIX) !== 0) { + return; + } - switch (command) { - case "ping": - if (isAdmin(message.author.id)) - message.reply("What is your command, almighty and glorious master!"); - break; - case "intro": - if (client.user.username == "A.D.A.M.") - sendMessage(message.channel.id, dialog.getDialog("intro", message.author.id)); - break; - case "introobsidian": - if (client.user.username == "Kamala, Obsidian Vice President") - sendMessage(message.channel.id, dialog.getDialog("introObsidian", message.author.id)); - break; - case "introgenesis": - // Typos officially cannon - if (client.user.username == "Captain Montgomery") - sendMessage(message.channel.id, dialog.getDialog("introGenesis", message.author.id)); - break; - case "introhand": - if (client.user.username == "Dairo, High Prophet of The Hand") - sendMessage(message.channel.id, dialog.getDialog("introHand", message.author.id)); - break; - case "introend": - if (client.user.username == "A.D.A.M.") - sendMessage(message.channel.id, dialog.getDialog("introEnd", message.author.id)); - break; - case "admingetroleids": - //for (var i in discordBot.servers[serverID].roles) { - // console.log(discordBot.servers[serverID].roles[i]); // issues - //} - console.log("!adminGetRoleIDs is Disabled for now"); - break; - case "obsidian": - if (client.user.username == "Kamala, Obsidian Vice President") - changeFaction(process.env.GROUP_A_ROLE, message.channel.id, message.author.id, - message.member, process.env.GROUP_A_BOT_ID); - break; - case "genesis": - if (client.user.username == "Captain Montgomery") - changeFaction(process.env.GROUP_B_ROLE, message.channel.id, message.author.id, - message.member, process.env.GROUP_B_BOT_ID); - break; - case "hand": - if (client.user.username == "Dairo, High Prophet of The Hand") - changeFaction(process.env.GROUP_C_ROLE, message.channel.id, message.author.id, - message.member, process.env.GROUP_C_BOT_ID); - break; - case "beginners": - if (!isAdmin()) break; - if (client.user.username == "A.D.A.M.") { + if (processBasicCommands(message)) { + return; + } - var timedEvents = `Mori will revive all weakened travelers every day, and may heal you for a cost, if Mori can find the right things to do so.`; + //check if can continue (used primarily by the faction leaders) + if (shared.CheckValidDisplay(client, message.member, message.channel)) { + return; + } - var commandsText = `These commands can be done in <#${process.env.GROUP_B_BOT_ID}>, <#${process.env.GROUP_C_BOT_ID}>, or <#${process.env.GROUP_A_BOT_ID}>.\n` + - `**!checkin** - For your help around the city, you can use this to be given a sum of **<:crystals:460974340247257089> Crystals** daily from your faction leader.\n` + - `**!stats** - Your faction leader can check your stats, and your total crystals, materials, etc., with this command.\n`; - - const embed = new Discord.RichEmbed() - .setAuthor( "SANCTUM Beginner's Guide", client.user.avatarURL) - .setColor("#f1c40f") - .setTitle("Welcome to SANCTUM!") - .setDescription("Welcome to SANCTUM, traveler. I hope you will understand the basics on how to survive after the Genesis ship's crash.") - .addField("Basic Commands", commandsText) - .addField("Mori", timedEvents) - - message.channel.send({embed}); - } - break; - case "questboard": - if (!isAdmin(message.author.id)) break; - if (client.user.username != "A.D.A.M.") break; - - var quests = { - "quests": [ - { - "title": "The Lost Pendant", - "id": "thelostpendant", - "description": "Lorem ipsum, or some placeholder text. I wish I knew what to put here, I'm no writer! I need to put more text here in order for the inlines to work more nicely. Not like it matters on mobile, however.", - "objective": "Go to <#${process.env.OUTSKIRTS_CHANNEL_ID}> and **!scavenge** in hopes to find the pendant.", - "userID": process.env.LIBRARIAN_ID, - "color": "keepersOfTheCityColor", - "recommendedLVL": 1, - "questLength": "Short", - "rewards": [ - { - "name": "Crystals", - "emote": "<:crystals:460974340247257089>", - "amount": 10 - }, - { - "name": "Electronics", - "emote": "<:melectronics:462682568911749120>", - "amount": 2 - }, - { - "name": "Gem", - "emote": "<:mgem:462450060718768148>", - "amount": 2 - } - ] - }, - { - "title": "Looming Ravager Outside", - "id": "loomingravager", - "description": "Hey, I have a problem, ya' see. There's a Ravager outside my tavern! And I've been waiting fo' it to go, but it ain't leaving!! I need your help to get rid of it, it's scaring me and my customers!", - "objective": "Go and help slay a Ravager.", - "userID": process.env.ALEXIS_ID, - "color": "keepersOfTheCityColor", - "recommendedLVL": 1, - "questLength": "Short", - "rewards": [ - { - "name": "Crystals", - "emote": "<:crystals:460974340247257089>", - "amount": 5 - } - ] - } - ] - } - - // Collects all preset colors - const keepersOfTheCityColor = message.guild.roles.find(role => role.name === "Keepers of the City").color; - console.log("COLOR: " + keepersOfTheCityColor); - - // Header & Footer (mobile design choice) for quests - const header = new Discord.RichEmbed() - .setAuthor("Quests", client.user.avatarURL) - .setColor(keepersOfTheCityColor) - .setTitle("The Travelers' Quest Board") - .setDescription("Residents of New Eden can post their help requests here, and whoever fulfils them can earn some rewards.") - .setFooter(`⏰ 7 hrs. before the quests are exchanged for new ones.`) - await message.channel.send({embed: header}); - - // Displays all quests in order - for (let i = 0; i < quests.quests.length; i++) { - const element = quests.quests[i]; - const bot = client.guilds.get(process.env.SANCTUM_ID).members.get(element.userID); - var newColor = element.color; - var newDescription = element.description; - var newObjective = element.objective; - var newReward = ""; - const questLength = `Quest Length: **${element.questLength}**.`; - - // Adds rewards up - element.rewards.forEach(reward => { - newReward += `> **${reward.emote} ${reward.name}** [${reward.amount}x]\n`; - }); - - // Returns internal color if needed - if (element.color === "keepersOfTheCityColor") newColor = keepersOfTheCityColor; - - // Replaces certain strings with internal channel data if needed - // NEED TO FIGURE OUT REGEX EXPRESSIONS FOR MASS REPLACE - newObjective = element.objective.replace("${process.env.OUTSKIRTS_CHANNEL_ID}", `${process.env.OUTSKIRTS_CHANNEL_ID}`); - - const body = new Discord.RichEmbed() - .setAuthor(`${bot.displayName}`, bot.user.avatarURL) - .setColor(newColor) - .setTitle(`📃 ${element.title}`) - .setDescription(newDescription) - .addField("Objective", newObjective) - .addField("Reward", newReward, true) - .addField("Info", `Recommended Level: **<:level:461650552506286093> ${element.recommendedLVL}+**.\n${questLength}`, true) - .setFooter(`React with ❗ to take on the quest, and help ${bot.displayName}.`) - - var bodyMessage = await message.channel.send({embed: body}); - await bodyMessage.react("❗"); - } - - // Specifically for mobile - await message.channel.send({embed: header}); - - break; - case "guild": - if (!isAdmin(message.author.id)) break; - if (client.user.username != "A.D.A.M.") break; - - switch (args[0]) { - case "create": - // Start message - var progressMessage = await message.channel.send(`${message.author} I will setup a safe place in the City, please wait.`); - - // Creates new channel & sets topic - var channelName = message.content.replace("!guild create ", '').trim(); - var newChannel = await message.guild.createChannel(channelName, 'text'); - await newChannel.setParent('496813609201172500'); - newChannel.setTopic(`This is the ${channelName} guild!`); - - // Chooses a role name - const roleName = channelName.replace(/\\/g, ""); - - // Creates role & adds it to author - var newRole = await message.guild.createRole({ - name: roleName, - color: 'DARK_AQUA', - }); - await message.member.addRole(newRole); - - // Sets permissions - await newChannel.overwritePermissions(message.guild.roles.find(role => role.name === '@everyone'), { - 'VIEW_CHANNEL': false - }); - await newChannel.overwritePermissions(message.guild.roles.find(role => role.name === roleName), { - 'VIEW_CHANNEL': true - }); - await newChannel.overwritePermissions(message.guild.roles.find(role => role.name === 'Can View All Guilds'), { - 'VIEW_CHANNEL': true - }); - - // Progress message - await progressMessage.edit(`${message.author} I have finished setting up your new ${newRole} guild, in the City. Put it into good use, traveler.`); - - break; - case "tag": - // Appends guild name to user (Grabs nickname by removing anything in []s) - // NOTE: CODE WORKS, JUST DOESN'T LOOK RIGHT - /* - const userNickname = message.member.displayName.replace(/\[(.*?)\]+/g, '').trim(); - message.member.setNickname(`[${roleName}] ${userNickname}`) - .catch((e) => { - console.log("ERROR HAPPENED I THINK") - console.log(e); - - // Catches >32 nickname - if (e.code == 50035) { - message.channel.send(`${message.author} I couldn't change your username in order to put your guild tag, as it would be too long.`) - } - }); - */ - break; - } - - break; - - } - - if (!checkValidDisplay(message.member, message.channel.id, true) && client.user.username != "A.D.A.M.") return; - - switch (command) { - case "checkin": - if (client.user.username == "A.D.A.M.") break; - var checkinAmount = calcRandom.random(4, 9); - var checkInResponse = String(dataRequest.sendServerData("checkin", checkinAmount, message.author.id)); - if (checkInResponse == "1") { - sendMessage(message.channel.id, dialog.getDialog("checkin", message.author.id, checkinAmount)); - addXP(message.author.id, 1); - } else { - sendMessage(message.channel.id, dialog.getDialog("checkinLocked", message.author.id, checkInResponse)); - } - break; - case "give": // Could revamp to make player ID and amount interchangable - if (client.user.username == "A.D.A.M.") break; - var giveAmount = Math.floor(args[0]); - if (message.mentions.members.size > 0) { - console.log(message.mentions.members); - var giveToID = message.mentions.members.first().id; - console.log("GIVE: " + giveToID + " | message.author.id: " + message.author.id) - if (giveToID === message.author.id) { - sendMessage(message.channel.id, dialog.getDialog("giveInvalidUserSelf", message.author.id)); - return; - } - var amountInAccount = dataRequest.loadServerData("account",message.author.id); - if (giveAmount > 0) { - if (amountInAccount >= giveAmount) { - if (dataRequest.sendServerData("transfer",giveToID,message.author.id,giveAmount) == 1) { - sendMessage(message.channel.id, dialog.getDialog("giveSuccessful", message.author.id, giveToID, giveAmount)); - } else { - sendMessage(message.channel.id, dialog.getDialog("giveFailed", message.author.id)); - } - } else { - sendMessage(message.channel.id, dialog.getDialog("giveNotEnoughInAccount", message.author.id)); - } - } else { - sendMessage(message.channel.id, dialog.getDialog("giveNotAboveZero", message.author.id)); - } - } else { - sendMessage(message.channel.id, dialog.getDialog("giveInvalidUser", message.author.id)); - } - break; - case "lore": - if (client.user.username == "A.D.A.M.") break; - sendMessage(message.channel.id, dialog.getDialog("lore", args[0])); - break; - case "tstats": - if (client.user.username == "A.D.A.M.") break; - getLevelUp(message.author.id); - - var attacker = String(dataRequest.loadServerData("userStats",message.author.id)); - var scavengeResponse = String(dataRequest.loadServerData("artifactsGet",message.author.id)); - var attackerStrength = parseFloat(attacker.split(",")[0]); - var attackerSpeed = parseFloat(attacker.split(",")[1]); - var attackerStamina = parseFloat(attacker.split(",")[2]); - var attackerHealth = parseFloat(attacker.split(",")[3]); - var attackerMaxStamina = parseFloat(attacker.split(",")[4]); - var attackerMaxHealth = parseFloat(attacker.split(",")[5]); - var attackerWallet = parseFloat(attacker.split(",")[6]); - var attackerXP = parseFloat(attacker.split(",")[7]); - var attackerLVL = Math.floor(parseFloat(attacker.split(",")[8])); - var attackerLvlPercent = parseFloat(attacker.split(",")[9]); - var attackerStatPoints = parseFloat(attacker.split(",")[10]); - var attackerChests = parseFloat(attacker.split(",")[11]); - - var items = scavengeResponse.split(","); - var response = items[0]; - var ultrarare = parseFloat(items[1]); - var rare = parseFloat(items[2]); - var uncommon = parseFloat(items[3]); - var common = parseFloat(items [4]); - var scrap = parseFloat(items[5]); - var totalQuantity = ultrarare + rare + uncommon + common + scrap; - var userStats = ""; - - if (attackerLVL >= 30) { - userStats += "<@" + message.author.id + "> <:level:461650552506286093> **" + attackerLVL + "** (MAX)\t\t" + "<:cannister:462046687058198530> **" + attackerStatPoints + "**\t\t" + "<:cyphercrate:464135029036154950> **" + attackerChests + "** (" + attackerLvlPercent + "%)"; - } else { - userStats += "<@" + message.author.id + "> <:level:461650552506286093> **" + attackerLVL + "** (" + attackerLvlPercent + "%)\t\t\t" + "<:cannister:462046687058198530> **" + attackerStatPoints + "**\t\t\t<:cyphercrate:464135029036154950> **" + attackerChests + "**"; - } - userStats += "```STR: " + attackerStrength + " | SPD: " + attackerSpeed + " | STAM: " + attackerStamina + "/" + attackerMaxStamina + " | HP: " + attackerHealth + "/" + attackerMaxHealth + "```"; - userStats += "<:crystals:460974340247257089> **" + attackerWallet + "**\t\t"; - if (response == "success") { - if (totalQuantity > 0) { - //userStats += "\n"; - if (scrap > 0) { userStats += "<:scrap:463436564379336715> **" + scrap + "**\t\t"; } - if (common > 0) { userStats += "<:mcloth:462682568483930123> **" + common + "**\t\t"; } - if (uncommon > 0) { userStats += "<:mmetal:462682568920137728> **" + uncommon + "**\t\t"; } - if (rare > 0) { userStats += "<:melectronics:462682568911749120> **" + rare + "**\t\t"; } - if (ultrarare > 0) {userStats += "<:mgem:462450060718768148> **" + ultrarare + "**\n\n"; } - } else {console.log("failure2");} - } else {console.log("failure");} - - sendMessage(message.channel.id, userStats); - break; - case "stats": - // Sees if the user is supposed to level up - getLevelUp(message.author.id); - - // Grabs all parameters from server - var attacker = String(dataRequest.loadServerData("userStats",message.author.id)); - var scavengeResponse = String(dataRequest.loadServerData("artifactsGet",message.author.id)); - var attackerStrength = parseFloat(attacker.split(",")[0]); - var attackerSpeed = parseFloat(attacker.split(",")[1]); - var attackerStamina = parseFloat(attacker.split(",")[2]); - var attackerHealth = parseFloat(attacker.split(",")[3]); - var attackerMaxStamina = parseFloat(attacker.split(",")[4]); - var attackerMaxHealth = parseFloat(attacker.split(",")[5]); - var attackerWallet = parseFloat(attacker.split(",")[6]); - var attackerXP = parseFloat(attacker.split(",")[7]); - var attackerLVL = Math.floor(parseFloat(attacker.split(",")[8])); - var attackerLvlPercent = parseFloat(attacker.split(",")[9]); - var attackerStatPoints = parseFloat(attacker.split(",")[10]); - var attackerChests = parseFloat(attacker.split(",")[11]); - - var items = scavengeResponse.split(","); - var response = items[0]; - var ultrarare = parseFloat(items[1]); - var rare = parseFloat(items[2]); - var uncommon = parseFloat(items[3]); - var common = parseFloat(items [4]); - var scrap = parseFloat(items[5]); - var totalQuantity = ultrarare + rare + uncommon + common + scrap; - - // Forms stats into a string - var levelText = `<:level:461650552506286093> **${attackerLVL}**`; - var levelProgress = `(${attackerLvlPercent}%)`; - var crystalText = `<:crystals:460974340247257089> **${attackerWallet}**`; - var cannisterText = `<:cannister:462046687058198530> **${attackerStatPoints}**`; - var cypherCrateText = `<:cyphercrate:464135029036154950> **${attackerChests}**`; - var userStats = "```" + `STR: ${attackerStrength} | SPD: ${attackerSpeed} | STAM: ${attackerStamina}/${attackerMaxStamina} | HP: ${attackerHealth}/${attackerMaxHealth}` + "```"; - var materialsText = ``; - - // Materials - if (response == "success") { - if (totalQuantity > 0) { - if (scrap > 0) { materialsText += `<:scrap:463436564379336715> **${scrap}**`; } - if (common > 0) { materialsText += ` | <:mcloth:462682568483930123> **${common}**`; } - if (uncommon > 0) { materialsText += ` | <:mmetal:462682568920137728> **${uncommon}**`; } - if (rare > 0) { materialsText += ` | <:melectronics:462682568911749120> **${rare}**`; } - if (ultrarare > 0) { materialsText += ` | <:mgem:462450060718768148> **${ultrarare}**`; } - } else {console.log("failure2");} - } else {console.log("failure");} - - // Says level is maxed out if it is LVL 30+ - if (attackerLVL >= 30) { - levelProgress = `(MAX)`; - cypherCrateText += ` (${attackerLvlPercent}%)`; - } - - // Creates embed & sends it - const embed = new Discord.RichEmbed() - .setAuthor(`${message.member.displayName}`, message.author.avatarURL) - .setColor(message.member.displayColor) - .setDescription(`${levelText} ${levelProgress} | ${crystalText} | ${cannisterText} | ${cypherCrateText}`) - .addField("Stats", userStats) - .addField("Materials", `${materialsText}`) - .setFooter("Commands: !inventory | !checkin | !upgrade | !heal | !quests") - - message.channel.send(embed); - break; - case "inventory": - if (args[0] !== undefined) { - var num = Math.floor(parseInt(args[0])); - if (Number.isSafeInteger(num)) { - return sendInventory(message, num); - } - } else { - return sendInventory(message); - } - break; - case "inv": - if (args[0] !== undefined) { - var num = Math.floor(parseInt(args[0])); - if (Number.isSafeInteger(num)) { - return sendInventory(message, num); - } - } else { - return sendInventory(message); - } - break; - case "item": - return appraiseItem(message); - - case "help": - if (client.user.username == "A.D.A.M.") break; - if (!args[0]) { - sendMessage(message.channel.id, dialog.getDialog("help", message.author.id)); - } else if (message.mentions.members.first() !== undefined) { - // MORI - if (message.mentions.members.first().id == process.env.MORI_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpMori", message.author.id)); - } - // RAVAGER - if (message.mentions.members.first().id == process.env.RAVAGER_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpRavager", message.author.id)); - - } - // MOSIAH - if (message.mentions.members.first().id == process.env.MOSIAH_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpMosiah", message.author.id)); - - } - // GRAZE - if (message.mentions.members.first().id == process.env.GRAZE_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpGraze", message.author.id)); - - } - // SONYA - /* - if (message.mentions.members.first().id == process.env.SONYA_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpSonya", message.author.id)); - } - */ - // REY - if (message.mentions.members.first().id == process.env.REY_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpRey", message.author.id)); - } - // ALEXIS - if (message.mentions.members.first().id == process.env.ALEXIS_ID) { - sendMessage(message.channel.id, dialog.getDialog("helpAlexis", message.author.id)); - } - //sendMessage(message.channel.id, ":frowning:" + message.mentions.members.first().id); - } - break; - } - + if (processGameplayCommands(message)) { + return; + } }); -client.on('error', console.error); +//Log our bot in +client.login(npcSettings.token); -// Gets footer commands for botspam channel commands -function getFooterCommands(currentCommand) { - var textFooter = ""; - const filtered = commandArray.filter(word => word !== currentCommand); - //console.log(filtered); +function processGateCommands(message) { + // If it's not the gate + if (message.channel.id !== process.env.GATE_CHANNEL_ID) { + return false; //not processed + } - filtered.forEach(element => { - var appendedText = " | "; - if (textFooter.length !== 0) textFooter += appendedText; - textFooter += element; - }); - //console.log(textFooter); - return textFooter; + //TODO: parse function for commands to hide these ugly lines + let args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); + let command = args.shift().toLowerCase(); + + //WARNING: string constants used here + + //if they haven't chosen a faction + if (!(command === "obsidian" || command === "genesis" || command === "hand")) { + message.reply("Please choose one of the factions by typing your desired faction shown above (!genesis, !obsidian, or !hand).") + .then(msg => msg.delete(10000)) //remove the error message + .catch(console.error); + } + + message.delete(100); //remove the user's input to keep the gate clean + return false; //TODO: set to true once the faction change commands have been assigned to other bots } -// Adds item to inventory -function addItem(userID, item, amount) { - // If item exists in inventory - console.log("[Add Item] " + amount); - var i = userItems.findIndex(i => i.name === item.name); - console.log("[Item Amount Item Exists] i Equals " + i); +function processBasicCommands(message) { + // "This is the best way to define args. Trust me." + // - Some tutorial dude on the internet + let args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); + let command = args.shift().toLowerCase(); - // If there is an item that exists in inventory - if (i !== -1) { - console.log("[Item Amount Start] " + userItems[i].amount); - userItems[i].amount += amount; // Increments amount value - console.log("[Item Amount Finish] " + userItems[i].amount); - // Disallows adding objects such as crystals - } else { - console.log("[Item Amount Wait] Created item for the first time."); - var clonedItem = JSON.parse(JSON.stringify(item)); // Clones item in order to not actually increment the rooms.js item JSON data - userItems.push(clonedItem); - addItem(userID, item, amount - 1); - } + switch (command) { + case "ping": + if (shared.IsAdmin(client, message.author)) { + shared.SendPublicMessage(client, message.author, message.channel, "PONG!"); + } + return true; + + case "obsidian": //TODO: move this to the other bots + return processFactionChangeAttempt(client, message, process.env.GROUP_A_ROLE, "Obsidian"); + + case "genesis": //TODO: move this to the other bots + return processFactionChangeAttempt(client, message, process.env.GROUP_B_ROLE, "Genesis"); + + case "hand": //TODO: move this to the other bots + return processFactionChangeAttempt(client, message, process.env.GROUP_C_ROLE, "Hand"); + + case "help": + case "lore": + shared.SendPublicMessage(client, message.author, message.channel, dialog(command, args[0])); + return true; + + case "xp": + shared.AddXP(client, message.author, args[0]); + return true; + } + + return false; } -// Sends inventory into chat -async function sendInventory(message, pageNum, newMessage) { - var items = ""; - var groupedArr = createGroupedArray(userItems, 5); - - // Sets a default page num, or makes it human readable - if (pageNum === undefined) pageNum = 1; else { - if (pageNum < 1) pageNum = 1; - if (groupedArr.length < pageNum) pageNum = groupedArr.length; - } +function processGameplayCommands(message) { + // "This is the best way to define args. Trust me." + // - Some tutorial dude on the internet + let args = message.content.slice(process.env.PREFIX.length).trim().split(/ +/g); + let command = args.shift().toLowerCase(); - // Checks if page number is valid - if (pageNum > groupedArr.length) { - // If it's longer than actual length, but isn't just an empty inventory - if (!groupedArr.length === 0) return; - } + switch (command) { + case "checkin": + let checkinAmount = calcRandom.random(4, 9); + let checkInResponse = String(dataRequest.sendServerData("checkin", checkinAmount, message.author.id)); + if (checkInResponse === "available") { + shared.SendPublicMessage(client, message.author, message.channel, dialog("checkin", checkinAmount)); + shared.AddXP(client, message.author, 1); //1XP + } else { + shared.SendPublicMessage(client, message.author, message.channel, dialog("checkinLocked", checkInResponse)); + } + return true; - //console.log(pageNum); + case "give": //TODO: fold this code into a function + let amount = Math.floor(args[0]); - // Grabs item in loop, parses it, then adds it to "items" variable - if (groupedArr[pageNum - 1]) { - for (let index = 0; index < groupedArr[pageNum - 1].length; index++) { - // Grabs an item, from a page index - const element = groupedArr[pageNum - 1][index]; + //not enough + if (amount <= 0) { + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveNotAboveZero")); + return true; + } - // Makes if there is an emote, it'll add an extra space - var emoteText = ""; - if (element.emote) emoteText = element.emote + " "; + //didn't mention anyone + if (message.mentions.members.size == 0) { + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveInvalidUser")); + return true; + } - // Adds it in - items += `> ${emoteText}**${element.name}** [${element.amount}x] ${element.info}\n`; - } - } + let targetMember = message.mentions.members.first(); - // No items message to fill field - if (items === "") items = "There are no items in the party's inventory."; + //can't give to yourself + if (targetMember.id === message.author.id) { + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveInvalidUserSelf")); + return true; + } - // To make the message of "Page 1/0" with no items in !inventory not happen - var moddedLength = groupedArr.length; - if (moddedLength < 1) moddedLength = 1; - var moddedPageNum = pageNum; - if (moddedPageNum < 1) moddedPageNum = 1; + let accountBalance = dataRequest.loadServerData("account",message.author.id); - const footer = getFooterCommands("!inventory"); + //not enough money in account + if (accountBalance < amount) { + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveNotEnoughInAccount")); + return true; + } - // Creates embed & sends it - const inv = new Discord.RichEmbed() - .setAuthor(`${message.member.displayName}`, message.author.avatarURL) - .setColor(message.member.displayColor) - .setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.") - .addField(`Items (Page ${moddedPageNum}/${moddedLength})`, items) - .setFooter(`Commands: ${footer}`) + //try to send the money + let val = dataRequest.sendServerData("transfer", targetMember.id, message.author.id, amount); + if (val != "success") { + shared.SendPublicMessage(client, message.author, message.channel, val); + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveFailed")); + return true; + } - var invMessage; - if (!newMessage) - invMessage = await message.channel.send({embed: inv}); - else { - invMessage = newMessage; - await invMessage.edit({embed: inv}); - } - - // Collector for emotes - const emotes = ['⬅', '❌', '➡']; - const collector = invMessage.createReactionCollector( - (reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id & message.author.id === user.id, { time: 15 * 1000 }); - var react = ""; - var endedOnReact; - - // Sends reactions - if (!newMessage) { - for (let i = 0; i < emotes.length; i++) { - const element = emotes[i]; - console.log(element); - await invMessage.react(element); - } - } + //print the success message + shared.SendPublicMessage(client, message.author, message.channel, dialog("giveSuccessful", targetMember.id, amount)); + return true; - // Collects reactions - collector.on("collect", async reaction => { - var user = reaction.users.last(); - react = reaction.emoji.name; - if (react !== '❌') { reaction.remove(user); } - endedOnReact = true; - collector.stop(); - }); + case "stats": //TODO: fold this code into a function + // Sees if the user is supposed to level up + let levelUp = shared.LevelUp(client, message.member); //TODO: process automatically - // Clears reactions - collector.once("end", async collecter => { - console.log("[Reaction Options] Ended collector, clearing emotes and sending timing out message if needed."); + // Grabs all parameters from server + //TODO: improve this once the server-side has been updated + let attacker = String(dataRequest.loadServerData("userStats",message.author.id)).split(","); - if (!endedOnReact) { - invMessage.clearReactions(); - return message.channel.send(":x: **Timed Out**: The emote reaction request timed out after 15 seconds."); - } - if (react === '❌') { - invMessage.clearReactions(); - return invMessage.edit(invMessage.content); - } + if (attacker[0] == "failure") { + shared.SendPublicMessage(client, message.author, message.channel, "The server returned an error."); + return true; + } - var pageNumModifier = 0; - if (react === emotes[0]) pageNumModifier -= 1; - if (react === emotes[2]) pageNumModifier += 1; - console.log(pageNum + " | " + pageNumModifier); - sendInventory(message, pageNum + pageNumModifier, invMessage); - }); + let attackerStrength = parseFloat(attacker[1]); //TODO: constants representing the player structure instead of [0] + let attackerSpeed = parseFloat(attacker[2]); + let attackerStamina = parseFloat(attacker[3]); + let attackerHealth = parseFloat(attacker[4]); + let attackerMaxStamina = parseFloat(attacker[5]); + let attackerMaxHealth = parseFloat(attacker[6]); + let attackerWallet = parseFloat(attacker[7]); + let attackerXP = parseFloat(attacker[8]); + let attackerLVL = Math.floor(parseFloat(attacker[9])); + let attackerLvlPercent = parseFloat(attacker[10]); + let attackerStatPoints = parseFloat(attacker[11]); + + // Forms stats into a string + var levelText = `:level: **${attackerLVL}**`; //NOTE: I don't like backticks + var levelProgress = `(${attackerLvlPercent}%)`; + var crystalText = `:crystals: **${attackerWallet}**`; + var cannisterText = `:cannister: **${attackerStatPoints}**`; + var userStats = "```" + `STR: ${attackerStrength} | SPD: ${attackerSpeed} | STAM: ${attackerStamina}/${attackerMaxStamina} | HP: ${attackerHealth}/${attackerMaxHealth}` + "```"; + + // Says level is maxed out if it is LVL 30+ + if (attackerLVL >= process.env.RANK_3_THRESHOLD) { + levelProgress = "(MAX)"; + } + + // Creates embed & sends it + const embed = new Discord.RichEmbed() + .setAuthor(`${message.member.displayName}`, message.author.avatarURL) + .setColor(message.member.displayColor) + .setDescription(`${levelText} ${levelProgress} | ${crystalText} | ${cannisterText}`) + .addField("Stats", userStats) + .setFooter("Commands: !help | !lore | !checkin"); + + message.channel.send(embed); + + //handle levelling up + if (levelUp === "levelUp" || levelUp === "RankUp") { + if (attackerLVL >= process.env.RANK_3_THRESHOLD) { + shared.SendPublicMessage(client, message.author, message.channel, dialog("levelUpCap", dialog("levelUpCapRemark"), attackerLVL)); + } else { + shared.SendPublicMessage(client, message.author, message.channel, dialog("LevelUp", dialog("levelUpRemark"), attackerLVL, attackerStatPoints)); + } + } + + return true; + } + + //didn't process it + return false; } -// Appraise an item -async function appraiseItem(message) { - const itemName = message.content.replace("!item", "").trim().toLowerCase(); - console.log("[Item Appraisal] " + `<< ${itemName} >>`); - - // Show if no parameter is given - if (itemName === "" || !itemName) { - message.channel.send(`:x: ${message.author} Please tell me the item name from your inventory, or I won't know which item you want me to look at.`); - return; - } - - var i = userItems.findIndex(i => i.name.toLowerCase() === itemName); - console.log("[Item Amount Item Exists] i Equals " + i); - - // If there is an item that exists in inventory - if (i !== -1) { - console.log(`[Item Appraisal] Found item in inventory!`); - const embed = new Discord.RichEmbed() - .setAuthor(`${message.member.displayName}`, message.author.avatarURL) - .setColor(message.member.displayColor) - .setTitle(userItems[i].name) - .setDescription(userItems[i].info) - - if (userItems[i].type.subtype) - embed.addField("Type", `${userItems[i].type.type}\n> ${userItems[i].type.subtype}`, true) - else - embed.addField("Type", `${userItems[i].type.type}`, true) - - if (userItems[i].type.stats) { - console.log(JSON.stringify(userItems[i].type.stats, null, 4)) - var itemStats = "There are no stats avaliable."; - var resetItemStats = false; - userItems[i].type.stats.forEach(element => { - if (element) { - if (!resetItemStats) { - resetItemStats = true; - itemStats = ""; - } - const types = [ - "attack", - "defence", - "speed", - "healing" - ]; - - types.forEach(type => { - if (element[type]) { - switch (type) { - case "attack": - itemStats += `ATK: ${element.attack}\n`; - break; - case "defence": - itemStats += `DEF: ${element.defence}\n`; - break; - case "speed": - itemStats += `SPD: ${element.speed}\n`; - break; - case "healing": - itemStats += `Healing: ${element.healing} HP\n`; - break; - } - } - }); - } - }); - } - - embed.addField("Stats", `${itemStats}`, true); - - message.channel.send(embed); - - // Disallows adding objects such as crystals - } else { - console.log("[Item Appraisal] Couldn't find item in inventory."); - message.channel.send(`:x: ${message.author} I'm unable to find "${itemName}" in your inventory.`); - } -} - -// Creates an array that creates multiple different arrays inside of that array -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] -// http://www.frontcoded.com/splitting-javascript-array-into-chunks.html -var createGroupedArray = function(arr, chunkSize) { - var groups = [], i; - for (i = 0; i < arr.length; i += chunkSize) { - groups.push(arr.slice(i, i + chunkSize)); - } - return groups; -} - -// See if the bot should display its message -function checkValidDisplay(member, channelID, checkRole) { - if (client.user.username == "Kamala, Obsidian Vice President" && channelID === process.env.GROUP_A_BOT_ID) { - if (checkRole) { if (member.roles.has(process.env.GROUP_A_ROLE)) return true; } else true; - } - else if (client.user.username == "Captain Montgomery" && channelID === process.env.GROUP_B_BOT_ID) { - if (checkRole) { if (member.roles.has(process.env.GROUP_B_ROLE)) return true; } else true; - } - else if (client.user.username == "Dairo, High Prophet of The Hand" && channelID === process.env.GROUP_C_BOT_ID) { - if (checkRole) { if (member.roles.has(process.env.GROUP_C_ROLE)) return true; } else true; - } - else if (client.user.username == "Ghost 5.0.1") { - // JSON - const rooms = require('../TextAdv/rooms.json'); - var roomExists = false; - - // Loops for all rooms - rooms.rooms.forEach(element => { - if (channelID === rooms[element].channel) roomExists = true; - }); - - if (!roomExists) { - if (channelID === process.env.TEST_CHANNEL_ID) return true; - } else return true; - - } - - return false; -} - -// Gets if user has an Overseers rank -function isAdmin(userID) { - var guild = client.guilds.get(process.env.SANCTUM_ID); - return guild.members.get(userID).roles.find(role => role.name === "Overseers"); -} - -// Change Faction -async function changeFaction(factionID, channelID, userID, member, botChannelID) { - if (member.roles.has(factionID)) { - if (factionID === process.env.GROUP_A_ROLE) - sendMessage(channelID, dialog.getDialog("orderAlreadyJoined", userID)); - else if (factionID === process.env.GROUP_B_ROLE) - sendMessage(channelID, dialog.getDialog("anarchyAlreadyJoined", userID)); - else if (factionID === process.env.GROUP_C_ROLE) - sendMessage(channelID, dialog.getDialog("religionAlreadyJoined", userID)); - } else { - if (dataRequest.loadServerData("hasConvertedToday", userID) == 1) { - sendMessage(channelID, dialog.getDialog("alreadyConvertedToday", userID)); - } else { - // Creates new user - var response = String(dataRequest.sendServerData("newUser", "New user.", userID)); - - //var response = "createdUser" - // Obsidian Tech. - if (factionID === process.env.GROUP_A_ROLE) { - await member.removeRole(process.env.GROUP_B_ROLE); - await member.removeRole(process.env.GROUP_C_ROLE); - await member.addRole(process.env.GROUP_A_ROLE); - - dataRequest.sendServerData("conversion", "Converted to The Order.", userID); - - if (response == "createdUser") { - client.users.get(userID).send(dialog.getDialog("newUserPM", userID, getFactionName(factionID))); - sendMessage(botChannelID, dialog.getDialog("newUserWelcome", userID, `<#${getFactionName(factionID)}>`)); - } else { - sendMessage(channelID, dialog.getDialog("orderJoin", userID)); - } - - // Genesis Command - } else if (factionID === process.env.GROUP_B_ROLE) { - await member.removeRole(process.env.GROUP_C_ROLE); - await member.removeRole(process.env.GROUP_A_ROLE); - await member.addRole(process.env.GROUP_B_ROLE); - - dataRequest.sendServerData("conversion", "Converted to the Anarchy.", userID); - - if (response == "createdUser") { - client.users.get(userID).send(dialog.getDialog("newUserPM", userID, getFactionName(factionID))); - sendMessage(botChannelID, dialog.getDialog("newUserWelcome", userID, `<#${getFactionName(factionID)}>`)); - } else { - sendMessage(channelID, dialog.getDialog("anarchyJoin", userID)); - } - - // The Hand - } else if (factionID === process.env.GROUP_C_ROLE) { - await member.removeRole(process.env.GROUP_A_ROLE); - await member.removeRole(process.env.GROUP_B_ROLE); - await member.addRole(process.env.GROUP_C_ROLE); - - dataRequest.sendServerData("conversion", "Converted to The Religion.", userID); - - if (response == "createdUser") { - client.users.get(userID).send(dialog.getDialog("newUserPM", userID, getFactionName(factionID))); - sendMessage(botChannelID, dialog.getDialog("newUserWelcome", userID, `<#${getFactionName(factionID)}>`)); - } else { - sendMessage(channelID, dialog.getDialog("religionJoin", userID)); - } - } - } - } -} - -function addXP(userID,amount) { - var response = String(dataRequest.sendServerData("addXP", amount, userID)); -} - -function getLevelUp(userID) { - const server = client.guilds.get(process.env.SANCTUM_ID); - const member = server.members.get(userID); - if (client.user.username == "Kamala, Obsidian Vice President" && !member.roles.has(process.env.GROUP_A_ROLE)) return; - if (client.user.username == "Captain Montgomery" && !member.roles.has(process.env.GROUP_B_ROLE)) return; - if (client.user.username == "Dairo, High Prophet of The Hand" && !member.roles.has(process.env.GROUP_C_ROLE)) return; - - //const user = server.members.get(userID); - var response = String(dataRequest.sendServerData("getLevelUp", 0, userID)); - var responseMessage = String(response.split(",")[0]); - var lvl = Math.floor(parseFloat(response.split(",")[1])); - var statPoints = parseFloat(response.split(",")[2]); - - var attacker = String(dataRequest.loadServerData("userStats", userID)); - var chests = parseFloat(attacker.split(",")[11]); - - console.log(response.split(",")); - - majorLevelUp(lvl, server, userID); - - if (responseMessage == "levelup") { - //if (true) { - console.log("Chests: " + chests) - checkinLevelUp(userID, lvl, statPoints, chests); - } -} - -async function majorLevelUp(level, server, userID) { - const user = server.members.get(userID); - - var newChannel = ""; - - var levels = [ - // Role, Level - [server.roles.find(role => role.name === "LVL 1+"), 1, process.env.CRYSTAL_SHORES_CHANNEL_ID], - [server.roles.find(role => role.name === "LVL 15+"), 15, process.env.SEA_OF_FOG_CHANNEL_ID], - [server.roles.find(role => role.name === "LVL 30+"), 30, process.env.DEADLANDS_CHANNEL_ID] - ] - - // Shrinking level - if (level < 30) { - level = 15; - } else if (level < 15) { - level = 1; - } - - // Rank Level Up - var levelRole = server.roles.find(role => role.name === `LVL ${level}+`); - if (levelRole) { - var memberRole = user.roles.has(levelRole.id); - if (!memberRole) { - user.addRole(levelRole).catch(console.error); - for (let i = 0; i < levels.length; i++) { - const element = levels[i]; - if (element[1] !== level) { - await user.removeRole(element[0]); - } - } - if (user !== undefined) {// && newChannel !== undefined) { - var levelMarks = [1, 15, 30]; - - for (let i = 0; i < levelMarks.length; i++) { - const element = levelMarks[i]; - // Gets channel of array - newChannel = client.channels.get(levels[levels.findIndex(level => level[1] === element)][2]); - if (level === element) - newChannel.send(dialog.getDialog("level" + level, user, newChannel)); - } - } - } - } -} - -// Gets the user's role by member -function getFactionChannel(member) { - var playerChannel; - var isGroupA = member.roles.has(process.env.GROUP_A_ROLE); - var isGroupB = member.roles.has(process.env.GROUP_B_ROLE); - var isGroupC = member.roles.has(process.env.GROUP_C_ROLE); - //console.log(member.roles); - //console.log("isGroup: " + isGroupA + " " + isGroupB + " " + isGroupC); - if (isGroupA) playerChannel = process.env.GROUP_A_BOT_ID; - else if (isGroupB) playerChannel = process.env.GROUP_B_BOT_ID; - else if (isGroupC) playerChannel = process.env.GROUP_C_BOT_ID; - - return playerChannel; -} - -// Gets faction names by ID -function getFactionName(factionID) { - if (factionID === process.env.GROUP_A_ROLE) { - return "Obsidian Technologies"; - } - if (factionID === process.env.GROUP_B_ROLE) { - return "Genesis Command"; - } - if (factionID === process.env.GROUP_C_ROLE) { - return "The Hand"; - } -} - -function checkinLevelUp(userID, lvl, statPoints, chests) { - const guild = client.guilds.get(process.env.SANCTUM_ID); - if (lvl === 30) { - //Post level cap level up! - sendMessage(userID, getFactionChannel(guild.members.get(userID)), dialog.getDialog("levelUpLevelCap", userID, lvl, chests)); - } else { - //regular level up - sendMessage(userID, getFactionChannel(guild.members.get(userID)), dialog.getDialog("levelUp", userID, lvl, statPoints)); - } - //sendMessage(testChannelID, dialog.getDialog("levelUp", userID, lvl, statPoints)); -} - -// Updates stamina (1) and health by 1% every 2 min. -cron.schedule('*/2 * * * *', function() { - if (client.user.username === "A.D.A.M.") { - console.log('Updating STAMINA every 2 min.'); - dataRequest.sendServerData("updateStamina", 0); - }; -}); - -// Send message handler -function sendMessage(userID, channelID, message) { - // Handle optional first argument (so much for default arugments in node) - if (message === undefined) { - message = channelID; - channelID = userID; - userID = null; - } - - // Utility trick (@userID with an optional argument) - if (userID != null) { - message = "<@" + userID + "> " + message; - } - - // Sends message (needs client var, therefore I think external script won't work) - client.channels.get(channelID).send(message); -} - -// Log our bot in -client.login(npcSettings.token); \ No newline at end of file +//tailor this for each faction leader +function processFactionChangeAttempt(client, message, factionRole, factionShorthand) { + shared.ChangeFaction(client, factionRole, message.channel, message.member) + .then(result => { + switch (result) { + case "alreadyJoined": + shared.SendPublicMessage(client, message.author, message.channel, dialog("alreadyJoined" + factionShorthand)); + break; + case "hasConvertedToday": + shared.SendPublicMessage(client, message.author, message.channel, dialog("conversionLocked")); + break; + case "createdUser": + shared.SendPublicMessage(client, message.author, message.channel, dialog("newUserPublicMessage", shared.GetFactionName(factionRole), "TODO: factionChannel")); + shared.SendPrivateMessage(client, message.author, dialog("newUserPrivateMessage", dialog("newUserPrivateMessageRemark" + factionShorthand))); + break; + case "joined": + shared.SendPublicMessage(client, message.author, message.channel, dialog("join" + factionShorthand)); + break; + default: + //DEBUGGING + console.log("processFactionChangeAttempt failed:" + result); + } + }) + .catch(console.error); + return true; +} \ No newline at end of file diff --git a/ADAM/dialog.json b/ADAM/dialog.json index b5679ee..abb08e8 100644 --- a/ADAM/dialog.json +++ b/ADAM/dialog.json @@ -1,36 +1,36 @@ { - "help": "_This world is strange and mysterious. And while I cannot help you on your journey or join your faction, I am here to help travelers to the best of my ability._\n\nHere is what I can do for you:\n\n!checkin\n```Once per day, you may come see me for a daily sum in exchange for your help around the city.```\n!stats\n```I can share all of your stats and your crystal count information.```\n!give [AMOUNT] [@USER]\n```I can transfer some of your crystals to another traveler's account. Just make sure you have enough.```\n!help [@NAME]\n```I can tell you a little bit about some of the other people with us here on New Eden.```\nI hope this helps you on your journey, traveler.", + "help": "*This world is strange and mysterious. And while I cannot help you on your journey or join your faction, I am here to help travelers to the best of my ability.*\n\n*Here is what I can do for you:*\n\n!checkin\n```Once per day, you may come see me for a daily sum in exchange for your help around the city.```\n!stats\n```I can share all of your stats and your crystal count information.```\n!give [AMOUNT] [@USER]\n```I can transfer some of your crystals to another traveler's account. Just make sure you have enough.```\n!help [@NAME]\n```I can tell you a little bit about some of the other people with us here on New Eden.```\nI hope this helps you on your journey, traveler.", "helpCptMon": "TODO: Data Missing.", "helpDairo": "TODO: Data Missing.", "helpGhost": "TODO: Data Missing.", "helpKamala": "TODO: Data Missing.", - "helpAlexis": "_Alexis is our top-of-the-line chemist who uses her talents to reward travelers with a nice and relaxing space. She'd be happy to have or provide you with some company._\n\n!buydrink\n```In #🍺travelers-watch, this allows you to buy a drink and relax.```\n!buydrink [@NAME]\n```In #🍺travelers-watch, you can buy a drink for a friend.```\n!tip [AMOUNT]\n```In #🍺travelers-watch, you can tip her for her great service. She might just give you a tip back.```", - "helpGraze": "_Graze is our loveable augmentation expert. He can help you upgrade your skills and boost your abilities. Here's what he can do:_\n\n!upgrade\n```Shows you the available upgrades that Graze can provide with your Nanotech Cannisters.```\n!upgrade [STAT]\n```Upgrades this specific stat permanently.```", + "helpAlexis": "*Alexis is our top-of-the-line chemist who uses her talents to reward travelers with a nice and relaxing space. She'd be happy to have or provide you with some company.*\n\n!buydrink\n```In #🍺travelers-watch, this allows you to buy a drink and relax.```\n!buydrink [@NAME]\n```In #🍺travelers-watch, you can buy a drink for a friend.```\n!tip [AMOUNT]\n```In #🍺travelers-watch, you can tip her for her great service. She might just give you a tip back.```", + "helpGraze": "*Graze is our loveable augmentation expert. He can help you upgrade your skills and boost your abilities. Here's what he can do:*\n\n!upgrade\n```Shows you the available upgrades that Graze can provide with your Nanotech Cannisters.```\n!upgrade [STAT]\n```Upgrades this specific stat permanently.```", "helpLibrarian": "TODO: Data Missing.", - "helpMori": "_Mori is our resident head of the medbay. He can tend to your wounds and get you back on your feet. Here's what he can do:_\n\n!heal\n```Shows you Mori's available procedures for healing.```\n!heal [ITEM]\n```Purchases a procedure directly from him, and with his nanotech, takes effect immediately.```", - "helpMosiah": "_Mosiah was exiled from our great city for many counts of misconduct, but it's been said he's been seen recently. I recommend you not deal with him at all, but should you need to, here's what he can do:_\n\n!wager [AMOUNT]\n```Wagers your crystals in a primative coin flip bet. Winner takes all.```", - "helpRey": "_Rey is a master of finding things that we need around the city. Resources are scarce, so anything you can help her find would be most helpful._\n\n!scavenge\n```In #🌘the-outskirts, this allows you to look for materials and resources with Rey.```\n!materials\n```Shows you the current materials that you have in your inventory.```", - "helpSonya": "_Professor Sonya is our resident archeologist, and she is fascinated by this world. Scavenge for some artifacts in the outskirts of the city, and she will apy you handsomely._\n\n!scavenge\n```In #🌘the-outskirts, this allows you to look for rare artifacts for the professor.```\n!artifacts\n```Shows you the current artifacts that you have in your inventory.```\n!artifacts sell\n```Shows you the current prices that the professor is willing to pay for any artifacts that you may find.```\n!artifacts sell [TYPE]\n```Sells all of the artifacts that you have of that type to the professor, at current prices.```", + "helpMori": "*Mori is our resident head of the medbay. He can tend to your wounds and get you back on your feet. Here's what he can do:*\n\n!heal\n```Shows you Mori's available procedures for healing.```\n!heal [ITEM]\n```Purchases a procedure directly from him, and with his nanotech, takes effect immediately.```", + "helpMosiah": "*Mosiah was exiled from our great city for many counts of misconduct, but it's been said he's been seen recently. I recommend you not deal with him at all, but should you need to, here's what he can do:*\n\n!wager [AMOUNT]\n```Wagers your crystals in a primative coin flip bet. Winner takes all.```", + "helpRey": "*Rey is a master of finding things that we need around the city. Resources are scarce, so anything you can help her find would be most helpful.*\n\n!scavenge\n```In #🌘the-outskirts, this allows you to look for materials and resources with Rey.```\n!materials\n```Shows you the current materials that you have in your inventory.```", + "helpSonya": "*Professor Sonya is our resident archeologist, and she is fascinated by this world. Scavenge for some artifacts in the outskirts of the city, and she will apy you handsomely.*\n\n!scavenge\n```In #🌘the-outskirts, this allows you to look for rare artifacts for the professor.```\n!artifacts\n```Shows you the current artifacts that you have in your inventory.```\n!artifacts sell\n```Shows you the current prices that the professor is willing to pay for any artifacts that you may find.```\n!artifacts sell [TYPE]\n```Sells all of the artifacts that you have of that type to the professor, at current prices.```", - "helpRavager": "_The Ravagers have been hunting us since crashing here on New Eden. They roam this planet and will attack travelers on sight. But you can defend yourself:_\n\n!attack\n```Sends your weapon towards an active Ravager. If you win the fight, you can loot their corpse for crystals. But be careful: they bite back.```\n!details\n```Shows you the details of the last Ravager fight to take place as well as the crystal distribution.```", + "helpRavager": "*The Ravagers have been hunting us since crashing here on New Eden. They roam this planet and will attack travelers on sight. But you can defend yourself:*\n\n!attack\n```Sends your weapon towards an active Ravager. If you win the fight, you can loot their corpse for crystals. But be careful: they bite back.```\n!details\n```Shows you the details of the last Ravager fight to take place as well as the crystal distribution.```", - "checkin": "<@{1}> your presence has been noted. I've added {2} crystals to your account.", - "checkinLocked": ":x: <@{1}> you already checked in with me {2}. You can check in again tomorrow.", - "conversionLocked": ":x: <@{1}> as anxious as you may be, please don't attempt to change factions so quickly. You can only change once every 30 days.", + "checkin": "Your presence has been noted. I've added {1} crystals to your account.", + "checkinLocked": ":x: You already checked in with me {1}. You can check in again tomorrow.", + "conversionLocked": ":x: As anxious as you may be, please don't attempt to change factions so quickly. You can only change once every 30 days.", "depositSuccessful": "<@{1}> your deposit of {2} crystals has been successful. Good luck.", "depositFailed": ":x: <@{1}> I can't make the deposit at the moment. I apologize for the inconvenience.", - "giveSuccessful": "<@{1}> I've transferred {3} crystals to <@{2}> as per your request.", - "giveFailed": ":x: <@{1}> I can't make that transfer at the moment. I apologize for the inconvenience.", - "giveNotEnoughInAccount": ":x: <@{1}> You don't have that many crystals in your account. As such, I can't complete the transfer.", - "giveNotAboveZero": ":x: <@{1}> In order for me to complete the transfer I need an amount above zero.", - "giveInvalidUser": ":x: <@{1}> I can't find that traveler. Sorry.", - "giveInvalidUserSelf": ":x: <@{1}> You can't send crystals to yourself. Sorry.", + "giveSuccessful": "I've transferred {2} crystals to <@{1}> as per your request.", + "giveFailed": ":x: I can't make that transfer at the moment. I apologize for the inconvenience.", + "giveNotEnoughInAccount": ":x: You don't have that many crystals in your account. As such, I can't complete the transfer.", + "giveNotAboveZero": ":x: In order for me to complete the transfer I need an amount above zero.", + "giveInvalidUser": ":x: I can't find that traveler. Sorry.", + "giveInvalidUserSelf": ":x: You can't send crystals to yourself. Sorry.", - "LevelUp": "You just hit __level {2}__!{1} I've added a :cannister: __Nanotech Cannister to your inventory so that you can upgrade your skills. You now have __{3}__ total (you can check this any time with !stats).", + "LevelUp": "You just hit **level {2}**!{1} I've added a :cannister: **Nanotech Cannister** to your inventory so that you can upgrade your skills. You now have **{3}** total (you can check this any time with !stats).", "levelUpRemark": [ " I appreciate all of your help.", " Thank you for doing so much for the city.", @@ -40,7 +40,7 @@ " The citizens of The Sanctum are most grateful.", " I cannot thank you enough for your help defending the city." ], - "levelUpCap": "You're currently at __level {2}__ which is the current level cap!{1} I've added a :cyphercrate: __Cypher Crate__ to your inventory. Hopefully it contains something useful for you on your journey. You now have __{3}__ total (you can check this any time with !stats). Good luck.", + "levelUpCap": "You're currently at **level {2}** which is the current level cap!{1} I've added a :cyphercrate: **Cypher Crate** to your inventory. Hopefully it contains something useful for you on your journey. You now have **{3}** total (you can check this any time with !stats). Good luck.", "levelUpCapRemark": [ " I appreciate all of your help.", " Thank you for doing so much for the city.", @@ -56,33 +56,35 @@ "victors": "Currently, {1} controls the fate of the codex.", "noVictors": "The fate of the codex is still undetermined.", - "alreadyJoinedObsidian": ":x: <@{1}> You are already employed by Obsidian Technologies. There's no need to request a change.", - "joinObsidian": "<@{1}> You are now employed by Obsidian Technologies.", + "alreadyJoinedObsidian": ":x: You are already employed by Obsidian Technologies. There's no need to request a change.", + "joinObsidian": "You are now employed by Obsidian Technologies.", - "alreadyJoinedGenesis": ":x: <@{1}> You are already serving Genesis Command. There's no need to request a change.", - "joinGenesis": "<@{1}> You have joined the Genesis Command. Finally, some order can be enacted in this chaos.", + "alreadyJoinedGenesis": ":x: You are already serving Genesis Command. There's no need to request a change.", + "joinGenesis": "You have joined the Genesis Command. Finally, some order can be enacted in this chaos.", - "alreadyJoinedHand": ":x: <@{1}> The Hand is happy to have you in their congregation already. There's no need to request a change.", - "joinHand": "<@{1}> You may now spread the word of the Hand. May the gods look favourably upon you.", + "alreadyJoinedHand": ":x: The Hand is happy to have you in their congregation already. There's no need to request a change.", + "joinHand": "You may now spread the word of the Hand. May the gods look favourably upon you.", - "newUserPublicMessage": "<@{1}> welcome to {2}. If you need me for anything, you can contact me via this secure channel. Just use __!help__ for a list of things I can do for you.\n\nAnd don't forget to say hello to your fellow travelers in {3}.", - "newUserPrivateMessage": "_Traveler, welcome to The Sanctum._\n\n{1}\n\nI'll get you patched up and give you access to our team to upgrade skills and meet the others. There's just a few things I need you to take care of around the city:\n\n__!checkin__ with me daily.\n```Once a day I'll give you your daily allotment of crystals in exchange for some help around the city.```\n__!attack__ any Ravagers in #the-deadlands.\n```With the constant bombardment from the enemies of the city, It's hard to keep us safe. I need your help```\n\n_Good luck. I'll be around if you need me._", + "newUserPublicMessage": "Welcome to {1}. If you need me for anything, you can contact me via this secure channel. Just use **!help** for a list of things I can do for you.\n\nAnd don't forget to say hello to your fellow travelers in {2}.", + "newUserPrivateMessage": "*Traveler, welcome to The Sanctum.*\n\n{1}\n\nI'll get you patched up and give you access to our team to upgrade skills and meet the others. There's just a few things I need you to take care of around the city:\n\n**!checkin** with me daily.\n```Once a day I'll give you your daily allotment of crystals in exchange for some help around the city.```\n**!attack** any Ravagers in #the-deadlands.\n```With the constant bombardment from the enemies of the city, It's hard to keep us safe. I need your help```\n\n*Good luck. I'll be around if you need me.*", - "newUserPrivateMessageRemarkObsidian": "I see that you've joined __Obsidian Technologies__. While they are the most chaotic of the 3 factions, I can see why you'd pick them. The Codex is a very powerful book, and should you be victorious, everyone will have equal access to it's secrets. TODO", - "newUserPrivateMessageRemarkGenesis": "I see that you've joined __Genesis Command__. The least reckless of the 3 factions, I can see why you'd pick them. You clearly understand that The Codex is a very powerful book, and should you be victorious, no one will have access to it's secrets. TODO", - "newUserPrivateMessageRemarkHand": "I see that you've joined __The Hand__. While they are certainly the most suspicious of the 3 factions, I can see why you'd pick them. The Codex is a very powerful book, and should you be victorious, it is your job to guide the rest of the city using it's secrets. TODO", + "newUserPrivateMessageRemarkObsidian": "I see that you've joined **Obsidian Technologies**. While they are the most chaotic of the 3 factions, I can see why you'd pick them. The Codex is a very powerful book, and should you be victorious, everyone will have equal access to it's secrets. TODO", + "newUserPrivateMessageRemarkGenesis": "I see that you've joined **Genesis Command**. The least reckless of the 3 factions, I can see why you'd pick them. You clearly understand that The Codex is a very powerful book, and should you be victorious, no one will have access to it's secrets. TODO", + "newUserPrivateMessageRemarkHand": "I see that you've joined **The Hand**. While they are certainly the most suspicious of the 3 factions, I can see why you'd pick them. The Codex is a very powerful book, and should you be victorious, it is your job to guide the rest of the city using it's secrets. TODO", - "intro": "_Hello weary traveler._\n\n_My name is A.D.A.M. and I would like to offer you the amenities of The Sanctum. However, I cannot come to your aid until you choose a faction. I am dearly sorry to be so blunt and put trivial human rules in place over your sustenance and safety, but this is the only way to protect The Codex. But the Codex no longer exists since the Librarian destroyed it, so make something up, player. TODO_\n\n_Your choices are as follows:_", - "introObsidian": "<@{1}> !obsidian\n```Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu aliquet mauris, id congue nisi. Integer et lobortis tellus. Sed bibendum a metus quis volutpat. Mauris faucibus quam at euismod scelerisque. Vestibulum a elit auctor, venenatis augue in, rhoncus nisi. Mauris sagittis sit amet ante eget luctus. Maecenas id malesuada elit. Vestibulum nec ante nec justo venenatis tincidunt.```", - "introGenesis": "<@{1}> !genesis\n```Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu aliquet mauris, id congue nisi. Integer et lobortis tellus. Sed bibendum a metus quis volutpat. Mauris faucibus quam at euismod scelerisque. Vestibulum a elit auctor, venenatis augue in, rhoncus nisi. Mauris sagittis sit amet ante eget luctus. Maecenas id malesuada elit. Vestibulum nec ante nec justo venenatis tincidunt.```", - "introHand": "<@{1}> !hand\n```Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu aliquet mauris, id congue nisi. Integer et lobortis tellus. Sed bibendum a metus quis volutpat. Mauris faucibus quam at euismod scelerisque. Vestibulum a elit auctor, venenatis augue in, rhoncus nisi. Mauris sagittis sit amet ante eget luctus. Maecenas id malesuada elit. Vestibulum nec ante nec justo venenatis tincidunt.```", - "introEnd": "_Choose wisely._", + "intro": "*Hello weary traveler.*\n\n*My name is A.D.A.M. and I would like to offer you the amenities of The Sanctum. However, I cannot come to your aid until you choose a faction. I am dearly sorry to be so blunt and put trivial human rules in place over your sustenance and safety, but this is the only way to protect The Codex. But the Codex no longer exists since the Librarian destroyed it, so make something up, player. TODO*\n\n*Your choices are as follows:*", + "introObsidian": "<@&{1}> !obsidian\n```Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu aliquet mauris, id congue nisi. Integer et lobortis tellus. Sed bibendum a metus quis volutpat. Mauris faucibus quam at euismod scelerisque. Vestibulum a elit auctor, venenatis augue in, rhoncus nisi. Mauris sagittis sit amet ante eget luctus. Maecenas id malesuada elit. Vestibulum nec ante nec justo venenatis tincidunt.```", + "introGenesis": "<@&{1}> !genesis\n```Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu aliquet mauris, id congue nisi. Integer et lobortis tellus. Sed bibendum a metus quis volutpat. Mauris faucibus quam at euismod scelerisque. Vestibulum a elit auctor, venenatis augue in, rhoncus nisi. Mauris sagittis sit amet ante eget luctus. Maecenas id malesuada elit. Vestibulum nec ante nec justo venenatis tincidunt.```", + "introHand": "<@&{1}> !hand\n```Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eu aliquet mauris, id congue nisi. Integer et lobortis tellus. Sed bibendum a metus quis volutpat. Mauris faucibus quam at euismod scelerisque. Vestibulum a elit auctor, venenatis augue in, rhoncus nisi. Mauris sagittis sit amet ante eget luctus. Maecenas id malesuada elit. Vestibulum nec ante nec justo venenatis tincidunt.```", + "introEnd": "*Choose wisely.*", - "LVL 1+": "Congratulations {1}, you have reached __{2}__! Travelers defend the city from Ravagers here, and you can earn some crystals.", - "LVL 15+": "Congratulations {1}, you have reached __{2}__, where there are more dangerous enemies lurking in the fog.", - "LVL 30+": "Congratulations {1}, you have reached __{2}__, the area most teeming with the strongest monsters. Watch your back, and good luck!", + "LVL 1+": "Congratulations {1}, you have reached **{2}**! Travelers defend the city from Ravagers here, and you can earn some crystals.", + "LVL 15+": "Congratulations {1}, you have reached **{2}**, where there are more dangerous enemies lurking in the fog.", + "LVL 30+": "Congratulations {1}, you have reached **{2}**, the area most teeming with the strongest monsters. Watch your back, and good luck!", - "loreBackstory": "_Mother Earth had failed us._\n\n_In her dying breath, she bore a starship, __The Genesis__, to save the last of humankind. But the __travelers__ aboard were not prepared for the unwelcoming winds of barren space._\n\n_On the brink of extinction our forefathers landed here, but this was no earth. The desolate landscape of __The Deadlands__ traded our starvation for thirst, our isolation for open and empty space. But despite our struggles, we could breathe again._\n\n_We walked for many days and many nights in __The Deadlands__, consuming only the native __crystals__ protruding from the ground for sustenance. Leaving the shelter of our vessel behind for the hope of a new home. Many withered away under the scorching heat of the twin suns and the constant attacks from __Ravagers__, but Mother Earth kept her promise._\n\n_In our darkest hour, we laid eyes on __The Sanctum__, a city of the gods. Complete with a vault full of our edible crystals, and more than enough room for the entire population; A city with human amenities in the middle of an inhuman world, bestowed upon a dying nation in need. This place was truly a divine gift._\n\n_At the highest point of the city in the tower that touched the clouds, we found __The Librarian__. A meticulous mechanical record keeper hovering over his book, the great __Codex Arcana__. This was a book written in detail to record the actions of every man, woman, and child that lived among us. But it was far too powerful, and the secrets it contained proved lethal in the wrong hands._\n\n_And so began the __factions__, vying for control over the Codex._\n\n- Excerpt from the __Teachings of Tiberius__. March 22, 2630.", + "lore": "Choose one of these: !lore [backstory, genesis, travelers, deadlands, sanctum, librarian, codex, factions]", + + "loreBackstory": "*Mother Earth had failed us.*\n\n*In her dying breath, she bore a starship, **The Genesis**, to save the last of humankind. But the **travelers** aboard were not prepared for the unwelcoming winds of barren space.*\n\n*On the brink of extinction our forefathers landed here, but this was no earth. The desolate landscape of **The Deadlands** traded our starvation for thirst, our isolation for open and empty space. But despite our struggles, we could breathe again.*\n\n*We walked for many days and many nights in **The Deadlands**, consuming only the native **crystals** protruding from the ground for sustenance. Leaving the shelter of our vessel behind for the hope of a new home. Many withered away under the scorching heat of the twin suns and the constant attacks from **Ravagers**, but Mother Earth kept her promise.*\n\n*In our darkest hour, we laid eyes on **The Sanctum**, a city of the gods. Complete with a vault full of our edible crystals, and more than enough room for the entire population; A city with human amenities in the middle of an inhuman world, bestowed upon a dying nation in need. This place was truly a divine gift.*\n\n*At the highest point of the city in the tower that touched the clouds, we found **The Librarian**. A meticulous mechanical record keeper hovering over his book, the great **Codex Arcana**. This was a book written in detail to record the actions of every man, woman, and child that lived among us. But it was far too powerful, and the secrets it contained proved lethal in the wrong hands.*\n\n*And so began the **factions**, vying for control over the Codex.*\n\n- Excerpt from the **Teachings of Tiberius**. March 22, 2630.", "loreGenesis": "TODO: Sorry. I recognize the term but am unable to process the request. There is a corruption in my cognitive core. Try again soon.", "loreTravelers": "TODO: Sorry. I recognize the term but am unable to process the request. There is a corruption in my cognitive core. Try again soon.", @@ -90,5 +92,5 @@ "loreSanctum": "TODO: Sorry. I recognize the term but am unable to process the request. There is a corruption in my cognitive core. Try again soon.", "loreLibrarian": "WARNING: DATA CORRUPTED", "loreCodex": "WARNING: DATA CORRUPTED", - "loreFactions": "TODO: Sorry. I recognize the term but am unable to process the request. There is a corruption in my cognitive core. Try again soon.", + "loreFactions": "TODO: Sorry. I recognize the term but am unable to process the request. There is a corruption in my cognitive core. Try again soon." } diff --git a/Shared/factions.js b/Shared/factions.js index 212762b..8b74575 100644 --- a/Shared/factions.js +++ b/Shared/factions.js @@ -79,11 +79,12 @@ exports.ChangeFaction = async function(client, factionRole, channel, member) { if (member.roles.has(factionRole)) { //can't change to this faction - return messaging.SendPublicMessage(client, member.user, channel, "You have already joined that faction."); + return "alreadyJoined"; } if (dataRequest.loadServerData("hasConvertedToday", member.user.id) == 1) { - return messaging.SendPublicMessage(client, member.user, channel, "You have already converted today."); + //can't change too fast + return "hasConvertedToday"; } //Creates a new user @@ -98,12 +99,11 @@ exports.ChangeFaction = async function(client, factionRole, channel, member) { //send the server the info (for logging) dataRequest.sendServerData("conversion", "Converted to " + exports.GetFactionName(factionRole), member.user.id); - //send the public welcoming message - messaging.SendPublicMessage(client, member.user, channel, "Welcome to " + exports.GetFactionName(factionRole)); - - //send the private welcoming message if (newUserResponse === "createdUser") { - //TODO: more dialog from adam & other faction leaders - messaging.SendPrivateMessage(client, member.user, "Welcome to SANCTUM."); + //send the private welcoming message + return newUserResponse; + } else { + //send the public welcoming message + return "joined"; } } diff --git a/Shared/progression.js b/Shared/progression.js index fcc0795..7295300 100644 --- a/Shared/progression.js +++ b/Shared/progression.js @@ -35,19 +35,16 @@ exports.LevelUp = function(client, member) { //NOTE: why is this called separate let response = String(dataRequest.sendServerData("getLevelUp", 0, member.user.id)); //TODO: please change the order of sendServerData's arguments! let responseArray = response.split(","); - //DEBUGGING -// console.log("response: " + response); - let responseMessage = responseArray[0]; let level = Math.floor(parseFloat(responseArray[1])); let statPoints = parseFloat(responseArray[2]); -// let userStats = String(dataRequest.loadServerData("userStats", member.user.id)); + let rankUp = exports.RankUp(client, member, level); - exports.RankUp(client, member, level); - - if (responseMessage == "levelup") { - //TODO: proper dialog + if (rankUp == "rankUp") { + return rankUp; + } else if (responseMessage === "levelup") { + return "levelUp"; } } @@ -85,7 +82,7 @@ exports.RankUp = async function(client, member, level) { } if (member.roles.has(levelRole.id)) { //member has this role already - return; + return ""; } //the ranks as roles @@ -102,4 +99,7 @@ exports.RankUp = async function(client, member, level) { //this will enable the new rooms member.addRole(levelRole); + + //return the result + return "rankUp"; } diff --git a/Shared/utility.js b/Shared/utility.js index fa216dc..edcf8e0 100644 --- a/Shared/utility.js +++ b/Shared/utility.js @@ -34,6 +34,10 @@ exports.GenerateDialogFunction = function(dialogJson) { result = dialogJson[key]; } + if (typeof(result) === "undefined") { + return ""; + } + let counter = 0; data.map((dat) => { counter++; @@ -162,7 +166,7 @@ exports.CheckValidDisplay = function(client, member, channel, checkRole) { //See return false; } default: - //default value - return false; + //default value: always show messages if not a faction leader + return true; } }