Last active
October 26, 2024 01:18
-
-
Save nabbynz/bc5edeae66f0a6d6b0a21cc0d9ab78fc to your computer and use it in GitHub Desktop.
Scoreboard Enhancer BASIC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Scoreboard Enhancer BASIC | |
// @version 0.5.8 | |
// @description A cleaner Scoreboard. Shows: Maximums, Team Stats, Old Scoreboard Position, Custom Weighted Scoreboard Position, Flaccids, Handoffs, K/D, G/C, Comeback!, OT Respawn in Replays. Quitters. | |
// @match https://tagpro.koalabeast.com/game | |
// @match https://tagpro.koalabeast.com/game?* | |
// @updateURL https://gist.github.com/nabbynz/bc5edeae66f0a6d6b0a21cc0d9ab78fc/raw/Scoreboard_Enhancer_BASIC.user.js | |
// @downloadURL https://gist.github.com/nabbynz/bc5edeae66f0a6d6b0a21cc0d9ab78fc/raw/Scoreboard_Enhancer_BASIC.user.js | |
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html | |
// @grant GM_addStyle | |
// @author nabby | |
// ==/UserScript== | |
'use strict'; | |
console.log('START: ' + GM_info.script.name + ' (v' + GM_info.script.version + ' by ' + GM_info.script.author + ')'); | |
/* eslint-env jquery */ | |
/* globals tagpro, tagproConfig */ | |
/* eslint-disable no-multi-spaces */ | |
//---------- Options ---------- | |
const SHOW_OLD_SCORE_POSITION = true; // show the *position* you would have been on the old pre-IPM scoreboard (S1) | |
const SHOW_OLD_SCORE_AS_VALUE = false; // instead of position, show the *points* you would have received on the old pre-IPM scoreboard | |
const SHOW_CUSTOM_SCORE_POSITION = false; // show the *position* you would have been on the custom weighted scoreboard (edit the `customWeight` values around line 181) (S2) | |
const SHOW_CUSTOM_SCORE_AS_VALUE = false; // instead of position, show the *points* you would have received on the custom weighted scoreboard | |
const SHOW_TOTAL_IPM = true; // show the T-IPM Score (NISH) | |
const SHOW_O_IPM = true; // show the O-IPM Score (NISH) | |
const SHOW_D_IPM = true; // show the D-IPM Score (NISH) | |
const STANDARDIZE_IPM_SCORES_TO_100 = true; // so the top player for "Score | O | D" always gets 100 | |
const SHOW_FLACCIDS = true; // CTF Only. When you grab and drop the flag within 2 seconds. | |
const SHOW_HANDOFFS = false; // CTF Handoff: When a teammate grabs within 2 seconds of a flaccid. NF Handoff: When the flag is quickly transferred to an enemy, and then to a teammate for cap within 2 seconds | |
const SHOW_GOOD_HANDOFFS = false; // CTF Good-Handoff: When a teammate grabs within 2 seconds of a flaccid AND they escape the prevent radius. NF Good-Handoff: When the flag is quickly transferred to an enemy, and then to a teammate for cap within 2 seconds (same as Handoff in NF?) | |
const SHOW_KD = true; // show the K/D (Tags/Pops) | |
const SHOW_GC = true; // show the G/C (Grabs/Caps) | |
const SHOW_OT_RESPAWN_TIMES = true; // show the Overtime Respawn Times (Replays only) | |
const SHOW_TIME_PLAYED_AS_PERCENTAGE = true; // show Active Time Played as a % of Time Played (Replays only) | |
//--------------------------- | |
//---------- Colors & Styles ---------- | |
const MAX_HIGHLIGHT_RED_COLOR = '#a13636'; | |
const MAX_HIGHLIGHT_BLUE_COLOR = '#194773'; | |
const SCORE_BACKGROUND_COLOR = 'rgba(0, 0, 0, 0.2)'; // use `revert` for none (yellow: 'rgba(185, 185, 23, 0.25)') | |
const O_BACKGROUND_COLOR = 'revert'; // use `revert` for none (red: 'rgba(240, 35, 61, 0.25)') | |
const D_BACKGROUND_COLOR = 'revert'; // use `revert` for none (blue: 'rgba(64, 116, 219, 0.25)') | |
const CAPS_BACKGROUND_COLOR = 'rgba(0, 0, 0, 0.2)'; // use `false` or `revert` for none | |
$('#options').css({ 'border':'2px outset #8bc34a', 'border-radius':'8px', 'box-shadow':'-10px 5px 20px black, 10px 5px 20px black' }); | |
$('#stats thead').find('th:contains("Popped")').text('Pops'); | |
$('#stats thead').find('th:contains("Captures")').text('Caps'); | |
$('#stats thead').find('th:contains("Power-ups")').text('PUPs'); | |
//------------------------------------ | |
/***** CHECK FOR EVENT - START *****/ | |
let isEvent = false; | |
let isHalloween = false; | |
let isBirthday = false; | |
let isEaster = false; | |
let isEgg = false; | |
let isHockey = false; | |
let isChristmas = false; | |
let isRacing = false; | |
let isAprilFools = false; | |
let isEggEvent; | |
let checkForEvent = function() { | |
let scriptSrcs = []; | |
if (tagproConfig.replay) { | |
let packets = tagpro.replayData.packets; | |
if (!Array.isArray(packets)) { | |
packets = packets.split('\n'); | |
} | |
for (let i = 0; i < packets.length; i++) { | |
const packet = Array.isArray(packets[i]) ? packets[i] : JSON.parse(packets[i]); | |
if (packet[1] === 'clientInfo' && packet[2].hasOwnProperty('eventScripts') && packet[2].eventScripts.length) { | |
scriptSrcs = packet[2].eventScripts; | |
break; | |
} | |
} | |
} | |
let scripts = $('script[src]').toArray(); | |
scripts.forEach(script => { | |
scriptSrcs.push(script.src); | |
}) | |
if (scriptSrcs) { | |
let scriptNames = ['halloween', 'birthday', 'easter', 'egg', 'hockey', 'pirates', 'christmas', 'racing']; // disable for certain events | |
for (let scriptName of scriptNames) { | |
if (scriptSrcs.some(e => e.includes(scriptName))) { //eg: https://static.koalabeast.com/events/easter-2017.js | |
isEvent = true; | |
if (scriptName === 'halloween') isHalloween = true; | |
if (scriptName === 'birthday' || scriptName === 'pirates') isBirthday = true; | |
if (scriptName === 'easter') isEaster = true; | |
if (scriptName === 'egg') isEgg = true; | |
if (scriptName === 'hockey') isHockey = true; | |
if (scriptName === 'christmas') isChristmas = true; | |
if (scriptName === 'racing') isRacing = true; | |
break; | |
} | |
} | |
} | |
isEggEvent = isEaster || isEgg || isHockey; | |
isAprilFools = !!document.querySelector('#redspecial'); // to detect the April Fools Event triangle & square ball shapes | |
console.log(GM_info.script.name + ':: checkForEvent() isEvent:'+isEvent, 'isHalloween:'+isHalloween, 'isBirthday:'+isBirthday, 'isEaster:'+isEaster, 'isEgg:'+isEgg, 'isHockey:'+isHockey, 'isChristmas:'+isChristmas, 'isRacing:'+isRacing, 'isAprilFools:'+isAprilFools, 'isEggEvent:'+isEggEvent); | |
}; | |
/***** CHECK FOR EVENT - END *****/ | |
tagpro.ready(function() { | |
checkForEvent(); | |
if (isEvent) { | |
// return; | |
} | |
let cats = $('#stats').children().eq(0).find('th'); //grab column headers | |
let order = ['name', 'score', 'oscore', 'dscore', 's-tags', 's-pops', 's-grabs', 's-drops', 's-hold', 's-captures', 's-prevent', 's-returns', 's-support', 's-powerups']; // , 'points', 'playTime' | |
let sorted = []; | |
for (let i = 0; i < cats.length; i++) { //setup column names and ids | |
let col = cats.eq(i); | |
col.attr('id', i); | |
if (!col.attr('name')) col.attr('name', order[i]); | |
} | |
tagpro.events.register({ | |
sortPlayers: function(players) { | |
sorted = $.extend([], players); | |
}, | |
modifyScoreUI: function() { | |
let current; | |
let max = []; | |
//find the maximum values in each column... | |
for (let i = 0; i < sorted.length; i++) { // player | |
for (let j = 0; j < cats.length - 4; j++) { // for each element that can be highlighted (skip: Rank Pts, Active, Report) | |
if (!max[j]) { | |
max[j] = [i]; | |
} else { | |
if (sorted[i][cats.eq(j + 1).attr('name')] > sorted[max[j][0]][cats.eq(j + 1).attr('name')]) { | |
max[j] = [i]; | |
} else if (sorted[i][cats.eq(j + 1).attr('name')] === sorted[max[j][0]][cats.eq(j + 1).attr('name')]) { | |
max[j].push(i); | |
} | |
} | |
} | |
} | |
// highlight the matching cell/s in each column... | |
for (let i = 0; i < max.length; i++) { | |
if (max[i].length !== sorted.length) { // don't highlight if everyone has max value | |
current = $('.template').next(); | |
for (let j = 0; j < sorted.length; j++) { | |
if (max[i].indexOf(j) > -1) { | |
current.children().eq(i + 1).css('background-color', sorted[j].team === 1 ? MAX_HIGHLIGHT_RED_COLOR : MAX_HIGHLIGHT_BLUE_COLOR); | |
} else { | |
current.children().eq(i + 1).css('background-color', 'revert-layer'); | |
} | |
current = current.next(); | |
} | |
} | |
} | |
// highlight the row we are positioned at... | |
current = $('.template').next(); | |
for (let i = 0; i < sorted.length; i++) { | |
if (sorted[i].id === tagpro.playerId) { | |
current.children().eq(0).css('border-left', '1px solid white'); | |
current.children().last().css('border-right', '1px solid white'); | |
} else { | |
current.children().eq(0).css('border-left', 'none'); | |
current.children().last().css('border-right', 'none'); | |
} | |
current = current.next(); | |
} | |
} | |
}); | |
let getDataFromReplay = function(packets, players, quitters) { | |
if (!Array.isArray(packets)) { | |
packets = packets.split('\n'); | |
} | |
for (let i = 0; i < packets.length; i++) { | |
const packet = Array.isArray(packets[i]) ? packets[i] : JSON.parse(packets[i]); | |
if (packet[1] === 'p') { | |
const arr = packet[2]; | |
for (let j = 0; j < arr.length; j++) { | |
const obj = arr[j]; | |
if (quitters[obj.id]) { | |
quitters[obj.id] = Object.assign(quitters[obj.id], obj); | |
} | |
} | |
} else if (packet[1] === 'chat') { | |
if (packet[2].from === null && packet[2].to == packet[2].for && packet[2].c !== '#63FE22') { // tips | |
let message = String(packet[2].message); | |
if (message.includes('During overtime, each death increases time to respawn. Currently:')) { | |
players[packet[2].for].otspawn = +message.slice(message.lastIndexOf(':') + 2); | |
} | |
} | |
} | |
} | |
}; | |
let createScoreboardData = function(players) { | |
let data = []; | |
let totals = { | |
// `weight` is the old pre-NISH scoreboard weightings (S1) | |
// `customWeight` can be used to compare different weighting values (change the values to see how it would affect the S2 scoreboard positions) | |
tags: { value:0, weight: 50, customWeight: 40 }, // 40 | |
pops: { value:0, weight:-50, customWeight:-25 }, // -25 | |
grabs: { value:0, weight: 50, customWeight: 0 }, // 0 | |
drops: { value:0, weight:-50, customWeight: 0 }, // 0 | |
hold: { value:0, weight: 50, customWeight: 45 }, // 45 | |
captures: { value:0, weight: 50, customWeight: 30 }, // 30 | |
prevent: { value:0, weight: 50, customWeight: 25 }, // 25 | |
returns: { value:0, weight: 50, customWeight: 40 }, // 40 | |
support: { value:0, weight: 50, customWeight: 10 }, // 10 | |
powerups: { value:0, weight: 50, customWeight: 0 }, // 0 | |
}; | |
let totalWeight = 0; | |
let totalCustomWeight = 0; | |
let doOnce = false; | |
let isNish = false; // for old scoreboards in replays | |
let hasFlaccids = false; | |
let quitters = {}; | |
for (let playerId in players) { | |
for (let stat in totals) { | |
totals[stat].value += players[playerId]['s-' + stat]; | |
if (!doOnce) { | |
totalWeight += totals[stat].weight; | |
totalCustomWeight += totals[stat].customWeight; | |
} | |
} | |
if (!doOnce) { | |
if (players[playerId].hasOwnProperty('oscore')) { | |
isNish = true; | |
} | |
if (players[playerId].hasOwnProperty('s-flaccids')) { | |
hasFlaccids = true; | |
} | |
doOnce = true; | |
} | |
} | |
if (tagproConfig.replay && tagpro.replayData && tagpro.replayData.packets[0][1] === 'recorder-metadata') { | |
let metadata = tagpro.replayData.packets[0][2]; | |
let actualGameStarted = metadata.started; | |
let actualGameDuration = metadata.duration; | |
let gameFinish = metadata.started + metadata.duration; | |
for (let i in metadata.players) { | |
if (metadata.players[i].finished) { | |
players[metadata.players[i].id].timePlayed = gameFinish - Math.max(metadata.players[i].joined, actualGameStarted); | |
players[metadata.players[i].id].timePlayedPC = players[metadata.players[i].id].timePlayed / actualGameDuration; | |
} else { | |
if (!quitters.hasOwnProperty([metadata.players[i].id])) { | |
quitters[metadata.players[i].id] = { userId: metadata.players[i].userId }; // displayName: metadata.players[i].displayName, userId: metadata.players[i].userId, joinedGame: metadata.players[i].joined, leftGame: metadata.players[i].left, team: metadata.players[i].team | |
} | |
} | |
} | |
getDataFromReplay(tagpro.replayData.packets, players, quitters); | |
} | |
for (let playerId in players) { | |
let thisData = { | |
id: playerId, | |
name: players[playerId].name, | |
team: players[playerId].team, | |
auth: players[playerId].auth, | |
tags: players[playerId]['s-tags'], | |
pops: players[playerId]['s-pops'], | |
grabs: players[playerId]['s-grabs'], | |
drops: players[playerId]['s-drops'], | |
hold: players[playerId]['s-hold'], | |
captures: players[playerId]['s-captures'], | |
prevent: players[playerId]['s-prevent'], | |
returns: players[playerId]['s-returns'], | |
support: players[playerId]['s-support'], | |
powerups: players[playerId]['s-powerups'], | |
flaccids: players[playerId]['s-flaccids'], | |
handoffs: players[playerId]['s-handoffs'], // assists | |
goodHandoffs: players[playerId]['s-goodHandoffs'], | |
oldScore: 0, | |
oldPos: '', | |
customScore: 0, | |
customPos: '', | |
score: +players[playerId].score, | |
oscore: +players[playerId].oscore, | |
dscore: +players[playerId].dscore, | |
points: players[playerId].points, | |
otspawn: players[playerId].otspawn || 0, | |
timePlayed: players[playerId].timePlayed || 0, | |
timePlayedPC: players[playerId].timePlayedPC || 0, | |
}; | |
for (let stat in totals) { | |
thisData.oldScore += players[playerId]['s-' + stat] / (totals[stat].value || 1) * totals[stat].weight * 300 / totalWeight; | |
thisData.customScore += players[playerId]['s-' + stat] / (totals[stat].value || 1) * totals[stat].customWeight * 300 / totalCustomWeight; | |
} | |
data.push(thisData); | |
} | |
data.sort(function(a, b) { | |
return (b.oldScore - a.oldScore ? b.oldScore - a.oldScore : a.id - b.id); | |
}); | |
for (let i = 0; i < data.length; i++) { | |
data[i].oldPos = i + 1; | |
} | |
data.sort(function(a, b) { | |
return (b.customScore - a.customScore ? b.customScore - a.customScore : a.id - b.id); | |
}); | |
for (let i = 0; i < data.length; i++) { | |
data[i].customPos = i + 1; | |
} | |
data.sort(function(a, b) { | |
return (b.score - a.score ? b.score - a.score : a.id - b.id); | |
}); | |
return { data:data, isNish:isNish, hasFlaccids:hasFlaccids, quitters: quitters }; | |
}; | |
let addSortability = function() { | |
$('#stats thead tr th').on('click', function() { | |
const dataset = this.dataset.column; | |
if (!dataset || dataset === 'player') { | |
return; | |
} | |
const index = this.cellIndex; | |
let sortasc = false; | |
if (!this.dataset.sortasc || this.dataset.sortasc === 'false') { | |
this.dataset.sortasc = 'true'; | |
sortasc = true; | |
} else { | |
this.dataset.sortasc = 'false'; | |
sortasc = false; | |
} | |
$('#stats tbody tr.SBEB_Sortable').sort(function(a, b) { | |
if (sortasc) { | |
return a.children[index].innerText.localeCompare(b.children[index].innerText, 'en', { numeric: true} ); | |
} else { | |
return b.children[index].innerText.localeCompare(a.children[index].innerText, 'en', { numeric: true} ); | |
} | |
}).prependTo( $('#stats tbody') ); | |
$('#stats thead tr th').css({ 'text-decoration': 'none' }); | |
$(this).css({ 'text-decoration': 'underline' }); | |
}); | |
}; | |
let getColumnIndex = function(columnHeading) { | |
const lastColumn = $('#stats thead tr th').last().index(); | |
for (let i = 0; i <= lastColumn; i++) { | |
const thisColumnHeading = $('#stats thead tr th:nth-child(' + i + ')').text().trim(); | |
if (thisColumnHeading === columnHeading) { | |
return i; | |
break; | |
} | |
} | |
return -1; | |
}; | |
let addQuitters = function(quitters) { | |
$('#stats').after('<div id="SBEB_ShowQuitters" style="text-align:right; font-size:12px; color:#dd5e13; margin:-5px 10px 0 0; cursor:pointer;">Show Quitters [' + Object.keys(quitters).length + ']</div>'); | |
$('#SBEB_ShowQuitters').on('click', function() { | |
$('#SBEB_ShowQuitters').remove(); | |
let ths = '<th>Quitter</th>'; | |
let trs = ''; | |
let columnsToShow = { // we're just going to show these columns (if they are visible on the main scoreboard)... | |
tags: { title: 'Tags', stat: 's-tags' }, | |
pops: { title: 'Pops', stat: 's-pops' }, | |
grabs: { title: 'Grabs', stat: 's-grabs' }, | |
drops: { title: 'Drops', stat: 's-drops' }, | |
hold: { title: 'Hold', stat: 's-hold' }, | |
captures: { title: 'Caps', stat: 's-captures' }, | |
prevent: { title: 'Prevent', stat: 's-prevent' }, | |
returns: { title: 'Returns', stat: 's-returns' }, | |
support: { title: 'Support', stat: 's-support' }, | |
powerups: { title: 'PUPs', stat: 's-powerups' }, | |
active: { title: 'Active', stat: 'playTime' } | |
}; | |
for (let column in columnsToShow) { | |
if ($('#stats thead th[data-column="' + column + '"]').is(':visible')) { | |
columnsToShow[column].visible = true; | |
ths += '<th>' + columnsToShow[column].title + '</th>'; | |
} | |
} | |
for (let quitter in quitters) { | |
let tds = '<td class="scoreName' + (quitters[quitter].team === 1 ? ' team-red' : quitters[quitter].team === 2 ? ' team-blue' : '') + '">' + (quitters[quitter].auth ? '<span class="scoreAuth">✓ </span>' : '') + (quitters[quitter].userId ? '<a href="/profile/' + quitters[quitter].userId + '" target="_blank" style="color:inherit;" title="View Profile (New Tab)">' + quitters[quitter].name + '</a>' : quitters[quitter].name) + '</td>'; | |
for (let column in columnsToShow) { | |
if (columnsToShow[column].visible) { | |
tds += '<td>' + (quitters[quitter].playTime === '00:00' ? '-' : quitters[quitter][columnsToShow[column].stat]) + '</td>'; | |
} | |
} | |
trs += '<tr>' + tds + '</tr>'; | |
} | |
$('#stats').after('<div id="SBEB_Quitters_Container" style="margin:0 10px 10px auto; padding:5px; width:720px; background:rgba(0, 0, 0, 0.5); border:1px dashed #dd5e13; border-radius: 5px;"><table class="table table-stripped" style="margin:0;">' + | |
' <thead><tr>' + ths + '</tr></thead>' + | |
' <tbody>' + trs + '</tbody>' + | |
'</table></div>'); | |
}); | |
}; | |
let redTeamName = 'Red'; | |
let blueTeamName = 'Blue'; | |
let mercyRule = 3; // assume 3 for a pub game. Will change if in a group. | |
let modifyScoreboard = function(data) { | |
let playersSorted = data.data; | |
let isNish = data.isNish; | |
let hasFlaccids = data.hasFlaccids; | |
let isOvertime = tagpro.overtimeStartedAt; | |
let trs = $('#stats tbody tr'); | |
let stats = [ 'oldScore', 'customScore', 'score', 'oscore', 'dscore', 'tags', 'pops', 'grabs', 'drops', 'hold', 'captures', 'prevent', 'returns', 'support', 'powerups', 'points', 'flaccids', 'handoffs', 'goodHandoffs', 'timePlayed', 'otspawn' ]; | |
let rStats = { oldScore:0, customScore:0, score:0, oscore:0, dscore:0, tags:0, pops:0, grabs:0, drops:0, hold:0, captures:0, prevent:0, returns:0, support:0, powerups:0, points:0, flaccids:0, handoffs:0, goodHandoffs:0, timePlayed:0, otspawn:0 }; | |
let bStats = { oldScore:0, customScore:0, score:0, oscore:0, dscore:0, tags:0, pops:0, grabs:0, drops:0, hold:0, captures:0, prevent:0, returns:0, support:0, powerups:0, points:0, flaccids:0, handoffs:0, goodHandoffs:0, timePlayed:0, otspawn:0 }; | |
let scoreboard = ''; | |
let maxScore = 0; | |
let maxOScore = 0; | |
let maxDScore = 0; | |
const thTitles = { | |
'S1': 'Pre-NISH Scoreboard Position / Score', | |
'S2': 'Custom Weighted Scoreboard Position / Score', | |
'FLA': 'CTF Flaccid: When you grab and drop the flag within 2 seconds\nNF Flaccid: Not applicable', | |
'HO': 'CTF Handoff: When a teammate grabs within 2 seconds of a flaccid\nNF Handoff: When the flag is quickly transferred to an enemy, and then to a teammate for cap within 2 seconds', | |
'GHO': 'CTF Good-Handoff: When a teammate grabs within 2 seconds of a flaccid AND they escape the prevent radius\nNF Good-Handoff: When the flag is quickly transferred to an enemy, and then to a teammate for cap within 2 seconds (same as Handoff in NF?)', | |
'K/D': 'Tags / Pops', | |
'G/C': 'Grabs / Caps', | |
}; | |
// modify header... | |
$('#stats thead tr th[data-column="player"]').after('<th data-column="s1" title="' + thTitles.S1 + '">S1</th><th data-column="s2" title="' + thTitles.S2 + '">S2</th>'); | |
if (tagproConfig.replay) { | |
if (SHOW_TIME_PLAYED_AS_PERCENTAGE) { | |
$('#stats thead tr th[data-column="active"]').text('Time'); | |
} | |
if (isOvertime) { | |
$('#stats thead tr th').last().text('OT').attr('title', 'Overtime Re-Spawn Times').attr('data-column', 'ot'); | |
} else { | |
$('#stats thead tr th').last().remove(); // report/mute | |
} | |
} | |
$('#stats thead tr th[data-column="active"]').after('<th data-column="flaccids" title="' + thTitles.FLA + '">FLA</th><th data-column="handoffs" title="' + thTitles.HO + '">HO</th><th data-column="goodhandoffs" title="' + thTitles.GHO + '">GHO</th><th data-column="kd" title="' + thTitles['K/D'] + '">K/D</th><th data-column="gc" title="' + thTitles['G/C'] + '">G/C</th>'); | |
$('#stats thead tr th[data-column="score"]').css({ 'text-decoration': 'underline' }); // default sort | |
// modify rows... | |
trs.each(function() { | |
$(this).addClass('SBEB_Sortable'); // for <th> click to sort | |
$(this).find('td').eq(0).after('<td data-column="s1">-</td><td data-column="s2">-</td>'); // Old Score | Custom Weighted Score | |
if (tagproConfig.replay) { | |
if (isOvertime) { | |
$(this).find('td[data-column="report"]').text('x'); // re-use this column for overtime spawn times | |
} else { | |
$(this).find('td[data-column="report"]').remove(); // remove the redundant report/mute cell | |
} | |
} | |
$(this).find('td[data-column="active"]').after('<td data-column="flaccids">-</td><td data-column="handoffs">-</td><td data-column="goodhandoffs">-</td><td data-column="kd">-</td><td data-column="gc">-</td>'); // Assists | Flaccids | Good H/O | K/D | G/C | |
}); | |
// insert new values... | |
for (let i in playersSorted) { | |
let player = playersSorted[i]; | |
$('#stats tbody tr').eq(i).attr('data-team', player.team); | |
$('#stats tbody tr').eq(i).find('td[data-column="s1"]').text(player.oldPos.toFixed(0)).attr('title', player.oldScore.toFixed(0)); | |
$('#stats tbody tr').eq(i).find('td[data-column="s2"]').text(player.customPos.toFixed(0)).attr('title', player.customScore.toFixed(0)); | |
$('#stats tbody tr').eq(i).find('td[data-column="flaccids"]').text(player.grabs > 0 ? player.flaccids + '/' + player.grabs : '-').attr('title', (player.flaccids / player.grabs * 100).toFixed(0) + '% Flaccid Grabs'); | |
$('#stats tbody tr').eq(i).find('td[data-column="handoffs"]').text(player.handoffs > 0 ? (player.handoffs) + '' : '-').attr('title', player.handoffs + ' Handoffs (Assists)'); | |
$('#stats tbody tr').eq(i).find('td[data-column="goodhandoffs"]').text(player.goodHandoffs > 0 ? (player.goodHandoffs ) + '' : '-').attr('title', player.goodHandoffs + ' Good Handoffs'); | |
$('#stats tbody tr').eq(i).find('td[data-column="kd"]').text(player.tags > 0 ? (player.tags / (player.pops || 1)).toFixed(2) : '-'); | |
$('#stats tbody tr').eq(i).find('td[data-column="gc"]').text(player.captures > 0 ? (player.grabs / player.captures).toFixed(2) : '-'); | |
if (tagproConfig.replay) { | |
if (SHOW_TIME_PLAYED_AS_PERCENTAGE) { | |
$('#stats tbody tr').eq(i).find('td[data-column="active"]').text((player.timePlayedPC * 100).toFixed(0) + '%').attr('title', 'Played for ' + tagpro.helpers.timeFromSeconds(Math.floor(player.timePlayed / 1000), true)); | |
} | |
if (isOvertime) { | |
$('#stats tbody tr').eq(i).find('td[data-column="report"]').text(player.otspawn || '-'); | |
} | |
} | |
for (let stat of stats) { | |
if (player.team === 1) { | |
rStats[stat] += player[stat]; | |
} else if (player.team === 2) { | |
bStats[stat] += player[stat]; | |
} | |
} | |
if (player.score > maxScore) { | |
maxScore = player.score; | |
} | |
if (player.oscore > maxOScore) { | |
maxOScore = player.oscore; | |
} | |
if (player.dscore > maxDScore) { | |
maxDScore = player.dscore; | |
} | |
} | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="s1"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:revert; }'); // S1 | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="s2"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:revert; }'); // S2 | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="score"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (SCORE_BACKGROUND_COLOR || 'revert') + '; opacity:1; }'); // Score | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="oscore"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (O_BACKGROUND_COLOR || 'revert') + '; opacity:1; }'); // O | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="dscore"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (D_BACKGROUND_COLOR || 'revert') + '; opacity:1; }'); // D | |
GM_addStyle('.game div#options .table.table-stripped td.o-ipm, .game div#options .table.table-stripped td.d-ipm { color:#ddd; font-weight:inherit !important; font-size:inherit !important; }'); // another O & D | |
GM_addStyle('#stats td[data-column="player"], #stats th[data-column="player"] { border-right:1px solid #4b4b4b !important; }'); // right of "Player" column | |
GM_addStyle('#stats td[data-column="score"], #stats th[data-column="score"] { border-right:none !important; }'); // clear previous in-game style from "Score" column | |
GM_addStyle('#stats td[data-column="dscore"], #stats th[data-column="dscore"] { border-right:1px solid #4b4b4b !important; }'); // right of "D" column | |
GM_addStyle('#stats td[data-column="active"], #stats th[data-column="active"] { border-right:1px solid #4b4b4b !important; }'); // right of "Active" column | |
GM_addStyle('#stats tbody tr:hover { background:rgba(15, 65, 15, 0.8) !important; }'); // row hover color | |
// highlght maxs... | |
setTimeout(() => { | |
let lastColumn = $('#stats thead tr th').last().index() + 1; | |
for (let i = 4; i <= lastColumn; i++) { // skip: Player | S1 | S2 | |
let column = $('#stats tbody tr td:nth-child(' + i + ')'); | |
let columnData = $('#stats tbody tr td:nth-child(' + i + ')').data('column'); | |
let prevMax = 0; | |
if (columnData === 'active' || columnData === 'flaccids') { | |
continue; | |
} | |
if (columnData === 'gc') { | |
prevMax = -9999; | |
} | |
$(column).each(function() { | |
let thisText = $(this).text().replace('%', ''); | |
if (thisText.includes(':')) { | |
thisText = toSeconds(thisText); | |
} else { | |
thisText = +thisText; | |
} | |
if (columnData === 'gc') { | |
thisText *= -1; | |
} | |
if (thisText > prevMax) { | |
$(column).removeClass('SBEB_SB_Max_Red SBEB_SB_Max_Blue'); | |
$(this).addClass( $(this).parent().data('team') === 1 ? 'SBEB_SB_Max_Red' : $(this).parent().data('team') === 2 ? 'SBEB_SB_Max_Blue' : '' ); | |
$(column).css({ 'color':'#ddd', 'background-color':'revert-layer' }); | |
$(this).css({ 'color':'#fff', 'background-color':$(this).parent().data('team') === 1 ? MAX_HIGHLIGHT_RED_COLOR : $(this).parent().data('team') === 2 ? MAX_HIGHLIGHT_BLUE_COLOR : 'rgba(0, 0, 0, 0)' }); | |
prevMax = thisText; | |
} else if (thisText === prevMax && prevMax !== 0) { | |
$(this).addClass( $(this).parent().data('team') === 1 ? 'SBEB_SB_Max_Red' : $(this).parent().data('team') === 2 ? 'SBEB_SB_Max_Blue' : '' ); | |
$(this).css({ 'color':'#fff', 'background-color':$(this).parent().data('team') === 1 ? MAX_HIGHLIGHT_RED_COLOR : $(this).parent().data('team') === 2 ? MAX_HIGHLIGHT_BLUE_COLOR : 'rgba(0, 0, 0, 0)' }); | |
} else { | |
if (columnData === 'score' && SCORE_BACKGROUND_COLOR && SCORE_BACKGROUND_COLOR !== 'revert') { | |
$(this).css({ 'color':'#ddd', 'background-color': SCORE_BACKGROUND_COLOR }); | |
} | |
if (columnData === 'oscore' && O_BACKGROUND_COLOR && O_BACKGROUND_COLOR !== 'revert') { | |
$(this).css({ 'color':'#ddd', 'background-color': O_BACKGROUND_COLOR }); | |
} | |
if (columnData === 'dscore' && D_BACKGROUND_COLOR && D_BACKGROUND_COLOR !== 'revert') { | |
$(this).css({ 'color':'#ddd', 'background-color': D_BACKGROUND_COLOR }); | |
} | |
if (columnData === 'captures' && CAPS_BACKGROUND_COLOR && CAPS_BACKGROUND_COLOR !== 'revert') { | |
$(this).css({ 'color':'#ddd', 'background-color': CAPS_BACKGROUND_COLOR }); | |
$('#stats thead tr th[data-column="captures"]').css('background', 'rgba(0, 0, 0, 0.2)') | |
} | |
} | |
if (STANDARDIZE_IPM_SCORES_TO_100) { | |
if (columnData === 'score' && maxScore) { | |
$(this).attr('title', thisText).text( (+thisText / maxScore * 100).toFixed(0) ); | |
} else if (columnData === 'oscore' && maxOScore) { | |
$(this).attr('title', thisText).text( (+thisText / maxOScore * 100).toFixed(0) ); | |
} else if (columnData === 'dscore' && maxDScore) { | |
$(this).attr('title', thisText).text( (+thisText / maxDScore * 100).toFixed(0) ); | |
} | |
} | |
}); | |
} | |
// teams stats... | |
if (!isEvent) { | |
GM_addStyle('.SBEB_SB_Max_Red { color:#fff !important; background-color:' + MAX_HIGHLIGHT_RED_COLOR + ' !important; }'); | |
GM_addStyle('.SBEB_SB_Max_Blue { color:#fff !important; background-color:' + MAX_HIGHLIGHT_BLUE_COLOR + ' !important; }'); | |
let redFG = (rStats.flaccids / (rStats.grabs || 1) * 100).toFixed(0); // Flaccid Grab % | |
let blueFG = (bStats.flaccids / (bStats.grabs || 1) * 100).toFixed(0); | |
let redKD = (rStats.tags / (rStats.pops || 1)).toFixed(2); | |
let blueKD = (bStats.tags / (bStats.pops || 1)).toFixed(2); | |
let redGC = rStats.captures ? (rStats.grabs / (rStats.captures || 1)).toFixed(2) : 0; | |
let blueGC = bStats.captures ? (bStats.grabs / (bStats.captures || 1)).toFixed(2) : 0; | |
$('#stats tbody').append('<tr><td colspan="100" id="SBEB_TeamStatsDivider" style="background:#adadad; padding:1px !important;"></td></tr>'); | |
$('#stats tbody').append('<tr>' + | |
' <td style="color:#ffb5bd; text-align:right; font-weight:bold; padding-right:3px !important;">' + redTeamName + ':</td>' + | |
' <td' + (rStats.customScore >= bStats.customScore ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="s1">' + rStats.customScore.toFixed(0) + '</td>' + | |
' <td' + (rStats.oldScore >= bStats.oldScore ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="s2">' + rStats.oldScore.toFixed(0) + '</td>' + | |
' <td' + (rStats.score >= bStats.score ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="score">' + rStats.score + '</td>' + | |
' <td' + (rStats.oscore >= bStats.oscore ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="oscore">' + rStats.oscore + '</td>' + | |
' <td' + (rStats.dscore >= bStats.dscore ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="dscore">' + rStats.dscore + '</td>' + | |
' <td' + (rStats.tags >= bStats.tags ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="tags">' + rStats.tags + '</td>' + | |
' <td' + (rStats.pops >= bStats.pops ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="pops">' + rStats.pops + '</td>' + | |
' <td' + (rStats.grabs >= bStats.grabs ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="grabs">' + rStats.grabs + '</td>' + | |
' <td' + (rStats.drops >= bStats.drops ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="drops">' + rStats.drops + '</td>' + | |
' <td' + (rStats.hold >= bStats.hold ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="hold">' + tagpro.helpers.timeFromSeconds(rStats.hold, true) + '</td>' + | |
' <td' + (rStats.captures >= bStats.captures ? ' class="SBEB_SB_Max_Red"' : ' style="background-color:rgba(0, 0, 0, 0.2);"') + ' data-column="captures">' + rStats.captures + '</td>' + | |
' <td' + (rStats.prevent >= bStats.prevent ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="prevent">' + tagpro.helpers.timeFromSeconds(rStats.prevent, true) + '</td>' + | |
' <td' + (rStats.returns >= bStats.returns ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="returns">' + rStats.returns + '</td>' + | |
' <td' + (rStats.support >= bStats.support ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="support">' + rStats.support + '</td>' + | |
' <td' + (rStats.powerups >= bStats.powerups ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="powerups">' + rStats.powerups + '</td>' + | |
' <td' + (rStats.points >= bStats.points ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="rankpoints">' + (rStats.points ? rStats.points : '-') + '</td>' + | |
' <td>-</td>' + // Time | |
' <td title="' + redFG + '% Flaccid Grabs"' + (rStats.flaccids && bStats.flaccids && rStats.flaccids >= bStats.flaccids ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="flaccids">' + (rStats.grabs ? rStats.flaccids + '/' + rStats.grabs : '-') + '</td>' + | |
' <td' + (rStats.handoffs && bStats.handoffs && rStats.handoffs >= bStats.handoffs ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="handoffs">' + (rStats.handoffs ? rStats.handoffs : '-') + '</td>' + | |
' <td' + (rStats.goodHandoffs && bStats.goodHandoffs && rStats.goodHandoffs >= bStats.goodHandoffs ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="goodhandoffs">' + (rStats.goodHandoffs ? rStats.goodHandoffs : '-') + '</td>' + | |
' <td' + (+redKD >= +blueKD ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="kd">' + (+redKD ? redKD : '-') + '</td>' + | |
' <td' + ((redGC > 0 && blueGC === 0) || (redGC > 0 && +redGC <= +blueGC) ? ' class="SBEB_SB_Max_Red"' : '') + ' data-column="gc">' + (+redGC ? redGC : '-') + '</td>' + | |
(isOvertime ? ' <td' + (rStats.otspawn >= bStats.otspawn ? ' class="SBEB_SB_Max_Red"':'') + ' data-column="rankpoints">' + (rStats.otspawn ? rStats.otspawn : '-') + '</td>' : '') + | |
'</tr>'); | |
$('#stats tbody').append('<tr>' + | |
' <td style="color:#cfcfff; text-align:right; font-weight:bold; padding-right:3px !important;">' + blueTeamName + ':</td>' + | |
' <td' + (bStats.customScore >= rStats.customScore ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="s1">' + bStats.customScore.toFixed(0) + '</td>' + | |
' <td' + (bStats.oldScore >= rStats.oldScore ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="s2">' + bStats.oldScore.toFixed(0) + '</td>' + | |
' <td' + (bStats.score >= rStats.score ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="score">' + bStats.score + '</td>' + | |
' <td' + (bStats.oscore >= rStats.oscore ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="oscore">' + bStats.oscore + '</td>' + | |
' <td' + (bStats.dscore >= rStats.dscore ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="dscore">' + bStats.dscore + '</td>' + | |
' <td' + (bStats.tags >= rStats.tags ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="tags">' + bStats.tags + '</td>' + | |
' <td' + (bStats.pops >= rStats.pops ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="pops">' + bStats.pops + '</td>' + | |
' <td' + (bStats.grabs >= rStats.grabs ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="grabs">' + bStats.grabs + '</td>' + | |
' <td' + (bStats.drops >= rStats.drops ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="drops">' + bStats.drops + '</td>' + | |
' <td' + (bStats.hold >= rStats.hold ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="hold">' + tagpro.helpers.timeFromSeconds(bStats.hold, true) + '</td>' + | |
' <td' + (bStats.captures >= rStats.captures ? ' class="SBEB_SB_Max_Blue"' : ' style="background-color:rgba(0, 0, 0, 0.2);"') + ' data-column="captures">' + bStats.captures + '</td>' + | |
' <td' + (bStats.prevent >= rStats.prevent ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="prevent">' + tagpro.helpers.timeFromSeconds(bStats.prevent, true) + '</td>' + | |
' <td' + (bStats.returns >= rStats.returns ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="returns">' + bStats.returns + '</td>' + | |
' <td' + (bStats.support >= rStats.support ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="support">' + bStats.support + '</td>' + | |
' <td' + (bStats.powerups >= rStats.powerups ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="powerups">' + bStats.powerups + '</td>' + | |
' <td' + (bStats.points >= rStats.points ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="ot">' + (bStats.points ? bStats.points : '-') + '</td>' + | |
' <td>-</td>' + // Time | |
' <td title="' + blueFG + '% Flaccid Grabs"' + (rStats.flaccids && bStats.flaccids && bStats.flaccids >= rStats.flaccids ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="flaccids">' + (bStats.grabs ? bStats.flaccids + '/' + bStats.grabs : '-') + '</td>' + | |
' <td' + (rStats.handoffs && bStats.handoffs && bStats.handoffs >= rStats.handoffs ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="handoffs">' + (bStats.handoffs ? bStats.handoffs : '-') + '</td>' + | |
' <td' + (rStats.goodHandoffs && bStats.goodHandoffs && bStats.goodHandoffs >= rStats.goodHandoffs ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="goodhandoffs">' + (bStats.goodHandoffs ? bStats.goodHandoffs : '-') + '</td>' + | |
' <td' + (+blueKD >= +redKD ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="kd">' + (+blueKD ? blueKD : '-') + '</td>' + | |
' <td' + ((blueGC > 0 && redGC === 0) || (blueGC > 0 && +blueGC <= +redGC) ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="gc">' + (+blueGC ? blueGC : '-') + '</td>' + | |
(isOvertime ? '<td' + (bStats.otspawn >= rStats.otspawn ? ' class="SBEB_SB_Max_Blue"' : '') + ' data-column="ot">' + (bStats.otspawn ? bStats.otspawn : '-') + '</td>' : '') + | |
'</tr>'); | |
} | |
// hide columns as per options... | |
trs = $('#stats tr'); | |
if (isNish && !SHOW_OLD_SCORE_POSITION || isEvent) { | |
$('#stats thead tr th[data-column="s1"]').hide(); | |
$('#stats tbody tr td[data-column="s1"]').hide(); | |
} | |
if (!SHOW_CUSTOM_SCORE_POSITION || isEvent) { | |
$('#stats thead tr th[data-column="s2"]').hide(); | |
$('#stats tbody tr td[data-column="s2"]').hide(); | |
} | |
if (!isNish || isNish && !SHOW_TOTAL_IPM) { | |
$('#stats thead tr th[data-column="score"]').hide(); | |
$('#stats tbody tr td[data-column="score"]').hide(); | |
} | |
if (!isNish) { | |
$('#stats thead tr th[data-column="score"]').text('Score'); | |
} | |
if (!isNish || !SHOW_O_IPM || isEvent) { | |
$('#stats thead tr th[data-column="oscore"]').hide(); | |
$('#stats tbody tr td[data-column="oscore"]').hide(); | |
} | |
if (!isNish || !SHOW_D_IPM || isEvent) { | |
$('#stats thead tr th[data-column="dscore"]').hide(); | |
$('#stats tbody tr td[data-column="dscore"]').hide(); | |
} | |
if (!hasFlaccids || !SHOW_FLACCIDS || isEvent) { | |
$('#stats thead tr th[data-column="flaccids"]').hide(); | |
$('#stats tbody tr td[data-column="flaccids"]').hide(); | |
} | |
if (!hasFlaccids || !SHOW_HANDOFFS || isEvent) { | |
$('#stats thead tr th[data-column="handoffs"]').hide(); | |
$('#stats tbody tr td[data-column="handoffs"]').hide(); | |
} | |
if (!hasFlaccids || !SHOW_GOOD_HANDOFFS || isEvent) { | |
$('#stats thead tr th[data-column="goodhandoffs"]').hide(); | |
$('#stats tbody tr td[data-column="goodhandoffs"]').hide(); | |
} | |
if (!SHOW_KD || isEvent) { | |
$('#stats thead tr th[data-column="kd"]').hide(); | |
$('#stats tbody tr td[data-column="kd"]').hide(); | |
} | |
if (!SHOW_GC || isEvent) { | |
$('#stats thead tr th[data-column="gc"]').hide(); | |
$('#stats tbody tr td[data-column="gc"]').hide(); | |
} | |
if (!SHOW_OT_RESPAWN_TIMES && tagproConfig.replay && isEvent) { | |
$('#stats thead tr th[data-column="gc"]').hide(); | |
$('#stats tbody tr td[data-column="gc"]').hide(); | |
} | |
trs.each(function() { | |
if ((!isNish || SHOW_OLD_SCORE_AS_VALUE) && SHOW_OLD_SCORE_POSITION) { | |
const prevText = $(this).find('td').eq(1).text(); | |
const prevTitle = $(this).find('td').eq(1).attr('title'); | |
$(this).find('td').eq(1).text(prevTitle).attr('title', 'Position: ' + prevText); | |
} | |
if ((!isNish || SHOW_CUSTOM_SCORE_AS_VALUE) && SHOW_CUSTOM_SCORE_POSITION) { | |
const prevText = $(this).find('td').eq(2).text(); | |
const prevTitle = $(this).find('td').eq(2).attr('title'); | |
$(this).find('td').eq(2).text(prevTitle).attr('title', 'Position: ' + prevText); | |
} | |
}); | |
$('#SBEB_TeamStatsDivider').show(); | |
if (!isEvent) { | |
updateComeback(); | |
} | |
addSortability(); | |
if (tagproConfig.replay && Object.keys(data.quitters).length) { | |
addQuitters(data.quitters); | |
} | |
$('#options').fadeIn(300); | |
// the rounded width is so we don't get pixel blur between columns | |
GM_addStyle('.game #options { width:auto !important; }'); | |
//GM_addStyle('.game #options { width:' + Math.max(960, (Math.round($('#options').width() / 2) * 2 + 24)) + 'px !important; top:180px !important; left:50% !important; translate:-50%; }'); | |
GM_addStyle('.game #options { width:' + Math.max(960, (Math.round($('#options').width() / 2) * 2 + 24)) + 'px !important; top:' + (Math.floor($('#viewport').position().top) + 50 + 65) + 'px !important; left:50% !important; translate:-50%; }'); | |
// this moves the "Red Wins!" sprite up 50px so it's more visible... | |
tagpro.renderer.layers.ui.children.every(sprite => { | |
if (sprite.text && sprite.text.includes('Wins!')) { | |
sprite.y = 50; | |
return false; | |
} | |
return true; | |
}); | |
}, 100); | |
}; | |
/******* Comeback! *******/ | |
let scores = []; | |
tagpro.socket.on('score', function(data) { | |
let scoreDiff = data.r - data.b; | |
if (scores.length === 0) { | |
scores.push({ score: { r:data.r, b:data.b }, diff:scoreDiff, time:0 }); | |
} else if (scores[scores.length - 1].diff !== scoreDiff) { | |
scores.push({ score: { r:data.r, b:data.b }, diff:scoreDiff, time:Date.now() }); | |
} | |
}); | |
GM_addStyle('.SBEB_Message { position:absolute; left:50%; translate:-50%; font-size:26px; text-align:center; font-family:Verdana; font-weight:bold; z-index:1; }'); | |
GM_addStyle('.SBEB_Message_Red { color:#fff; text-shadow:0px 0px 18px #f70, 0px 0px 10px #f00, 0px 0px 5px #f00, 1px 1px 2px black; }'); | |
GM_addStyle('.SBEB_Message_Blue { color:#fff; text-shadow:0px 0px 18px #0089ff, 0px 0px 10px #00ffdc, 0px 0px 5px #00ffdc, 1px 1px 2px black; }'); | |
function updateComeback() { | |
$('#options').prepend('<div id="SBEB_Options_Header" style="position:relative; font-size:12px; max-width:340px; min-height:60px;"></div>' + | |
'<div id="SBEB_Table_Container" style="position:relative; min-height:280px; max-height:370px; overflow-x:hidden; overflow-y:auto;"></div>'); | |
$('#SBEB_Options_Header').append($('#gameSocket')); | |
$('#SBEB_Options_Header').append($('#mapInfo').css({ 'margin-top':'2px' })); | |
$('#SBEB_Options_Header').append($('#musicInfo').css({ 'margin-bottom':'2px', 'font-weight':'bold' })); | |
$('#SBEB_Options_Header').append($('#flairInfo').css({ 'margin-top':'2px', 'margin-bottom':'2px' })); | |
$('#SBEB_Table_Container').append($('table#stats')); | |
$('#replayInfo').css({ 'position':'absolute', 'z-index':'2', 'top':'5px', 'right':'10px' }); | |
$('#optionsName').css({ 'margin':'-12px 0 0 0' }); | |
$('#mapRatingContainer').css({ 'margin':'-12px 0 0 10px' }); | |
$('#optionsLinks').css({ 'padding':'12px 0 0 0' }); | |
$('#optionsAd').remove(); | |
// make the players table scrollable (for when there are lots of players/dnf's)... | |
GM_addStyle('#SBEB_Table_Container::-webkit-scrollbar { width:2px; }'); | |
GM_addStyle('#SBEB_Table_Container::-webkit-scrollbar-thumb { background:#292; border-radius:4px; }'); | |
GM_addStyle('#SBEB_Table_Container::-webkit-scrollbar-track { background:#ddd; border-radius:4px; }'); | |
for (let i = 0; i < scores.length; i++) { | |
if (tagpro.score.b > tagpro.score.r && scores[i].diff !== 0) { | |
scores[i].diff = scores[i].diff * -1; | |
} | |
} | |
let lowestScoreDifferenceIndex; | |
let i = scores.length - 1; | |
while (i > 0) { | |
if (scores[i - 1].diff < scores[i].diff) { | |
if (scores[i - 1].diff < 0) { | |
lowestScoreDifferenceIndex = i - 1; | |
} | |
} else { | |
break; | |
} | |
i--; | |
} | |
let winningTeamName = ''; | |
let colorClass = ''; | |
let winMargin = Math.abs(tagpro.score.r - tagpro.score.b); | |
if (tagpro.score.r > tagpro.score.b) { | |
winningTeamName = redTeamName; | |
colorClass = 'SBEB_Message_Red'; | |
} else if (tagpro.score.r < tagpro.score.b) { | |
winningTeamName = blueTeamName; | |
colorClass = 'SBEB_Message_Blue'; | |
} | |
if (tagpro.score.r !== tagpro.score.b && lowestScoreDifferenceIndex >= 0) { | |
if (tagpro.overtimeStartedAt) { | |
$('#options').prepend('<div class="SBEB_Message ' + colorClass + '" style="top:40px; font-size:18px; font-style:italic;">Overtime Win</div>'); | |
} | |
$('#options').prepend('<div class="SBEB_Message ' + colorClass + '">' + scores[lowestScoreDifferenceIndex].score.r + '-' + scores[lowestScoreDifferenceIndex].score.b + ' Comeback!</div>'); | |
} else { | |
if (tagpro && tagpro.group && tagpro.group.socket !== null && tagpro.group.socket.connected) { | |
$('#options').prepend('<div class="SBEB_Message ' + colorClass + '">+' + winMargin + ' ' + winningTeamName + ' Win!</div>'); | |
} else if (mercyRule > 0 && (winMargin === mercyRule)) { | |
$('#options').prepend('<div class="SBEB_Message ' + colorClass + '">+' + mercyRule + ' Mercy Win!</div>'); | |
} else if (tagpro.overtimeStartedAt) { | |
$('#options').prepend('<div class="SBEB_Message ' + colorClass + '">Overtime Win!</div>'); | |
} | |
} | |
} | |
/*************************/ | |
// these styles are for the scoreboard during the game (they will be changed at the EOG)... | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="score"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (SCORE_BACKGROUND_COLOR || 'revert') + '; }'); // Score | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="oscore"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (O_BACKGROUND_COLOR || 'revert') + '; }'); // O | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="dscore"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (D_BACKGROUND_COLOR || 'revert') + '; }'); // D | |
GM_addStyle('.game div#options .table.table-stripped td[data-column="captures"] { color:#ddd; font-weight:inherit; font-size:inherit; background-color:' + (CAPS_BACKGROUND_COLOR || 'revert') + '; }'); // Caps | |
GM_addStyle('.game div#options .table.table-stripped td.o-ipm, .game div#options .table.table-stripped td.d-ipm { color:#ddd; font-weight:inherit !important; font-size:inherit !important; }'); // another O & D style | |
GM_addStyle('.game div#options table tbody td { text-shadow:1px 1px 2px #000; border-right:none; }'); | |
GM_addStyle('.game #options { width:' + Math.max(960, (Math.round($('#options').width() / 2) * 2 + 24)) + 'px; left:50% !important; translate:-50%; }'); | |
GM_addStyle('#stats tbody { color: #ddd; }'); | |
GM_addStyle('.game div#options table td:nth-child(n+2), .game div#options table th:nth-child(n+2) { min-width:45px !important; width:45px; padding:3px 5px !important; white-space:nowrap; }'); | |
GM_addStyle('#stats td:first-child, #stats th:first-child { min-width:120px !important; width:120px !important; }'); | |
GM_addStyle('#stats td[data-column="dscore"], #stats th[data-column="dscore"] { border-right:1px solid #4b4b4b !important; }'); // right of "D" column | |
tagpro.socket.on('end', function() { | |
$('#options').hide(); | |
setTimeout(() => { // need a delay here | |
$('#stats tbody').removeClass('stats'); // stop the scoreboard from updating | |
$('#stats tbody tr.template').remove(); // not needed anymore | |
let playersSorted = createScoreboardData(tagpro.players); | |
modifyScoreboard(playersSorted); | |
}, 100); | |
}); | |
// detect some group settings... | |
let startCounter = 0; | |
let waitForGroupSocket = function() { | |
if (!tagpro || !tagpro.group || tagpro.group.socket !== null && !tagpro.group.socket.connected) { | |
startCounter++; | |
if (startCounter < 50) { | |
setTimeout(waitForGroupSocket, 20); | |
return false; | |
} | |
} | |
if (tagpro && tagpro.group && tagpro.group.socket !== null && tagpro.group.socket.connected) { | |
let settingCount = 0; | |
function handleSetting(data) { | |
// console.log('SBEB:: handleSetting():', data.name, data.value); | |
if (data.name === 'mercyRule') { | |
mercyRule = data.value; | |
settingCount++; | |
} else if (data.name === 'redTeamName') { | |
redTeamName = data.value; | |
settingCount++; | |
} else if (data.name === 'blueTeamName') { | |
blueTeamName = data.value; | |
settingCount++; | |
} | |
if (settingCount === 3) { | |
tagpro.group.socket.removeListener('setting', handleSetting); | |
} | |
} | |
tagpro.group.socket.on('setting', handleSetting); | |
} | |
}; | |
waitForGroupSocket(); | |
//Helpers... | |
function toSeconds(value) { | |
return value.split(':').reduce((acc, time) => (60 * acc) + +time); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment