Apps Home
|
Create an App
goal X
Author:
loulouw
Description
Source Code
Launch App
Current Users
Created by:
Loulouw
cb.settings_choices = [ {name: 'admins', label: 'Users who can use app commands', type: 'str', required: false, defaultValue: cb.room_slug + ', codeanon'}, {name: 'goals', label: 'Goals', type: 'str', required: false, defaultValue: '1200: shirt off, 2400: topless, 3600: naked'}, {name: 'ignore', label: 'Ignore these tip amounts when calculating goals', type: 'str', required: false}, {name: 'subj', label: 'Room hashtags', type: 'str', required: false, defaultValue: ''}, {name: 'interval', label: 'Show goals to room every ___ seconds (0 = off)', type: 'int', minValue: 0, defaultValue: 180}, {name: 'color', label: 'Text color', type: 'str', required: false, defaultValue: '#DC0000'} ]; var cbs = JSON.parse(JSON.stringify(cb.settings)); var capFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1); 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 admins = cbs.admins ? cbs.admins.split(/\s*,\s*/) : [cb.room_slug] var goals = []; var mvp = {user: '---', amount: 0}; var tipCount = 0; var tipLedger = {}; var ignore = cbs.ignore ? cbs.ignore.split(/\s*,\s*/).map((elm) => Number(elm)) : []; if (cbs.goals) { cbs.goals.split(/\s*,\s*/).forEach(function (item) { var goal = item.split(/\s*:\s*/); var num = Number(goal[0]); var val = goal[1] ? goal[1].trim() : ''; if (val && num) goals.push({num: num, val: val}); }); goals.sort((a,b) => a.num - b.num); } cb.onTip((tip) => doTip(tip)); cb.onMessage((msg) => doMessage(msg)); cb.onDrawPanel(function () { return { 'template': '3_rows_12_21_31', 'row1_label': '[TIP GOAL X] -->', 'row1_value': tipCount + ' tks received', 'row2_value': goalText(), 'row3_value': 'MVP :: ' + mvp.user + ' (' + mvp.amount + ')' }; }); function doTip (tip) { if (!ignore.includes(tip.amount)) { tipCount += tip.amount; addTip(tip.amount, tip.from_user); updateSubject(calcGoal()); cb.drawPanel(); } } function addTip(amount, user) { tipLedger[user] = tipLedger[user] || 0; tipLedger[user] += amount; if (mvp.user === user) { mvp.amount += amount; } else if (tipLedger[user] > mvp.amount && user !== 'The Force') { mvp = {user: user, amount: tipLedger[user]}; } } function doMessage (msg) { if (doCommand(msg)) return msg; } function remaining () { if (goals[0]) return goals[0].num - tipCount; return ''; } function doCommand (msg) { msg.m = msg.m.trim(); if (msg.m.charAt(0) !== '/') return false; msg['X-Spam'] = true; if (!admins.includes(msg.user) && msg.user !== cb.room_slug) return false; var data = msg.m.slice(1).split(/\s+/); var cmd = data[0].toLowerCase(); var params = data.slice(1); switch(cmd) { case 'count': var n = Number(params[0]); if (!n) break; tipCount = n; break; case 'addgoal': if (params.length < 2) break; var num = Number(params[0]); var val = params.slice(1).join(' ').trim(); if (num && val.length) { var ind = goals.findIndex((elm) => elm.num === num); if (ind > -1) { goals[ind].val = val; } else if (num > tipCount) { goals.push({num: num, val: val}); goals.sort((a,b) => a.num - b.num); } say('Goals modified.', msg.user); updateSubject(); } break; case 'remgoal': var num = Number(params[0]); if (!num) break; var ind = goals.findIndex((elm) => elm.num === num); if (ind > -1) { goals.splice(ind, 1); say('Goals modified.', msg.user); updateSubject(); } break; case 'subj': if (!params.length) break; updateSubject(true, params.join(' ')); break; case 'force': var n = Number(params[0]); if (!n) break; doTip({from_user: 'The Force', amount: n}); break; case '#': evaluate(params.join(' '), msg.user); break; case 'h': case 'help': var sep = '\n\u2007\u2007'; say(['\u25CF ----- [COMMANDS] ----- \u25CF', '/h or /help ' + sep + ' Show the help menu.', '/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.', '/subj [H (text)] ' + sep + ' Changes the room hashtags to H.', '/count [X (number)] ' + sep + ' Sets the number of tokens received to X.', '/# [JavaScript] ' + sep + ' Execute JavaScript. Only use in emergencies.', ].join('\n'), user); break; } cb.drawPanel(); } 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 calcGoal () { if (!goals[0]) return false; while (goals[0] && tipCount >= goals[0].num) { say (':starx\nGOAL REACHED: ' + goals[0].val + '\n:starx'); goals.shift(); } return true; } function goalText () { if (goals[0]) return goals[0].val + ' in ' + remaining() + ' tks'; return 'All goals reached!' } function updateSubject(force, text) { cbs.subj = text || cbs.subj || ''; if (goals[0] || force) cb.changeRoomSubject('[' + goalText() + '] ' + cbs.subj); } 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); } /////////// updateSubject(); rotateGoals();
© Copyright Chaturbate 2011- 2025. All Rights Reserved.