mirror of
https://github.com/Ratstail91/SANCTUM.git
synced 2025-11-29 02:24:27 +11:00
Added package.json for modules to wor, and !inventory Pg. 0 bugfix
This commit is contained in:
@@ -743,6 +743,8 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// To make the message of "Page 1/0" with no items in !inventory not happen
|
// To make the message of "Page 1/0" with no items in !inventory not happen
|
||||||
var moddedLength = groupedArr.length;
|
var moddedLength = groupedArr.length;
|
||||||
if (moddedLength < 1) moddedLength = 1;
|
if (moddedLength < 1) moddedLength = 1;
|
||||||
|
var moddedPageNum = pageNum;
|
||||||
|
if (moddedPageNum < 1) moddedPageNum = 1;
|
||||||
|
|
||||||
const footer = getFooterCommands("!inventory");
|
const footer = getFooterCommands("!inventory");
|
||||||
|
|
||||||
@@ -751,7 +753,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
||||||
.setColor(message.member.displayColor)
|
.setColor(message.member.displayColor)
|
||||||
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
||||||
.addField(`Items (Page ${pageNum}/${moddedLength})`, items)
|
.addField(`Items (Page ${moddedPageNum}/${moddedLength})`, items)
|
||||||
.setFooter(`Commands: ${footer}`)
|
.setFooter(`Commands: ${footer}`)
|
||||||
|
|
||||||
var invMessage;
|
var invMessage;
|
||||||
@@ -765,7 +767,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// Collector for emotes
|
// Collector for emotes
|
||||||
const emotes = ['⬅', '❌', '➡'];
|
const emotes = ['⬅', '❌', '➡'];
|
||||||
const collector = invMessage.createReactionCollector(
|
const collector = invMessage.createReactionCollector(
|
||||||
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id , { time: 15 * 1000 });
|
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id & message.author.id === user.id, { time: 15 * 1000 });
|
||||||
var react = "";
|
var react = "";
|
||||||
var endedOnReact;
|
var endedOnReact;
|
||||||
|
|
||||||
|
|||||||
@@ -743,6 +743,8 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// To make the message of "Page 1/0" with no items in !inventory not happen
|
// To make the message of "Page 1/0" with no items in !inventory not happen
|
||||||
var moddedLength = groupedArr.length;
|
var moddedLength = groupedArr.length;
|
||||||
if (moddedLength < 1) moddedLength = 1;
|
if (moddedLength < 1) moddedLength = 1;
|
||||||
|
var moddedPageNum = pageNum;
|
||||||
|
if (moddedPageNum < 1) moddedPageNum = 1;
|
||||||
|
|
||||||
const footer = getFooterCommands("!inventory");
|
const footer = getFooterCommands("!inventory");
|
||||||
|
|
||||||
@@ -751,7 +753,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
||||||
.setColor(message.member.displayColor)
|
.setColor(message.member.displayColor)
|
||||||
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
||||||
.addField(`Items (Page ${pageNum}/${moddedLength})`, items)
|
.addField(`Items (Page ${moddedPageNum}/${moddedLength})`, items)
|
||||||
.setFooter(`Commands: ${footer}`)
|
.setFooter(`Commands: ${footer}`)
|
||||||
|
|
||||||
var invMessage;
|
var invMessage;
|
||||||
@@ -765,7 +767,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// Collector for emotes
|
// Collector for emotes
|
||||||
const emotes = ['⬅', '❌', '➡'];
|
const emotes = ['⬅', '❌', '➡'];
|
||||||
const collector = invMessage.createReactionCollector(
|
const collector = invMessage.createReactionCollector(
|
||||||
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id , { time: 15 * 1000 });
|
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id & message.author.id === user.id, { time: 15 * 1000 });
|
||||||
var react = "";
|
var react = "";
|
||||||
var endedOnReact;
|
var endedOnReact;
|
||||||
|
|
||||||
|
|||||||
@@ -743,6 +743,8 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// To make the message of "Page 1/0" with no items in !inventory not happen
|
// To make the message of "Page 1/0" with no items in !inventory not happen
|
||||||
var moddedLength = groupedArr.length;
|
var moddedLength = groupedArr.length;
|
||||||
if (moddedLength < 1) moddedLength = 1;
|
if (moddedLength < 1) moddedLength = 1;
|
||||||
|
var moddedPageNum = pageNum;
|
||||||
|
if (moddedPageNum < 1) moddedPageNum = 1;
|
||||||
|
|
||||||
const footer = getFooterCommands("!inventory");
|
const footer = getFooterCommands("!inventory");
|
||||||
|
|
||||||
@@ -751,7 +753,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
||||||
.setColor(message.member.displayColor)
|
.setColor(message.member.displayColor)
|
||||||
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
||||||
.addField(`Items (Page ${pageNum}/${moddedLength})`, items)
|
.addField(`Items (Page ${moddedPageNum}/${moddedLength})`, items)
|
||||||
.setFooter(`Commands: ${footer}`)
|
.setFooter(`Commands: ${footer}`)
|
||||||
|
|
||||||
var invMessage;
|
var invMessage;
|
||||||
@@ -765,7 +767,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// Collector for emotes
|
// Collector for emotes
|
||||||
const emotes = ['⬅', '❌', '➡'];
|
const emotes = ['⬅', '❌', '➡'];
|
||||||
const collector = invMessage.createReactionCollector(
|
const collector = invMessage.createReactionCollector(
|
||||||
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id , { time: 15 * 1000 });
|
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id & message.author.id === user.id, { time: 15 * 1000 });
|
||||||
var react = "";
|
var react = "";
|
||||||
var endedOnReact;
|
var endedOnReact;
|
||||||
|
|
||||||
|
|||||||
@@ -743,6 +743,8 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// To make the message of "Page 1/0" with no items in !inventory not happen
|
// To make the message of "Page 1/0" with no items in !inventory not happen
|
||||||
var moddedLength = groupedArr.length;
|
var moddedLength = groupedArr.length;
|
||||||
if (moddedLength < 1) moddedLength = 1;
|
if (moddedLength < 1) moddedLength = 1;
|
||||||
|
var moddedPageNum = pageNum;
|
||||||
|
if (moddedPageNum < 1) moddedPageNum = 1;
|
||||||
|
|
||||||
const footer = getFooterCommands("!inventory");
|
const footer = getFooterCommands("!inventory");
|
||||||
|
|
||||||
@@ -751,7 +753,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
||||||
.setColor(message.member.displayColor)
|
.setColor(message.member.displayColor)
|
||||||
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
||||||
.addField(`Items (Page ${pageNum}/${moddedLength})`, items)
|
.addField(`Items (Page ${moddedPageNum}/${moddedLength})`, items)
|
||||||
.setFooter(`Commands: ${footer}`)
|
.setFooter(`Commands: ${footer}`)
|
||||||
|
|
||||||
var invMessage;
|
var invMessage;
|
||||||
@@ -765,7 +767,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// Collector for emotes
|
// Collector for emotes
|
||||||
const emotes = ['⬅', '❌', '➡'];
|
const emotes = ['⬅', '❌', '➡'];
|
||||||
const collector = invMessage.createReactionCollector(
|
const collector = invMessage.createReactionCollector(
|
||||||
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id , { time: 15 * 1000 });
|
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id & message.author.id === user.id, { time: 15 * 1000 });
|
||||||
var react = "";
|
var react = "";
|
||||||
var endedOnReact;
|
var endedOnReact;
|
||||||
|
|
||||||
|
|||||||
@@ -743,6 +743,8 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// To make the message of "Page 1/0" with no items in !inventory not happen
|
// To make the message of "Page 1/0" with no items in !inventory not happen
|
||||||
var moddedLength = groupedArr.length;
|
var moddedLength = groupedArr.length;
|
||||||
if (moddedLength < 1) moddedLength = 1;
|
if (moddedLength < 1) moddedLength = 1;
|
||||||
|
var moddedPageNum = pageNum;
|
||||||
|
if (moddedPageNum < 1) moddedPageNum = 1;
|
||||||
|
|
||||||
const footer = getFooterCommands("!inventory");
|
const footer = getFooterCommands("!inventory");
|
||||||
|
|
||||||
@@ -751,7 +753,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
.setAuthor(`${message.member.displayName}`, message.author.avatarURL)
|
||||||
.setColor(message.member.displayColor)
|
.setColor(message.member.displayColor)
|
||||||
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
.setDescription("I can appraise your items with `!item [ITEM NAME]`, traveler.")
|
||||||
.addField(`Items (Page ${pageNum}/${moddedLength})`, items)
|
.addField(`Items (Page ${moddedPageNum}/${moddedLength})`, items)
|
||||||
.setFooter(`Commands: ${footer}`)
|
.setFooter(`Commands: ${footer}`)
|
||||||
|
|
||||||
var invMessage;
|
var invMessage;
|
||||||
@@ -765,7 +767,7 @@ async function sendInventory(message, pageNum, newMessage) {
|
|||||||
// Collector for emotes
|
// Collector for emotes
|
||||||
const emotes = ['⬅', '❌', '➡'];
|
const emotes = ['⬅', '❌', '➡'];
|
||||||
const collector = invMessage.createReactionCollector(
|
const collector = invMessage.createReactionCollector(
|
||||||
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id , { time: 15 * 1000 });
|
(reaction, user) => emotes.includes(reaction.emoji.name) && user.id !== client.user.id & message.author.id === user.id, { time: 15 * 1000 });
|
||||||
var react = "";
|
var react = "";
|
||||||
var endedOnReact;
|
var endedOnReact;
|
||||||
|
|
||||||
|
|||||||
180
Enemy/enemy.js
180
Enemy/enemy.js
@@ -31,7 +31,7 @@ class EnemyBatchInstance {
|
|||||||
this.channel = channel; // Channel of spawning
|
this.channel = channel; // Channel of spawning
|
||||||
this.spawnPrecentage = 100;
|
this.spawnPrecentage = 100;
|
||||||
this.hostileLevel = 1;
|
this.hostileLevel = 1;
|
||||||
this.fastSummon = true; // Show prowling
|
this.fastSummon = false; // Show prowling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ client.on('message', async message => {
|
|||||||
if (isAdmin(message.author.id))
|
if (isAdmin(message.author.id))
|
||||||
message.reply("***...MRGRGRGR!***");
|
message.reply("***...MRGRGRGR!***");
|
||||||
break;
|
break;
|
||||||
case "ravager":
|
case npcSettings.id:
|
||||||
if (args[0].toLowerCase() === "summon" && isAdmin(message.author.id)) {
|
if (args[0].toLowerCase() === "summon" && isAdmin(message.author.id)) {
|
||||||
generateEnemy(process.env.DEADLANDS_CHANNEL_ID);
|
generateEnemy(process.env.DEADLANDS_CHANNEL_ID);
|
||||||
}
|
}
|
||||||
@@ -317,69 +317,151 @@ async function enemyTimer(newEnemy, data, channel, fleeTime, newMessage) {
|
|||||||
.setTitle("Status")
|
.setTitle("Status")
|
||||||
.setDescription("...")
|
.setDescription("...")
|
||||||
|
|
||||||
|
const sendMessageMinimum = true;
|
||||||
var isReadyToFlee = false;
|
var isReadyToFlee = false;
|
||||||
var attackingUsers = [];
|
var attackingUsers = [];
|
||||||
var tempAttackUsers = "";
|
var tempAttackUsers = "";
|
||||||
var newChannel = client.channels.get(channel);
|
var newChannel = client.channels.get(channel);
|
||||||
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
||||||
|
|
||||||
// Collects emotes and reacts upon the reaction
|
|
||||||
const collector = newMessage.createReactionCollector(
|
|
||||||
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
|
||||||
|
|
||||||
// Possible reaction attacks can go here
|
// Possible reaction attacks can go here
|
||||||
var options = ['🇦', '🇧', '🇨']
|
var options = ['💥', '🇦', '🇧', '🇨']
|
||||||
sendReactions(options);
|
|
||||||
|
|
||||||
// Collect
|
|
||||||
collector.once("collect", async reaction => {
|
|
||||||
var user = reaction.users.last();
|
|
||||||
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
|
||||||
addUserToArray(user.id);
|
|
||||||
|
|
||||||
// Send damage to server
|
// System for no message sending except the minimum
|
||||||
// TODO
|
if (sendMessageMinimum) {
|
||||||
});
|
// Collects emotes and reacts upon the reaction
|
||||||
|
const collector = newMessage.createReactionCollector(
|
||||||
// Ends
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
collector.once("end", async collector => {
|
|
||||||
|
|
||||||
});
|
sendReactions(options);
|
||||||
|
|
||||||
|
// Collect
|
||||||
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
// Goes every 4 seconds
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
var emoteRefresh = setInterval(async () => {
|
if (user.id === client.user.id) {
|
||||||
await newMessage.clearReactions();
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
interactionEmbed.setDescription("...");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
// Send damage to server
|
||||||
console.log("Has fled!");
|
// TODO
|
||||||
interactionEmbed.setDescription("👣 The Ravager has fled...")
|
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
clearInterval(emoteRefresh);
|
addUserToArray(user.id);
|
||||||
collector.stop();
|
console.log("Collecting a user! " + user.username)
|
||||||
} else {
|
});
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
sendReactions(options);
|
// Ends
|
||||||
|
collector.once("end", async collector => {
|
||||||
|
console.log("Ended collector.")
|
||||||
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
|
await sleep(fleeTime);
|
||||||
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
tempAttackUsers = "";
|
// Collects emotes and reacts upon the reaction
|
||||||
}, 5 * 1000);
|
var collector = newMessage.createReactionCollector(
|
||||||
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
|
|
||||||
// Waits to see if killed, and if not send a fleeing message
|
|
||||||
await sleep(fleeTime);
|
|
||||||
if (newEnemy.state === EnemyState.ACTIVE) {
|
|
||||||
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
|
||||||
await sleep(20 * 1000);
|
|
||||||
|
|
||||||
// If still there despawn
|
sendReactions(options);
|
||||||
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
|
||||||
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
// Collect
|
||||||
isReadyToFlee = true;
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
|
if (user.id === client.user.id) {
|
||||||
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send damage to server
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ends
|
||||||
|
collector.once("end", async collector => {
|
||||||
|
console.log("Ended collector.")
|
||||||
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
|
await sleep(fleeTime);
|
||||||
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does flee sequence
|
||||||
async function flee(newEnemy, data, newChannel) {
|
async function flee(newEnemy, data, newChannel) {
|
||||||
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
||||||
socket.emit('fled', {
|
socket.emit('fled', {
|
||||||
@@ -391,6 +473,8 @@ async function flee(newEnemy, data, newChannel) {
|
|||||||
await client.user.setPresence('invisible');
|
await client.user.setPresence('invisible');
|
||||||
client.user.setActivity('Prowling...');
|
client.user.setActivity('Prowling...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health bar
|
// Health bar
|
||||||
|
|||||||
@@ -11,18 +11,70 @@ const io = require('socket.io-client');
|
|||||||
var socket = io.connect('http://localhost:80');
|
var socket = io.connect('http://localhost:80');
|
||||||
|
|
||||||
// Bot Modules
|
// Bot Modules
|
||||||
|
const npcSettings = require('./npcSettings')
|
||||||
const dataRequest = require('../modules/dataRequest');
|
const dataRequest = require('../modules/dataRequest');
|
||||||
const calcRandom = require('../modules/calcRandom');
|
const calcRandom = require('../modules/calcRandom');
|
||||||
|
|
||||||
// State Machine
|
// State Machine
|
||||||
var RavagerState = {
|
var EnemyState = {
|
||||||
INACTIVE: 0,
|
INACTIVE: 0,
|
||||||
PROWLING: 1,
|
PROWLING: 1,
|
||||||
ACTIVE: 2,
|
ACTIVE: 2,
|
||||||
UNCONSCIOUS: 3
|
UNCONSCIOUS: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
const prowling = 'Prowling...';
|
// Enemy lists
|
||||||
|
class EnemyBatchInstance {
|
||||||
|
constructor(channel) {
|
||||||
|
this.state = EnemyState.INACTIVE;
|
||||||
|
this.enemies = []; // Array of `new Enemy()`s
|
||||||
|
this.channel = channel; // Channel of spawning
|
||||||
|
this.spawnPrecentage = 100;
|
||||||
|
this.hostileLevel = 1;
|
||||||
|
this.fastSummon = false; // Show prowling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enemy instance
|
||||||
|
class Enemy {
|
||||||
|
constructor(type) {
|
||||||
|
this.state = EnemyState.INACTIVE;
|
||||||
|
this.type = type;
|
||||||
|
this.level = 1;
|
||||||
|
this.health = 420;
|
||||||
|
this.speed = 21;
|
||||||
|
this.strength = 33;
|
||||||
|
this.stash = 0;
|
||||||
|
this.fleeTime = undefined;
|
||||||
|
this.guid = undefined;
|
||||||
|
this.deletePrevMessage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates flee time by randomization
|
||||||
|
get randomFleeTime() {
|
||||||
|
var randomFleeTime;
|
||||||
|
randomFleeTime = calcRandom.random(3 * 60 * 1000, 6 * 60 * 1000);
|
||||||
|
randomFleeTime -= (randomFleeTime % 1000);
|
||||||
|
return randomFleeTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var enemyBatchCollection = [];
|
||||||
|
|
||||||
|
// Spawning patterns
|
||||||
|
var spawnPatterns = {
|
||||||
|
"types": ['default', 'randomBatch2'],
|
||||||
|
"default": {
|
||||||
|
"ravager": {
|
||||||
|
"amount": 1
|
||||||
|
},
|
||||||
|
"type": "incrememt"
|
||||||
|
},
|
||||||
|
"randomBatch2": {
|
||||||
|
"amount": 2,
|
||||||
|
"type": "incrememt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var socketReady = false;
|
var socketReady = false;
|
||||||
socket.on('spawn', (data) => {
|
socket.on('spawn', (data) => {
|
||||||
@@ -52,10 +104,15 @@ client.on('ready', async () => {
|
|||||||
// You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb)
|
// You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb)
|
||||||
client.user.setStatus('invisible');
|
client.user.setStatus('invisible');
|
||||||
// Sets your "Playing"
|
// Sets your "Playing"
|
||||||
client.user.setActivity(prowling);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Connected! \
|
console.log(`Connected! \
|
||||||
\nLogged in as: ${client.user.username} - (${client.user.id})`);
|
\nLogged in as: ${client.user.username} - (${client.user.id})`);
|
||||||
|
|
||||||
// Corrects Ravager username
|
// Corrects Ravager username
|
||||||
if (client.user.username == "Raveger") {
|
if (client.user.username == "Raveger") {
|
||||||
const newName = "Ravager";
|
const newName = "Ravager";
|
||||||
@@ -91,6 +148,11 @@ client.on('message', async message => {
|
|||||||
if (isAdmin(message.author.id))
|
if (isAdmin(message.author.id))
|
||||||
message.reply("***...MRGRGRGR!***");
|
message.reply("***...MRGRGRGR!***");
|
||||||
break;
|
break;
|
||||||
|
case npcSettings.id:
|
||||||
|
if (args[0].toLowerCase() === "summon" && isAdmin(message.author.id)) {
|
||||||
|
generateEnemy(process.env.DEADLANDS_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -100,20 +162,95 @@ cron.schedule('*/10 * * * *', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function generateEnemy(channelID) {
|
||||||
|
console.log("Generating enemy...")
|
||||||
|
|
||||||
|
// Gets an enemy batch instance, or creates if non-existant
|
||||||
|
var index = enemyBatchCollection.findIndex(data => data.channel === channelID);
|
||||||
|
var enemyBatch;
|
||||||
|
console.log(index <= -1)
|
||||||
|
if (index <= -1) {
|
||||||
|
enemyBatch = new EnemyBatchInstance(channelID);
|
||||||
|
} else {
|
||||||
|
enemyBatch = enemyBatchCollection[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a spawn pattern
|
||||||
|
var randomSpawnPattern = spawnPatterns.types[calcRandom.randomExc(0, spawnPatterns.types.length)];
|
||||||
|
var newSpawnPattern = spawnPatterns[randomSpawnPattern];
|
||||||
|
newSpawnPattern = spawnPatterns["default"]; // Overruled!
|
||||||
|
|
||||||
|
// Creates a bunch of new enemies
|
||||||
|
var amount = newSpawnPattern[npcSettings.id].amount;
|
||||||
|
var newEnemies = [];
|
||||||
|
for (let i = 0; i < amount; i++) {
|
||||||
|
var enemy = new Enemy(npcSettings.id);
|
||||||
|
var elevel = enemyBatch.hostileLevel;
|
||||||
|
|
||||||
|
// Replication of newHostile in sendData.php
|
||||||
|
const healthBase = 50; const strengthBase = 3; const speedBase = 3; const stashBase = 3;
|
||||||
|
|
||||||
|
const healthMin = (healthBase * elevel) / 2;
|
||||||
|
const healthMax = healthBase * elevel;
|
||||||
|
|
||||||
|
const strengthMin = (strengthBase * elevel) / 2;
|
||||||
|
const strengthMax = strengthBase * elevel;
|
||||||
|
|
||||||
|
const speedMin = (speedBase * elevel) / 2;
|
||||||
|
const speedMax = speedBase * elevel;
|
||||||
|
|
||||||
|
const stashMin = (stashBase * elevel) / 2;
|
||||||
|
const stashMax = stashBase * elevel;
|
||||||
|
|
||||||
|
const health = Math.floor(calcRandom.randomExc(healthMin, healthMax));
|
||||||
|
const strength = Math.floor(calcRandom.randomExc(strengthMin, strengthMax));
|
||||||
|
const speed = Math.floor(calcRandom.randomExc(speedMin, speedMax));
|
||||||
|
const stash = Math.floor(calcRandom.randomExc(stashMin, stashMax));
|
||||||
|
|
||||||
|
enemy.level = elevel;
|
||||||
|
enemy.health = health;
|
||||||
|
enemy.strength = strength;
|
||||||
|
enemy.speed = speed;
|
||||||
|
enemy.stash = stash;
|
||||||
|
enemy.state = EnemyState.PROWLING;
|
||||||
|
enemy.fleeTime = enemy.randomFleeTime;
|
||||||
|
enemy.guid = guidGenerator();
|
||||||
|
|
||||||
|
// Logs stats
|
||||||
|
console.log(`\n[===== | Enemy Stats | =====]`);
|
||||||
|
console.log(`HEALTH: ${health} > ${healthMin} - ${healthMax}`);
|
||||||
|
console.log(`STRENGTH: ${strength} > ${strengthMin} - ${strengthMax}`);
|
||||||
|
console.log(`SPEED: ${speed} > ${speedMin} - ${speedMax}`);
|
||||||
|
console.log(`STASH: ${stash} > ${stashMin} - ${stashMax}`);
|
||||||
|
console.log(`[===========================]\n`);
|
||||||
|
newEnemies.push(enemy);
|
||||||
|
}
|
||||||
|
enemyBatch.enemies = newEnemies;
|
||||||
|
enemyBatch.hostileLevel++;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(newEnemies, null, 2));
|
||||||
|
|
||||||
|
if (calcRandom.gamble(enemyBatch.spawnPrecentage)) {
|
||||||
|
enemyBatch.spawnPrecentage = 50;
|
||||||
|
|
||||||
|
// Creation of Ravager timer
|
||||||
|
var creationTime = calcRandom.random(35000, 540000);
|
||||||
|
creationTime = 3 * 1000; // shortcuts
|
||||||
|
|
||||||
|
console.log(`[Enemy Spawn] ${amount} "${npcSettings.id}" will be created in ${fmtMSS(creationTime / 1000)} min.`);
|
||||||
|
await sleep(creationTime);
|
||||||
|
console.log(`[Enemy Spawn] ${amount} "${npcSettings.id}" has spawned!`);
|
||||||
|
summonEnemy(enemyBatch);
|
||||||
|
|
||||||
|
enemyBatch.hostileLevel++;
|
||||||
|
} else {
|
||||||
|
console.log("[Enemy Spawn] Fail to spawn. Adding 10% more to chances.");
|
||||||
|
enemyBatch.spawnPrecentage += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Turn online and turn offline
|
// Turn online and turn offline
|
||||||
async function summonEnemy(data) {
|
async function summonEnemy(data) {
|
||||||
// Scans for Ravager already in channel
|
|
||||||
/*
|
|
||||||
var isRavagerInChannel = false;
|
|
||||||
ravagerCollection.forEach(element => {
|
|
||||||
if (element.channel === data.channel) {
|
|
||||||
console.log("There is already a Ravager in channel " + element.channel);
|
|
||||||
isRavagerInChannel = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (isRavagerInChannel) return;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// If timer exists, do outpost
|
// If timer exists, do outpost
|
||||||
const summonTime = 4; // 4 is debug, normal is 35
|
const summonTime = 4; // 4 is debug, normal is 35
|
||||||
if (!data.fastSummon) {
|
if (!data.fastSummon) {
|
||||||
@@ -124,7 +261,7 @@ async function summonEnemy(data) {
|
|||||||
// Sets prowling states on the Ravagers
|
// Sets prowling states on the Ravagers
|
||||||
for (let i = 0; i < data.enemies.length; i++) {
|
for (let i = 0; i < data.enemies.length; i++) {
|
||||||
const element = data.enemies[i];
|
const element = data.enemies[i];
|
||||||
element.state = RavagerState.PROWLING;
|
element.state = EnemyState.PROWLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification code
|
// Notification code
|
||||||
@@ -151,14 +288,14 @@ async function summonEnemy(data) {
|
|||||||
|
|
||||||
for (let i = 0; i < data.enemies.length; i++) {
|
for (let i = 0; i < data.enemies.length; i++) {
|
||||||
const element = data.enemies[i];
|
const element = data.enemies[i];
|
||||||
element.state = RavagerState.ACTIVE;
|
element.state = EnemyState.ACTIVE;
|
||||||
}
|
}
|
||||||
enemyTimer(element, data, data.channel, element.fleeTime, newMessage);
|
enemyTimer(element, data, data.channel, element.fleeTime, newMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counts down
|
// Counts down
|
||||||
async function enemyTimer(newRavager, data, channel, fleeTime, newMessage) {
|
async function enemyTimer(newEnemy, data, channel, fleeTime, newMessage) {
|
||||||
function addUserToArray(userID) {
|
function addUserToArray(userID) {
|
||||||
attackingUsers.push(userID);
|
attackingUsers.push(userID);
|
||||||
}
|
}
|
||||||
@@ -180,84 +317,164 @@ async function enemyTimer(newRavager, data, channel, fleeTime, newMessage) {
|
|||||||
.setTitle("Status")
|
.setTitle("Status")
|
||||||
.setDescription("...")
|
.setDescription("...")
|
||||||
|
|
||||||
|
const sendMessageMinimum = true;
|
||||||
var isReadyToFlee = false;
|
var isReadyToFlee = false;
|
||||||
var attackingUsers = [];
|
var attackingUsers = [];
|
||||||
var tempAttackUsers = "";
|
var tempAttackUsers = "";
|
||||||
var newChannel = client.channels.get(channel);
|
var newChannel = client.channels.get(channel);
|
||||||
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
||||||
|
|
||||||
// Collects emotes and reacts upon the reaction
|
|
||||||
const collector = newMessage.createReactionCollector(
|
|
||||||
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
|
||||||
|
|
||||||
// Possible reaction attacks can go here
|
// Possible reaction attacks can go here
|
||||||
var options = ['🇦', '🇧', '🇨']
|
var options = ['💥', '🇦', '🇧', '🇨']
|
||||||
sendReactions(options);
|
|
||||||
|
// System for no message sending except the minimum
|
||||||
// Collect
|
if (sendMessageMinimum) {
|
||||||
collector.once("collect", async reaction => {
|
// Collects emotes and reacts upon the reaction
|
||||||
var user = reaction.users.last();
|
const collector = newMessage.createReactionCollector(
|
||||||
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
addUserToArray(user.id);
|
|
||||||
console.log(tempAttackUsers);
|
sendReactions(options);
|
||||||
if (!interactionMessage.deleted) {
|
|
||||||
interactionEmbed.setDescription(`${tempAttackUsers}`);
|
// Collect
|
||||||
interactionMessage = await newChannel.edit({embed: interactionEmbed});
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
|
if (user.id === client.user.id) {
|
||||||
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send damage to server
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ends
|
||||||
|
collector.once("end", async collector => {
|
||||||
|
console.log("Ended collector.")
|
||||||
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
|
await sleep(fleeTime);
|
||||||
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Send damage.
|
// Collects emotes and reacts upon the reaction
|
||||||
|
var collector = newMessage.createReactionCollector(
|
||||||
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
|
|
||||||
});
|
sendReactions(options);
|
||||||
|
|
||||||
// Ends
|
|
||||||
collector.once("end", async collector => {
|
|
||||||
|
|
||||||
});
|
// Collect
|
||||||
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
// Goes every 4 seconds
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
var emoteRefresh = setInterval(async () => {
|
if (user.id === client.user.id) {
|
||||||
await newMessage.clearReactions();
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
interactionEmbed.setDescription("...");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isReadyToFlee && newRavager.state !== RavagerState.UNCONSCIOUS) {
|
// Send damage to server
|
||||||
interactionEmbed.setDescription("👣 The Ravager has fled...")
|
// TODO
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
clearInterval(emoteRefresh);
|
|
||||||
collector.stop();
|
|
||||||
} else {
|
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
sendReactions(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
tempAttackUsers = "";
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
}, 5 * 1000);
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
// Waits to see if killed, and if not send a fleeing message
|
// Ends
|
||||||
await sleep(fleeTime);
|
collector.once("end", async collector => {
|
||||||
if (newRavager.state === RavagerState.ACTIVE) {
|
console.log("Ended collector.")
|
||||||
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
await sleep(20 * 1000);
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
// If still there despawn
|
|
||||||
if (newRavager.state !== RavagerState.UNCONSCIOUS) {
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
await sleep(fleeTime);
|
||||||
isReadyToFlee = true;
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flee(newRavager, data, newChannel) {
|
// Does flee sequence
|
||||||
|
async function flee(newEnemy, data, newChannel) {
|
||||||
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
||||||
socket.emit('fled', {
|
socket.emit('fled', {
|
||||||
data: data,
|
data: data,
|
||||||
ravager: newRavager
|
ravager: newEnemy
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.length < 1) {
|
if (data.length < 1) {
|
||||||
await client.user.setPresence('invisible');
|
await client.user.setPresence('invisible');
|
||||||
client.user.setActivity('Prowling...');
|
client.user.setActivity('Prowling...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health bar
|
// Health bar
|
||||||
@@ -306,6 +523,14 @@ function fmtMSS(s){ // accepts seconds as Number or String. Returns m:ss
|
|||||||
) + s ; // and we add Number s to the string (converting it to String as well)
|
) + s ; // and we add Number s to the string (converting it to String as well)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/6860853/generate-random-string-for-div-id/6860916#6860916
|
||||||
|
function guidGenerator() {
|
||||||
|
var S4 = function() {
|
||||||
|
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||||
|
};
|
||||||
|
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||||
|
}
|
||||||
|
|
||||||
function getDialog(dialogTag, data = "", data2 = "") {
|
function getDialog(dialogTag, data = "", data2 = "") {
|
||||||
switch(dialogTag) {
|
switch(dialogTag) {
|
||||||
case "onTheProwl":
|
case "onTheProwl":
|
||||||
|
|||||||
@@ -11,18 +11,70 @@ const io = require('socket.io-client');
|
|||||||
var socket = io.connect('http://localhost:80');
|
var socket = io.connect('http://localhost:80');
|
||||||
|
|
||||||
// Bot Modules
|
// Bot Modules
|
||||||
|
const npcSettings = require('./npcSettings')
|
||||||
const dataRequest = require('../modules/dataRequest');
|
const dataRequest = require('../modules/dataRequest');
|
||||||
const calcRandom = require('../modules/calcRandom');
|
const calcRandom = require('../modules/calcRandom');
|
||||||
|
|
||||||
// State Machine
|
// State Machine
|
||||||
var RavagerState = {
|
var EnemyState = {
|
||||||
INACTIVE: 0,
|
INACTIVE: 0,
|
||||||
PROWLING: 1,
|
PROWLING: 1,
|
||||||
ACTIVE: 2,
|
ACTIVE: 2,
|
||||||
UNCONSCIOUS: 3
|
UNCONSCIOUS: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
const prowling = 'Prowling...';
|
// Enemy lists
|
||||||
|
class EnemyBatchInstance {
|
||||||
|
constructor(channel) {
|
||||||
|
this.state = EnemyState.INACTIVE;
|
||||||
|
this.enemies = []; // Array of `new Enemy()`s
|
||||||
|
this.channel = channel; // Channel of spawning
|
||||||
|
this.spawnPrecentage = 100;
|
||||||
|
this.hostileLevel = 1;
|
||||||
|
this.fastSummon = false; // Show prowling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enemy instance
|
||||||
|
class Enemy {
|
||||||
|
constructor(type) {
|
||||||
|
this.state = EnemyState.INACTIVE;
|
||||||
|
this.type = type;
|
||||||
|
this.level = 1;
|
||||||
|
this.health = 420;
|
||||||
|
this.speed = 21;
|
||||||
|
this.strength = 33;
|
||||||
|
this.stash = 0;
|
||||||
|
this.fleeTime = undefined;
|
||||||
|
this.guid = undefined;
|
||||||
|
this.deletePrevMessage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates flee time by randomization
|
||||||
|
get randomFleeTime() {
|
||||||
|
var randomFleeTime;
|
||||||
|
randomFleeTime = calcRandom.random(3 * 60 * 1000, 6 * 60 * 1000);
|
||||||
|
randomFleeTime -= (randomFleeTime % 1000);
|
||||||
|
return randomFleeTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var enemyBatchCollection = [];
|
||||||
|
|
||||||
|
// Spawning patterns
|
||||||
|
var spawnPatterns = {
|
||||||
|
"types": ['default', 'randomBatch2'],
|
||||||
|
"default": {
|
||||||
|
"ravager": {
|
||||||
|
"amount": 1
|
||||||
|
},
|
||||||
|
"type": "incrememt"
|
||||||
|
},
|
||||||
|
"randomBatch2": {
|
||||||
|
"amount": 2,
|
||||||
|
"type": "incrememt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var socketReady = false;
|
var socketReady = false;
|
||||||
socket.on('spawn', (data) => {
|
socket.on('spawn', (data) => {
|
||||||
@@ -52,10 +104,15 @@ client.on('ready', async () => {
|
|||||||
// You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb)
|
// You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb)
|
||||||
client.user.setStatus('invisible');
|
client.user.setStatus('invisible');
|
||||||
// Sets your "Playing"
|
// Sets your "Playing"
|
||||||
client.user.setActivity(prowling);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Connected! \
|
console.log(`Connected! \
|
||||||
\nLogged in as: ${client.user.username} - (${client.user.id})`);
|
\nLogged in as: ${client.user.username} - (${client.user.id})`);
|
||||||
|
|
||||||
// Corrects Ravager username
|
// Corrects Ravager username
|
||||||
if (client.user.username == "Raveger") {
|
if (client.user.username == "Raveger") {
|
||||||
const newName = "Ravager";
|
const newName = "Ravager";
|
||||||
@@ -91,6 +148,11 @@ client.on('message', async message => {
|
|||||||
if (isAdmin(message.author.id))
|
if (isAdmin(message.author.id))
|
||||||
message.reply("***...MRGRGRGR!***");
|
message.reply("***...MRGRGRGR!***");
|
||||||
break;
|
break;
|
||||||
|
case npcSettings.id:
|
||||||
|
if (args[0].toLowerCase() === "summon" && isAdmin(message.author.id)) {
|
||||||
|
generateEnemy(process.env.DEADLANDS_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -100,20 +162,95 @@ cron.schedule('*/10 * * * *', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function generateEnemy(channelID) {
|
||||||
|
console.log("Generating enemy...")
|
||||||
|
|
||||||
|
// Gets an enemy batch instance, or creates if non-existant
|
||||||
|
var index = enemyBatchCollection.findIndex(data => data.channel === channelID);
|
||||||
|
var enemyBatch;
|
||||||
|
console.log(index <= -1)
|
||||||
|
if (index <= -1) {
|
||||||
|
enemyBatch = new EnemyBatchInstance(channelID);
|
||||||
|
} else {
|
||||||
|
enemyBatch = enemyBatchCollection[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a spawn pattern
|
||||||
|
var randomSpawnPattern = spawnPatterns.types[calcRandom.randomExc(0, spawnPatterns.types.length)];
|
||||||
|
var newSpawnPattern = spawnPatterns[randomSpawnPattern];
|
||||||
|
newSpawnPattern = spawnPatterns["default"]; // Overruled!
|
||||||
|
|
||||||
|
// Creates a bunch of new enemies
|
||||||
|
var amount = newSpawnPattern[npcSettings.id].amount;
|
||||||
|
var newEnemies = [];
|
||||||
|
for (let i = 0; i < amount; i++) {
|
||||||
|
var enemy = new Enemy(npcSettings.id);
|
||||||
|
var elevel = enemyBatch.hostileLevel;
|
||||||
|
|
||||||
|
// Replication of newHostile in sendData.php
|
||||||
|
const healthBase = 50; const strengthBase = 3; const speedBase = 3; const stashBase = 3;
|
||||||
|
|
||||||
|
const healthMin = (healthBase * elevel) / 2;
|
||||||
|
const healthMax = healthBase * elevel;
|
||||||
|
|
||||||
|
const strengthMin = (strengthBase * elevel) / 2;
|
||||||
|
const strengthMax = strengthBase * elevel;
|
||||||
|
|
||||||
|
const speedMin = (speedBase * elevel) / 2;
|
||||||
|
const speedMax = speedBase * elevel;
|
||||||
|
|
||||||
|
const stashMin = (stashBase * elevel) / 2;
|
||||||
|
const stashMax = stashBase * elevel;
|
||||||
|
|
||||||
|
const health = Math.floor(calcRandom.randomExc(healthMin, healthMax));
|
||||||
|
const strength = Math.floor(calcRandom.randomExc(strengthMin, strengthMax));
|
||||||
|
const speed = Math.floor(calcRandom.randomExc(speedMin, speedMax));
|
||||||
|
const stash = Math.floor(calcRandom.randomExc(stashMin, stashMax));
|
||||||
|
|
||||||
|
enemy.level = elevel;
|
||||||
|
enemy.health = health;
|
||||||
|
enemy.strength = strength;
|
||||||
|
enemy.speed = speed;
|
||||||
|
enemy.stash = stash;
|
||||||
|
enemy.state = EnemyState.PROWLING;
|
||||||
|
enemy.fleeTime = enemy.randomFleeTime;
|
||||||
|
enemy.guid = guidGenerator();
|
||||||
|
|
||||||
|
// Logs stats
|
||||||
|
console.log(`\n[===== | Enemy Stats | =====]`);
|
||||||
|
console.log(`HEALTH: ${health} > ${healthMin} - ${healthMax}`);
|
||||||
|
console.log(`STRENGTH: ${strength} > ${strengthMin} - ${strengthMax}`);
|
||||||
|
console.log(`SPEED: ${speed} > ${speedMin} - ${speedMax}`);
|
||||||
|
console.log(`STASH: ${stash} > ${stashMin} - ${stashMax}`);
|
||||||
|
console.log(`[===========================]\n`);
|
||||||
|
newEnemies.push(enemy);
|
||||||
|
}
|
||||||
|
enemyBatch.enemies = newEnemies;
|
||||||
|
enemyBatch.hostileLevel++;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(newEnemies, null, 2));
|
||||||
|
|
||||||
|
if (calcRandom.gamble(enemyBatch.spawnPrecentage)) {
|
||||||
|
enemyBatch.spawnPrecentage = 50;
|
||||||
|
|
||||||
|
// Creation of Ravager timer
|
||||||
|
var creationTime = calcRandom.random(35000, 540000);
|
||||||
|
creationTime = 3 * 1000; // shortcuts
|
||||||
|
|
||||||
|
console.log(`[Enemy Spawn] ${amount} "${npcSettings.id}" will be created in ${fmtMSS(creationTime / 1000)} min.`);
|
||||||
|
await sleep(creationTime);
|
||||||
|
console.log(`[Enemy Spawn] ${amount} "${npcSettings.id}" has spawned!`);
|
||||||
|
summonEnemy(enemyBatch);
|
||||||
|
|
||||||
|
enemyBatch.hostileLevel++;
|
||||||
|
} else {
|
||||||
|
console.log("[Enemy Spawn] Fail to spawn. Adding 10% more to chances.");
|
||||||
|
enemyBatch.spawnPrecentage += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Turn online and turn offline
|
// Turn online and turn offline
|
||||||
async function summonEnemy(data) {
|
async function summonEnemy(data) {
|
||||||
// Scans for Ravager already in channel
|
|
||||||
/*
|
|
||||||
var isRavagerInChannel = false;
|
|
||||||
ravagerCollection.forEach(element => {
|
|
||||||
if (element.channel === data.channel) {
|
|
||||||
console.log("There is already a Ravager in channel " + element.channel);
|
|
||||||
isRavagerInChannel = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (isRavagerInChannel) return;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// If timer exists, do outpost
|
// If timer exists, do outpost
|
||||||
const summonTime = 4; // 4 is debug, normal is 35
|
const summonTime = 4; // 4 is debug, normal is 35
|
||||||
if (!data.fastSummon) {
|
if (!data.fastSummon) {
|
||||||
@@ -124,7 +261,7 @@ async function summonEnemy(data) {
|
|||||||
// Sets prowling states on the Ravagers
|
// Sets prowling states on the Ravagers
|
||||||
for (let i = 0; i < data.enemies.length; i++) {
|
for (let i = 0; i < data.enemies.length; i++) {
|
||||||
const element = data.enemies[i];
|
const element = data.enemies[i];
|
||||||
element.state = RavagerState.PROWLING;
|
element.state = EnemyState.PROWLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification code
|
// Notification code
|
||||||
@@ -151,14 +288,14 @@ async function summonEnemy(data) {
|
|||||||
|
|
||||||
for (let i = 0; i < data.enemies.length; i++) {
|
for (let i = 0; i < data.enemies.length; i++) {
|
||||||
const element = data.enemies[i];
|
const element = data.enemies[i];
|
||||||
element.state = RavagerState.ACTIVE;
|
element.state = EnemyState.ACTIVE;
|
||||||
}
|
}
|
||||||
enemyTimer(element, data, data.channel, element.fleeTime, newMessage);
|
enemyTimer(element, data, data.channel, element.fleeTime, newMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counts down
|
// Counts down
|
||||||
async function enemyTimer(newRavager, data, channel, fleeTime, newMessage) {
|
async function enemyTimer(newEnemy, data, channel, fleeTime, newMessage) {
|
||||||
function addUserToArray(userID) {
|
function addUserToArray(userID) {
|
||||||
attackingUsers.push(userID);
|
attackingUsers.push(userID);
|
||||||
}
|
}
|
||||||
@@ -180,84 +317,164 @@ async function enemyTimer(newRavager, data, channel, fleeTime, newMessage) {
|
|||||||
.setTitle("Status")
|
.setTitle("Status")
|
||||||
.setDescription("...")
|
.setDescription("...")
|
||||||
|
|
||||||
|
const sendMessageMinimum = true;
|
||||||
var isReadyToFlee = false;
|
var isReadyToFlee = false;
|
||||||
var attackingUsers = [];
|
var attackingUsers = [];
|
||||||
var tempAttackUsers = "";
|
var tempAttackUsers = "";
|
||||||
var newChannel = client.channels.get(channel);
|
var newChannel = client.channels.get(channel);
|
||||||
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
||||||
|
|
||||||
// Collects emotes and reacts upon the reaction
|
|
||||||
const collector = newMessage.createReactionCollector(
|
|
||||||
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
|
||||||
|
|
||||||
// Possible reaction attacks can go here
|
// Possible reaction attacks can go here
|
||||||
var options = ['🇦', '🇧', '🇨']
|
var options = ['💥', '🇦', '🇧', '🇨']
|
||||||
sendReactions(options);
|
|
||||||
|
// System for no message sending except the minimum
|
||||||
// Collect
|
if (sendMessageMinimum) {
|
||||||
collector.once("collect", async reaction => {
|
// Collects emotes and reacts upon the reaction
|
||||||
var user = reaction.users.last();
|
const collector = newMessage.createReactionCollector(
|
||||||
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
addUserToArray(user.id);
|
|
||||||
console.log(tempAttackUsers);
|
sendReactions(options);
|
||||||
if (!interactionMessage.deleted) {
|
|
||||||
interactionEmbed.setDescription(`${tempAttackUsers}`);
|
// Collect
|
||||||
interactionMessage = await newChannel.edit({embed: interactionEmbed});
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
|
if (user.id === client.user.id) {
|
||||||
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send damage to server
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ends
|
||||||
|
collector.once("end", async collector => {
|
||||||
|
console.log("Ended collector.")
|
||||||
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
|
await sleep(fleeTime);
|
||||||
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Send damage.
|
// Collects emotes and reacts upon the reaction
|
||||||
|
var collector = newMessage.createReactionCollector(
|
||||||
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
|
|
||||||
});
|
sendReactions(options);
|
||||||
|
|
||||||
// Ends
|
|
||||||
collector.once("end", async collector => {
|
|
||||||
|
|
||||||
});
|
// Collect
|
||||||
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
// Goes every 4 seconds
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
var emoteRefresh = setInterval(async () => {
|
if (user.id === client.user.id) {
|
||||||
await newMessage.clearReactions();
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
interactionEmbed.setDescription("...");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isReadyToFlee && newRavager.state !== RavagerState.UNCONSCIOUS) {
|
// Send damage to server
|
||||||
interactionEmbed.setDescription("👣 The Ravager has fled...")
|
// TODO
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
clearInterval(emoteRefresh);
|
|
||||||
collector.stop();
|
|
||||||
} else {
|
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
sendReactions(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
tempAttackUsers = "";
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
}, 5 * 1000);
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
// Waits to see if killed, and if not send a fleeing message
|
// Ends
|
||||||
await sleep(fleeTime);
|
collector.once("end", async collector => {
|
||||||
if (newRavager.state === RavagerState.ACTIVE) {
|
console.log("Ended collector.")
|
||||||
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
await sleep(20 * 1000);
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
// If still there despawn
|
|
||||||
if (newRavager.state !== RavagerState.UNCONSCIOUS) {
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
await sleep(fleeTime);
|
||||||
isReadyToFlee = true;
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flee(newRavager, data, newChannel) {
|
// Does flee sequence
|
||||||
|
async function flee(newEnemy, data, newChannel) {
|
||||||
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
||||||
socket.emit('fled', {
|
socket.emit('fled', {
|
||||||
data: data,
|
data: data,
|
||||||
ravager: newRavager
|
ravager: newEnemy
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.length < 1) {
|
if (data.length < 1) {
|
||||||
await client.user.setPresence('invisible');
|
await client.user.setPresence('invisible');
|
||||||
client.user.setActivity('Prowling...');
|
client.user.setActivity('Prowling...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health bar
|
// Health bar
|
||||||
@@ -306,6 +523,14 @@ function fmtMSS(s){ // accepts seconds as Number or String. Returns m:ss
|
|||||||
) + s ; // and we add Number s to the string (converting it to String as well)
|
) + s ; // and we add Number s to the string (converting it to String as well)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/6860853/generate-random-string-for-div-id/6860916#6860916
|
||||||
|
function guidGenerator() {
|
||||||
|
var S4 = function() {
|
||||||
|
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||||
|
};
|
||||||
|
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||||
|
}
|
||||||
|
|
||||||
function getDialog(dialogTag, data = "", data2 = "") {
|
function getDialog(dialogTag, data = "", data2 = "") {
|
||||||
switch(dialogTag) {
|
switch(dialogTag) {
|
||||||
case "onTheProwl":
|
case "onTheProwl":
|
||||||
|
|||||||
@@ -11,18 +11,70 @@ const io = require('socket.io-client');
|
|||||||
var socket = io.connect('http://localhost:80');
|
var socket = io.connect('http://localhost:80');
|
||||||
|
|
||||||
// Bot Modules
|
// Bot Modules
|
||||||
|
const npcSettings = require('./npcSettings')
|
||||||
const dataRequest = require('../modules/dataRequest');
|
const dataRequest = require('../modules/dataRequest');
|
||||||
const calcRandom = require('../modules/calcRandom');
|
const calcRandom = require('../modules/calcRandom');
|
||||||
|
|
||||||
// State Machine
|
// State Machine
|
||||||
var RavagerState = {
|
var EnemyState = {
|
||||||
INACTIVE: 0,
|
INACTIVE: 0,
|
||||||
PROWLING: 1,
|
PROWLING: 1,
|
||||||
ACTIVE: 2,
|
ACTIVE: 2,
|
||||||
UNCONSCIOUS: 3
|
UNCONSCIOUS: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
const prowling = 'Prowling...';
|
// Enemy lists
|
||||||
|
class EnemyBatchInstance {
|
||||||
|
constructor(channel) {
|
||||||
|
this.state = EnemyState.INACTIVE;
|
||||||
|
this.enemies = []; // Array of `new Enemy()`s
|
||||||
|
this.channel = channel; // Channel of spawning
|
||||||
|
this.spawnPrecentage = 100;
|
||||||
|
this.hostileLevel = 1;
|
||||||
|
this.fastSummon = false; // Show prowling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enemy instance
|
||||||
|
class Enemy {
|
||||||
|
constructor(type) {
|
||||||
|
this.state = EnemyState.INACTIVE;
|
||||||
|
this.type = type;
|
||||||
|
this.level = 1;
|
||||||
|
this.health = 420;
|
||||||
|
this.speed = 21;
|
||||||
|
this.strength = 33;
|
||||||
|
this.stash = 0;
|
||||||
|
this.fleeTime = undefined;
|
||||||
|
this.guid = undefined;
|
||||||
|
this.deletePrevMessage = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates flee time by randomization
|
||||||
|
get randomFleeTime() {
|
||||||
|
var randomFleeTime;
|
||||||
|
randomFleeTime = calcRandom.random(3 * 60 * 1000, 6 * 60 * 1000);
|
||||||
|
randomFleeTime -= (randomFleeTime % 1000);
|
||||||
|
return randomFleeTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var enemyBatchCollection = [];
|
||||||
|
|
||||||
|
// Spawning patterns
|
||||||
|
var spawnPatterns = {
|
||||||
|
"types": ['default', 'randomBatch2'],
|
||||||
|
"default": {
|
||||||
|
"ravager": {
|
||||||
|
"amount": 1
|
||||||
|
},
|
||||||
|
"type": "incrememt"
|
||||||
|
},
|
||||||
|
"randomBatch2": {
|
||||||
|
"amount": 2,
|
||||||
|
"type": "incrememt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var socketReady = false;
|
var socketReady = false;
|
||||||
socket.on('spawn', (data) => {
|
socket.on('spawn', (data) => {
|
||||||
@@ -52,10 +104,15 @@ client.on('ready', async () => {
|
|||||||
// You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb)
|
// You can set status to 'online', 'invisible', 'away', or 'dnd' (do not disturb)
|
||||||
client.user.setStatus('invisible');
|
client.user.setStatus('invisible');
|
||||||
// Sets your "Playing"
|
// Sets your "Playing"
|
||||||
client.user.setActivity(prowling);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Connected! \
|
console.log(`Connected! \
|
||||||
\nLogged in as: ${client.user.username} - (${client.user.id})`);
|
\nLogged in as: ${client.user.username} - (${client.user.id})`);
|
||||||
|
|
||||||
// Corrects Ravager username
|
// Corrects Ravager username
|
||||||
if (client.user.username == "Raveger") {
|
if (client.user.username == "Raveger") {
|
||||||
const newName = "Ravager";
|
const newName = "Ravager";
|
||||||
@@ -91,6 +148,11 @@ client.on('message', async message => {
|
|||||||
if (isAdmin(message.author.id))
|
if (isAdmin(message.author.id))
|
||||||
message.reply("***...MRGRGRGR!***");
|
message.reply("***...MRGRGRGR!***");
|
||||||
break;
|
break;
|
||||||
|
case npcSettings.id:
|
||||||
|
if (args[0].toLowerCase() === "summon" && isAdmin(message.author.id)) {
|
||||||
|
generateEnemy(process.env.DEADLANDS_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -100,20 +162,95 @@ cron.schedule('*/10 * * * *', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function generateEnemy(channelID) {
|
||||||
|
console.log("Generating enemy...")
|
||||||
|
|
||||||
|
// Gets an enemy batch instance, or creates if non-existant
|
||||||
|
var index = enemyBatchCollection.findIndex(data => data.channel === channelID);
|
||||||
|
var enemyBatch;
|
||||||
|
console.log(index <= -1)
|
||||||
|
if (index <= -1) {
|
||||||
|
enemyBatch = new EnemyBatchInstance(channelID);
|
||||||
|
} else {
|
||||||
|
enemyBatch = enemyBatchCollection[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a spawn pattern
|
||||||
|
var randomSpawnPattern = spawnPatterns.types[calcRandom.randomExc(0, spawnPatterns.types.length)];
|
||||||
|
var newSpawnPattern = spawnPatterns[randomSpawnPattern];
|
||||||
|
newSpawnPattern = spawnPatterns["default"]; // Overruled!
|
||||||
|
|
||||||
|
// Creates a bunch of new enemies
|
||||||
|
var amount = newSpawnPattern[npcSettings.id].amount;
|
||||||
|
var newEnemies = [];
|
||||||
|
for (let i = 0; i < amount; i++) {
|
||||||
|
var enemy = new Enemy(npcSettings.id);
|
||||||
|
var elevel = enemyBatch.hostileLevel;
|
||||||
|
|
||||||
|
// Replication of newHostile in sendData.php
|
||||||
|
const healthBase = 50; const strengthBase = 3; const speedBase = 3; const stashBase = 3;
|
||||||
|
|
||||||
|
const healthMin = (healthBase * elevel) / 2;
|
||||||
|
const healthMax = healthBase * elevel;
|
||||||
|
|
||||||
|
const strengthMin = (strengthBase * elevel) / 2;
|
||||||
|
const strengthMax = strengthBase * elevel;
|
||||||
|
|
||||||
|
const speedMin = (speedBase * elevel) / 2;
|
||||||
|
const speedMax = speedBase * elevel;
|
||||||
|
|
||||||
|
const stashMin = (stashBase * elevel) / 2;
|
||||||
|
const stashMax = stashBase * elevel;
|
||||||
|
|
||||||
|
const health = Math.floor(calcRandom.randomExc(healthMin, healthMax));
|
||||||
|
const strength = Math.floor(calcRandom.randomExc(strengthMin, strengthMax));
|
||||||
|
const speed = Math.floor(calcRandom.randomExc(speedMin, speedMax));
|
||||||
|
const stash = Math.floor(calcRandom.randomExc(stashMin, stashMax));
|
||||||
|
|
||||||
|
enemy.level = elevel;
|
||||||
|
enemy.health = health;
|
||||||
|
enemy.strength = strength;
|
||||||
|
enemy.speed = speed;
|
||||||
|
enemy.stash = stash;
|
||||||
|
enemy.state = EnemyState.PROWLING;
|
||||||
|
enemy.fleeTime = enemy.randomFleeTime;
|
||||||
|
enemy.guid = guidGenerator();
|
||||||
|
|
||||||
|
// Logs stats
|
||||||
|
console.log(`\n[===== | Enemy Stats | =====]`);
|
||||||
|
console.log(`HEALTH: ${health} > ${healthMin} - ${healthMax}`);
|
||||||
|
console.log(`STRENGTH: ${strength} > ${strengthMin} - ${strengthMax}`);
|
||||||
|
console.log(`SPEED: ${speed} > ${speedMin} - ${speedMax}`);
|
||||||
|
console.log(`STASH: ${stash} > ${stashMin} - ${stashMax}`);
|
||||||
|
console.log(`[===========================]\n`);
|
||||||
|
newEnemies.push(enemy);
|
||||||
|
}
|
||||||
|
enemyBatch.enemies = newEnemies;
|
||||||
|
enemyBatch.hostileLevel++;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(newEnemies, null, 2));
|
||||||
|
|
||||||
|
if (calcRandom.gamble(enemyBatch.spawnPrecentage)) {
|
||||||
|
enemyBatch.spawnPrecentage = 50;
|
||||||
|
|
||||||
|
// Creation of Ravager timer
|
||||||
|
var creationTime = calcRandom.random(35000, 540000);
|
||||||
|
creationTime = 3 * 1000; // shortcuts
|
||||||
|
|
||||||
|
console.log(`[Enemy Spawn] ${amount} "${npcSettings.id}" will be created in ${fmtMSS(creationTime / 1000)} min.`);
|
||||||
|
await sleep(creationTime);
|
||||||
|
console.log(`[Enemy Spawn] ${amount} "${npcSettings.id}" has spawned!`);
|
||||||
|
summonEnemy(enemyBatch);
|
||||||
|
|
||||||
|
enemyBatch.hostileLevel++;
|
||||||
|
} else {
|
||||||
|
console.log("[Enemy Spawn] Fail to spawn. Adding 10% more to chances.");
|
||||||
|
enemyBatch.spawnPrecentage += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Turn online and turn offline
|
// Turn online and turn offline
|
||||||
async function summonEnemy(data) {
|
async function summonEnemy(data) {
|
||||||
// Scans for Ravager already in channel
|
|
||||||
/*
|
|
||||||
var isRavagerInChannel = false;
|
|
||||||
ravagerCollection.forEach(element => {
|
|
||||||
if (element.channel === data.channel) {
|
|
||||||
console.log("There is already a Ravager in channel " + element.channel);
|
|
||||||
isRavagerInChannel = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (isRavagerInChannel) return;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// If timer exists, do outpost
|
// If timer exists, do outpost
|
||||||
const summonTime = 4; // 4 is debug, normal is 35
|
const summonTime = 4; // 4 is debug, normal is 35
|
||||||
if (!data.fastSummon) {
|
if (!data.fastSummon) {
|
||||||
@@ -124,7 +261,7 @@ async function summonEnemy(data) {
|
|||||||
// Sets prowling states on the Ravagers
|
// Sets prowling states on the Ravagers
|
||||||
for (let i = 0; i < data.enemies.length; i++) {
|
for (let i = 0; i < data.enemies.length; i++) {
|
||||||
const element = data.enemies[i];
|
const element = data.enemies[i];
|
||||||
element.state = RavagerState.PROWLING;
|
element.state = EnemyState.PROWLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification code
|
// Notification code
|
||||||
@@ -151,14 +288,14 @@ async function summonEnemy(data) {
|
|||||||
|
|
||||||
for (let i = 0; i < data.enemies.length; i++) {
|
for (let i = 0; i < data.enemies.length; i++) {
|
||||||
const element = data.enemies[i];
|
const element = data.enemies[i];
|
||||||
element.state = RavagerState.ACTIVE;
|
element.state = EnemyState.ACTIVE;
|
||||||
}
|
}
|
||||||
enemyTimer(element, data, data.channel, element.fleeTime, newMessage);
|
enemyTimer(element, data, data.channel, element.fleeTime, newMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Counts down
|
// Counts down
|
||||||
async function enemyTimer(newRavager, data, channel, fleeTime, newMessage) {
|
async function enemyTimer(newEnemy, data, channel, fleeTime, newMessage) {
|
||||||
function addUserToArray(userID) {
|
function addUserToArray(userID) {
|
||||||
attackingUsers.push(userID);
|
attackingUsers.push(userID);
|
||||||
}
|
}
|
||||||
@@ -180,84 +317,164 @@ async function enemyTimer(newRavager, data, channel, fleeTime, newMessage) {
|
|||||||
.setTitle("Status")
|
.setTitle("Status")
|
||||||
.setDescription("...")
|
.setDescription("...")
|
||||||
|
|
||||||
|
const sendMessageMinimum = true;
|
||||||
var isReadyToFlee = false;
|
var isReadyToFlee = false;
|
||||||
var attackingUsers = [];
|
var attackingUsers = [];
|
||||||
var tempAttackUsers = "";
|
var tempAttackUsers = "";
|
||||||
var newChannel = client.channels.get(channel);
|
var newChannel = client.channels.get(channel);
|
||||||
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
var interactionMessage = await newChannel.send({embed: interactionEmbed});
|
||||||
|
|
||||||
// Collects emotes and reacts upon the reaction
|
|
||||||
const collector = newMessage.createReactionCollector(
|
|
||||||
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
|
||||||
|
|
||||||
// Possible reaction attacks can go here
|
// Possible reaction attacks can go here
|
||||||
var options = ['🇦', '🇧', '🇨']
|
var options = ['💥', '🇦', '🇧', '🇨']
|
||||||
sendReactions(options);
|
|
||||||
|
// System for no message sending except the minimum
|
||||||
// Collect
|
if (sendMessageMinimum) {
|
||||||
collector.once("collect", async reaction => {
|
// Collects emotes and reacts upon the reaction
|
||||||
var user = reaction.users.last();
|
const collector = newMessage.createReactionCollector(
|
||||||
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
addUserToArray(user.id);
|
|
||||||
console.log(tempAttackUsers);
|
sendReactions(options);
|
||||||
if (!interactionMessage.deleted) {
|
|
||||||
interactionEmbed.setDescription(`${tempAttackUsers}`);
|
// Collect
|
||||||
interactionMessage = await newChannel.edit({embed: interactionEmbed});
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
|
if (user.id === client.user.id) {
|
||||||
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send damage to server
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ends
|
||||||
|
collector.once("end", async collector => {
|
||||||
|
console.log("Ended collector.")
|
||||||
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
|
await sleep(fleeTime);
|
||||||
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Send damage.
|
// Collects emotes and reacts upon the reaction
|
||||||
|
var collector = newMessage.createReactionCollector(
|
||||||
|
(reaction, user) => options.includes(reaction.emoji.name) && user.id !== client.user.id);
|
||||||
|
|
||||||
});
|
sendReactions(options);
|
||||||
|
|
||||||
// Ends
|
|
||||||
collector.once("end", async collector => {
|
|
||||||
|
|
||||||
});
|
// Collect
|
||||||
|
collector.on("collect", async reaction => {
|
||||||
|
var user = reaction.users.last();
|
||||||
|
|
||||||
// Goes every 4 seconds
|
// Just in case, I managed to bug out Ravager to display its own name.
|
||||||
var emoteRefresh = setInterval(async () => {
|
if (user.id === client.user.id) {
|
||||||
await newMessage.clearReactions();
|
console.log("Well then. It bypassed the collector filter, we're stopping the Ravager from attacking itself. Would be interesting though!");
|
||||||
interactionEmbed.setDescription("...");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isReadyToFlee && newRavager.state !== RavagerState.UNCONSCIOUS) {
|
// Send damage to server
|
||||||
interactionEmbed.setDescription("👣 The Ravager has fled...")
|
// TODO
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
clearInterval(emoteRefresh);
|
|
||||||
collector.stop();
|
|
||||||
} else {
|
|
||||||
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
|
||||||
sendReactions(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
tempAttackUsers = "";
|
tempAttackUsers += `${user} :crossed_swords: 11 DAM | <:hitback:460969716580745236> MISS (150/150)\n`;
|
||||||
}, 5 * 1000);
|
addUserToArray(user.id);
|
||||||
|
console.log("Collecting a user! " + user.username)
|
||||||
|
});
|
||||||
|
|
||||||
// Waits to see if killed, and if not send a fleeing message
|
// Ends
|
||||||
await sleep(fleeTime);
|
collector.once("end", async collector => {
|
||||||
if (newRavager.state === RavagerState.ACTIVE) {
|
console.log("Ended collector.")
|
||||||
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
flee(newEnemy, data, client.channels.get(channel));
|
||||||
await sleep(20 * 1000);
|
});
|
||||||
|
|
||||||
|
// Goes every 4 seconds
|
||||||
|
var emoteRefresh = setInterval(async () => {
|
||||||
|
await newMessage.clearReactions();
|
||||||
|
|
||||||
|
if (isReadyToFlee && newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log("Has fled!");
|
||||||
|
//interactionEmbed.setDescription("👣 The Ravager has fled...")
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
clearInterval(emoteRefresh);
|
||||||
|
collector.stop();
|
||||||
|
} else {
|
||||||
|
console.log("Sending refreshed embed... |" + tempAttackUsers + "|")
|
||||||
|
if (tempAttackUsers === "") tempAttackUsers = "...";
|
||||||
|
interactionEmbed.setDescription(tempAttackUsers);
|
||||||
|
if (interactionMessage) await interactionMessage.edit({embed: interactionEmbed});
|
||||||
|
sendReactions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempAttackUsers = "";
|
||||||
|
}, 5 * 1000);
|
||||||
|
|
||||||
// If still there despawn
|
|
||||||
if (newRavager.state !== RavagerState.UNCONSCIOUS) {
|
// Waits to see if killed, and if not send a fleeing message
|
||||||
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
await sleep(fleeTime);
|
||||||
isReadyToFlee = true;
|
if (newEnemy.state === EnemyState.ACTIVE) {
|
||||||
|
newChannel.send("**YOU ARE WEAK. THERE IS NO CHALLENGE FOR ME HERE.**\n:bangbang:***ATTEMPTING TO FLEE...***");
|
||||||
|
await sleep(20 * 1000);
|
||||||
|
|
||||||
|
// If still there despawn
|
||||||
|
if (newEnemy.state !== EnemyState.UNCONSCIOUS) {
|
||||||
|
console.log('Hostile is now able to flee, now awaiting for collector to finish.');
|
||||||
|
isReadyToFlee = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flee(newRavager, data, newChannel) {
|
// Does flee sequence
|
||||||
|
async function flee(newEnemy, data, newChannel) {
|
||||||
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
newChannel.send("**THE POOR, ILL-EQUIPPED TRAVELERS PUT UP NO FIGHT...**\n:footprints:***RETURNS TO THE WILD. ***");
|
||||||
socket.emit('fled', {
|
socket.emit('fled', {
|
||||||
data: data,
|
data: data,
|
||||||
ravager: newRavager
|
ravager: newEnemy
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data.length < 1) {
|
if (data.length < 1) {
|
||||||
await client.user.setPresence('invisible');
|
await client.user.setPresence('invisible');
|
||||||
client.user.setActivity('Prowling...');
|
client.user.setActivity('Prowling...');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health bar
|
// Health bar
|
||||||
@@ -306,6 +523,14 @@ function fmtMSS(s){ // accepts seconds as Number or String. Returns m:ss
|
|||||||
) + s ; // and we add Number s to the string (converting it to String as well)
|
) + s ; // and we add Number s to the string (converting it to String as well)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/6860853/generate-random-string-for-div-id/6860916#6860916
|
||||||
|
function guidGenerator() {
|
||||||
|
var S4 = function() {
|
||||||
|
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||||
|
};
|
||||||
|
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||||
|
}
|
||||||
|
|
||||||
function getDialog(dialogTag, data = "", data2 = "") {
|
function getDialog(dialogTag, data = "", data2 = "") {
|
||||||
switch(dialogTag) {
|
switch(dialogTag) {
|
||||||
case "onTheProwl":
|
case "onTheProwl":
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -7,7 +7,7 @@ SANCTUM is an open-source Discord MMO, with 200+ players.
|
|||||||
- [Discord Game Invite Link](https://discord.gg/D7dyrVn)
|
- [Discord Game Invite Link](https://discord.gg/D7dyrVn)
|
||||||
- [Developer's Discord](https://discord.gg/mP98ZYv)
|
- [Developer's Discord](https://discord.gg/mP98ZYv)
|
||||||
|
|
||||||
# Run the bots
|
# Run the Bots
|
||||||
## Requirements:
|
## Requirements:
|
||||||
You will need:
|
You will need:
|
||||||
- [Node.js](https://nodejs.org/en/) (recommended v8.12.0 LTS)
|
- [Node.js](https://nodejs.org/en/) (recommended v8.12.0 LTS)
|
||||||
@@ -26,7 +26,11 @@ You will need:
|
|||||||
Make sure you're in the project folder!
|
Make sure you're in the project folder!
|
||||||
On Windows, you can hold Shift and Right Click the folder to get the option of a command prompt, inside that folder.
|
On Windows, you can hold Shift and Right Click the folder to get the option of a command prompt, inside that folder.
|
||||||
```bash
|
```bash
|
||||||
# You have to be in the project folder first to navigate through it
|
# If you already haven't, clone the repo
|
||||||
|
git clone https://github.com/TimRuswick/SANCTUM
|
||||||
|
cd "SANCTUM"
|
||||||
|
|
||||||
|
# Choose a bot
|
||||||
cd "A.D.A.M."
|
cd "A.D.A.M."
|
||||||
npm i
|
npm i
|
||||||
node adam.js
|
node adam.js
|
||||||
@@ -34,7 +38,7 @@ You will need:
|
|||||||
|
|
||||||
4. ???
|
4. ???
|
||||||
|
|
||||||
5. Profit! You did it, unless something has happened along the way. ~~Probably likely, sadly.~~
|
5. Profit! You did it, unless something has happened along the way. ~~Developer luck says yes.~~
|
||||||
|
|
||||||
## Quality of Life
|
## Quality of Life
|
||||||
|
|
||||||
|
|||||||
293
package-lock.json
generated
Normal file
293
package-lock.json
generated
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
{
|
||||||
|
"name": "Sanctuary",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/concat-stream": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "http://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz",
|
||||||
|
"integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/form-data": {
|
||||||
|
"version": "0.0.33",
|
||||||
|
"resolved": "http://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
|
||||||
|
"integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "9.6.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.35.tgz",
|
||||||
|
"integrity": "sha512-h5zvHS8wXHGa+Gcqs9K8vqCgOtqjr0+NqG/DDJmQIX1wpR9HivAfgV8bjcD3mGM4bPfQw5Aneb2Pn8355L83jA=="
|
||||||
|
},
|
||||||
|
"@types/qs": {
|
||||||
|
"version": "6.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.5.1.tgz",
|
||||||
|
"integrity": "sha512-mNhVdZHdtKHMMxbqzNK3RzkBcN1cux3AvuCYGTvjEIQT2uheH3eCAyYsbMbh2Bq8nXkeOWs1kyDiF7geWRFQ4Q=="
|
||||||
|
},
|
||||||
|
"asap": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
|
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||||
|
},
|
||||||
|
"asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||||
|
},
|
||||||
|
"buffer-from": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||||
|
},
|
||||||
|
"caseless": {
|
||||||
|
"version": "0.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||||
|
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||||
|
},
|
||||||
|
"cjopus": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cjopus/-/cjopus-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-RvPPyWuD99eERt6LTP2ZS1iJqaA="
|
||||||
|
},
|
||||||
|
"combined-stream": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
|
||||||
|
"requires": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"concat-stream": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^2.2.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"core-util-is": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||||
|
},
|
||||||
|
"delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||||
|
},
|
||||||
|
"discord.io": {
|
||||||
|
"version": "github:woor/discord.io#4333acbc6f15542971f7503f4c1b1a07976a6615",
|
||||||
|
"from": "github:woor/discord.io#gateway_v6",
|
||||||
|
"requires": {
|
||||||
|
"cjopus": "^0.0.4",
|
||||||
|
"tweetnacl": "^0.14.0",
|
||||||
|
"ws": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dotenv": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw=="
|
||||||
|
},
|
||||||
|
"form-data": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
|
||||||
|
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
|
||||||
|
"requires": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "1.0.6",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get-port": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
|
||||||
|
"integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw="
|
||||||
|
},
|
||||||
|
"http-basic": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-basic/-/http-basic-7.0.0.tgz",
|
||||||
|
"integrity": "sha1-gvClBr6UJzLsje6+6A50bvVzbbo=",
|
||||||
|
"requires": {
|
||||||
|
"@types/concat-stream": "^1.6.0",
|
||||||
|
"@types/node": "^9.4.1",
|
||||||
|
"caseless": "~0.12.0",
|
||||||
|
"concat-stream": "^1.4.6",
|
||||||
|
"http-response-object": "^3.0.1",
|
||||||
|
"parse-cache-control": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"http-response-object": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-6L0Fkd6TozA8kFSfh9Widst0wfza3U1Ex2RjJ6zNDK0vR1U1auUR6jY4Nn2Xl7CCy0ikFmxW1XcspVpb9RvwTg==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "^9.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.36.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
|
||||||
|
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
|
||||||
|
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "~1.36.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node-cron": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-jJC8XccjpWKJsHhmVatKHEy2A2g="
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
|
||||||
|
},
|
||||||
|
"parse-cache-control": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104="
|
||||||
|
},
|
||||||
|
"process-nextick-args": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||||
|
},
|
||||||
|
"promise": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise/-/promise-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-EIyzM39FpVOMbqgzEHhxdrEhtOSDOtjMZQ0M6iVfCE+kWNgCkAyOdnuCWqfmflylftfadU6FkiMgHZA2kUzwRw==",
|
||||||
|
"requires": {
|
||||||
|
"asap": "~2.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||||
|
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.3.6",
|
||||||
|
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||||
|
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.3",
|
||||||
|
"isarray": "~1.0.0",
|
||||||
|
"process-nextick-args": "~2.0.0",
|
||||||
|
"safe-buffer": "~5.1.1",
|
||||||
|
"string_decoder": "~1.1.1",
|
||||||
|
"util-deprecate": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sync-request": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-jGNIAlCi9iU4X3Dm4oQnNQshDD3h0/1A7r79LyqjbjUnj69sX6mShAXlhRXgImsfVKtTcnra1jfzabdZvp+Lmw==",
|
||||||
|
"requires": {
|
||||||
|
"http-response-object": "^3.0.1",
|
||||||
|
"sync-rpc": "^1.2.1",
|
||||||
|
"then-request": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sync-rpc": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-Iug+t1ICVFenUcTnDu8WXFnT+k8IVoLKGh8VA3eXUtl2Rt9SjKX3YEv33OenABqpTPL9QEaHv1+CNn2LK8vMow==",
|
||||||
|
"requires": {
|
||||||
|
"get-port": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"then-request": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-xA+7uEMc+jsQIoyySJ93Ad08Kuqnik7u6jLS5hR91Z3smAoCfL3M8/MqMlobAa9gzBfO9pA88A/AntfepkkMJQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/concat-stream": "^1.6.0",
|
||||||
|
"@types/form-data": "0.0.33",
|
||||||
|
"@types/node": "^8.0.0",
|
||||||
|
"@types/qs": "^6.2.31",
|
||||||
|
"caseless": "~0.12.0",
|
||||||
|
"concat-stream": "^1.6.0",
|
||||||
|
"form-data": "^2.2.0",
|
||||||
|
"http-basic": "^7.0.0",
|
||||||
|
"http-response-object": "^3.0.1",
|
||||||
|
"promise": "^8.0.0",
|
||||||
|
"qs": "^6.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": {
|
||||||
|
"version": "8.10.36",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.36.tgz",
|
||||||
|
"integrity": "sha512-SL6KhfM7PTqiFmbCW3eVNwVBZ+88Mrzbuvn9olPsfv43mbiWaFY+nRcz/TGGku0/lc2FepdMbImdMY1JrQ+zbw=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tweetnacl": {
|
||||||
|
"version": "0.14.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||||
|
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||||
|
},
|
||||||
|
"typedarray": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||||
|
},
|
||||||
|
"ultron": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
|
||||||
|
},
|
||||||
|
"util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
|
||||||
|
"requires": {
|
||||||
|
"options": ">=0.0.5",
|
||||||
|
"ultron": "1.0.x"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
package.json
Normal file
17
package.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "Sanctuary",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A text-based massively multiplayer game about the survival of the fittest.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Tim",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"discord.io": "github:woor/discord.io#gateway_v6",
|
||||||
|
"dotenv": "^6.0.0",
|
||||||
|
"node-cron": "^1.2.1",
|
||||||
|
"sync-request": "^6.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user