Bots Home
|
Create an App
Cam Quest3
Author:
ohmygodasdf
Description
Source Code
Launch Bot
Current Users
Created by:
Ohmygodasdf
/* CamQuest v0.3 - Full fresh copy/paste version Interactive Chaturbate App: tip menu + quest progress + colorful notices + voting. No image uploads required. */ cb.settings_choices = [ { name: 'theme', type: 'choice', choice1: 'Fantasy Dungeon', choice2: 'Space Mission', choice3: 'Haunted Hotel', defaultValue: 'Fantasy Dungeon', label: 'Quest Theme' }, { name: 'goal_tokens', type: 'int', minValue: 25, maxValue: 9999, defaultValue: 250, label: 'Tokens Needed To Finish Each Chapter' }, { name: 'announce_minutes', type: 'int', minValue: 1, maxValue: 30, defaultValue: 5, label: 'Repeat Tip Menu Every X Minutes' } ]; var totalTips = 0; var stageTips = 0; var currentStage = 0; var lastTipper = 'None yet'; var lastEvent = 'The quest is waiting to begin.'; var topHero = 'None yet'; var topHeroAmount = 0; var voteOpen = false; var voteOne = 0; var voteTwo = 0; var voters = {}; function safeNumber(value, fallback) { var n = parseInt(value, 10); if (isNaN(n)) { return fallback; } return n; } function getGoal() { return safeNumber(cb.settings.goal_tokens, 250); } function getAnnounceMinutes() { return safeNumber(cb.settings.announce_minutes, 5); } function getStyle() { if (cb.settings.theme === 'Space Mission') { return { icon: 'π', title: 'SPACE MISSION', bg: '#071A33', bg2: '#102A54', specialBg: '#27155C', winBg: '#083B3B', dangerBg: '#3A0E1F', text: '#EAF6FF', accent: '#7DF9FF', sparkle: 'β¦' }; } if (cb.settings.theme === 'Haunted Hotel') { return { icon: 'π―οΈ', title: 'HAUNTED HOTEL', bg: '#19051F', bg2: '#2B0B35', specialBg: '#3D143F', winBg: '#26320A', dangerBg: '#3A0713', text: '#FFF3D6', accent: '#FFB000', sparkle: 'β§' }; } return { icon: 'π', title: 'FANTASY DUNGEON', bg: '#160B2E', bg2: '#26104D', specialBg: '#40206B', winBg: '#143B20', dangerBg: '#4A1111', text: '#FFF7E8', accent: '#FFD166', sparkle: 'β¦' }; } function getStages() { if (cb.settings.theme === 'Space Mission') { return [ { name: 'Launch Pad', goal: 'Fuel the rocket', win: 'The rocket launches into the stars!', vote1: 'Visit the Moon Base', vote2: 'Enter the Asteroid Cave' }, { name: 'Moon Base', goal: 'Repair the airlock', win: 'The Moon Base doors slide open.', vote1: 'Search the lab', vote2: 'Follow the strange signal' }, { name: 'Alien Ruins', goal: 'Activate the crystal gate', win: 'The ancient crystal gate glows to life.', vote1: 'Step through the gate', vote2: 'Scan the ruins first' } ]; } if (cb.settings.theme === 'Haunted Hotel') { return [ { name: 'Hotel Lobby', goal: 'Unlock the elevator', win: 'The elevator unlocks with a spooky ding.', vote1: 'Go to the Penthouse', vote2: 'Go to the Basement' }, { name: 'Basement Hall', goal: 'Light the old lantern', win: 'The lantern flickers on and reveals old footprints.', vote1: 'Open the red door', vote2: 'Follow the whisper' }, { name: 'Penthouse Suite', goal: 'Find the silver key', win: 'The silver key appears under the rug.', vote1: 'Escape the hotel', vote2: 'Enter the mirror room' } ]; } return [ { name: 'Village Gate', goal: 'Open the old gate', win: 'The old gate creaks open.', vote1: 'Enter the forest', vote2: 'Enter the cave' }, { name: 'Crystal Cave', goal: 'Wake the crystal', win: 'The crystal begins to glow.', vote1: 'Touch the crystal', vote2: 'Search deeper' }, { name: 'Dragon Chamber', goal: 'Defeat the tiny dragon', win: 'The tiny dragon has been defeated.', vote1: 'Claim the treasure', vote2: 'Befriend the dragon' } ]; } function getStage() { var stages = getStages(); return stages[currentStage % stages.length]; } function makeBar(current, goal) { var totalBlocks = 12; var filled = Math.floor((current / goal) * totalBlocks); var bar = ''; var i; if (filled < 0) { filled = 0; } if (filled > totalBlocks) { filled = totalBlocks; } for (i = 0; i < filled; i += 1) { bar += 'β'; } for (i = filled; i < totalBlocks; i += 1) { bar += 'β'; } return bar; } function sendQuestNotice(title, body, kind, toUser) { var s = getStyle(); var bg = s.bg; if (kind === 'status') { bg = s.bg2; } else if (kind === 'special') { bg = s.specialBg; } else if (kind === 'win') { bg = s.winBg; } else if (kind === 'danger') { bg = s.dangerBg; } cb.sendNotice( s.sparkle + ' ' + s.icon + ' ' + title + ' ' + s.icon + ' ' + s.sparkle + '\n' + body, toUser || '', bg, s.text, 'bold' ); } function tipMenuText() { return 'π² TIP THIS MUCH TO DO SOMETHING\n\n' + '11 tokens β Explore the area\n' + '25 tokens β Find a quest item\n' + '50 tokens β Unlock a clue\n' + '100 tokens β Trigger mystery event\n' + '250 tokens β Big hero move\n\n' + 'Every tip also fills the chapter goal.'; } function progressText() { var s = getStyle(); var stage = getStage(); var goal = getGoal(); return 'π Theme: ' + s.title + '\n' + 'π Chapter: ' + stage.name + '\n' + 'π― Goal: ' + stage.goal + '\n' + 'β‘ Progress: ' + makeBar(stageTips, goal) + ' ' + stageTips + '/' + goal + '\n' + 'π Top Hero: ' + topHero + ' +' + topHeroAmount + '\n' + 'π¬ Type /quest to see this again.'; } function announceFullMenu(toUser) { sendQuestNotice( 'CAMQUEST MENU', tipMenuText() + '\n\n' + progressText(), 'special', toUser || '' ); } function getTipAction(amount, message) { var lowerMessage = (message || '').toLowerCase(); if (amount >= 250 || lowerMessage.indexOf('big hero') !== -1) { return 'BIG HERO MOVE'; } if (amount >= 100 || lowerMessage.indexOf('mystery') !== -1) { return 'MYSTERY EVENT'; } if (amount >= 50 || lowerMessage.indexOf('clue') !== -1) { return 'CLUE UNLOCKED'; } if (amount >= 25 || lowerMessage.indexOf('item') !== -1) { return 'QUEST ITEM FOUND'; } if (amount >= 11 || lowerMessage.indexOf('explore') !== -1) { return 'EXPLORING'; } return 'QUEST POWER ADDED'; } function actionFlavor(action, username) { var stage = getStage(); if (action === 'EXPLORING') { return 'π§ ' + username + ' explores ' + stage.name + '. Something interesting is nearby...'; } if (action === 'QUEST ITEM FOUND') { return 'π ' + username + ' found a useful quest item.'; } if (action === 'CLUE UNLOCKED') { return 'π ' + username + ' unlocked a clue. The path ahead is becoming clearer.'; } if (action === 'BIG HERO MOVE') { return 'βοΈ ' + username + ' made a big hero move. The whole room surges forward.'; } return 'π° ' + username + ' added quest power.'; } function randomMiniEvent(username) { var events = [ 'found a hidden key π', 'triggered a mystery sparkle β¨', 'opened a secret drawer ποΈ', 'summoned a tiny helper π§', 'activated bonus quest energy β‘', 'found a strange glowing map πΊοΈ', 'woke up something ancient ποΈ', 'found a secret shortcut π' ]; var pick = events[Math.floor(Math.random() * events.length)]; lastEvent = username + ' ' + pick + '!'; sendQuestNotice( 'MYSTERY EVENT', 'π² ' + username + ' ' + pick + '!\n\n' + 'The adventure just got weirder.', 'special', '' ); } function updateHero(username, amount) { if (amount > topHeroAmount) { topHero = username; topHeroAmount = amount; sendQuestNotice( 'NEW TOP HERO', 'π ' + username + ' is now the Top Hero with a ' + amount + ' token move!', 'win', '' ); } } function startVote() { var stage = getStage(); voteOpen = true; voteOne = 0; voteTwo = 0; voters = {}; sendQuestNotice( 'THE ROOM MUST CHOOSE', 'π³οΈ Vote for the next path!\n\n' + 'Type /vote 1 β ' + stage.vote1 + '\n' + 'Type /vote 2 β ' + stage.vote2 + '\n\n' + 'Voting closes in 60 seconds.', 'special', '' ); cb.setTimeout(closeVote, 60000); } function closeVote() { var stage; var winner; if (!voteOpen) { return; } voteOpen = false; stage = getStage(); if (voteOne > voteTwo) { winner = stage.vote1; } else if (voteTwo > voteOne) { winner = stage.vote2; } else { winner = 'Tie! The path is chosen by fate.'; } currentStage += 1; stageTips = 0; lastEvent = 'Vote result: ' + winner; sendQuestNotice( 'NEW CHAPTER UNLOCKED', 'β Vote Result: ' + winner + '\n\n' + progressText() + '\n\n' + tipMenuText(), 'win', '' ); cb.drawPanel(); } function unlockStage() { var stage = getStage(); lastEvent = stage.win; sendQuestNotice( 'QUEST COMPLETE', 'β¨ ' + stage.win + ' β¨\n\n' + 'The next path is opening...', 'win', '' ); startVote(); cb.drawPanel(); } cb.onStart(function(user) { announceFullMenu(''); function autoAnnounce() { announceFullMenu(''); cb.setTimeout(autoAnnounce, getAnnounceMinutes() * 60 * 1000); } cb.setTimeout(autoAnnounce, getAnnounceMinutes() * 60 * 1000); }); cb.onTip(function(tip) { var amount = safeNumber(tip.amount, 0); var username = tip.is_anon_tip ? 'Anonymous' : tip.from_user; var message = tip.message || ''; var goal = getGoal(); var action = getTipAction(amount, message); var flavor = actionFlavor(action, username); var kind = 'status'; totalTips += amount; stageTips += amount; lastTipper = username + ' +' + amount; lastEvent = flavor; updateHero(username, amount); if (action === 'MYSTERY EVENT') { randomMiniEvent(username); } else { if (action === 'CLUE UNLOCKED' || action === 'QUEST ITEM FOUND') { kind = 'special'; } if (action === 'BIG HERO MOVE') { kind = 'win'; } sendQuestNotice( action, flavor + '\n\n' + 'β‘ Chapter Progress:\n' + makeBar(stageTips, goal) + ' ' + stageTips + '/' + goal, kind, '' ); } if (stageTips >= goal && !voteOpen) { unlockStage(); } cb.drawPanel(); }); cb.onMessage(function(msg) { var text = (msg.m || '').toLowerCase(); if (text === '/quest') { announceFullMenu(msg.user); msg['X-Spam'] = true; return msg; } if (text === '/menu') { announceFullMenu(msg.user); msg['X-Spam'] = true; return msg; } if (text === '/event') { sendQuestNotice('LAST EVENT', lastEvent, 'status', msg.user); msg['X-Spam'] = true; return msg; } if (text === '/resetquest') { if (msg.user === cb.room_slug || msg.is_mod) { totalTips = 0; stageTips = 0; currentStage = 0; lastTipper = 'None yet'; lastEvent = 'The quest was reset.'; topHero = 'None yet'; topHeroAmount = 0; voteOpen = false; voteOne = 0; voteTwo = 0; voters = {}; sendQuestNotice( 'QUEST RESET', 'π CamQuest has been reset to chapter one.\n\n' + tipMenuText(), 'danger', '' ); cb.drawPanel(); } msg['X-Spam'] = true; return msg; } if (text === '/vote 1' || text === '/vote1') { if (voteOpen && !voters[msg.user]) { voteOne += 1; voters[msg.user] = true; sendQuestNotice( 'VOTE LOCKED', msg.user + ' voted for option 1.\n\n' + 'Option 1: ' + voteOne + ' | Option 2: ' + voteTwo, 'special', '' ); } else if (!voteOpen) { sendQuestNotice('NO VOTE OPEN', 'There is no quest vote open right now.', 'danger', msg.user); } msg['X-Spam'] = true; return msg; } if (text === '/vote 2' || text === '/vote2') { if (voteOpen && !voters[msg.user]) { voteTwo += 1; voters[msg.user] = true; sendQuestNotice( 'VOTE LOCKED', msg.user + ' voted for option 2.\n\n' + 'Option 1: ' + voteOne + ' | Option 2: ' + voteTwo, 'special', '' ); } else if (!voteOpen) { sendQuestNotice('NO VOTE OPEN', 'There is no quest vote open right now.', 'danger', msg.user); } msg['X-Spam'] = true; return msg; } return msg; }); cb.tipOptions(function(user) { return { label: 'Choose a CamQuest action:', options: [ { label: '11 tokens β Explore the area' }, { label: '25 tokens β Find a quest item' }, { label: '50 tokens β Unlock a clue' }, { label: '100 tokens β Trigger mystery event' }, { label: '250 tokens β Big hero move' } ] }; }); cb.onDrawPanel(function(user) { var s = getStyle(); var stage = getStage(); var goal = getGoal(); return { template: 'image_template', layers: [ { type: 'text', text: s.icon + ' CAMQUEST', top: 3, left: 8, width: 260, color: s.accent, 'font-size': 13, 'font-style': 'normal' }, { type: 'text', text: 'Chapter: ' + stage.name, top: 25, left: 8, width: 260, color: '#ffffff', 'font-size': 11 }, { type: 'text', text: makeBar(stageTips, goal) + ' ' + stageTips + '/' + goal, top: 47, left: 8, width: 260, color: s.accent, 'font-size': 11 } ] }; }); cb.drawPanel();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.