Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 132 additions & 17 deletions gags/ring.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,142 @@
const garbleText = (text, parent, intensity) => {
let newtextparts = text.split(" ");
let outtext = "";
for (let i = 0; i < newtextparts.length; i++) {
for (let t = 0; t < newtextparts[i].length; t++) {
if (newtextparts[i].charAt(t).match(/[a-z]/i)) {
if (t == 0) {
outtext = `${outtext}g`;
/***************************
* Ring gag - Ring gag update
* ~ Kali
* Standing on the shoulders of giants...
* Inspired by:
* Ball Gag setup by DollLia
***************************/

// Character map stored in a separate file for code cleanliness/reusability
const { ringGagCharMap } = require("./ring/ringCharMap.js");
// Ring gag interrupt messages list stored in separate file
const { ringGagInterruptList } = require("./ring/ringInterruptMessages.js");
// Pronouns conversion function import for gag interrupts
const { convertPronounsText } = require("../functions/other/convertPronounsText");

const isAllCaps = (text) => {
return text == text.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;
};

const garbleText = (text, parent, intensity, msg) => {
let output = "";
//splits by regex of any whitespace char so we have word arra
let words = text.split(/\s/);

/* custom Ring gag addition - vars to define interrupt behaviour */
let wordsNeededForInterruptReset = 20;
let minInterruptWords = 8;
let wordGracePeriodAfterFirst = 5;

let gagInterruptUsed = false;
let doGagInterrupt = false;
let interruptPosition = 0;

let interruptIntensityRNGWeightPercent = 3;
let interruptWordRNGWeightPercent = 1;
let baselineChanceToInterrupt = intensity * interruptIntensityRNGWeightPercent;
// initial check to enable gag interrupt for sentences with enough words in them
if (words.length >= minInterruptWords) {
doGagInterrupt = true;

/*
Feel like I should explain this one - basically takes a portion of intensity or raw intensity value
and uses that to randomly determine message interrupt location from the end of the message
with the intent being that higher intensity means higher chance to encounter the interrupt sooner in the message
*/
let wordsInFirstPart = words.length % wordsNeededForInterruptReset;
if (words.length >= wordsNeededForInterruptReset){
wordsInFirstPart = wordsNeededForInterruptReset;
}
interruptPosition = wordsInFirstPart - Math.min(Math.floor(Math.random() * intensity) + 1, wordsInFirstPart - 1);
}

//console.log("interruptMinPosition: " + interruptPosition); // informative logging for dev purposes
for (let x = 0; x < words.length; x++) {
/* Gag interrupt message handling */
// does the reset every predetermined amount of words so interrupt messages can show up more than once in long sentences
if (gagInterruptUsed && x % wordsNeededForInterruptReset == 0) {
gagInterruptUsed = false;
interruptPosition = x + wordGracePeriodAfterFirst;
}

// check if can do interrupt, interrupt has not been used within this word interval and current word is past initial position for interrupt
//console.log("interruptPosition: " + interruptPosition + " gagInterruptUsed: " + gagInterruptUsed + " x: " + x); // informative logging for dev purposes
if (doGagInterrupt && !gagInterruptUsed && x >= interruptPosition) {
// do rng based on intensity to proc the message
let chanceToInterrupt = baselineChanceToInterrupt + (x % wordsNeededForInterruptReset) * interruptWordRNGWeightPercent;
let roll = Math.floor(Math.random() * 100) + 1;
//console.log("roll: " + roll + " chanceToInterrupt: " + chanceToInterrupt); // informative logging for dev purposes
if(roll <= chanceToInterrupt) {
gagInterruptUsed = true;

//randomly choose interruption message
let msgIndex = Math.floor(Math.random() * ringGagInterruptList.length);
// convert and add the message to interrupt
output = `${output.slice(0, -1)}-` // Replace the last space with a - to indicate an interrupt!
output += convertPronounsText(ringGagInterruptList[msgIndex], { interactionuser: msg.member });
output += " ";
}

}

/* gag garble code - quick adaptation from DollLia's ball gag one */
let allCaps = isAllCaps(words[x]);
// Special case for "I", "a", etc.
if (allCaps && totalAlphas(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.
let newChar = ringGagCharMap.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 {
outtext = `${outtext}h`;
nextChar = isUppercase ? newChar[0].toUpperCase() + (newChar[1] ? newChar[1] : "") : newChar;
}
} else if (newtextparts[i].charAt(t).match(/[A-Z]/i)) {
if (t == 0) {
outtext = `${outtext}G`;
} else {
outtext = `${outtext}H`;

if (allCaps) {
nextChar = nextChar.toUpperCase();
}
output += nextChar;
} else {
outtext = `${outtext}${newtextparts[i].charAt(t)}`;
// Append an unmodified character.
output += char;
}
prevChar = char; // Store previous char
itr++; // THEN iterate
}

if (x < words.length - 1) {
output += " ";
}
outtext = `${outtext} `;
}
return outtext;

return output;
};

exports.garbleText = garbleText;
Expand Down
37 changes: 37 additions & 0 deletions gags/ring/ringCharMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/************************************************
* Character Map for Ring Gag
*
* ~Kali :3
************************************************/

const ringCharMap = new Map([
['a',"a"],
['b',"b"],
['c',"e"],
['d',"m"],
['e',"e"],
['f',"h"],
['g',"m"],
['h',"h"],
['i',"i"],
['j',"a"],
['k',"k"],
['l',"a"],
['m',"m"],
['n',"n"],
['o',"o"],
['p',"p"],
['q',"kh"],
['r',"a"],
['s',"z"],
['t',"e"],
['u',"u"],
['v',"v"],
['w',"w"],
['x',"kh"],
['y',"y"],
['z',"s"],
]);

// Exporting the map for use in other functions.
exports.ringGagCharMap = ringCharMap
11 changes: 11 additions & 0 deletions gags/ring/ringInterruptMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const ringGagInterruptList = [
`\n*Pauses for a moment, trying to control the tidal wave of drool!*\n`,
`\n*Shifts USER_THEIR head around a bit to try to stop the messy stream of saliva flowing out of USER_THEIR mouth!*\n`,
`\n*Tries desperately to suck in the escaping drool, to no avail...*\n`,
`\n*Groans as USER_THEIR chin is glistening with USER_THEIR drool!*\n`,
`\n*A stream of drool flows over USER_THEIR chin, dripping from it...*\n`,
"\n*Quickly stops talking and tries to swallow all the saliva that has accumulated!*\n",
"\n*Bit of drool drips down the corner of USER_THEIR mouth, disrupting USER_THEIR train of thought a moment...*\n",
];

exports.ringGagInterruptList = ringGagInterruptList;
Loading