Apps Home
|
Create an App
TokenMakeitHappen
Author:
wonderalice69
Description
Source Code
Launch App
Current Users
Created by:
Wonderalice69
/* Name: Multi-Goal Author: mx2k6 Version History ============================================ v1.0 08/02/2013: First release v1.1 22/02/2013: Added /stats and /reset commands. See Description for more v1.2 08/03/2013: Added /skip (thanks to jcummings for that) v1.3 12/03/2013: Added /goals command for moderators and /upnext command for broadcasters. See Description for more v1.4 13/03/2013: Minor cleanup to make code more readable. Modified /upnext to actually use the broadcaster's message instead of chat notice v1.5 07/04/2013: Added some debugging code so I can get to the bottom of why chat commands don't always respond v1.6 13/04/2013: Fixed an embarrassing bug where all broadcaster and debug commands were ignored v1.7 20/04/2013: Tipper leaderboard now available on /stats output - see who your top 10 tippers are v1.8 21/04/2013: Goal timer function now available - /timer x now sets a countdown to when the goal needs tp be in by Credits and Props ============================================ Based on the bog standard tip goal app, with multiple goals, tip goal king, and generally less suckiness. */ // vars var total_tipped = 0; var current_total_tipped = 0; var high_tip_username = null; var high_tip_amount = 0; var low_tip_username = null; var low_tip_amount = 0; var last_tip_username = null; var last_tip_amount = 0; var all_tippers = []; var subject_is_final = false; var current_goal = 1; var final_goal_met = false; cb.settings_choices = [ {name: 'goal_1_tokens', label: 'Goal 1 Token Amount', type: 'int', minValue: 1, defaultValue: 200}, {name: 'goal_1_description', label: 'Goal 1 Description', type: 'str', minLength: 1, maxLength: 255}, {name: 'goal_2_tokens', label: 'Goal 2 Token Amount', type: 'int', minValue: 1, defaultValue: 200, required: false}, {name: 'goal_2_description', label: 'Goal 2 Description', type: 'str', minLength: 0, maxLength: 255, required: false}, {name: 'goal_3_tokens', label: 'Goal 3 Token Amount', type: 'int', minValue: 1, defaultValue: 200, required: false}, {name: 'goal_3_description', label: 'Goal 3 Description', type: 'str', minLength: 0, maxLength: 255, required: false}, {name: 'goal_4_tokens', label: 'Goal 4 Token Amount', type: 'int', minValue: 1, defaultValue: 200, required: false}, {name: 'goal_4_description', label: 'Goal 4 Description', type: 'str', minLength: 0, maxLength: 255, required: false}, {name: 'goal_5_tokens', label: 'Goal 5 Token Amount', type: 'int', minValue: 1, defaultValue: 200, required: false}, {name: 'goal_5_description', label: 'Goal 5 Description', type: 'str', minLength: 0, maxLength: 255, required: false}, {name: 'finality_message', label: 'Final Goal Met Subject', type: 'str', minLength: 1, maxLength: 255, defaultValue: 'Goal reached! Thanks to all tippers!'}, {name: 'highlight_goal_king', label: 'Highlight highest tipper', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'show_timer_in_subject', label: 'Add time remaining to subject if running?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'mod_allow_broadcaster_cmd', label: 'Allow mods to use broadcaster commands?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'} ]; var goalTimer = { secondsDown: 60, timeRemaining: 0, timerRunning: false, spamMessage: "Time's running out! Only %time minutes left to tip to the goal!", timesUpMessage: "Time's Up! Sorry, the goal didn't happen in time.", hookOnTimer: function() { }, startTimer: function(minutes) { this.timeRemaining = minutes; this.timerRunning = true; this.hookOnTimer(); this.announce(); cb.setTimeout(function() { goalTimer.onTimer(); }, 60000); }, stopTimer: function() { this.timerRunning = false; }, onTimer: function() { if (this.timerRunning) { cb.log("goalTimer.onTimer reached!"); this.timeRemaining--; this.hookOnTimer(); this.announce(); if (this.timeRemaining === 0) { this.timerRunning = false; } else { cb.setTimeout(function() { goalTimer.onTimer(); }, 60000); } } }, getExtraText: function() { if (this.timerRunning) { return this.timeRemaining + " min left"; } else { return ""; } }, announce: function() { if (this.timeRemaining > 0 && cb.settings.show_timer_in_subject !== "Yes" ) { cb.chatNotice(this.spamMessage.replace("%time", this.timeRemaining)); } else if ( this.timeRemaining === 0 ) { cb.chatNotice(this.timesUpMessage); } } }; function getCurrentGoalDescription() { return cb.settings['goal_' + current_goal + '_description']; } function getCurrentGoalAmount() { return cb.settings['goal_' + current_goal + '_tokens']; } function getSumTotalGoal() { var total_goal = 0; var i = 1; for (i = 1; i <= 5; i++) { if (cb.settings['goal_' + i + '_description'] !== "" && cb.settings['goal_' + i + '_tokens'] !== 0 ) { total_goal += cb.settings['goal_' + i + '_tokens']; } } return total_goal; } function getAllGoals() { var all_goals = ""; for (i = 1; i <= 5; i++) { if (cb.settings['goal_' + i + '_description'] !== "" && cb.settings['goal_' + i + '_tokens'] !== 0 ) { all_goals += cb.settings['goal_' + i + '_description'] + ' (' + cb.settings['goal_' + i + '_tokens'] + ' tokens)\n'; } } all_goals += "- All Goals: " + getSumTotalGoal(); return all_goals; } function getLeaderBoard() { var leaderboard = ""; for (var idx = 0; idx < all_tippers.length && idx < 10; idx++) { if (all_tippers[idx] !== undefined) { leaderboard += all_tippers[idx].name + ' (' + all_tippers[idx].tokens + ')\n'; } } return leaderboard; } function skipGoal() { current_goal++; checkFinality(); update_goals(); } function getNextGoalAnnouncement() { return tips_remaining() + " tokens to next goal: " + cb.settings['goal_' + ( current_goal + 1 ) + '_description']; } function checkFinality() { if (getCurrentGoalAmount() <= 0 || getCurrentGoalDescription() === "" || current_goal === 6) { final_goal_met = true; } } function tips_remaining() { var r = getCurrentGoalAmount() - current_total_tipped; return (r < 0) ? 0 : r; } function format_username(val) { return (val === null) ? "--" : val.substring(0, 12); } function update_goals() { var new_subject = ""; if (subject_is_final) { return; } if (final_goal_met) { cb.log("Final goal met - notifying broadcaster and setting finality"); cb.chatNotice("Your final goal has been met! You can type '/reset' to start again from zero.", cb.room_slug); new_subject = cb.settings.finality_message; subject_is_final = true; } else { new_subject = getCurrentGoalDescription() + " [" + tips_remaining() + " tokens remaining]"; if (cb.settings.show_timer_in_subject === "Yes" && goalTimer.timerRunning) { new_subject += " (" + goalTimer.getExtraText() + ")"; } } cb.log("Changing subject to: " + new_subject); cb.changeRoomSubject(new_subject); } function recordTip(username, tokens) { var tipper_found = false; for (var idx = 0; idx < all_tippers.length; idx++) { if (all_tippers[idx].name == username) { tipper_found = true; all_tippers[idx].tokens += tokens; break; } } if (!tipper_found) { all_tippers.push({ name: username, tokens: tokens }); } all_tippers.sort(function (a, b) { return b.tokens - a.tokens; }); } function goalTimerOnTimer() { cb.drawPanel(); if (cb.settings.show_timer_in_subject === "Yes") { update_goals(); } } function reset() { cb.log("Resetting all goals"); low_tip_amount = 0; high_tip_amount = 0; last_tip_amount = 0; low_tip_username = null; high_tip_username = null; last_tip_username = null; current_goal = 1; current_total_tipped = 0; final_goal_met = false; all_tippers = []; cb.drawPanel(); update_goals(); } cb.onTip(function (tip) { total_tipped += tip.amount; current_total_tipped += tip.amount; while (current_total_tipped >= getCurrentGoalAmount()) { cb.log("Total tipped has exceeded current goal - incrementing step"); current_total_tipped = current_total_tipped - getCurrentGoalAmount(); cb.chatNotice("* Goal met: " + getCurrentGoalDescription(), cb.room_slug); current_goal++; checkFinality(); } update_goals(); last_tip_amount = tip.amount; last_tip_username = tip.from_user; if (tip.amount > high_tip_amount) { high_tip_amount = tip.amount; high_tip_username = tip.from_user; } if (tip.amount <= low_tip_amount || low_tip_amount == 0) { low_tip_amount = tip.amount; low_tip_username = tip.from_user; } recordTip(tip.from_user, tip.amount); cb.drawPanel(); }); cb.onDrawPanel(function (user) { var panel = {}; if (final_goal_met) { panel = { 'template': '3_rows_of_labels', 'row1_label': 'Total Tips:', 'row1_value': total_tipped, 'row2_label': 'Highest Tip:', 'row2_value': format_username(high_tip_username) + ' (' + high_tip_amount + ')', 'row3_label': 'Latest Tip Received:', 'row3_value': format_username(last_tip_username) + ' (' + last_tip_amount + ')' }; } else { panel = { 'template': '3_rows_of_labels', 'row1_label': 'Tip Received / Goal (Total):', 'row1_value': current_total_tipped + ' / ' + getCurrentGoalAmount() + ' (' + total_tipped + ')', 'row2_label': 'Highest Tip:', 'row2_value': format_username(high_tip_username) + ' (' + high_tip_amount + ')', 'row3_label': 'Latest Tip Received:', 'row3_value': format_username(last_tip_username) + ' (' + last_tip_amount + ')' }; if (goalTimer.timerRunning) { panel.row3_label = 'Time Remaining:'; panel.row3_value = goalTimer.getExtraText(); } } return panel; }); cb.onMessage(function (msg) { var i = 0; var key = null; /* Tip king highlighting */ if (cb.settings.highlight_goal_king === "Yes" && msg.user === high_tip_username) { msg.background = '#9F9'; } /* If it starts with a /, suppress that shit and assume it's a command */ if (msg.m.substring(0,1) === "/") { msg["X-Spam"] = true; if (msg.user === cb.room_slug || msg.is_mod) { /* Broadcaster or mod commands */ if (msg.m.substring(1) === "stats") { cb.log("Stats command received from " + msg.user); cb.chatNotice("=== Total Stats ===", msg.user); cb.chatNotice("Sum Total Goal: " + getSumTotalGoal(), msg.user); cb.chatNotice("Total Tipped so far: " + total_tipped, msg.user); cb.chatNotice("Total goal remaining: " + (getSumTotalGoal() - total_tipped), msg.user); cb.chatNotice("=== Tip Stats ===", msg.user); cb.chatNotice("Awesomest tip: " + high_tip_amount + " from " + high_tip_username, msg.user); cb.chatNotice("Stingiest tip: " + low_tip_amount + " from " + low_tip_username, msg.user); cb.chatNotice("Most recent tip: " + last_tip_amount + " from " + last_tip_username, msg.user); cb.chatNotice("=== Leaderboard (Top 10) ===", msg.user); cb.chatNotice(getLeaderBoard(), msg.user); } else if (msg.m.substring(1) === "goals") { cb.log("Goals command received from " + msg.user); cb.chatNotice("=== All Goals ===", msg.user); cb.chatNotice(getAllGoals(), msg.user); } else if (msg.m.substring(1) === "help") { cb.log("Help command received from " + msg.user); cb.chatNotice("=== Help ===", msg.user); cb.chatNotice("/stats - displays token statistics, including the sum total goal, amount so far, and misc information", msg.user); cb.chatNotice("/goals - displays all goals in in order", msg.user); cb.chatNotice("/upnext - announces the next goal to the room (broadcaster only)", msg.user); cb.chatNotice("/skip - skips the current goal, and moves onto the next one (broadcaster only)", msg.user); cb.chatNotice("/reset - resets goal status back to zero (broadcaster only)", msg.user); cb.chatNotice("/timer x - sets goal timer to x minutes (broadcaster only)", msg.user); cb.chatNotice("/timer stop - stops the running goal timer (broadcaster only)", msg.user); } } if (msg.user === cb.room_slug || (cb.settings.mod_allow_broadcaster_cmd === "Yes" && msg.is_mod)) { /* Broadcaster only commands, unless the option to allow mods to use them is enabled */ if (msg.m.substring(1) === "reset") { cb.log("Reset command received from " + msg.user); reset(); } else if (msg.m.substring(1) === "skip") { cb.log("Skip command received from " + msg.user); skipGoal(); } else if (msg.m.substring(1) === "upnext") { cb.log("Upnext command received from " + msg.user); cb.chatNotice("* I ate your message. Sorry about that. But I did let the viewers know about the next goal!", msg.user); msg.m = getNextGoalAnnouncement(); msg["X-Spam"] = false; } } if (msg.user === cb.room_slug) { /* Broadcaster only commands at all times */ if (msg.m.substring(1,6) === "timer") { cb.log("Timer command received from " + msg.user); if (msg.m.length >= 8) { var params = msg.m.substring(7); if (params === "stop") { goalTimer.stopTimer(); } else { var timer = parseInt(params, 10); if (timer > 0 && timer <= 60) { goalTimer.startTimer(timer); cb.chatNotice("Goal timer set to " + timer + " minutes. Type '/timer stop' if you want to stop it early", msg.user); } else { cb.chatNotice("You need to enter the number of minutes, in the form /timer <x> where <x> is a number from 1 to 60", msg.user); } } } else { cb.chatNotice("You need to enter the number of minutes, in the form /timer <x> where <x> is a number from 1 to 60", msg.user); } } } if (msg.user === "mx2k6") { /* Developer commands. Debugging use only! */ if (msg.m.substring(1) === "dumpsettings") { cb.chatNotice(cb.settings, msg.user); } } } /* Code to allow the developer to seem more important if necessary (e.g. for tech support) */ if (msg.user === "mx2k6" && msg.m.substring(0,1) === "#") { msg.m = msg.m.substring(1); msg.background = "#b1b3bc"; } return msg; }); function init() { goalTimer.hookOnTimer = function() { goalTimerOnTimer(); }; cb.chatNotice("Tip Multi-Goal started. Broadcasters and mods can type '/stats' for token stats, and '/help' for more commands."); update_goals(); } init();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.