diff --git a/eventfunctions/gags/chocolate.js b/eventfunctions/gags/chocolate.js new file mode 100644 index 00000000..1058bfac --- /dev/null +++ b/eventfunctions/gags/chocolate.js @@ -0,0 +1,33 @@ +const { getOption } = require("../../functions/configfunctions") +const { messageSendChannel } = require("../../functions/messagefunctions") +const { getUserVar, setUserVar } = require("../../functions/usercontext") +const { getGag, assignGag, deleteGag} = require("../../functions/gagfunctions.js"); +const { getPronouns } = require("../../functions/pronounfunctions.js"); + +const DISSOLVE_RATE_MS = 60000; + +async function functiontick(userID) { + // Init Countdown Variable on First Run if not already present + if (getUserVar(userID, "confectionaryDissolveTimer") == undefined) { + setUserVar(userID, "confectionaryDissolveTimer", Date.now() + DISSOLVE_RATE_MS) + } + + // Decrement Intensity every timer interval + if (getUserVar(userID, "confectionaryDissolveTimer") < Date.now() && getGag(userID, "chocolate") && process.recentmessages[userID]) { + if(getGag(userID, "chocolate").intensity > 1){ + setUserVar(userID, "confectionaryDissolveTimer", Date.now() + DISSOLVE_RATE_MS) + // Get Intensity and push decremented version + let oldIntensity = getGag(userID, "chocolate").intensity + assignGag(userID, "chocolate", oldIntensity - 1) + messageSendChannel(`<@${userID}>'s licking has shrunk ${getPronouns(userID, "reflexive")} Chocolate Gag a little bit!`, process.recentmessages[userID]) + } + else { + // Clear Gag and Dissolve Timer + setUserVar(userID, "confectionaryDissolveTimer", undefined) + deleteGag(userID, "chocolate") + messageSendChannel(`<@${userID}>'s Chocolate Gag has dissolved away!`, process.recentmessages[userID]) + } + } +} + +exports.functiontick = functiontick; \ No newline at end of file diff --git a/eventfunctions/gags/gummy.js b/eventfunctions/gags/gummy.js new file mode 100644 index 00000000..141009a1 --- /dev/null +++ b/eventfunctions/gags/gummy.js @@ -0,0 +1,32 @@ +const { getOption } = require("../../functions/configfunctions") +const { messageSendChannel } = require("../../functions/messagefunctions") +const { getUserVar, setUserVar } = require("../../functions/usercontext") +const { getGag, assignGag, deleteGag} = require("../../functions/gagfunctions.js"); + +const DISSOLVE_RATE_MS = 300000; + +async function functiontick(userID) { + // Init Countdown Variable on First Run if not already present + if (getUserVar(userID, "confectionaryDissolveTimer") == undefined) { + setUserVar(userID, "confectionaryDissolveTimer", Date.now() + DISSOLVE_RATE_MS) + } + + // Decrement Intensity every timer interval + if (getUserVar(userID, "confectionaryDissolveTimer") < Date.now() && getGag(userID, "gummy") && process.recentmessages[userID]) { + if(getGag(userID, "gummy").intensity > 1){ + setUserVar(userID, "confectionaryDissolveTimer", Date.now() + DISSOLVE_RATE_MS) + // Get Intensity and push decremented version + let oldIntensity = getGag(userID, "gummy").intensity + assignGag(userID, "gummy", oldIntensity - 1) + messageSendChannel(`<@${userID}>'s licking has shrunk ${getPronouns(userID, "reflexive")} Gummy Gag a little bit!`, process.recentmessages[userID]) + } + else { + // Clear Gag and Dissolve Timer + setUserVar(userID, "confectionaryDissolveTimer", undefined) + deleteGag(userID, "gummy") + messageSendChannel(`<@${userID}>'s Gummy Gag has dissolved away!`, process.recentmessages[userID]) + } + } +} + +exports.functiontick = functiontick; \ No newline at end of file diff --git a/eventfunctions/gags/jawbreaker.js b/eventfunctions/gags/jawbreaker.js new file mode 100644 index 00000000..ab11cd9e --- /dev/null +++ b/eventfunctions/gags/jawbreaker.js @@ -0,0 +1,32 @@ +const { getOption } = require("../../functions/configfunctions") +const { messageSendChannel } = require("../../functions/messagefunctions") +const { getUserVar, setUserVar } = require("../../functions/usercontext") +const { getGag, assignGag, deleteGag} = require("../../functions/gagfunctions.js"); + +const DISSOLVE_RATE_MS = 1200000; + +async function functiontick(userID) { + // Init Countdown Variable on First Run if not already present + if (getUserVar(userID, "confectionaryDissolveTimer") == undefined) { + setUserVar(userID, "confectionaryDissolveTimer", Date.now() + DISSOLVE_RATE_MS) + } + + // Decrement Intensity every timer interval + if (getUserVar(userID, "confectionaryDissolveTimer") < Date.now() && getGag(userID, "jawbreaker") && process.recentmessages[userID]) { + if(getGag(userID, "jawbreaker").intensity > 1){ + setUserVar(userID, "confectionaryDissolveTimer", Date.now() + DISSOLVE_RATE_MS) + // Get Intensity and push decremented version + let oldIntensity = getGag(userID, "jawbreaker").intensity + assignGag(userID, "jawbreaker", oldIntensity - 1) + messageSendChannel(`<@${userID}>'s licking has shrunk ${getPronouns(userID, "reflexive")} Jawbreaker Gag a little bit!`, process.recentmessages[userID]) + } + else { + // Clear Gag and Dissolve Timer + setUserVar(userID, "confectionaryDissolveTimer", undefined) + deleteGag(userID, "jawbreaker") + messageSendChannel(`<@${userID}>'s Jawbreaker Gag has dissolved away!`, process.recentmessages[userID]) + } + } +} + +exports.functiontick = functiontick; \ No newline at end of file diff --git a/functions/pronounfunctions.js b/functions/pronounfunctions.js index d6ed50dc..1bf3e77a 100644 --- a/functions/pronounfunctions.js +++ b/functions/pronounfunctions.js @@ -32,10 +32,14 @@ const pronounsMap = new Map([ /******************************************** * getPronoun() - * Get a user's pronoun of the necessary form. + * Get a userID's pronoun of the necessary form. * - * If no form specified, give the object containing all. Useful to reduce calls? - * > To create "she/her", you need subject/object + * If no form specified, give the object containing all. + * - subject: "they", + * - object: "them", + * - possessive: "theirs", + * - possessiveDeterminer: "their", + * - reflexive: "themself" *******************************************/ const getPronouns = (user, form, capitalize = false) => { if (process.pronouns == undefined) { diff --git a/gags/chocolate.js b/gags/chocolate.js new file mode 100644 index 00000000..0125b81e --- /dev/null +++ b/gags/chocolate.js @@ -0,0 +1,111 @@ +/*************************** + * Chocolate Gag for Gagbot + * ~ Pyra - Derived from Ball Gag by DollLia + ***************************/ + +// Character maps stored in an array in a separate file for code cleanliness +const { ballGagCharMaps } = require("./ball/ballCharMap.js"); + +const isAllCaps = (text) => { + //(words[x].match(/[A-Z]/) && !words[x].match(/[a-z]/)) ? true : false; + return text == text.toLowerCase().toUpperCase() && /[A-Z]/g.test(text); +}; + +const totalAlphas = (text) => { + let count = 0; + for (let itr = 0; itr < text.length; itr++) { + if (text[itr].match(/[A-Za-z]/)) { + count++; + } + } + return count; +}; + +// Helper function to garble a text segment. +const garbleText = (text, parent, intensity) => { + //console.log("Text Seg: " + text) + + let output = ""; + let words = text.split(/\s/); + + for (let x = 0; x < words.length; x++) { + let allCaps = isAllCaps(words[x]); + // Special case for "I", "a", etc. + if (allCaps && totalAlphas(words[x]) == 1) { + //words[x].length == 1){ + //console.log(`Run Test: ${words[x-1]} - ${words[x]} - ${words[x+1]}`) + if ((words[x - 1] && isAllCaps(words[x - 1])) || (words[x + 1] && isAllCaps(words[x + 1]))) { + } else { + allCaps = false; + } + } + + let itr = 0; + let prevChar = null; + for (const char of words[x]) { + // Test for uppercase. + let isUppercase = allCaps || char != char.toLowerCase(); + + // Get the new character using the array of character maps. + // 10 intensities, only five maps. + let newChar = ballGagCharMaps[Math.ceil(intensity / 2) - 1].get(char.toLowerCase()); + + if (newChar) { + // If char is mapped, swap it + + let nextChar; + if (newChar.length == 2 && char.toLowerCase() == (prevChar ? prevChar.toLowerCase() : null)) { + //console.log("Prev: " + prevChar + "; Next: " + char) + nextChar = isUppercase ? newChar[1].toUpperCase() : newChar[1]; + } else { + nextChar = isUppercase ? newChar[0].toUpperCase() + (newChar[1] ? newChar[1] : "") : newChar; + } + + if (allCaps) { + nextChar = nextChar.toUpperCase(); + } + output += nextChar; + } else { + // Append an unmodified character. + output += char; + } + prevChar = char; // Store previous char + itr++; // THEN iterate + } + + if (x < words.length - 1) { + output += " "; + } + } + + return output; +}; + +exports.garbleText = garbleText; +exports.breathRecovery = (_user, intensity) => 1 - intensity / 20; +exports.choicename = "Chocolate Gag"; + +// Clear Dissolve Timer +exports.onUnlock = (data) => { + setUserVar(userID, "confectionaryDissolveTimer", undefined) +} + +// Unit Tests + +//Test Gag Intensities +// let intensityTestMsg = "I AM LOUD. I am quiet." +// let intensityTestMsg2 = "Ha! I, in my brattiness, created test-4, a test. . . just to anger DOLL-0014 into domming me!!" + +// console.log(`Original: ${intensityTestMsg}\n`) +// console.log(`Intensity 1-2: ${garbleText(intensityTestMsg, 1)}`) +// console.log(`Intensity 3-4: ${garbleText(intensityTestMsg, 3)}`) +// console.log(`Intensity 5-6: ${garbleText(intensityTestMsg, 5)}`) +// console.log(`Intensity 7-8: ${garbleText(intensityTestMsg, 7)}`) +// console.log(`Intensity 9-10: ${garbleText(intensityTestMsg, 9)}`) + +// console.log(`\nOriginal: ${intensityTestMsg2}\n`) +// console.log(`Intensity 1-2: ${garbleText(intensityTestMsg2, 2)}`) +// console.log(`Intensity 3-4: ${garbleText(intensityTestMsg2, 4)}`) +// console.log(`Intensity 5-6: ${garbleText(intensityTestMsg2, 6)}`) +// console.log(`Intensity 7-8: ${garbleText(intensityTestMsg2, 8)}`) +// console.log(`Intensity 9-10: ${garbleText(intensityTestMsg2, 10)}`) diff --git a/gags/gummy.js b/gags/gummy.js new file mode 100644 index 00000000..02640faf --- /dev/null +++ b/gags/gummy.js @@ -0,0 +1,111 @@ +/*************************** + * Gummy Gag for Gagbot + * ~ Pyra - Derived from Ball Gag by DollLia + ***************************/ + +// Character maps stored in an array in a separate file for code cleanliness +const { ballGagCharMaps } = require("./ball/ballCharMap.js"); + +const isAllCaps = (text) => { + //(words[x].match(/[A-Z]/) && !words[x].match(/[a-z]/)) ? true : false; + return text == text.toLowerCase().toUpperCase() && /[A-Z]/g.test(text); +}; + +const totalAlphas = (text) => { + let count = 0; + for (let itr = 0; itr < text.length; itr++) { + if (text[itr].match(/[A-Za-z]/)) { + count++; + } + } + return count; +}; + +// Helper function to garble a text segment. +const garbleText = (text, parent, intensity) => { + //console.log("Text Seg: " + text) + + let output = ""; + let words = text.split(/\s/); + + for (let x = 0; x < words.length; x++) { + let allCaps = isAllCaps(words[x]); + // Special case for "I", "a", etc. + if (allCaps && totalAlphas(words[x]) == 1) { + //words[x].length == 1){ + //console.log(`Run Test: ${words[x-1]} - ${words[x]} - ${words[x+1]}`) + if ((words[x - 1] && isAllCaps(words[x - 1])) || (words[x + 1] && isAllCaps(words[x + 1]))) { + } else { + allCaps = false; + } + } + + let itr = 0; + let prevChar = null; + for (const char of words[x]) { + // Test for uppercase. + let isUppercase = allCaps || char != char.toLowerCase(); + + // Get the new character using the array of character maps. + // 10 intensities, only five maps. + let newChar = ballGagCharMaps[Math.ceil(intensity / 2) - 1].get(char.toLowerCase()); + + if (newChar) { + // If char is mapped, swap it + + let nextChar; + if (newChar.length == 2 && char.toLowerCase() == (prevChar ? prevChar.toLowerCase() : null)) { + //console.log("Prev: " + prevChar + "; Next: " + char) + nextChar = isUppercase ? newChar[1].toUpperCase() : newChar[1]; + } else { + nextChar = isUppercase ? newChar[0].toUpperCase() + (newChar[1] ? newChar[1] : "") : newChar; + } + + if (allCaps) { + nextChar = nextChar.toUpperCase(); + } + output += nextChar; + } else { + // Append an unmodified character. + output += char; + } + prevChar = char; // Store previous char + itr++; // THEN iterate + } + + if (x < words.length - 1) { + output += " "; + } + } + + return output; +}; + +exports.garbleText = garbleText; +exports.breathRecovery = (_user, intensity) => 1 - intensity / 20; +exports.choicename = "Gummy Gag"; + +// Clear Dissolve Timer +exports.onUnlock = (data) => { + setUserVar(userID, "confectionaryDissolveTimer", undefined) +} + +// Unit Tests + +//Test Gag Intensities +// let intensityTestMsg = "I AM LOUD. I am quiet." +// let intensityTestMsg2 = "Ha! I, in my brattiness, created test-4, a test. . . just to anger DOLL-0014 into domming me!!" + +// console.log(`Original: ${intensityTestMsg}\n`) +// console.log(`Intensity 1-2: ${garbleText(intensityTestMsg, 1)}`) +// console.log(`Intensity 3-4: ${garbleText(intensityTestMsg, 3)}`) +// console.log(`Intensity 5-6: ${garbleText(intensityTestMsg, 5)}`) +// console.log(`Intensity 7-8: ${garbleText(intensityTestMsg, 7)}`) +// console.log(`Intensity 9-10: ${garbleText(intensityTestMsg, 9)}`) + +// console.log(`\nOriginal: ${intensityTestMsg2}\n`) +// console.log(`Intensity 1-2: ${garbleText(intensityTestMsg2, 2)}`) +// console.log(`Intensity 3-4: ${garbleText(intensityTestMsg2, 4)}`) +// console.log(`Intensity 5-6: ${garbleText(intensityTestMsg2, 6)}`) +// console.log(`Intensity 7-8: ${garbleText(intensityTestMsg2, 8)}`) +// console.log(`Intensity 9-10: ${garbleText(intensityTestMsg2, 10)}`) diff --git a/gags/jawbreaker.js b/gags/jawbreaker.js new file mode 100644 index 00000000..5d8cc1a6 --- /dev/null +++ b/gags/jawbreaker.js @@ -0,0 +1,111 @@ +/*************************** + * Jawbreaker Gag for Gagbot + * ~ Pyra - Derived from Ball Gag by DollLia + ***************************/ + +// Character maps stored in an array in a separate file for code cleanliness +const { ballGagCharMaps } = require("./ball/ballCharMap.js"); + +const isAllCaps = (text) => { + //(words[x].match(/[A-Z]/) && !words[x].match(/[a-z]/)) ? true : false; + return text == text.toLowerCase().toUpperCase() && /[A-Z]/g.test(text); +}; + +const totalAlphas = (text) => { + let count = 0; + for (let itr = 0; itr < text.length; itr++) { + if (text[itr].match(/[A-Za-z]/)) { + count++; + } + } + return count; +}; + +// Helper function to garble a text segment. +const garbleText = (text, parent, intensity) => { + //console.log("Text Seg: " + text) + + let output = ""; + let words = text.split(/\s/); + + for (let x = 0; x < words.length; x++) { + let allCaps = isAllCaps(words[x]); + // Special case for "I", "a", etc. + if (allCaps && totalAlphas(words[x]) == 1) { + //words[x].length == 1){ + //console.log(`Run Test: ${words[x-1]} - ${words[x]} - ${words[x+1]}`) + if ((words[x - 1] && isAllCaps(words[x - 1])) || (words[x + 1] && isAllCaps(words[x + 1]))) { + } else { + allCaps = false; + } + } + + let itr = 0; + let prevChar = null; + for (const char of words[x]) { + // Test for uppercase. + let isUppercase = allCaps || char != char.toLowerCase(); + + // Get the new character using the array of character maps. + // 10 intensities, only five maps. + let newChar = ballGagCharMaps[Math.ceil(intensity / 2) - 1].get(char.toLowerCase()); + + if (newChar) { + // If char is mapped, swap it + + let nextChar; + if (newChar.length == 2 && char.toLowerCase() == (prevChar ? prevChar.toLowerCase() : null)) { + //console.log("Prev: " + prevChar + "; Next: " + char) + nextChar = isUppercase ? newChar[1].toUpperCase() : newChar[1]; + } else { + nextChar = isUppercase ? newChar[0].toUpperCase() + (newChar[1] ? newChar[1] : "") : newChar; + } + + if (allCaps) { + nextChar = nextChar.toUpperCase(); + } + output += nextChar; + } else { + // Append an unmodified character. + output += char; + } + prevChar = char; // Store previous char + itr++; // THEN iterate + } + + if (x < words.length - 1) { + output += " "; + } + } + + return output; +}; + +exports.garbleText = garbleText; +exports.breathRecovery = (_user, intensity) => 1 - intensity / 20; +exports.choicename = "Jawbreaker Gag"; + +// Clear Dissolve Timer +exports.onUnlock = (data) => { + setUserVar(userID, "confectionaryDissolveTimer", undefined) +} + +// Unit Tests + +//Test Gag Intensities +// let intensityTestMsg = "I AM LOUD. I am quiet." +// let intensityTestMsg2 = "Ha! I, in my brattiness, created test-4, a test. . . just to anger DOLL-0014 into domming me!!" + +// console.log(`Original: ${intensityTestMsg}\n`) +// console.log(`Intensity 1-2: ${garbleText(intensityTestMsg, 1)}`) +// console.log(`Intensity 3-4: ${garbleText(intensityTestMsg, 3)}`) +// console.log(`Intensity 5-6: ${garbleText(intensityTestMsg, 5)}`) +// console.log(`Intensity 7-8: ${garbleText(intensityTestMsg, 7)}`) +// console.log(`Intensity 9-10: ${garbleText(intensityTestMsg, 9)}`) + +// console.log(`\nOriginal: ${intensityTestMsg2}\n`) +// console.log(`Intensity 1-2: ${garbleText(intensityTestMsg2, 2)}`) +// console.log(`Intensity 3-4: ${garbleText(intensityTestMsg2, 4)}`) +// console.log(`Intensity 5-6: ${garbleText(intensityTestMsg2, 6)}`) +// console.log(`Intensity 7-8: ${garbleText(intensityTestMsg2, 8)}`) +// console.log(`Intensity 9-10: ${garbleText(intensityTestMsg2, 10)}`)