Apps Home
|
Create an App
mxsvndev
Author:
mxsvn
Description
Source Code
Launch App
Current Users
Created by:
Mxsvn
const appName = "mxcam"; const sym = "\u00BB "; const appVersion = "0.1.0"; const maxStatusIndex = 29; const panelInterval = 67; // Approximately 15 fps. const maxStatusMsThreshold = 1000; const maxStatusStep = 6; const secInterval = 1000; const energyInterval = 4000; const backgroundImage = "05b83220-1ccc-4871-9333-70f97488de00"; const threshEnergyLevels = Math.ceil(maxStatusMsThreshold / panelInterval); const totalEnergyLevels = maxStatusStep + threshEnergyLevels; const infoMsg = `${sym}${appName} (pronounced mike's cam) [version ${appVersion}]\n${sym} generates fake images from random noise for sexy, freaky fun. tip with a single-letter message to make a selection. keep energy max by tipping often.`; const rulesMsg = `save suggestions and bug reports for tip notes (log them please: see /menu). have a good time and be nice to everyone. type /rules or /info to see this message again.` const ALPHABET = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; const tippers = {}; const menuOptions = {}; var menuMsg = `${sym}~*~*~*~*~*~ MENU ~*~*~*~*~*~`; var sequenceNum = 1; var msSinceStatusUpdate = 0; var curStatusMsThreshold = maxStatusMsThreshold; var curStatusStep = 1; var curStatusIndex = 0; var curEnergyLevel = 0; var lastEnergyLevel = 0; var highestTip = 0; var highestTipper = ""; var lastHighestTipper = ""; cb.settings_choices = [ {name: "numChoices", type: "int", minValue: 1, maxValue: 26, defaultValue: 4, label: "Number of tip message options to choose from"}, {name: "menuSec", type: "int", minValue: 0, maxValue: 1000, defaultValue: 120, label: "Seconds between menu broadcasts"}, {name: "incRate", type: "int", minValue: 1, maxValue: 100, defaultValue: 10, label: "Percentage per tip to increase energy"}, {name: "decayRate", type: "int", minValue: 1, maxValue: 100, defaultValue: 1, label: "Percentage per second to decay energy"}, ]; const updatePanel = () => { cb.drawPanel(); cb.setTimeout(updatePanel, panelInterval); }; const updateEnergy = () => { incrementEnergyLevel(-1 * cb.settings.decayRate); if (curEnergyLevel !== lastEnergyLevel) { const energyNotify = { "level": curEnergyLevel, "numLevels": totalEnergyLevels, "kind": "energy", "seq": sequenceNum++, }; cb.sendNotice("NotifyOnEnergy: " + JSON.stringify(energyNotify), cb.room_slug); } lastEnergyLevel = curEnergyLevel; cb.setTimeout(updateEnergy, energyInterval); }; const incrementEnergyLevel = (percentage) => { var steps = (percentage / 100) * totalEnergyLevels; if (percentage < 0 && steps === 0) { steps = -1; } else if (percentage > 0 && steps === 0) { steps = 1; } curEnergyLevel = Math.floor(curEnergyLevel + steps); if (curEnergyLevel >= totalEnergyLevels) { curEnergyLevel = totalEnergyLevels - 1; } if (curEnergyLevel < 0) { curEnergyLevel = 0; } if (curEnergyLevel < threshEnergyLevels) { curStatusStep = 1; curStatusMsThreshold = maxStatusMsThreshold - (curEnergyLevel * panelInterval); } else { curStatusStep = curEnergyLevel - threshEnergyLevels + 1; curStatusMsThreshold = panelInterval; } }; const broadcastMenu = () => { if (cb.settings.menuSec > 0) { cb.sendNotice(menuMsg); cb.setTimeout(broadcastMenu, cb.settings.menuSec * 1000); } }; cb.onStart(user => { cb.sendNotice(sym + user["user"] + ` started ${appName} ${appVersion}!\n${sym}For information type /info.\n${sym}For menu type /menu.`); var maxMenuLetter = ALPHABET[cb.settings.numChoices-1]; menuMsg += `\n${sym}~*~ Tip with a single-letter message A-${maxMenuLetter} to make a choice! ~*~`; menuMsg += `\n${sym}4 tokens - show kitty` menuMsg += `\n${sym}8 tokens - zoom in for 2 seconds (tip note chooses letter)` menuMsg += `\n${sym}16 tokens - zoom in for 4 seconds (tip note chooses letter)` menuMsg += `\n${sym}32 tokens - log a suggestion or bug report from tip note` menuMsg += `\n${sym}128 tokens - get a download link (tip note chooses letter, link valid until end of stream)` updatePanel(); updateEnergy(); broadcastMenu(); }); cb.onEnter(user => { cb.sendNotice(`${sym}Welcome ${user["user"]}!\n${sym}${appName} ${appVersion} is running.\n${sym}For information type /info.\n${sym}For menu type /menu.`, user["user"]); cb.sendNotice(menuMsg, user["user"]); }); cb.onMessage(message => { if (message["m"] === "/menu") { cb.sendNotice(menuMsg, message["user"]); } else if (message["m"] === "/info") { cb.sendNotice(infoMsg, message["user"]); cb.sendNotice(rulesMsg, message["user"]); } else if (message["m"] === "/rules") { cb.sendNotice(rulesMsg, message["user"]); } }); cb.onTip(tip => { if (!tippers[tip["from_user"]]){ tippers[tip["from_user"]] = 0; } const amount = parseInt(tip["amount"]); tippers[tip["from_user"]] += amount; if (tippers[tip["from_user"]] > highestTip) { highestTip = tippers[tip["from_user"]]; highestTipper = tip["from_user"]; if (highestTipper !== lastHighestTipper) { const leaderNotify = { "leader": highestTipper, "amount": highestTip, "kind": "leader", "seq": sequenceNum++, }; cb.sendNotice("NotifyOnLeader: " + JSON.stringify(leaderNotify), cb.room_slug); } lastHighestTipper = highestTipper; } var message = tip["message"]; incrementEnergyLevel(cb.settings.incRate * amount); const tipNotify = { "user": tip["from_user"], "message": message, "amount": amount, "kind": "tip", "seq": sequenceNum++, }; cb.sendNotice("NotifyOnTip: " + JSON.stringify(tipNotify), cb.room_slug); }); cb.onDrawPanel(user => { // Update the status. var status = ""; for (var i=0; i < curStatusIndex; i++) { status += "-"; } for (var i=0; i < 3; i++) { status += "+"; } for (var i=curStatusIndex+3; i < maxStatusIndex; i++) { status += "-"; } if (status.length > maxStatusIndex) { const extra = status.length - maxStatusIndex; status = status.slice(maxStatusIndex) + status.slice(extra, maxStatusIndex) } msSinceStatusUpdate += panelInterval; if (msSinceStatusUpdate >= curStatusMsThreshold) { msSinceStatusUpdate = 0; curStatusIndex = (curStatusIndex + curStatusStep) % maxStatusIndex; } // Set the highest tipper text. const leader = `(${highestTip}) ${highestTipper}`; var max = ""; if (curEnergyLevel >= totalEnergyLevels - maxStatusStep) { max = "MAX!"; } return { "template": "image_template", "layers": [ { "type": "image", "fileID": backgroundImage }, { "type": "text", "text": "", "top": 5, "left": 20, "color": "#cccccc", }, { "type": "text", "text": "ENERGY", "top": 29, "left": 20, "color": "#cccccc", }, { "type": "text", "text": "", "top": 52, "left": 24, "color": "#cccccc", }, { "type": "text", "text": "", "top": 5, "left": 76, "color": "#81bf76", }, { "type": "text", "text": "[" + status + "] " + max, "top": 29, "left": 76, "color": "#81bf76", }, { "type": "text", "text": "", "top": 51, "left": 76, "color": "#81bf76", }, ], }; });
© Copyright Chaturbate 2011- 2024. All Rights Reserved.