Apps Home
|
Create an App
Jungle Keno v1
Author:
magnus76m
Description
Source Code
Launch App
Current Users
Created by:
Magnus76m
/* * Token Keno by magnus76m. * (C) 2020 magnus76m. */ var keno = { load: function() { cb.settings_choices = [ { name: "keno_min", type: "int", label: "Lowest number on board, 1 - 100", minValue: 1, maxValue: 100, defaultValue: 10 }, { name: "keno_max", type: "int", label: "Highest number on board, 10 - 199", minValue: 10, maxValue: 199, defaultValue: 99 }, { name: "keno_min_rand", type: "int", label: "Starting number for random prizes", minValue: 1, maxValue: 100, defaultValue: 1 }, { name: "keno_min_big", type: "int", label: "Starting number for big random prizes (start prize with ! to indicate big prize, see prizes below)", minValue: 1, maxValue: 100, defaultValue: 1 }, { name: "keno_avoid_num", type: "str", label: "Numbers to skip on board (use to avoid amounts in tip menu etc.)", defaultValue: "6,12,21,34,40,44,89", required: false }, { name: "keno_multiple", type: "choice", label: "Big tips call multiple numbers", choice1: "No", choice2: "Yes", defaultValue: "No" }, { name: "keno_grouptip", type: "choice", label: "Allow group tipping (small tips add up towards the highest number)", choice1: "No", choice2: "Yes", defaultValue: "No" }, { name: "keno_interval", type: "int", label: "Board display interval (0 = disable)", minValue: 0, maxValue: 60, defaultValue: 5 }, { name: "keno_prize1", type: "str", label: "Prize 1 (start with ! to indicate a big prize)", required: false } ]; for( var i = 2; i <= 100; i++ ) { cb.settings_choices.push( { name: "keno_prize" + i, type: "str", label: "Prize " + i, required: false } ); } return this; }, enabled: false, min: 0, max: 0, min_rand: 1, min_big: 1, call_multiples: false, group_tipping: false, group_pot: 0, board: {}, prizes: 0, won: [], timer: null, interval: 0, addPrize: function(prize, number) { if( (number in this.board) && (this.board[number] != null) ) { return false; } this.board[number] = prize; return true; }, numStr: function(num, digits) { var str = "\u2007\u2007" + num; return str.substr(-digits); }, remaining: function() { return Object.keys(this.board).length; }, showBoard: function(user = "") { if( !this.enabled ) return; var rows = []; var row = []; var digits = this.max >= 100 ? 3 : 2; for( var i = this.min; i <= this.max; i++ ) { if( i in this.board ) { row.push(this.numStr(i, digits)); } else { var l = i > 99 ? 3 : i > 9 ? 2 : 1; row.push('\u2007'.repeat(digits - l) + '\u2012'.repeat(l)) } if( (row.length >= 10) || (i == this.max) ) { while( row.length < 10 ) { row.push('\u2007'.repeat(digits)); } rows.push('\uD83C\uDF34\u2007' + row.join("\u2007") + '\u2007\uD83C\uDF34'); row = []; } } var sp = "\u2007".repeat(digits == 3 ? 11 : 6); msg = "\u2007\uD83D\uDC12" + sp + "Token Keno Board:" + sp + "\uD83D\uDC12\n" + rows.join("\n") + "\n"; msg += "/p - show prizes\u2007\u2007/w - show winners\n"; msg += "/b - show board"; if( this.group_tipping ) { msg += "\nGroup tipping is active" } cb.sendNotice(msg, user, "", "", "bold"); }, showWinners: function(user = "") { if( !this.enabled ) return; var msg = "Already won prizes:\n"; for( var w of this.won ) { msg += "\u25FE " + w.prize + " won by " + w.user + " behind #" + w.num + "\n"; } cb.sendNotice(msg.trim(), user); }, updateCount: function() { var count = 0; for( var p in this.board ) { if( this.board[p] != null ) { count++; } } this.prizes = count; }, showPrizes: function(user = "") { if( !this.enabled ) return; var list = []; for( var p in this.board ) { if( this.board[p] != null ) { list.push(this.board[p]); } } var msg = "Prizes still on board (in random order):\n"; while( list.length > 0 ) { var i = Math.floor(Math.random() * list.length); msg += "\u25FE " + list[i] + "\n"; list.splice(i, 1); } cb.sendNotice(msg.trim(), user); }, findHighest: function(upper) { var high = 0; for( var p in this.board ) { if( p <= upper ) { high = Math.max(high, p); } } return high; }, checkTip: function(amount, user) { if( amount in this.board ) { var prize = this.board[amount]; delete this.board[amount]; var msg = user + " called " + amount + ":\n"; if( prize != null ) { msg += '\uD83C\uDF34 '.repeat(10) msg += "\n\uD83D\uDC35 Winner! " + prize + " \uD83D\uDC35\n"; msg += '\uD83C\uDF34 '.repeat(10) this.won.push({user: user, num: amount, prize: prize}); } else { msg += ":mellow Sorry, no prize, better luck next time"; } cb.sendNotice(msg, "", "", "", "bold"); this.updateCount(); cb.drawPanel(); return true; } return false; }, tip: function(amount, user) { if( !this.enabled ) return; if( amount >= this.min ) { if( this.checkTip(amount, user) ) { return; } else if( this.call_multiples ) { var next = this.findHighest(amount); while( (next > 0) && (amount >= next) ) { this.checkTip(next, user); amount -= next; if( amount >= this.min ) { next = this.findHighest(amount); } else { next = 0; } } } else { var next = this.findHighest(amount); if( next > 0 ) { this.checkTip(next, user); return; } } } if( this.group_tipping && (amount > 0) ) { this.group_pot += amount; if( this.group_pot >= this.min ) { var next = this.findHighest(this.max); if( (next > 0) && (this.group_pot >= next) ) { this.checkTip(next, "Group tipping"); this.group_pot -= next; } } } }, onDrawPanel: function(user) { if( !this.enabled ) return; return { 'template': '3_rows_11_21_31', 'row1_value': '\uD83C\uDF34 Jungle Keno \uD83C\uDF34', 'row2_value': '' + this.remaining() + ' numbers / ' + this.prizes + ' prizes', 'row3_value': user.user != '' ? 'Tip a number on the board for a chance to win' : 'Join CB now for your chance to win' }; }, announce: function() { if( this.interval > 0 ) { this.timer = cb.setTimeout(this.announce.bind(this), this.interval * 60 * 1000); } this.showBoard(); }, sendError: function(msg) { cb.sendNotice( msg, cb.room_slug, "", "red", "bold" ); }, init: function() { var avoid_num = []; var rand_prizes = []; var big_prizes = []; var total = 0; var prizeNum = 0; this.min = parseInt(cb.settings.keno_min); this.max = parseInt(cb.settings.keno_max); var x = parseInt(cb.settings.keno_min_rand); if( !isNaN(x) ) this.min_rand = x; x = parseInt(cb.settings.keno_min_big) if( !isNaN(x) ) this.min_big = x; this.call_multiples = (cb.settings.keno_multiple == "Yes"); this.group_tipping = (cb.settings.keno_grouptip == "Yes"); this.interval = parseInt(cb.settings.keno_interval); if( this.min >= this.max ) { this.sendError( "ERROR: Highest number must be greater than lowest number" ); return false; } if( cb.settings.keno_avoid_num ) { cb.settings.keno_avoid_num.split(/\s*,\s*/).forEach(element => { avoid_num.push(parseInt(element)) }); } for( var i = this.min; i <= this.max; i++ ) { if( avoid_num.indexOf(i) < 0 ) { this.board[i] = null; total += i; } } for( var i = 1; i <= 100; i++ ) { if( cb.settings['keno_prize' + i] ) { var prize = cb.settings['keno_prize' + i].trim(); if( prize != "" ) { var big_prize = false; if( prize.startsWith('!') ) { big_prize = true; prize = prize.substring(1).trim(); } if( big_prize ) { big_prizes.push(prize); } else { rand_prizes.push(prize); } prizeNum += 1; } } } this.prizes = prizeNum; var free_nums = []; Object.keys(this.board).forEach(num => {if((num >= this.min_big) && (this.board[num] == null)) free_nums.push(num)}); if( big_prizes.length > free_nums.length ) { if( this.min_big > this.max ) { this.sendError( "ERROR: Starting number for big prizes must be less than highest number on board." ); } else { this.sendError( "ERROR: Not enough numbers above " + this.min_big + " to hold all big prizes\n" + "(" + big_prizes.length + " prizes, " + free_nums.length + " numbers)\n" + "Please either increase highest number on board, or lower starting number for big prizes, or remove some big prizes." ); } return false; } for( var prize of big_prizes ) { var i = Math.floor(Math.random() * free_nums.length); this.addPrize(prize, free_nums[i]); free_nums.splice(i, 1); } free_nums = []; Object.keys(this.board).forEach(num => {if((num >= this.min_rand) && (this.board[num] == null)) free_nums.push(num)}); if( rand_prizes.length > free_nums.length ) { if( this.min_rand > this.max ) { this.sendError( "ERROR: Starting number for random prizes must be less than highest number on board." ); } else { this.sendError( "ERROR: Not enough numbers above " + this.min_rand + " to hold all prizes\n" + "(" + rand_prizes.length + " prizes, " + free_nums.length + " numbers)\n" + "Please either increase highest number on board, or lower starting number for random prizes, or remove some prizes." ); } return false; } for( var prize of rand_prizes ) { var i = Math.floor(Math.random() * free_nums.length); this.addPrize(prize, free_nums[i]); free_nums.splice(i, 1); } this.enabled = true; this.announce(); cb.sendNotice( this.remaining() + " numbers on board, " + total + " tokens if cleared.\n" + prizeNum + " prizes in total, including " + big_prizes.length + " big prizes.", cb.room_slug ); cb.onDrawPanel(this.onDrawPanel.bind(this)); } }.load(); if( cb.settings ) { keno.init(); cb.onTip(function(tip) { var amount = parseInt(tip['amount']); keno.tip(amount, tip['from_user']); }); cb.onMessage(function(msg) { var txt = msg['m'].trim(); var user = msg['user']; var is_mod = (user == cb.room_slug || msg['is_mod']); if( txt.charAt(0) == '/' ) { msg['X-Spam'] = true; switch( txt.substring(1).toLowerCase() ) { case 'pa': if( is_mod ) user = ""; case 'p': keno.showPrizes(user); break; case 'wa': if( is_mod ) user = ""; case 'w': keno.showWinners(user); break; case 'ba': if( is_mod ) user = ""; case 'b': keno.showBoard(user); break; } } return msg; }); }
© Copyright Chaturbate 2011- 2026. All Rights Reserved.