Apps Home
|
Create an App
Heating Up
Author:
lactose_intolerant
Description
Source Code
Launch App
Current Users
Created by:
Lactose_Intolerant
/* Heating Up! 0.1 * Written by lactose_intolerant, 2014 */ // PLATFORM.JS ////////////////////////////////////////////////// // Written by lactose_intolerant, 2014 // Version 1.0-r1 // Licensed under BSD (function( ) { platform = {}; // Steal some CB functions. for (var k in cb) platform[k] = cb[k]; var events; var isOnMockPlatform = !!cb.cbUsers; platform.colors = { "fg" : "#000000", "bg" : "#FFFFFF" }; platform.users = {}; var init = function( ) { events = new platform.Events( ["onMessage", "onEnter", "onLeave", "onTip", "onDrawPanel"] ); cb.onMessage( cbOnMessage ); cb.onDrawPanel( cbOnDrawPanel ); cb.onTip( cbOnTip ); if (!isOnMockPlatform) { cb.onEnter( cbOnEnter ); cb.onLeave( cbOnLeave ); } } platform.map = function( list, transform ) { var result = []; for (var i = 0; i < list.length; ++i) result.push( transform( list[i] ) ); return result; } platform.fromCharCode = function( charCode ) { if (charCode > 0xFFFF) { charCode -= 0x10000; return String.fromCharCode( 0xD800 + (charCode >> 10), 0xDC00 + (charCode & 0x3FF) ); } else return String.fromCharCode( charCode ); } var secondsInAMinute = 60; var secondsInAnHour = 60 * secondsInAMinute; var splitSeconds = function( seconds ) { var hours = 0; var minutes = 0; if (seconds >= secondsInAnHour) hours = Math.floor( seconds / secondsInAnHour ); seconds = seconds - hours * secondsInAnHour; if (seconds >= secondsInAMinute) minutes = Math.floor( seconds / secondsInAMinute ); seconds = Math.floor( seconds - minutes * secondsInAMinute ); return { 'seconds' : seconds, 'minutes' : minutes, 'hours' : hours }; } platform.createReadableDuration = function( seconds ) { parts = splitSeconds( seconds ); var components = []; if (parts.hours > 0) components.push( parts.hours + ":" ); components.push( parts.minutes + ":" ); components.push( parts.seconds ); return components.join( "" ); } platform.createReadableDuration2 = function( seconds ) { parts = splitSeconds( seconds ); var components = []; if (parts.hours > 0) components.push( parts.hours + " hours" ); if (parts.minutes > 0) components.push( parts.minutes + " minutes" ); if (components.length === 0 || parts.seconds > 0) components.push( parts.seconds + " seconds" ); return components.join( ", " ); } platform.parseDurationString = function( str ) { var match = /(?:(\d+)h)?\s*(?:(\d+)m)?\s*(?:(\d+)s)?/.exec( str ); if (match === null) return null; if (!match[1] && !match[2] && !match[3]) return null; var seconds = 0; if (match[1]) seconds += parseInt( match[1] ) * secondsInAnHour; if (match[2]) seconds += parseInt( match[2] ) * secondsInAMinute; if (match[3]) seconds += parseInt( match[3] ); return seconds; } platform.getTimeSinceEpochInSeconds = function( ) { return (new Date( )).valueOf( ) / 1000.0; } platform.mergeObjects = function( a, b ) { var result = {}; for (var k in a) result[k] = a[k]; for (k in b) result[k] = b[k]; return result; } platform.randomArrayItem = function( array ) { var i = Math.floor( Math.random( ) * array.length ); return array[i]; } var addUser = function( cbUser ) { platform.users[cbUser.user.toLowerCase( )] = cbUser; } var removeUserByName = function( username ) { delete platform.users[username.toLowerCase( )]; } platform.isUserPresent = function( username ) { return username.toLowerCase( ) in platform.users; } platform.getUserByName = function( username ) { return platform.users[username.toLowerCase( )]; } platform.onMessage = function( handler ) { events.add( "onMessage", handler ); } platform.onEnter = function( handler ) { events.add( "onEnter", handler ); } platform.onLeave = function( handler ) { events.add( "onLeave", handler ); } platform.onDrawPanel = function( handler ) { events.add( "onDrawPanel", handler ); } platform.onTip = function( handler ) { events.add( "onTip", handler ); } platform.fakeLeave = function( usernameOrObj ) { var cbUser = usernameOrObj; if (typeof usernameOrObj == "string") cbUser = createFakeUserObj( usernameOrObj ); cbOnLeave( cbUser ); } platform.fakeEnter = function( usernameOrObj ) { var cbUser = usernameOrObj; if (typeof usernameOrObj == "string") cbUser = createFakeUserObj( usernameOrObj ); cbOnEnter( cbUser ); } platform.setInterval = function( func, timeout ) { cb.setTimeout( function( ) { cb.setTimeout( arguments.callee, timeout ); try { func( ); } catch (e) { handleException( "onTimeout", e ); } }, timeout ); } var createFakeUserObj = function( name ) { return { "user" : name, "in_fanclub" : false, "has_tokens" : 0, "is_mod" : false, "tipped_recently" : false, "gender" : "m" }; } var cbOnMessage = function( cbMsg ) { try { var cbUser = platform.mergeObjects( cbMsg, {} ); delete cbUser.c; delete cbUser.m; delete cbUser.f; updateUser( cbUser ); events.raise( "onMessage", cbMsg ); } catch (e) { handleException( "onMessage", e ); } return cbMsg; } var cbOnEnter = function( cbUser ) { try { addUser( cbUser ); events.raise( "onEnter", cbUser ); } catch (e) { handleException( "onEnter", e ); } } var cbOnLeave = function( cbUser ) { try { removeUserByName( cbUser.user ); events.raise( "onLeave", cbUser ); } catch (e) { handleException( "onLeave", e ); } } var cbOnTip = function( cbTip ) { try { var cbUser = { "user" : cbTip.from_user, "in_fanclub" : cbTip.from_user_in_fanclub, "has_tokens" : cbTip.from_user_has_tokens, "is_mod" : cbTip.from_user_is_mod, "tipped_recently" : cbTip.from_user_tipped_recently, "gender" : cbTip.from_user_gender }; updateUser( cbUser ); events.raise( "onTip", cbTip ); } catch (e) { handleException( "onTip", e ); } } var updateUser = function( cbUser ) { if (!platform.isUserPresent( cbUser.user )) platform.fakeEnter( cbUser ); else addUser( cbUser ); } var cbOnDrawPanel = function( ) { try { return events.raise( "onDrawPanel" ); } catch (e) { handleException( "onDrawPanel", e ); } } platform.announce = function( msg ) { platform.chatNotice( msg, '', platform.colors.bg, platform.colors.fg, 'bold' ); } platform.notify = function( username, msg ) { platform.chatNotice( msg, username, platform.colors.bg, platform.colors.fg, 'bold' ); } var handleException = function( eventName, e ) { var msg = "<EXCEPTION>: \"" ; if ('message' in e) msg += e.message; else msg += e; msg += "\""; msg += " <EVENT>: " + eventName; if ('trace' in e) msg += " <TRACE>: " + e.stack; cb.log( msg ); } // Events type platform.Events = function( names ) { var handlers = {}; var init = function( ) { for (var i = 0; i < names.length; ++i) handlers[names[i]] = []; } this.add = function( event, handler ) { handlers[event].push( handler ); } this.raise = function( event /*, *args */ ) { var raiseArgs = Array.prototype.slice.call( arguments, 1 ); var rval; for (var i = 0; i < handlers[event].length; ++i) rval = handlers[event][i].apply( null, raiseArgs ); return rval; } init( ); }; // Command parser type platform.CommandParser = function( ) { var commands = []; var init = function( ) { platform.onMessage( onMessage ); } this.register = function( key, handler, optModelOnly ) { commands.push( { 'key' : key, 'model' : !!optModelOnly, 'handler' : handler } ); } var onMessage = function( cbMsg ) { var key = getKey( cbMsg.m ); var cmd = findCommand( cbMsg.user, key ); if (!!cmd) { cbMsg['X-Spam'] = true; cmd.handler.apply( null, [cbMsg.user].concat( getCommandArgs( cbMsg.m ) ) ); } return cbMsg; } var getKey = function( msg ) { var m = /^\/(\S+)/.exec( msg ); if (!!m) return m[1]; } var findCommand = function( username, key ) { for (var i = 0; i < commands.length; ++i) { var cmd = commands[i]; if (cmd.key == key && (!cmd.model || username == platform.room_slug)) return cmd; } return null; } var getCommandArgs = function( msg ) { var m = /^\/\S+\s+(.*)/.exec( msg ); if (!m) return []; return m[1].split( /\s+/ ); } init( ); } init( ); })( ); // END OF PLATFORM.JS ///////////////////////////////////////////////////////////// var main = function( ) { var level = 0; var maxInflation = 2; var maxInflationPopulation = 256; var levels = [ { "length" : 10 * 60, "cost": 100 } ]; var currentLevelInfo = { "nextLevelIndex" : 0, "tipsReceived" : 0, "timeLeft" : 0 }; var lastTickTime = platform.getTimeSinceEpochInSeconds( ); var currentBluePopulation = 0; var init = function( ) { platform.colors.fg = "#FF0000"; platform.colors.bg = "#FFA90A"; loadSettings( ); platform.onDrawPanel( onDrawPanel ); platform.setInterval( onTick, 1500 ); platform.onEnter( onEnter ); platform.onLeave( onLeave ); platform.onTip( onTip ); initCommands( ); } var initCommands = function( ) { var cmds = new platform.CommandParser( ); cmds.register( "raise", onRaiseLevelCommand, true ); cmds.register( "drop", onDropLevelCommand, true ); } var onRaiseLevelCommand = function( ) { if (currentLevelInfo.nextLevelIndex < levels.length) raiseLevel( ); } var onDropLevelCommand = function( ) { if (currentLevelInfo.nextLevelIndex >= 1) dropLevel( ); } var loadSettings = function( ) { var fields = platform.settings.levelsConfig.split( ";" ); if (fields.length == 0 || fields.length % 2 != 0) throw "Bad configuration string."; levels = []; for (var i = 0; i < fields.length / 2; ++i) { var level = {}; level["cost"] = parseInt( fields[i*2] ); level["length"] = platform.parseDurationString( fields[i*2+1] ); levels.push( level ); } maxInflation = parseFloat( platform.settings.maxInflation ); maxInflationPopulation = parseInt( platform.settings.maxInflationPopulation ); } var onTip = function( cbTip ) { var amount = deflateCost( parseInt( cbTip.amount ) ); while (amount > 0) { var tokensConsumed = creditLevel( amount ); amount -= tokensConsumed; } } var creditLevel = function( amount ) { var tokensConsumed = amount; if (currentLevelInfo.nextLevelIndex < levels.length) { var nextLevel = levels[currentLevelInfo.nextLevelIndex]; var tokensNeeded = nextLevel.cost - currentLevelInfo.tipsReceived; tokensConsumed = Math.min( tokensNeeded, amount ); currentLevelInfo.tipsReceived += tokensConsumed; if (currentLevelInfo.tipsReceived >= nextLevel.cost) raiseLevel( ); } else // Extend the show time. extendShowByTokens( amount ); return tokensConsumed; } var extendShowByTokens = function( amount ) { var level = levels[currentLevelInfo.nextLevelIndex-1]; var f = Math.log( (amount / level.cost) + 1 ) / Math.log( 3 ); f = Math.min( 1.5, f ); var dt = f * level.length; currentLevelInfo.timeLeft += dt; announceTimeAdded( dt ); } var announceTimeAdded = function( dt ) { platform.announce( Math.ceil( dt ) + " seconds have been added!" ); } var raiseLevel = function( ) { var level = levels[currentLevelInfo.nextLevelIndex]; currentLevelInfo.nextLevelIndex++; currentLevelInfo.tipsReceived = 0; currentLevelInfo.timeLeft = level.length; announceLevelRaise( ); } var announceLevelRaise = function( ) { if (currentLevelInfo.nextLevelIndex < levels.length) platform.announce( "Things are heating up but they could get hotter! Tip to reach the next level." ) else platform.announce( "We're on fire! Tip to show appreciation or to extend the show!" ); } var onEnter = function( cbUser ) { if (cbUser.has_tokens) currentBluePopulation++; } var onLeave = function( cbUser ) { if (cbUser.has_tokens || cbUser.tipped_recently) currentBluePopulation = Math.max( 0, currentBluePopulation-1 ); } var onTick = function( ) { var t = platform.getTimeSinceEpochInSeconds( ); var dt = t - lastTickTime; lastTickTime = t; updateCurrentLevel( dt ); platform.drawPanel( ); } var updateCurrentLevel = function( dt ) { if (currentLevelInfo.nextLevelIndex > 0) { currentLevelInfo.timeLeft -= dt; if (currentLevelInfo.timeLeft <= 0) dropLevel( ); } } var dropLevel = function( ) { if (currentLevelInfo.nextLevelIndex > 1) { var level = levels[currentLevelInfo.nextLevelIndex-2]; currentLevelInfo.nextLevelIndex--; currentLevelInfo.timeLeft = level.length; } else { currentLevelInfo.nextLevelIndex = 0; currentLevelInfo.timeLeft = 0; } currentLevelInfo.tipsReceived = 0; announceLevelDrop( ); } var announceLevelDrop = function( ) { platform.announce( "Oh no, things are cooling down! Tip to heat things back up again." ) } var onDrawPanel = function( ) { return { "template" : "3_rows_12_21_31", "row1_label" : "Heat Level", "row1_value" : createHeatPanelValueString( ), "row2_value" : createTimeLeftPanelValueString( ), "row3_value" : createTokensLeftPanelValueString( ) }; } var createTokensLeftPanelValueString = function( ) { if (currentLevelInfo.nextLevelIndex < levels.length) { var tokensNeeded = levels[currentLevelInfo.nextLevelIndex].cost - currentLevelInfo.tipsReceived; return inflateCost( tokensNeeded ) + " tokens till next level"; } return ""; } var createTimeLeftPanelValueString = function( ) { if (currentLevelInfo.nextLevelIndex > 0) return "Time left: " + createClockEmojiCharacter( ) + " " + platform.createReadableDuration( currentLevelInfo.timeLeft ); return ""; } var createClockEmojiCharacter = function( ) { return platform.fromCharCode( 0x231B ); /* var t = platform.getTimeSinceEpochInSeconds( ); t = Math.round( t / 2 ); return platform.fromCharCode( 0x1F550 + Math.floor( t % 12 ) ); */ } var createHeatPanelValueString = function( ) { var str = ""; for (var i = 0; i < levels.length; ++i) { if (i > 0) str = str + " "; if (i < currentLevelInfo.nextLevelIndex) str = str + platform.fromCharCode( 0x1F608 ); else str = str + platform.fromCharCode( 0x26AC ); } str = str + " (" + currentLevelInfo.nextLevelIndex + "/" + levels.length + ")"; return str; } var inflateCost = function( cost ) { return Math.ceil( cost * computeInflation( ) ); } var deflateCost = function( cost ) { return Math.ceil( cost / computeInflation( ) ); } var computeInflation = function( ) { return Math.max( 1, (currentBluePopulation / maxInflationPopulation) * maxInflation ); } init( ); } var initSettings = function( ) { cb.settings_choices = [ { "name" : "levelsConfig", "label" : "Levels", "type" : "str", "required" : false, "defaultValue" : "10;5m", }, { "name" : "maxInflation", "label" : "Max Inflation", "type" : "str", "required" : true, "defaultValue" : "2.5" }, { "name" : "maxInflationPopulation", "label" : "Max population", "type" : "int", "required" : true, "defaultValue" : "256" } ]; } new (function( ) { if (Object.keys( cb.settings ).length > 0) main( ); else initSettings( ); })( );
© Copyright Camscaster.Com 2011- 2024. All Rights Reserved.