NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Rolling 300 Timeline // @description Shows your Rolling 300 Timeline & Streaks (using official game data) on your chosen server homepage. // @version 1.8.0 // • Fixed 2 small bugs (header blocks & games/day graph) // • Added "Start With Last Day Played" option // @include http://tagpro*.koalabeast.com* // @include http://*.newcompte.fr* // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_addStyle // @updateURL https://gist.github.com/nabbynz/23a54cace27ad097d671/raw/TagPro_Rolling300Timeline.user.js // @downloadURL https://gist.github.com/nabbynz/23a54cace27ad097d671/raw/TagPro_Rolling300Timeline.user.js // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // @author nabby // ==/UserScript== console.log('START: ' + GM_info.script.name + ' (v' + GM_info.script.version + ' by ' + GM_info.script.author + ')'); var options = { //defaults //Best not to edit these ones (you can select them through the on-page menu)... 'R300MainPages': { display:'Home,Profile,Joiner', type:'checkbox', value:0, title:'Home,Profile'}, 'R300HeaderPages': { display:'Home,Profile,Joiner,Game', type:'checkbox', value:0, title:'Home,Profile,Joiner,Game'}, 'MaxR300Games': { display:'# Games to View: ', type:'overwritten', value:50, title:''}, 'ShowR300Timeline': { display:'Show Timeline', type:'checkbox', value:true, title:''}, 'ShowR300Intervals': { display:'Show Win % Bands for...', type:'checkbox', value:true, title:''}, 'R300WinBands': { display:'20,25,30,50,75,100,150', type:'subradio', value:50, title:''}, 'ShowR300WinPercentage': { display:'Show Win %', type:'checkbox', value:true, title:''}, 'ShowR300Count': { display:'Show Count', type:'checkbox', value:true, title:''}, 'ShowR300HighestLowestEver': { display:'Show Highest/Lowest %\'s (ever)', type:'checkbox', value:true, title:''}, 'ShowR300CTFNF': { display:'Show CTF/NF Win %\'s', type:'checkbox', value:true, title:''}, 'ShowR300OldestGame': { display:'Show "Oldest Game"', type:'checkbox', value:false, title:''}, 'ShowR300NextGameAffect': { display:'Show "Next Game" effect', type:'checkbox', value:true, title:''}, 'ShowR300GamesPieChart': { display:'Show Pie Chart', type:'checkbox', value:true, title:''}, 'ShowR300BestStreak': { display:'Show Best Streak', type:'checkbox', value:true, title:''}, 'ShowR300CurrentStreak': { display:'Show Current Streak', type:'checkbox', value:true, title:''}, 'ShowR300WinStreakMessage': { display:'Show "Best Streak" Messages', type:'checkbox', value:true, title:'Show messages like: "You are currently on your best win streak!"'}, 'ShowR300LossStreakMessage': { display:'Show "Worst Streak" Messages', type:'checkbox', value:false, title:'Show messages like: "You are currently on your worst losing streak"'}, 'ShowR300PerDayGraph': { display:'Show # Games Per Day Graph', type:'checkbox', value:true, title:''}, 'ShowR300PerDay': { display:'Show # Games Per Day', type:'checkbox', value:true, title:''}, 'ShowR300PUPs': { display:'Show Power-Up Stats', type:'checkbox', value:true, title:''}, 'ShowR300PUPsPerGame': { display:'Show values as "Per-Game"', type:'overwritten', value:true, title:'Click to change between per-game averages & totals'}, 'ShowR300ShowGap': { display:'Show a gap between games in Timeline', type:'checkbox', value:true, title:''}, 'ShowBoxShadowBorder': { display:'Show Shadow around Border?', type:'checkbox', value:false, title:''}, 'ShowLessThan300GamesWarning': { display:'Show the "Mini Selection" Window', type:'checkbox', value:true, title:''}, 'ShowR300TrimmedGamesPieChart': { display:'Show Mini Pie Chart', type:'checkbox', value:true, title:''}, 'ShowR300TrimmedPUPs': { display:'Show Power-Up Stats', type:'checkbox', value:true, title:''}, 'AlwaysShowLastDayPlayed': { display:'Always Start With Last Day Played', type:'checkbox', value:true, title:''}, //You can manually edit the "value" for these options if you want (but they will revert when the script updates)... 'Win_Color': { display:' Color for a "Win"', type:'manual', value:'#22DD22', title:''}, 'Loss_Color': { display:' Color for a "Loss"', type:'manual', value:'#EE2020', title:''}, 'DC_Color': { display:' Color for a "DC (Loss)"', type:'manual', value:'#FFFF00', title:''}, 'SSA_Color': { display:' Color for a "Successful Save Attempt (Win)"', type:'manual', value:'#166C16', title:''}, 'FSA_Color': { display:' Color for a "Unsuccessful Save Attempt"', type:'manual', value:'#157798', title:''}, 'Tie_Color': { display:' Color for a "Tie (Loss)"', type:'manual', value:'#ff9900', title:''}, 'Unknown_Color': { display:' Color for a "Unknown"', type:'manual', value:'#888888', title:''}, //just in case! //These are updated by the script... 'R300SavedGames': { type:'script', display:'', value:'' }, }; var R300_Selections; // = options; $.get('http://i.imgur.com/WKZPcQA.gif'); //preload the ajax loading gif function secondsToHMS(d) { d = Number(d); var h = Math.floor(d / 3600); var m = Math.floor(d % 3600 / 60); var s = Math.floor(d % 3600 % 60); return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s); } function scaleBetween(unscaledNum, minAllowed, maxAllowed, min, max){ return (maxAllowed-minAllowed)*(unscaledNum-min)/(max - min) + minAllowed; } function capitaliseFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function WhichPageAreWeOn(){ if (window.location.port) { //In a real game return('ingame'); } else if (document.URL.indexOf('/games/find') > 0) { //Joining page return('joining'); } else if ($('#play').length) { //Chosen server homepage return('server'); } else if (document.URL.indexOf('/profile/') > 0) { if ($('#showSettings').length) { return('profile'); //Profile page and logged in } else { return('profileNotOurs'); //Profile page, but not our one (or we're logged out) } } else if ( ((window.location.host == 'tagpro.koalabeast.com') || (window.location.host == 'tagpro.gg')) && (window.location.pathname === '/') ) { //Choose server homepage return('home'); } } var PageLoc = WhichPageAreWeOn(); function getUsefulText(value, what){ if (what == 'gamemode') { if (value === 1) { return 'CTF'; } else if (value === 2) { return 'Neutral Flag'; } else { return ''; } } else if (what == 'outcome') { if (value === '10') { //value must be passed as a string ('outcome'+'saved') return 'Win'; } else if (value === '20') { return 'Loss'; } else if (value === '30') { return 'DC'; } else if (value === '41') { return 'Unsuccessful Save Attempt'; } else if (value === '12') { return 'Successful Save Attempt'; } else if (value === '50') { return 'Tie'; } } } function getOldestGamesBlock(data, numberGamesToShow) { numberGamesToShow = numberGamesToShow || 3; if (data.length > numberGamesToShow) { var blocks = '<div style="display:inline-block; margin-right:5px" title="Oldest '+numberGamesToShow+' Games">'; for (var i=0; i<(numberGamesToShow); i++) { if (data[i].outcome === 1) { if (data[i].saved === 2) { blocks += '<div class="fl_ssa" title="'+getGameInfoAsText(data[i])+'"></div>'; } else { blocks += '<div class="fl_win" title="'+getGameInfoAsText(data[i])+'"></div>'; } } else if (data[i].outcome === 2) { blocks += '<div class="fl_loss" title="'+getGameInfoAsText(data[i])+'"></div>'; } else if (data[i].outcome === 3) { blocks += '<div class="fl_dc" title="'+getGameInfoAsText(data[i])+'"></div>'; } else if (data[i].outcome === 4) { //Save Attempt if (data[i].saved === 1) { //Unsuccessful blocks += '<div class="fl_fsa" title="'+getGameInfoAsText(data[i])+'"></div>'; } } else if (data[i].outcome === 5) { //Tie blocks += '<div class="fl_tie" title="'+getGameInfoAsText(data[i])+'"></div>'; } else { //Unknown blocks += '<div class="fl_unk" title="'+getGameInfoAsText(data[i])+'"></div>'; } } blocks+= '</div>'; return blocks; } else { return ''; } } function getLatestGamesBlock(data, numberGamesToShow) { numberGamesToShow = numberGamesToShow || 3; if (data.length > numberGamesToShow) { var blocks = '<div style="display:inline-block; margin-left:5px" title="Latest '+numberGamesToShow+' Games">'; for (var i=data.length-numberGamesToShow; i<data.length; i++) { if (data[i].outcome === 1) { if (data[i].saved === 2) { blocks += '<div class="fl_ssa" title="'+getGameInfoAsText(data[i])+'"></div>'; } else { blocks += '<div class="fl_win" title="'+getGameInfoAsText(data[i])+'"></div>'; } } else if (data[i].outcome === 2) { blocks += '<div class="fl_loss" title="'+getGameInfoAsText(data[i])+'"></div>'; } else if (data[i].outcome === 3) { blocks += '<div class="fl_dc" title="'+getGameInfoAsText(data[i])+'"></div>'; } else if (data[i].outcome === 4) { //Save Attempt if (data[i].saved === 1) { //Unsuccessful blocks += '<div class="fl_fsa" title="'+getGameInfoAsText(data[i])+'"></div>'; } } else if (data[i].outcome === 5) { //Tie blocks += '<div class="fl_tie" title="'+getGameInfoAsText(data[i])+'"></div>'; } else { //Unknown blocks += '<div class="fl_unk" title="'+getGameInfoAsText(data[i])+'"></div>'; } } blocks+= '</div>'; return blocks; } else { return ''; } } function getNextGamePercentage(data) { var i, wins=0, losses=0; var IfWin='', IfLose=''; for (i=0; i<data.length; i++) { if (data[i].outcome == 1) { wins++; } else if ((data[i].outcome == 2) || (data[i].outcome == 3) || (data[i].outcome == 5)) { losses++; } } if (data[0].outcome === 1) { if (data.length < 300) { IfWin = ((wins+1) / (wins+1+losses) * 100).toFixed(2); IfLose = ((wins) / (wins+losses+1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next:ꜛ'+IfWin + '%</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next:ꜜ'+IfLose+'%</span>'); } else if (data.length === 300) { IfLose = ((wins-1) / (wins-1+losses+1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next: No effect</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next:ꜜ'+IfLose+'%</span>'); } } else if ((data[0].outcome === 2) || (data[0].outcome == 3)) { if (data.length < 300) { IfWin = ((wins+1) / (wins+1+losses) * 100).toFixed(2); IfLose = ((wins) / (wins+losses+1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next:ꜛ'+IfWin + '%</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next:ꜜ'+IfLose+'%</span>'); } else if (data.length === 300) { IfWin = ((wins+1) / (wins+1+losses-1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next:ꜛ'+IfWin + '%</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next: No effect</span>'); } } else if (data[0].outcome === 4) { //Save Attempt if (data[0].saved === 1) { //Unsuccessful IfWin = ((wins+1) / (wins+1+losses) * 100).toFixed(2); IfLose = ((wins) / (wins+losses+1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next:ꜛ'+IfWin + '%</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next:ꜜ'+IfLose+'%</span>'); } } else if (data[0].outcome === 5) { //Tie if (data.length < 300) { IfWin = ((wins+1) / (wins+1+losses) * 100).toFixed(2); IfLose = ((wins) / (wins+losses+1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next:ꜛ'+IfWin + '%</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next:ꜜ'+IfLose+'%</span>'); } else if (data.length === 300) { IfWin = ((wins+1) / (wins+1+losses-1) * 100).toFixed(2); return ('<span style="color:'+R300_Selections.Win_Color.value+'">Win Next:ꜛ'+IfWin + '%</span> | <span style="color:'+R300_Selections.Loss_Color.value+'">Lose Next: No effect</span>'); } } else { return ''; } } function getWinPercentage(data) { var i, wins=0, losses=0; if (data.length) { for (i=0; i<data.length; i++) { if (data[i].outcome == 1) { wins++; } else if ((data[i].outcome == 2) || (data[i].outcome == 3) || (data[i].outcome == 5)) { losses++; } } return (wins / (wins+losses) * 100).toFixed(2); } } function getGamesTilNextFlair(data, winP) { //thanks Snaps! var thresholds = [55, 65, 75]; var threshold; var outcomes = data.map(function (d) { return d.outcome; }); for (var i = 0; i < thresholds.length; i++) { if (winP < thresholds[i]) { threshold = thresholds[i]; break; } } if (!threshold) return false; function getPct(vals) { return vals.goods / (vals.goods + vals.bads); } var bads = [2, 3, 5]; var vals = outcomes.reduce(function (vals, outcome) { if (outcome === 1) { vals.goods++; } else if (bads.indexOf(outcome) !== -1) { vals.bads++; } return vals; }, { goods: 0, bads: 0 }); var winsNeeded = 0; var game = 0; while (getPct(vals) * 100 < threshold && game < outcomes.length) { var outcome = outcomes[game]; if (bads.indexOf(outcome) !== -1) { vals.goods++; vals.bads--; } else if (outcome === 4) { vals.goods++; } winsNeeded++; game++; } return { wins: winsNeeded, goal: threshold }; } function showWinPercentageHeader(data) { var WinP_Div = '<div id="R300_WinNextHeader" style="position:relative; width:100%; top:1px; font-size:12px;font-weight:bold; color:#fff; text-align:center; text-shadow:1px 2px 1px #222; clear:both"></div>'; if (PageLoc === 'server') { //Chosen server home page $('body').prepend(WinP_Div); } else if ((PageLoc === 'profile') || (PageLoc === 'profileNotOurs')) { //Profile page $('body').prepend(WinP_Div); } else if (PageLoc === 'joining') { //Joining page $('body').prepend(WinP_Div); $('#R300_Settings_Button').hide(0); } else if (PageLoc === 'ingame') { //in a game $('body').prepend(WinP_Div); } //if (((PageLoc === 'server') && (R300_Selections.R300HeaderPages.title.indexOf('Home') >= 0)) || (((PageLoc === 'profile') || (PageLoc === 'profileNotOurs')) && (R300_Selections.R300HeaderPages.title.indexOf('Profile') >= 0)) || ((PageLoc === 'joining') && (R300_Selections.R300HeaderPages.title.indexOf('Joiner') >= 0)) || ((PageLoc === 'ingame') && (R300_Selections.R300HeaderPages.title.indexOf('Game') >= 0)) ) { //alert('yar'); var blocks = ""; // Oldest games. blocks += '<div style="display:inline-block">'+getOldestGamesBlock(data)+'</div>'; // Current Win %. var winP = getWinPercentage(data); blocks += '<div style="display:inline-block">Current: ' + winP + '% | </div>'; // Predicted Win %. blocks += '<div class="R300_Stats_Dependent" style="display:inline-block; color:#bbb">' + getNextGamePercentage(data) + ' | </div>'; // # of games to next % flair. var nextFlairInfo = getGamesTilNextFlair(data, winP); if (nextFlairInfo) { blocks += '<div class="R300_Stats_Dependent" style="display:inline-block; color:#bbb">' + nextFlairInfo.wins + ' wins needed for ' + nextFlairInfo.goal + '% flair</div>'; } else { blocks += '<div class="R300_Stats_Dependent" style="display:inline-block; color:#bbb">You\'re above 75%!</div>'; } // Most recent games. blocks += '<div style="display:inline-block">'+getLatestGamesBlock(data)+'</div>'; $('#R300_WinNextHeader').append(blocks); $('.fl_win').css ({ 'display':'inline-block', 'margin-left':'1px' , 'background-color':R300_Selections.Win_Color.value, 'height':'8px', 'width':'8px' }); $('.fl_loss').css({ 'display':'inline-block', 'margin-left':'1px' , 'background-color':R300_Selections.Loss_Color.value, 'height':'8px', 'width':'8px' }); $('.fl_dc').css ({ 'display':'inline-block', 'margin' :'0 0 2px 1px', 'background-color':R300_Selections.DC_Color.value, 'height':'4px', 'width':'8px' }); $('.fl_ssa').css ({ 'display':'inline-block', 'margin-left':'1px' , 'background-color':R300_Selections.SSA_Color.value, 'height':'6px', 'width':'8px', 'border-top' :'2px solid white' }); $('.fl_fsa').css ({ 'display':'inline-block', 'margin-left':'1px' , 'background-color':R300_Selections.FSA_Color.value, 'height':'6px', 'width':'8px', 'border-bottom':'2px solid white' }); $('.fl_tie').css ({ 'display':'inline-block', 'margin-left':'1px' , 'background-color':R300_Selections.Tie_Color.value, 'height':'8px', 'width':'8px' }); $('.fl_unk').css ({ 'display':'inline-block', 'margin-left':'1px' , 'background-color':R300_Selections.Unknown_Color.value, 'height':'8px', 'width':'8px' }); //add strikethrough if stats are off... var getProfilePage = $.get('/profile/'+data[0].userId); getProfilePage.done(function(settings) { if ($(settings).find('#stats').children('input').length) { //will only be available if it's our profile var statsOn = true; statsOn = $(settings).find('#stats').children('input').is(':checked'); if (statsOn === false) { $('.R300_Stats_Dependent').css('text-decoration', 'line-through').css('text-shadow', 'none').attr('title', 'Stats are OFF'); } } }); //} } function getProfileID() { var url, R300ProfileID; if (PageLoc === 'server') { url = $('a[href^="/profile"][class="button"]').attr('href'); if (url !== undefined) { R300ProfileID = url.substring(url.lastIndexOf('/') + 1); R300_Selections.R300SavedGames.display = R300ProfileID; GM_setValue('R300_Selections', R300_Selections); return R300ProfileID; } else { //on server home page, but not logged in so clear the saved games data & profile id R300_Selections.R300SavedGames.display = ''; //holds profile id R300_Selections.R300SavedGames.value = ''; //holds saved game data GM_setValue('R300_Selections', R300_Selections); } } else if ((PageLoc === 'profile') || (PageLoc === 'profileNotOurs')) { url = document.URL; R300ProfileID = url.substring(url.lastIndexOf('/') + 1); return R300ProfileID; } } var allGames = []; function loadData() { var profileID = getProfileID(); if (profileID !== undefined) { var serverRequests = GM_getValue('serverRequests', []); var gotCount = 0; if (serverRequests.length > 0) { for (var i=serverRequests.length; i>=0; i--) { if (serverRequests[i] > Date.now()-60000) gotCount++; } } if (gotCount >= 4) { $('#R300').prepend('<div style="margin:5px 10px; padding:10px 2px; background:#f00; color:#fff; border-radius:3px">WARNING<br>If you request/refresh this data too often you <em>may</em> be blocked for 1 hour.</div>'); } if (gotCount < 5) { var nowSeconds = Date.now(); var getGames = $.getJSON("/profile_rolling/" + profileID); getGames.done(function(data) { serverRequests.push(nowSeconds); if (serverRequests.length > 5) serverRequests.shift(); GM_setValue('serverRequests', serverRequests); if (data.length > 0) { data.reverse(); for (var key=0, l=data.length; key<l; key++) { data[key].gameNumber = (data.length - key); } allGames = data.slice(0); //make a copy for when we adjust the # games to show R300_Selections.R300SavedGames.value = data; if (PageLoc !== 'profileNotOurs') { GM_setValue('R300_Selections', R300_Selections); } $('#R300_loading').remove(); $('#R300_Trimmed').show(0); showData(); showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); showWinPercentageHeader(data); buildMenu(); bindEvents(); setSavedValues(); } else { $('#R300_Settings_Button').hide(0); $('#R300').empty(); $('#R300').append('No data for Rolling 300 Timeline - go play some games!'); } }); getGames.fail(function(){ $(document).ajaxError(function( event, jqxhr, settings, thrownError ) { if ((PageLoc !== 'profileNotOurs') && (R300_Selections.R300SavedGames.value.length > 0)) { $('#R300_loading').remove(); $('#R300').prepend('<div style="margin:5px 10px; padding:10px 2px; background:#b0b; color:#fff; border-radius:3px">Could not get data from server for Rolling 300 Timeline: <i>'+jqxhr.status+' '+thrownError+'</i>'+((jqxhr.status === 500) ? '<br>(Too many requests/refreshes, too often?)' : '')+'<br>Using saved data instead (this might not be accurate)...</div>'); var data = R300_Selections.R300SavedGames.value; allGames = data.slice(0); //make a copy showWinPercentageHeader(data); if ($('#R300').length) { $('#R300_Trimmed').show(0); showData(); showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); buildMenu(); bindEvents(); } setSavedValues(); } else { $('#R300_Settings_Button').hide(0); $('#R300').empty(); $('#R300').append('Could not get data from server for Rolling 300 Timeline: <i>'+jqxhr.status+' '+thrownError+'</i>'); } }); }); } else { $('#R300_loading').remove(); $('#R300').empty(); $('#R300').append('Too many requests/refreshes. Please wait a few minutes...'); } } else { if (R300_Selections.R300SavedGames.value.length === 0) { if (GM_getValue('R300_Selections').R300SavedGames.value.length) { R300_Selections.R300SavedGames.value = GM_getValue('R300_Selections').R300SavedGames.value; } } if (R300_Selections.R300SavedGames.value.length) { //use saved data if it exists... var data = R300_Selections.R300SavedGames.value; allGames = data.slice(0); //make a copy showWinPercentageHeader(data); if ($('#R300').length) { //$('#R300_InnerContainer').append('<div style="width:60%; margin:0 auto; background:#b0b; color:#fff; border-radius:3px">Note: Using saved data</div>'); $('#R300_Trimmed').show(0); showData(); showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); buildMenu(); bindEvents(); } setSavedValues(); } else { $('#R300_Settings_Button').hide(0); $('#R300').empty(); $('#R300').append('Could not get data for Rolling 300 Timeline (not logged in?)'); } } GM_addStyle('.gamesperday_bar { margin-left:1px; background:#777 }'); GM_addStyle('.gamesperday_bar:hover { background:#fff }'); GM_addStyle('.R300_CTFNFWP:hover { border-bottom:1px dotted #9264DA }'); } function buildMenu() { //Build the settings menu... $('#R300_Settings_Button').after('<div id="R300_Settings_Menu" style="display:none; position:absolute; right:0; width:300px; margin:-75px -50px 0 0; padding:10px 10px 15px; font-size:11px; text-align:left; background:linear-gradient(#3A8C66, #00a); opacity:0.95; border-radius:8px; box-shadow:0px 0px 8px #fff; z-index:6000"></div>'); $('#R300_Settings_Menu').append('<div style="margin:0 auto; padding-bottom:5px; font-size:16px; font-weight:bold; color:#000; text-align:center; text-shadow:2px 1px 2px #aaa;">Rolling 300 Timeline Options</div>'); var pages = []; $.each(R300_Selections, function(key, value) { if (value.type === 'checkbox') { if (key === 'ShowR300Intervals') { if (allGames.length === 300) { //Only show the bands if there's 300 games available... $('#R300_Settings_Menu').append('<li style="list-style:none" title="' + value.title + '"><label><input type="checkbox" id="' + key + '" class="'+ value.type + '" ' + (value.value === true ? 'checked' : '') + '>' + value.display + '</label></li>'); $('#R300_Settings_Menu').append('<div id="R300WinBands" style="margin-left:18px; font-size:11px"></div>'); var intBands = (R300_Selections.R300WinBands.display).split(','); $.each(intBands, function(k,v) { $('#R300WinBands').append('<label style="margin-left:4px" title="# games"><input type="radio" name="intBand" data-band="'+v+'" ' + (v == R300_Selections.R300WinBands.value ? 'checked' : '') + ' style="margin:3px 1px 3px 3px">'+v+'</label>'); }); } } else if (key === 'R300MainPages') { $('#R300_Settings_Menu').append('<div id="R300MainPages" style="text-align:center; font-size:11px">Main Window:</div>'); pages = (R300_Selections.R300MainPages.display).split(','); $.each(pages, function(k,v) { $('#R300MainPages').append('<label style="margin-left:4px"><input type="checkbox" name="mainPage" data-page="'+v+'" ' + ((R300_Selections.R300MainPages.title).indexOf(v) >= 0 ? 'checked' : '') + ' style="margin:3px 1px 3px 3px">'+v+'</label>'); }); } else if (key === 'R300HeaderPages') { $('#R300_Settings_Menu').append('<div id="R300HeaderPages" style="margin-bottom:5px; text-align:center; font-size:11px">Win % Header:</div>'); pages = (R300_Selections.R300HeaderPages.display).split(','); $.each(pages, function(k,v) { $('#R300HeaderPages').append('<label style="margin-left:4px"><input type="checkbox" name="headerPage" data-page="'+v+'" ' + ((R300_Selections.R300HeaderPages.title).indexOf(v) >= 0 ? 'checked' : '') + ' style="margin:3px 1px 3px 3px">'+v+'</label>'); }); } else if (key === 'ShowLessThan300GamesWarning') { //this is the start of the "mini-window" options $('#R300_Settings_Menu').append('<li style="list-style:none; margin-top:10px">Mini-Window Options...</li>'); $('#R300_Settings_Menu').append('<li style="list-style:none" title="' + value.title + '"><label><input type="checkbox" id="' + key + '" class="'+ value.type + '" ' + (value.value === true ? 'checked' : '') + '>' + value.display + '</label></li>'); } else if (key === 'ShowR300HighestLowestEver') { $('#R300_Settings_Menu').append('<li style="list-style:none" title="' + value.title + '"><label><input type="checkbox" id="' + key + '" class="'+ value.type + '" ' + (value.value === true ? 'checked' : '') + '>' + value.display + '</label><div id="R300ClearHighestLowestEver" style="display:inline-block; margin:0 5px; font-size:7px; border:1px solid #099; cursor:pointer" title="Clear/Reset the saved high/low values">CLEAR</div></li>'); } else { $('#R300_Settings_Menu').append('<li style="list-style:none" title="' + value.title + '"><label><input type="checkbox" id="' + key + '" class="'+ value.type + '" ' + (value.value === true ? 'checked' : '') + '>' + value.display + '</label></li>'); } } }); $('#R300_Settings_Menu').append('<div style="position:absolute; bottom:2px; right:5px; text-align:right"><a href="https://gist.github.com/nabbynz/23a54cace27ad097d671" target="_blank" style="font-size:11px; color:#888" title="Version: ' + GM_info.script.version + '. Click to manually check for updates (script will auto-update if enabled)...">v' + GM_info.script.version + '</a</div>'); } function setSavedValues() { //update with the user saved values... $.each(R300_Selections, function(key, value) { if (key === 'R300MainPages') { if (PageLoc === 'server') { if (R300_Selections[key].title.indexOf('Home') < 0) { $('#R300_InnerContainer').hide(0); } else { $('#R300_InnerContainer').fadeIn(1200); } } else if ((PageLoc === 'profile') || (PageLoc === 'profileNotOurs')) { if (R300_Selections[key].title.indexOf('Profile') < 0) { $('#R300').hide(0); } else { $('#R300_InnerContainer').show(0); } } else if (PageLoc === 'joining') { if (R300_Selections[key].title.indexOf('Joiner') < 0) { $('#R300').hide(0); } else { $('#R300_InnerContainer').show(0); } } } else if (key === 'R300HeaderPages') { if (PageLoc === 'server') { if (R300_Selections[key].title.indexOf('Home') < 0) { $('#R300_WinNextHeader').hide(0); } else { $('#R300_WinNextHeader').show(0); } } else if ((PageLoc === 'profile') || (PageLoc === 'profileNotOurs')) { if (R300_Selections[key].title.indexOf('Profile') < 0) { $('#R300_WinNextHeader').hide(0); } else { $('#R300_WinNextHeader').show(0); } } else if (PageLoc === 'joining') { if (R300_Selections[key].title.indexOf('Joiner') < 0) { $('#R300_WinNextHeader').hide(0); } else { $('#R300_WinNextHeader').show(0); } } else if (PageLoc === 'ingame') { if (R300_Selections[key].title.indexOf('Game') < 0) { $('#R300_WinNextHeader').hide(0); } else { $('#R300_WinNextHeader').show(0); } } } else if (key == 'ShowR300PUPsPerGame') { if (value.value === true) { $('.R300_pups_pergame').show(0); $('.R300_pups_total').hide(0); } else { $('.R300_pups_pergame').hide(0); $('.R300_pups_total').show(0); } } else if (key === 'ShowBoxShadowBorder') { if (value.value === true) { $('#R300').css('box-shadow', '#fff 0px 0px 10px'); } else { $('#R300').css('box-shadow', 'none'); } } else if (value.type === 'checkbox') { //Hide certain elements according to the saved values... if (value.value === false) { if (key == 'ShowR300Timeline') { $('#R300_Timeline').hide(0); } else if (key === 'ShowR300Intervals') { $('#R300_Intervals').hide(0); $('#R300WinBands input').prop('disabled', true); } else if (key === 'ShowR300GamesPieChart') { $('#R300_Pie').hide(0); } else if (key === 'ShowR300WinPercentage') { $('#R300_Wins').hide(0); } else if (key === 'ShowR300PerDay') { $('#R300_GamesPerDay').hide(0); } else if (key === 'ShowR300PerDayGraph') { $('#R300_GamesPerDayGraph').hide(0); } else if (key === 'ShowR300Count') { $('#R300_Count').hide(0); } else if (key === 'ShowR300HighestLowestEver') { $('#R300_HighestLowestEver').hide(0); } else if (key === 'ShowR300CTFNF') { $('#R300_CTFNF').hide(0); } else if (key === 'ShowR300NextGameAffect') { $('#R300_NextGameAffectWin, #R300_NextGameAffectLose').hide(0); } else if (key === 'ShowR300OldestGame') { $('#R300_OldestGame').hide(0); } else if (key === 'ShowR300BestStreak') { $('#R300_BestStreak').hide(0); } else if (key === 'ShowR300CurrentStreak') { $('#R300_CurrentStreak').hide(0); } else if (key === 'ShowR300WinStreakMessage') { $('#R300_BestStreakMessage').hide(0); } else if (key === 'ShowR300LossStreakMessage') { $('#R300_WorstStreakMessage').hide(0); } else if (key === 'ShowR300PUPs') { $('#R300_PUPs').hide(0); } else if (key === 'ShowLessThan300GamesWarning') { $('#R300_Trimmed').hide(0); $('#ShowR300TrimmedGamesPieChart').prop('disabled', true); } } } }); } function bindEvents() { $('#R300_Settings_Button').on('click', function() { $('#R300_Settings_Menu').slideToggle(400); }); $("#R300_Settings_Menu").mouseleave(function() { $('#R300_Settings_Menu').fadeOut(100); }); $('#R300WinBands input').on('click', function() { R300_Selections.R300WinBands.value = $(this).data('band'); GM_setValue('R300_Selections', R300_Selections); showData(); if (R300_Selections.ShowLessThan300GamesWarning.value) showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); }); $('#R300MainPages input').on('click', function() { var newSelection = ''; $.each($('#R300MainPages input'), function() { if ($(this).is(':checked')) newSelection += $(this).data('page') + ","; }); R300_Selections.R300MainPages.title = newSelection; GM_setValue('R300_Selections', R300_Selections); if (($(this).data('page') === 'Home') && (PageLoc === 'server')) { $('#R300_InnerContainer').slideToggle(600); } else if (($(this).data('page') === 'Profile') && ((PageLoc === 'profile') || (PageLoc === 'profileNotOurs'))) { $('#R300').slideToggle(600); } }); $('#R300HeaderPages input').on('click', function() { var newSelection = ''; $.each($('#R300HeaderPages input'), function() { if ($(this).is(':checked')) newSelection += $(this).data('page') + ","; }); R300_Selections.R300HeaderPages.title = newSelection; GM_setValue('R300_Selections', R300_Selections); if (($(this).data('page') === 'Home') && (PageLoc === 'server')) { $('#R300_WinNextHeader').slideToggle(400); } else if (($(this).data('page') === 'Profile') && ((PageLoc === 'profile') || (PageLoc === 'profileNotOurs'))) { $('#R300_WinNextHeader').slideToggle(400); } }); $('#R300_Settings_Menu .checkbox').on('click', function() { R300_Selections[$(this).attr('id')].value = $(this).is(':checked'); GM_setValue('R300_Selections', R300_Selections); if ($(this).attr('id') == 'ShowR300Timeline') { $('#R300_Timeline').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300Intervals') { $('#R300_Intervals').fadeToggle(400); $('#R300WinBands input').prop('disabled', ($(this).prop('checked') ? false : true)); } else if ($(this).attr('id') == 'ShowR300GamesPieChart') { $('#R300_Pie').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300Pages') { $('#R300_WinNextHeader').fadeToggle(400); $('#R300HeaderPages input').prop('disabled', ($(this).prop('checked') ? false : true)); } else if ($(this).attr('id') == 'ShowR300WinPercentage') { $('#R300_Wins').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300PerDay') { $('#R300_GamesPerDay').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300PerDayGraph') { $('#R300_GamesPerDayGraph').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300Count') { $('#R300_Count').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300HighestLowestEver') { $('#R300_HighestLowestEver').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300CTFNF') { $('#R300_CTFNF').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300NextGameAffect') { $('#R300_NextGameAffectWin, #R300_NextGameAffectLose').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300OldestGame') { $('#R300_OldestGame').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300BestStreak') { $('#R300_BestStreak').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300CurrentStreak') { $('#R300_CurrentStreak').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300WinStreakMessage') { $('#R300_BestStreakMessage').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300LossStreakMessage') { $('#R300_WorstStreakMessage').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300PUPs') { $('#R300_PUPs').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300TrimmedPUPs') { $('#R300T_PUPs').fadeToggle(400); } else if ($(this).attr('id') == 'ShowR300PUPsPerGame') { $('.R300_pups_pergame').toggle(0); $('.R300_pups_total').toggle(0); } else if ($(this).attr('id') == 'ShowR300ShowGap') { showData(); if (R300_Selections.ShowLessThan300GamesWarning.value) showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); setSavedValues(); } else if ($(this).attr('id') == 'ShowLessThan300GamesWarning') { //Not a warning anymore - just an on/off toggle for the mini window $('#R300_Trimmed').fadeToggle(400); $('#ShowR300TrimmedGamesPieChart').prop('disabled', ($(this).prop('checked') ? false : true)); $('#ShowR300TrimmedPUPs').prop('disabled', ($(this).prop('checked') ? false : true)); $('#AlwaysShowLastDayPlayed').prop('disabled', ($(this).prop('checked') ? false : true)); if (R300_Selections.ShowLessThan300GamesWarning.value) { setTimelineCellHeights(Cell_Width); showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); } } else if ($(this).attr('id') == 'ShowR300TrimmedGamesPieChart') { if (R300_Selections.ShowLessThan300GamesWarning.value) showTrimmedData(R300_Selections.MaxR300Games.value, R300_Selections.MaxR300Games.value); } else if ($(this).attr('id') == 'ShowBoxShadowBorder') { if ($(this).is(':checked')) { $('#R300').css('box-shadow', '#fff 0px 0px 10px'); } else { $('#R300').css('box-shadow', 'none'); } } }); $('#R300ClearHighestLowestEver').on('click', function() { var response = confirm("Your current highest/lowest saved values will be cleared.\n\nOK to continue?"); if (response) { GM_deleteValue('R300_HighestEver'); GM_deleteValue('R300_LowestEver'); showData(); setSavedValues(); } }); } function setTimelineCellHeights(Cell_Width) { Cell_Width = Cell_Width || 1; $('.r300_win').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.Win_Color.value, 'height':'10px', 'width':Cell_Width+'px' }); $('.r300_loss').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.Loss_Color.value, 'height':'10px', 'width':Cell_Width+'px' }); $('.r300_dc').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin' :'0px 0px 2px '+(R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.DC_Color.value, 'height':' 6px', 'width':Cell_Width+'px' }); $('.r300_ssa').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.SSA_Color.value, 'height':' 7px', 'width':Cell_Width+'px', 'border-top':'3px solid white' }); $('.r300_fsa').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.FSA_Color.value, 'height':' 7px', 'width':Cell_Width+'px', 'border-bottom':'3px solid white' }); $('.r300_tie').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.Tie_Color.value, 'height':'10px', 'width':Cell_Width+'px' }); $('.r300_unknown').css ({ 'display':'inline-block', 'cursor':'pointer', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? 1 : 0)+'px', 'background-color':R300_Selections.Unknown_Color.value, 'height':'10px', 'width':Cell_Width+'px' }); } function getGameInfoAsText(gameData) { var text = "Game #" + gameData.gameNumber + ": "; if (gameData.outcome === 1) { if (gameData.saved === 2) { text += 'Win - Successful Save Attempt! (' + getUsefulText(gameData.gameMode, 'gamemode') + ')'; } else { text += 'Win (' + getUsefulText(gameData.gameMode, 'gamemode') + ')'; } } else if (gameData.outcome === 2) { text += 'Loss (' + getUsefulText(gameData.gameMode, 'gamemode') + ')'; } else if (gameData.outcome === 3) { text += 'DC/Loss (' + getUsefulText(gameData.gameMode, 'gamemode') + ')'; } else if (gameData.outcome === 4) { //Save Attempt if (gameData.saved === 1) { //Unsuccessful text += 'Unsuccessful Save Attempt (' + getUsefulText(gameData.gameMode, 'gamemode') + ')'; } } else if (gameData.outcome === 5) { //Tie text += 'Tie/Loss (' + getUsefulText(gameData.gameMode, 'gamemode') + ')'; } else { //Unknown text += 'Unknown Result!'; } text += "\n" + new Date(parseInt(Date.parse(gameData.played))).toLocaleTimeString() + ' (' + new Date(parseInt(Date.parse(gameData.played))).toDateString() + ')'; text += "\nYou played for " + secondsToHMS(gameData.timePlayed); text += "\n\nCaps: " + gameData.captures + " | Grabs: " + gameData.grabs + " | Drops: " + gameData.drops + " | Popped: " + gameData.pops + " | Tags: " + gameData.tags + " | Returns: " + gameData.returns + "\nHold: " + secondsToHMS(gameData.hold) + " | Prevent: " + secondsToHMS(gameData.prevent) + " | Support: " + gameData.support + " | PUP%: " + (gameData.powerups / gameData.potentialPowerups * 100).toFixed(2) + "\nCaps/Grab: " + ((gameData.grabs?gameData.captures:0)/(gameData.grabs?gameData.grabs:1)).toFixed(3) + " | Tags/Pop: " + ((gameData.pops?gameData.tags:0)/(gameData.pops?gameData.pops:1)).toFixed(3); return text; } /************************************************************************************/ // Main Rolling 300 Timeline & Streaks... /************************************************************************************/ function showData() { var Timeline_MaxWidth = 780; var Cell_Width = 18; //This value will adjust (smaller) according to MaxGames & Timeline_MaxWidth. Default=18 var i, j; var totals = {'all': { win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0 }, 'ctf': { win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0 }, 'nf': { win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0 }, 'pups': { tags:0, pops:0, grabs:0, drops:0, hold:0, captures:0, prevent:0, returns:0, support:0, powerups:0, timePlayed:0 }, 'streaks': { win:0, loss:0, temp_win:0, temp_loss:0, last_win:0, last_loss:0 } }; var data = allGames.slice(0); var New_Cell_Width = Math.floor((Timeline_MaxWidth - 26) / data.length); if (New_Cell_Width < Cell_Width) Cell_Width = New_Cell_Width - (R300_Selections.ShowR300ShowGap.value ? 1 : 0); if (Cell_Width <= 0) Cell_Width = 1; $('#R300_Intervals').empty(); $('#R300_Timeline').empty(); $('#R300_Messages').empty(); $('#R300_Pie').empty(); $('#R300_PUPs').remove(); var totalPotentialPowerups = 0; var dayCounts = []; var dayCountsKey=0; var d1 = ''; var d2 = ''; $(data).each(function(key, value) { d1 = new Date(value.played); if (key === 0) { //first game, nothing to compare to yet so just push it dayCounts.push( { day:d1.toDateString(), firstGameNumber:key, win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0, timePlayed:0 } ); } else { j = Math.ceil((d1 - d2) / (1000 * 3600 * 24)); if ( (d2 !== '') && (d1.toDateString() !== d2.toDateString()) ) { for (i=dayCountsKey+1; i<dayCountsKey+j; i++) { dayCounts.push( { day:0, firstGameNumber:0, win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0, timePlayed:0 } ); //push 0's for the in-between days we haven't played on (this could get big?!?) } dayCounts.push( { day:d1.toDateString(), firstGameNumber:key, win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0, timePlayed:0 } ); dayCountsKey += j; } } d2 = d1; //save for compare on next loop dayCounts[dayCountsKey].timePlayed += value.timePlayed; totalPotentialPowerups += value.potentialPowerups; $.each(totals.pups, function(key1, value1) { totals.pups[key1] += value[key1]; }); switch (value.outcome) { case 1: //win if (value.saved === 2) { totals.all.ssa++; dayCounts[dayCountsKey].ssa++; if (value.gameMode === 1) { totals.ctf.ssa++; } else if (value.gameMode === 2) { totals.nf.ssa++; } $('#R300_Timeline').append('<div class="r300_ssa" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); } else { totals.all.win++; dayCounts[dayCountsKey].win++; if (value.gameMode === 1) { totals.ctf.win++; } else if (value.gameMode === 2) { totals.nf.win++; } $('#R300_Timeline').append('<div class="r300_win" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); } //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_win === 0) || ((i > 0) && ((data[i-1].outcome === 1)) ) ) totals.streaks.temp_win++; if (totals.streaks.temp_win > totals.streaks.win) totals.streaks.win = totals.streaks.temp_win; totals.streaks.temp_loss = 0; if (totals.streaks.temp_win > 0) totals.streaks.last_win = totals.streaks.temp_win; break; case 2: //loss totals.all.loss++; dayCounts[dayCountsKey].loss++; if (value.gameMode === 1) { totals.ctf.loss++; } else if (value.gameMode === 2) { totals.nf.loss++; } $('#R300_Timeline').append('<div class="r300_loss" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_loss === 0) || ((i > 0) && ((data[i-1].outcome === 2) || (data[i-1].outcome === 3) || (data[i-1].outcome === 5)) ) ) totals.streaks.temp_loss++; if (totals.streaks.temp_loss > totals.streaks.loss) totals.streaks.loss = totals.streaks.temp_loss; totals.streaks.temp_win = 0; if (totals.streaks.temp_loss > 0) totals.streaks.last_loss = totals.streaks.temp_loss; break; case 3: //dc totals.all.dc++; dayCounts[dayCountsKey].dc++; if (value.gameMode === 1) { totals.ctf.dc++; } else if (value.gameMode === 2) { totals.nf.dc++; } $('#R300_Timeline').append('<div class="r300_dc" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_loss === 0) || ((i > 0) && ((data[i-1].outcome === 2) || (data[i-1].outcome === 3) || (data[i-1].outcome === 5)) ) ) totals.streaks.temp_loss++; if (totals.streaks.temp_loss > totals.streaks.loss) totals.streaks.loss = totals.streaks.temp_loss; totals.streaks.temp_win = 0; if (totals.streaks.temp_loss > 0) totals.streaks.last_loss = totals.streaks.temp_loss; break; case 4: //save attempt if (value.saved === 1) { //failed save attempt... totals.all.fsa++; dayCounts[dayCountsKey].fsa++; if (value.gameMode === 1) { totals.ctf.fsa++; } else if (value.gameMode === 2) { totals.nf.fsa++; } $('#R300_Timeline').append('<div class="r300_fsa" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); } break; case 5: //tie totals.all.tie++; dayCounts[dayCountsKey].tie++; if (value.gameMode === 1) { totals.ctf.tie++; } else if (value.gameMode === 2) { totals.nf.tie++; } $('#R300_Timeline').append('<div class="r300_tie" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_loss === 0) || ((i > 0) && ((data[i-1].outcome === 2) || (data[i-1].outcome === 3) || (data[i-1].outcome === 5)) ) ) totals.streaks.temp_loss++; if (totals.streaks.temp_loss > totals.streaks.loss) totals.streaks.loss = totals.streaks.temp_loss; totals.streaks.temp_win = 0; if (totals.streaks.temp_loss > 0) totals.streaks.last_loss = totals.streaks.temp_loss; break; default: //just in case! title += getGameInfoAsText(value); $('#R300_Timeline').append('<div class="r300_unknown" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); break; } }); setTimelineCellHeights(Cell_Width); //Win %... var currentWinPC = ((totals.all.win+totals.all.ssa) / (totals.all.win+totals.all.ssa + totals.all.loss+totals.all.dc+totals.all.tie) * 100).toFixed(2); $('#R300_Messages').append('<div id="R300_Wins">Win % over your last <span style="color:' + R300_Selections.Win_Color.value + '">' + data.length + '</span> games: <span style="color:'+R300_Selections.Win_Color.value+'">' + currentWinPC + '%</span></div>'); //Game Count... $('#R300_Messages').append('<div id="R300_Count">(<span style="color:'+R300_Selections.Win_Color.value+'" title="Includes Successful Save Attempts">' + (totals.all.win+totals.all.ssa) + ' Win'+((totals.all.win+totals.all.ssa)==1?'':'s')+'</span> | <span style="color:'+R300_Selections.Loss_Color.value+'" title="Does NOT include DC\'s">'+ (totals.all.loss) + ' Loss'+(totals.all.loss==1?'':'es')+'</span> | <span style="color:'+R300_Selections.Tie_Color.value+'" title="Included in Losses">'+ (totals.all.tie) + ' Tie'+(totals.all.tie==1?'':'s')+'</span> | <span style="color:'+R300_Selections.DC_Color.value+'" title="DC\'s are counted as a Loss">' + totals.all.dc + ' DC'+(totals.all.dc==1?'':'s')+'</span> | <span style="color:'+R300_Selections.SSA_Color.value+'" title="Included in Wins">' + totals.all.ssa + ' Save'+(totals.all.ssa==1?'':'s')+'</span> | <span style="color:'+R300_Selections.FSA_Color.value+'" title="Unsuccessful Save Attempts do NOT count as a Loss (or a Win)">' + totals.all.fsa + ' USA'+(totals.all.fsa==1?'':'s')+'</span>)</div>'); //Highest/Lowest % Ever (while running this script)... if (PageLoc !== 'profileNotOurs') { if (document.URL.indexOf('.koalabeast.com') >= 0) { //only save if on a koalabeast server if (currentWinPC > GM_getValue('R300_HighestEver', 0)) GM_setValue('R300_HighestEver', currentWinPC); if (currentWinPC < GM_getValue('R300_LowestEver', 100)) GM_setValue('R300_LowestEver', currentWinPC); } $('#R300_Messages').append('<div id="R300_HighestLowestEver" title="'+R300_Selections.ShowR300HighestLowestEver.title+'"><span style="color:#2CAD9C'+(currentWinPC === GM_getValue('R300_HighestEver') ? '; text-decoration:underline':'')+'" title="Highest Win % Ever">Highest: ' + GM_getValue('R300_HighestEver') + '%</span> | <span style="color:#2CAD9C'+(currentWinPC === GM_getValue('R300_LowestEver') ? '; text-decoration:underline':'')+'" title="Lowest Win % Ever">Lowest: ' + GM_getValue('R300_LowestEver') + '%</span></div>'); } //CTF / NF... var totalCTF = (totals.ctf.win+totals.ctf.ssa + totals.ctf.loss+totals.ctf.dc+totals.ctf.tie); var CTFWinPC = (totalCTF === 0) ? 0 : ((totals.ctf.win+totals.ctf.ssa) / totalCTF * 100).toFixed(2); var totalNF = (totals.nf.win+totals.nf.ssa + totals.nf.loss+totals.nf.dc+totals.nf.tie); var NFWinPC = (totalNF === 0) ? 0 : ((totals.nf.win+totals.nf.ssa) / totalNF * 100).toFixed(2); $('#R300_Messages').append('<div id="R300_CTFNF"><span id="R300_CTFWP" class="R300_CTFNFWP" style="color:#9264DA; cursor:pointer" title="Click to show CTF games">CTF: ' + CTFWinPC + '% ('+(totalCTF+totals.ctf.fsa)+')</span> | <span id="R300_NFWP" class="R300_CTFNFWP" style="color:#9264DA; cursor:pointer" title="Click to show Neutral Flag games">NF: ' + NFWinPC + '% ('+(totalNF+totals.nf.fsa)+')</span></div>'); //Oldest Game... var oldestGame = getUsefulText( (data[0].outcome.toString() + data[0].saved.toString()), 'outcome'); $('#R300_Messages').append('<div id="R300_OldestGame">Oldest game: ' + (oldestGame) + '</div>'); //How next game affect's Win%... $('#R300_Messages').append('<div id="R300_NextGameAffectLose">' + getNextGamePercentage(data) + '</div>'); //Win % Bands... if (data.length === 300) { var intervalSize = R300_Selections.R300WinBands.value; var int_win, int_loss; var intervalWins = []; for (i=0; i<data.length; i+=intervalSize) { int_win=0; int_loss=0; for (j=i; j<i+intervalSize; j++) { if (data[j].outcome == 1) { int_win++; } else if ((data[j].outcome == 2) || (data[j].outcome == 3) || (data[j].outcome == 5)) { int_loss++; } } intervalWins.push((int_win / (int_win + int_loss))*100); if (i % intervalSize === 0) { var IntervalCellWidth = ((Cell_Width+(R300_Selections.ShowR300ShowGap.value ? 1 : 0))*intervalSize-1); var IntervalMarginLeft = 0; if ((i === 0) || (i === data.length-intervalSize)) { //need to adjust for first & last cells... IntervalCellWidth = ((Cell_Width+(R300_Selections.ShowR300ShowGap.value ? 1 : 0))*intervalSize-2); if (i === 0) IntervalMarginLeft = 2; } $('#R300_Intervals').append('<div class="R300_Interval" data-firstgame="'+(data.length-i)+'" style="display:inline-block; cursor:pointer; font-size:11px; color:#777; width:'+IntervalCellWidth+'px; height:10px; ' + (i===0 ? 'border-left:1px solid #777; ' : '') + 'border-right:1px solid #777; margin-left:'+IntervalMarginLeft+'px;" title="Games: ' + (data.length-i-intervalSize+1) + '-' + (data.length-i) + ' (' +intervalSize+')"> '+ (intervalWins[i/intervalSize]).toFixed(1) + '%</div>'); } } } //Games Pie Chart... $('#R300_Messages').append('<div id="R300_Pie"></div>'); $('#R300_Pie').append('<canvas id="gamesPieChart" width="80" height="80" />'); var canvas = document.getElementById("gamesPieChart"); var context = canvas.getContext("2d"); var lastend = 1.5*Math.PI; var gamesPieData = [totals.all.win, totals.all.loss, totals.all.tie, totals.all.dc, totals.all.fsa, totals.all.ssa]; var gamesPieColors = [R300_Selections.Win_Color.value, R300_Selections.Loss_Color.value, R300_Selections.Tie_Color.value, R300_Selections.DC_Color.value, R300_Selections.FSA_Color.value, R300_Selections.SSA_Color.value]; for (i = 0; i < gamesPieData.length; i++) { context.fillStyle = gamesPieColors[i]; context.beginPath(); context.moveTo(canvas.width / 2, canvas.height / 2); context.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, lastend, lastend + (Math.PI * 2 * (gamesPieData[i] / data.length)), false); context.lineTo(canvas.width / 2, canvas.height / 2); context.fill(); lastend += Math.PI * 2 * (gamesPieData[i] / data.length); } //Best Streaks... $('#R300_Messages').append('<div id="R300_BestStreak" style="text-align:center">Best Streaks: <span style="color:' + R300_Selections.Win_Color.value + '">' + totals.streaks.win + ' Win' + (totals.streaks.win == 1 ? '' : 's') + '</span> | <span style="color:' + R300_Selections.Loss_Color.value + '">' + totals.streaks.loss + ' Loss' + (totals.streaks.loss == 1 ? '' : 'es') + '</span></div>'); //Current Streak... if (data[data.length-1].outcome === 1) { $('#R300_Messages').append('<div id="R300_CurrentStreak" style="text-align:center">Current Streak: <span style="color:' + R300_Selections.Win_Color.value + '">' + totals.streaks.last_win + ' Win' + (totals.streaks.last_win == 1 ? '' : 's') + '</span></div>'); } else if ((data[data.length-1].outcome === 2) || (data[data.length-1].outcome === 3)) { $('#R300_Messages').append('<div id="R300_CurrentStreak" style="text-align:center">Current Streak: <span style="color:' + R300_Selections.Loss_Color.value + '">' + totals.streaks.last_loss + ' Loss' + (totals.streaks.last_loss == 1 ? '' : 'es') + '</span></div>'); } //Best Streak Messages... if ( (data[data.length-1].outcome === 1) && (totals.streaks.last_win >= totals.streaks.win) && (data.length > 5) ) { $('#R300_Messages').append('<div id="R300_BestStreakMessage" style="padding:3px 0; text-align:center; border-radius:5px; color:#fff; background-color:' + R300_Selections.Win_Color.value + '">You are currently on your best win streak!!!</div>'); } else if ( (data[data.length-1].outcome === 1) && (totals.streaks.last_win == totals.streaks.win-1) && (data.length > 5) ) { $('#R300_Messages').append('<div id="R300_BestStreakMessage" style="padding:3px 0; text-align:center; border-radius:5px; color:#fff; background-color:' + R300_Selections.Win_Color.value + '">You are just <u>1 win away</u> from your best win streak!</div>'); } //Worst Streak Messages... if ( ((data[data.length-1].outcome === 2) || (data[data.length-1].outcome === 3)) && (totals.streaks.last_loss >= totals.streaks.loss) && (data.length > 5) ) { $('#R300_Messages').append('<div id="R300_WorstStreakMessage" style="padding:3px 0; text-align:center; border-radius:5px; color:#fff; background-color:' + R300_Selections.Loss_Color.value + '">You are currently on your worst losing streak :(</div>'); } else if ( ((data[data.length-1].outcome === 2) || (data[data.length-1].outcome === 3)) && (totals.streaks.last_loss == totals.streaks.loss-1) && (data.length > 5) ) { $('#R300_Messages').append('<div id="R300_WorstStreakMessage" style="padding:3px 0; text-align:center; border-radius:5px; color:#fff; background-color:' + R300_Selections.Loss_Color.value + '">You are only <u>1 loss away</u> from your worst losing streak...</div>'); } //# Games Per Day Bar Graph... var minPlays=100, maxPlays=0, daysWithGamesCount=0; var gamesperday_barwidth = Math.floor(300 / dayCounts.length); if (gamesperday_barwidth < 1) gamesperday_barwidth = 1; if (gamesperday_barwidth > 10) gamesperday_barwidth = 10; $('#R300_Messages').append('<div id="R300_GamesPerDayGraph" style="display:flex; align-items:baseline; width:'+(dayCounts.length*(gamesperday_barwidth+1))+'px; margin:0 auto; border-bottom:1px solid #fff"></div>'); $.each(dayCounts, function(key, value) { i = (value.win+value.loss+value.dc+value.ssa+value.fsa+value.tie); if (i > maxPlays) maxPlays = i; if (i < minPlays) minPlays = i; if (i > 0) daysWithGamesCount++; }); if (R300_Selections.AlwaysShowLastDayPlayed.value) { R300_Selections.MaxR300Games.value = data.length - dayCounts[dayCounts.length-1].firstGameNumber; } var totalTimePlayed = 0; $.each(dayCounts, function(key, value) { i = (value.win+value.loss+value.dc+value.ssa+value.fsa+value.tie); totalTimePlayed += dayCounts[key].timePlayed; $('#R300_GamesPerDayGraph').append('<div class="gamesperday_bar" data-firstgame="'+(data.length-value.firstGameNumber)+'" data-gamecount="'+i+'" style="height:'+scaleBetween(i, (value?5:0), 30, minPlays, maxPlays)+'px; width:'+gamesperday_barwidth+'px" title="'+i+' Games on ' + dayCounts[key].day + " (" + secondsToHMS(dayCounts[key].timePlayed) + " played)\n"+value.win+' Wins, '+ value.loss+' Losses, '+ value.tie +' Ties,'+ value.dc+' DCs, '+ value.ssa+' Saves, '+ value.fsa+' USAs"></div>'); }); GM_addStyle('.gamesperday_bar { margin-left:1px; background:#777 }'); GM_addStyle('.gamesperday_bar:hover { background:#fff }'); //# Games Per Day... $('#R300_Messages').append('<div id="R300_GamesPerDay" style="font-size:11px">' + daysWithGamesCount + ' Game Days (' + (data.length/daysWithGamesCount).toFixed(2) + ' games/day, ' + secondsToHMS(totalTimePlayed/daysWithGamesCount) + ' mins/day)</div>'); //Power Up Stats... $('#R300_MessagesPie').after('<div id="R300_PUPs" style="width:96%; margin:5px auto; padding:1px 0; font-family:monospace; display:flex; flex-wrap:wrap; justify-content:center; align-items:center; font-size:12px; border:1px solid #222; border-radius:3px; cursor:pointer"></div>'); $.each(totals.pups, function(key, value) { var keytitle=''; if (key === 'timePlayed') { keytitle = 'Time'; } else if (key === 'powerups') { keytitle = 'PUPs'; } else if (key === 'captures') { keytitle = 'Caps'; } else { keytitle = capitaliseFirstLetter(key); } if ((key == 'hold') || (key == 'prevent') || (key == 'timePlayed')) { $('#R300_PUPs').append('<div class="R300_pups_pergame" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? '' : 'display:none') + '" title="'+keytitle+' Per Game (click for totals)"><u>'+keytitle+'</u><br>'+secondsToHMS(value / data.length)+'</div>'); $('#R300_PUPs').append('<div class="R300_pups_total" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? 'display:none' : '') + '" title="'+keytitle+' Total (click for per-game)"><u>'+keytitle+'</u><br>'+secondsToHMS(value)+'</div>'); } else { $('#R300_PUPs').append('<div class="R300_pups_pergame" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? '' : 'display:none') + '" title="'+keytitle+' Per Game (click for totals)"><u>'+keytitle+'</u><br>'+(value / data.length).toFixed(2)+'</div>'); if (key == 'powerups') { $('#R300_PUPs').append('<div class="R300_pups_total" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? 'display:none' : '') + '" title="'+keytitle+' Total (click for per-game)"><u>'+keytitle+'</u><br>'+(value / totalPotentialPowerups * 100).toFixed(2)+'%</div>'); } else { $('#R300_PUPs').append('<div class="R300_pups_total" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? 'display:none' : '') + '" title="'+keytitle+' Total (click for per-game)"><u>'+keytitle+'</u><br>'+(value)+'</div>'); } } }); $('#R300_PUPs').append('<div style="margin:0 7px;" title="Caps/Grab"><u>C/G</u><br>'+(totals.pups.captures / totals.pups.grabs).toFixed(3)+'</div>'); $('#R300_PUPs').append('<div style="margin:0 7px;" title="Tags/Pop"><u>T/P</u><br>'+(totals.pups.tags / totals.pups.pops).toFixed(3)+'</div>'); $('#R300_GamesPerDayGraph .gamesperday_bar').on('click', function() { R300_Selections.MaxR300Games.value = $(this).data('firstgame'); GM_setValue('R300_Selections', R300_Selections); setTimelineCellHeights(Cell_Width); showTrimmedData($(this).data('firstgame'), $(this).data('gamecount')); }); $('#R300_Intervals .R300_Interval').on('click', function() { R300_Selections.MaxR300Games.value = $(this).data('firstgame'); GM_setValue('R300_Selections', R300_Selections); setTimelineCellHeights(Cell_Width); $('#R300_Intervals .R300_Interval').css('color', '#777'); $(this).css('color', '#ddd'); showTrimmedData($(this).data('firstgame'), intervalSize); }); $('#R300_Timeline div').on('click', function() { R300_Selections.MaxR300Games.value = $(this).data('gamenumber'); GM_setValue('R300_Selections', R300_Selections); setTimelineCellHeights(Cell_Width); $('#R300_Intervals .R300_Interval').css('color', '#777'); showTrimmedData($(this).data('gamenumber'), $(this).data('gamenumber')); }); $('#R300_PUPs').on('click', function(){ R300_Selections.ShowR300PUPsPerGame.value = !R300_Selections.ShowR300PUPsPerGame.value; GM_setValue('R300_Selections', R300_Selections); $('#ShowR300PUPsPerGame').prop('checked', R300_Selections.ShowR300PUPsPerGame.value); if (R300_Selections.ShowR300PUPsPerGame.value === true) { $('.R300_pups_pergame').show(0); $('.R300_pups_total').hide(0); } else { $('.R300_pups_pergame').hide(0); $('.R300_pups_total').show(0); } }); $('#R300_CTFWP').on('click', function(){ R300_Selections.MaxR300Games.value = 'CTF'; GM_setValue('R300_Selections', R300_Selections); setTimelineCellHeights(Cell_Width); showTrimmedData(0,0); }); $('#R300_NFWP').on('click', function(){ R300_Selections.MaxR300Games.value = 'NF'; GM_setValue('R300_Selections', R300_Selections); setTimelineCellHeights(Cell_Width); showTrimmedData(0,0); }); } /************************************************************************************/ // Mini Timeline... /************************************************************************************/ function showTrimmedData(start, count) { var WinPercentageText; var Timeline_MaxWidth = 390; var Cell_Width = 8; //This value will adjust (smaller) according to MaxGames & Timeline_MaxWidth. Default=8 var ShowGapMarginLeft = 1; var i; var totals = {'all': { win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0 }, 'ctf': { win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0 }, 'nf': { win:0, loss:0, dc:0, ssa:0, fsa:0, tie:0 }, 'pups': { tags:0, pops:0, grabs:0, drops:0, hold:0, captures:0, prevent:0, returns:0, support:0, powerups:0, timePlayed:0 }, 'streaks': { win:0, loss:0, temp_win:0, temp_loss:0, last_win:0, last_loss:0 } }; var data = allGames.slice(0); if (R300_Selections.MaxR300Games.value === 'CTF') { var newData = []; for (var key=0, l=data.length; key<l; key++) { if (data[key].gameMode === 1) newData.push(data[key]); } data = newData.slice(0); start = data.length; count = data.length; WinPercentageText = 'Win % over these <span style="color:' + R300_Selections.Win_Color.value + '">' + data.length + '</span> CTF games:'; } else if (R300_Selections.MaxR300Games.value === 'NF') { var newData = []; for (var key=0, l=data.length; key<l; key++) { if (data[key].gameMode === 2) newData.push(data[key]); } data = newData.slice(0); start = data.length; count = data.length; WinPercentageText = 'Win % over these <span style="color:' + R300_Selections.Win_Color.value + '">' + data.length + '</span> NF games:'; } else { if (!start) start = 0; if (!count) count = data.length; $('#R300_Timeline').find('[data-gamenumber="' + start + '"]').css('height', '+=6'); if (count > 1) $('#R300_Timeline').find('[data-gamenumber="' + (start-count+1) + '"]').css('height', '+=6'); start = data.length-start; data = data.splice(start, count); WinPercentageText = 'Win % over these <span style="color:' + R300_Selections.Win_Color.value + '">' + data.length + '</span> games ' + (start>=0 ? '('+(allGames.length-start-count+1)+'-'+(allGames.length-start)+'): ' : ''); } if (count > 200) ShowGapMarginLeft = 0; var New_Cell_Width = Math.floor((Timeline_MaxWidth - 34) / data.length); if (New_Cell_Width < Cell_Width) Cell_Width = New_Cell_Width - (R300_Selections.ShowR300ShowGap.value ? (count > 200 ? 0 : 1) : 0); if (Cell_Width <= 0) Cell_Width = 1; $('#R300T_Timeline').empty(); $('#R300T_Messages').empty(); $('#R300T_PUPs').remove(); var totalPotentialPowerups = 0; $(data).each(function(key, value) { totalPotentialPowerups += value.potentialPowerups; $.each(totals.pups, function(key1, value1) { totals.pups[key1] += value[key1]; }); switch (value.outcome) { case 1: //win if (value.saved === 2) { totals.all.ssa++; if (value.gameMode === 1) { totals.ctf.ssa++; } else if (value.gameMode === 2) { totals.nf.ssa++; } $('#R300T_Timeline').append('<div class="r300t_ssa" title="' + getGameInfoAsText(value) + '"></div>'); } else { totals.all.win++; if (value.gameMode === 1) { totals.ctf.win++; } else if (value.gameMode === 2) { totals.nf.win++; } $('#R300T_Timeline').append('<div class="r300t_win" title="' + getGameInfoAsText(value) + '"></div>'); } //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_win === 0) || ((i > 0) && ((data[i-1].outcome === 1)) ) ) totals.streaks.temp_win++; if (totals.streaks.temp_win > totals.streaks.win) totals.streaks.win = totals.streaks.temp_win; totals.streaks.temp_loss = 0; if (totals.streaks.temp_win > 0) totals.streaks.last_win = totals.streaks.temp_win; break; case 2: //loss totals.all.loss++; if (value.gameMode === 1) { totals.ctf.loss++; } else if (value.gameMode === 2) { totals.nf.loss++; } $('#R300T_Timeline').append('<div class="r300t_loss" title="' + getGameInfoAsText(value) + '"></div>'); //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_loss === 0) || ((i > 0) && ((data[i-1].outcome === 2) || (data[i-1].outcome === 3) || (data[i-1].outcome === 5)) ) ) totals.streaks.temp_loss++; if (totals.streaks.temp_loss > totals.streaks.loss) totals.streaks.loss = totals.streaks.temp_loss; totals.streaks.temp_win = 0; if (totals.streaks.temp_loss > 0) totals.streaks.last_loss = totals.streaks.temp_loss; break; case 3: //dc totals.all.dc++; if (value.gameMode === 1) { totals.ctf.dc++; } else if (value.gameMode === 2) { totals.nf.dc++; } $('#R300T_Timeline').append('<div class="r300t_dc" title="' + getGameInfoAsText(value) + '"></div>'); //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_loss === 0) || ((i > 0) && ((data[i-1].outcome === 2) || (data[i-1].outcome === 3) || (data[i-1].outcome === 5)) ) ) totals.streaks.temp_loss++; if (totals.streaks.temp_loss > totals.streaks.loss) totals.streaks.loss = totals.streaks.temp_loss; totals.streaks.temp_win = 0; if (totals.streaks.temp_loss > 0) totals.streaks.last_loss = totals.streaks.temp_loss; break; case 4: //save attempt if (value.saved === 1) { //failed save attempt... totals.all.fsa++; if (value.gameMode === 1) { totals.ctf.fsa++; } else if (value.gameMode === 2) { totals.nf.fsa++; } $('#R300T_Timeline').append('<div class="r300t_fsa" title="' + getGameInfoAsText(value) + '"></div>'); } break; case 5: //tie totals.all.tie++; if (value.gameMode === 1) { totals.ctf.tie++; } else if (value.gameMode === 2) { totals.nf.tie++; } $('#R300T_Timeline').append('<div class="r300t_tie" data-gamenumber="' + (data.length-key) + '" title="' + getGameInfoAsText(value) + '"></div>'); //streak... i=key; while ( (i > 0) && ((data[i-1].outcome === 4)&&(data[i-1].saved === 1)) ) { //unsuccessful saves shouldn't break a streak! i--; } if ( (totals.streaks.temp_loss === 0) || ((i > 0) && ((data[i-1].outcome === 2) || (data[i-1].outcome === 3) || (data[i-1].outcome === 5)) ) ) totals.streaks.temp_loss++; if (totals.streaks.temp_loss > totals.streaks.loss) totals.streaks.loss = totals.streaks.temp_loss; totals.streaks.temp_win = 0; if (totals.streaks.temp_loss > 0) totals.streaks.last_loss = totals.streaks.temp_loss; break; default: //just in case! $('#R300T_Timeline').append('<div class="r300t_unknown" data-gamenumber="' + (data.length-key) + '" title="Unknown Result"></div>'); break; } }); $('.r300t_win').css ({ 'display':'inline-block', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.Win_Color.value, 'height':'6px', 'width':Cell_Width+'px' }); $('.r300t_loss').css ({ 'display':'inline-block', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.Loss_Color.value, 'height':'6px', 'width':Cell_Width+'px' }); $('.r300t_dc').css ({ 'display':'inline-block', 'margin' :'0px 0px 1px '+(R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.DC_Color.value, 'height':'4px', 'width':Cell_Width+'px' }); $('.r300t_ssa').css ({ 'display':'inline-block', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.SSA_Color.value, 'height':'4px', 'width':Cell_Width+'px', 'border-top' :'2px solid white' }); $('.r300t_fsa').css ({ 'display':'inline-block', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.FSA_Color.value, 'height':'4px', 'width':Cell_Width+'px', 'border-bottom':'2px solid white' }); $('.r300t_tie').css ({ 'display':'inline-block', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.Tie_Color.value, 'height':'6px', 'width':Cell_Width+'px' }); $('.r300t_unknown').css ({ 'display':'inline-block', 'margin-left': (R300_Selections.ShowR300ShowGap.value ? ShowGapMarginLeft : 0)+'px', 'background-color':R300_Selections.Unknown_Color.value, 'height':'6px', 'width':Cell_Width+'px' }); //Win %... var currentWinPC = ((totals.all.win+totals.all.ssa) / (totals.all.win+totals.all.ssa + totals.all.loss+totals.all.dc+totals.all.tie) * 100).toFixed(2); $('#R300T_Messages').append('<div id="R300T_Wins">' + WinPercentageText + ' <span style="color:'+R300_Selections.Win_Color.value+'">' + currentWinPC + '%</span></div>'); //Games Count... $('#R300T_Messages').append('<div id="R300T_Count">(<span style="color:'+R300_Selections.Win_Color.value+'" title="Includes Successful Save Attempts">' + (totals.all.win+totals.all.ssa) + ' Win'+((totals.all.win+totals.all.ssa)==1?'':'s')+'</span> | <span style="color:'+R300_Selections.Loss_Color.value+'" title="Does NOT include DC\'s">'+ (totals.all.loss) + ' Loss'+(totals.all.loss==1?'':'es')+'</span> | <span style="color:'+R300_Selections.Tie_Color.value+'" title="Included in Losses">'+ (totals.all.tie) + ' Tie'+(totals.all.tie==1?'':'s')+'</span> | <span style="color:'+R300_Selections.DC_Color.value+'" title="DC\'s are counted as a Loss">' + totals.all.dc + ' DC'+(totals.all.dc==1?'':'s')+'</span> | <span style="color:'+R300_Selections.SSA_Color.value+'" title="Included in Wins">' + totals.all.ssa + ' Save'+(totals.all.ssa==1?'':'s')+'</span> | <span style="color:'+R300_Selections.FSA_Color.value+'" title="Unsuccessful Save Attempts do NOT count as a Loss (or a Win)">' + totals.all.fsa + ' USA'+(totals.all.fsa==1?'':'s')+'</span>)</div>'); //CTF / NF... var totalCTF = (totals.ctf.win+totals.ctf.ssa + totals.ctf.loss+totals.ctf.dc+totals.ctf.tie); var CTFWinPC = (totalCTF === 0) ? 0 : ((totals.ctf.win+totals.ctf.ssa) / totalCTF * 100).toFixed(2); var totalNF = (totals.nf.win+totals.nf.ssa + totals.nf.loss+totals.nf.dc+totals.nf.tie); var NFWinPC = (totalNF === 0) ? 0 : ((totals.nf.win+totals.nf.ssa) / totalNF * 100).toFixed(2); $('#R300T_Messages').append('<div id="R300T_CTFNF"><span style="color:#9264DA">CTF: ' + CTFWinPC + '% ('+(totalCTF+totals.ctf.fsa)+')</span> | <span style="color:#9264DA">NF: ' + NFWinPC + '% ('+(totalNF+totals.nf.fsa)+')</span></div>'); //Best Streaks... $('#R300T_Messages').append('<div id="R300T_BestStreak" style="text-align:center">Best Streaks: <span style="color:' + R300_Selections.Win_Color.value + '">' + totals.streaks.win + ' Win' + (totals.streaks.win == 1 ? '' : 's') + '</span> | <span style="color:' + R300_Selections.Loss_Color.value + '">' + totals.streaks.loss + ' Loss' + (totals.streaks.loss == 1 ? '' : 'es') + '</span></div>'); //Games Mini Pie Chart... if (R300_Selections.ShowR300TrimmedGamesPieChart.value) { $('#R300T_Messages').append('<div id="R300T_Pie"></div>'); $('#R300T_Pie').append('<canvas id="gamesPieChartTrimmed" width="50" height="50" />'); var canvas = document.getElementById("gamesPieChartTrimmed"); var context = canvas.getContext("2d"); var lastend = 1.5*Math.PI; var gamesPieData = [totals.all.win, totals.all.loss, totals.all.tie, totals.all.dc, totals.all.fsa, totals.all.ssa]; var gamesPieColors = [R300_Selections.Win_Color.value, R300_Selections.Loss_Color.value, R300_Selections.Tie_Color.value, R300_Selections.DC_Color.value, R300_Selections.FSA_Color.value, R300_Selections.SSA_Color.value]; for (i = 0; i < gamesPieData.length; i++) { context.fillStyle = gamesPieColors[i]; context.beginPath(); context.moveTo(canvas.width / 2, canvas.height / 2); context.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, lastend, lastend + (Math.PI * 2 * (gamesPieData[i] / data.length)), false); context.lineTo(canvas.width / 2, canvas.height / 2); context.fill(); lastend += Math.PI * 2 * (gamesPieData[i] / data.length); } } //Power Up Stats... if (R300_Selections.ShowR300TrimmedPUPs.value) { $('#R300T_Messages').append('<div id="R300T_PUPs" style="max-width:300px; margin:5px auto; display:flex; flex-wrap:wrap; justify-content:center; align-items:center; font-family:monospace; font-size:11px; border:1px solid #222; border-radius:3px; cursor:pointer"></div>'); $.each(totals.pups, function(key, value) { var keytitle=''; if (key === 'timePlayed') { keytitle = 'Time'; } else if (key === 'powerups') { keytitle = 'PUPs'; } else if (key === 'captures') { keytitle = 'Caps'; } else { keytitle = capitaliseFirstLetter(key); } if ((key == 'hold') || (key == 'prevent') || (key == 'timePlayed')) { $('#R300T_PUPs').append('<div class="R300_pups_pergame" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? '' : 'display:none') + '" title="'+keytitle+' Per Game (click for totals)"><u>'+keytitle+'</u><br>'+secondsToHMS(value / data.length)+'</div>'); $('#R300T_PUPs').append('<div class="R300_pups_total" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? 'display:none' : '') + '" title="'+keytitle+' Total (click for per-game)"><u>'+keytitle+'</u><br>'+secondsToHMS(value)+'</div>'); } else { $('#R300T_PUPs').append('<div class="R300_pups_pergame" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? '' : 'display:none') + '" title="'+keytitle+' Per Game (click for totals)"><u>'+keytitle+'</u><br>'+(value / data.length).toFixed(2)+'</div>'); if (key == 'powerups') { $('#R300T_PUPs').append('<div class="R300_pups_total" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? 'display:none' : '') + '" title="'+keytitle+' Total (click for per-game)"><u>'+keytitle+'</u><br>'+(value / totalPotentialPowerups * 100).toFixed(2)+'%</div>'); } else { $('#R300T_PUPs').append('<div class="R300_pups_total" style="margin:0 7px;' + (R300_Selections.ShowR300PUPsPerGame.value ? 'display:none' : '') + '" title="'+keytitle+' Total (click for per-game)"><u>'+keytitle+'</u><br>'+(value)+'</div>'); } } }); $('#R300T_PUPs').append('<div style="margin:0 7px;" title="Caps/Grab"><u>C/G</u><br>'+(totals.pups.captures / totals.pups.grabs).toFixed(3)+'</div>'); $('#R300T_PUPs').append('<div style="margin:0 7px;" title="Tags/Pop"><u>T/P</u><br>'+(totals.pups.tags / totals.pups.pops).toFixed(3)+'</div>'); $('#R300T_PUPs').on('click', function(){ R300_Selections.ShowR300PUPsPerGame.value = !R300_Selections.ShowR300PUPsPerGame.value; GM_setValue('R300_Selections', R300_Selections); $('#ShowR300PUPsPerGame').prop('checked', R300_Selections.ShowR300PUPsPerGame.value); if (R300_Selections.ShowR300PUPsPerGame.value === true) { $('.R300_pups_pergame').show(0); $('.R300_pups_total').hide(0); } else { $('.R300_pups_pergame').hide(0); $('.R300_pups_total').show(0); } }); } } tagpro.ready(function() { if (PageLoc === 'ingame') { //in a game var serverRequests = GM_getValue('serverRequests', []); tagpro.socket.on('settings', function(data) { if (tagpro.settings.stats === false) { $('.R300_Stats_Dependent').css('text-decoration', 'line-through').css('text-shadow', 'none'); $('.R300_Stats_Dependent').attr('title', 'Stats are OFF'); } }); tagpro.socket.on('end', function(data) { if (!tagpro.spectator && tagpro.settings.stats && GM_getValue('R300_Selections').R300SavedGames.display) { //.display holds our profile id setTimeout(function() { var nowSeconds = Date.now(); $.getJSON("http://"+tagpro.serverHost+"/profile_rolling/" + GM_getValue('R300_Selections').R300SavedGames.display) .done(function(gamesdata) { R300_Selections.R300SavedGames.value = gamesdata.reverse(); GM_setValue('R300_Selections', R300_Selections); serverRequests.push(nowSeconds); if (serverRequests.length > 5) serverRequests.shift(); GM_setValue('serverRequests', serverRequests); }) .fail(function(gamesdata) { console.log('R300: FAILED to get server data for profile: '+R300_Selections.R300SavedGames.display); //$('body').prepend('<div style="width:60%; margin:0 auto; background:#b0b; color:#fff; border-radius:3px">Could not get timeline data from server. Will try again next game...</div>'); R300_Selections.R300SavedGames.value.push({outcome:999, saved:999}); //push an unknown outcome onto our saved data if (R300_Selections.R300SavedGames.value.length > 300) R300_Selections.R300SavedGames.value.shift(); GM_setValue('R300_Selections', R300_Selections); }); }, 3000); } }); } }); //Get things ready and start the script... R300_Selections = $.extend(true, {}, options, GM_getValue('R300_Selections', options)); $.each(R300_Selections, function(key, value) { R300_Selections[key].type = options[key].type; if (key !== 'R300SavedGames') { R300_Selections[key].display = options[key].display; if ((key !== 'R300MainPages') && (key !== 'R300HeaderPages')) { R300_Selections[key].title = options[key].title; } } }); if (GM_getValue('R300_Selections') === 'undefined') { //first time GM_setValue('R300_Selections', R300_Selections); } //Setup the main div location depending on which page we are on... var R300_Div = '<div id="R300" style="position:relative; margin:20px auto 0 auto; padding:10px; width:-webkit-fit-content; color:#fff; text-align:center; text-shadow:2px 1px 2px #000000; border-radius:8px; ' + (R300_Selections.ShowBoxShadowBorder.value ? 'box-shadow:#fff 0px 0px 10px; ' : '') + 'background:rgba(0,0,0,0.1); white-space:nowrap;">' + '<div style="display:inline-block">Rolling 300 Timeline</div>' + '<div id="R300_Settings_Button" style="display:inline-block; font-size:11px; text-align:center; margin-left:10px; height:13px; width:14px; border:2px solid #3A8CBB; border-radius:8px; cursor:pointer" title="Options">⁞</div>' + '</div>'; if (PageLoc === 'server') { //Chosen server page $('#play').parent().next().after(R300_Div); if (R300_Selections.R300MainPages.title.indexOf('Home') >= 0) $('#R300').append('<div id="R300_loading" style="margin:20px; font-size:18px; color:#ff0">Getting Data...<div style="background:#000000 url(\'http://i.imgur.com/WKZPcQA.gif\') no-repeat center; margin-top:10px; opacity:0.7; height:64px; width:100%;"></div></div>'); } else if (PageLoc === 'profile') { //Profile page $('h1').parent('a').after(R300_Div); } else if (PageLoc === 'profileNotOurs') { //Someone else's profile page $('h1').parent('a').after(R300_Div); } else if (PageLoc === 'joining') { //Joining page $('#message').after(R300_Div); } if ($('#R300').length) { $('#R300').append('<div id="R300_InnerContainer" style="display:none"></div>'); $('#R300_InnerContainer').append('<div id="R300_Intervals"></div>'); $('#R300_InnerContainer').append('<div id="R300_Timeline"></div>'); $('#R300_InnerContainer').append('<div id="R300_MessagesPie" style="display:flex; align-items:center; justify-content:center; font-size:12px"></div>'); $('#R300_MessagesPie').append('<div id="R300_Messages" style="flex:0 0 auto; align-self:flex-start;"></div>'); $('#R300_MessagesPie').append('<div id="R300_Trimmed" style="display:none; flex:0 0 auto; margin:0 0 0 20px; padding:4px; border:1px solid #aaa; border-radius:3px; font-size:11px"></div>'); $('#R300_Trimmed').append('<div id="R300T_Timeline" style="padding:0"></div>'); $('#R300_Trimmed').append('<div id="R300T_Messages"></div>'); } loadData();