// ==UserScript==
// @name TagPro Timers With Previews
// @description A timer script to be used with TagPro. All boosts, bombs, powerups, and player respawns will have a countdown.
// @locale
// @version 0.4.1
// @match *://*.koalabeast.com/*
// @match *://*.jukejuice.com/*
// @match *://*.newcompte.fr/*
// @author Some Ball -1 modified by Niplepotamus
// @grant GM_setValue
// @grant GM_getValue
// @license MIT
// @namespace https://greasyfork.org/users/840828
// ==/UserScript==
tagpro.ready(function() {
tr = tagpro.renderer;
tr.layers.timers = new PIXI.DisplayObjectContainer();
tr.layers.pupTimes = new PIXI.DisplayObjectContainer();
var timers = [],
redflag, blueflag, spawntime,
pup = false,
pups = [],
powerups = [],
lastTime = [],
me;
var enable = GM_getValue('timers',true);
$('#optionsName').append('<label style="margin-left: 50px;"><input id="timers" type="checkbox"'+(enable ? ' checked' : '')+'/>Enable Timers</label>');
function enableDisable()
{
if(enable)
{
tr.layers.timers.alpha = 1;
if(!tagpro.spectator && tagpro.players[tagpro.playerId].sprites.timers)
tagpro.players[tagpro.playerId].sprites.timers.alpha = 1;
}
else if(!enable)
{
tr.layers.timers.alpha = 0;
if(!tagpro.spectator && tagpro.players[tagpro.playerId].sprites.timers)
tagpro.players[tagpro.playerId].sprites.timers.alpha = 0;
}
}
$('#timers').change(function() {
enable = $(this).is(':checked');
GM_setValue('timers',enable);
enableDisable();
});
tagpro.socket.on('end', function() {
for(var x in timers)
{
for(var y in timers[x])
{
clearInterval(timers[x][y][4])
}
}
for(var i = 0; i < 4; i++)
{
if (powerups[i] && powerups[i][3])
{
clearInterval(powerups[i][3])
}
}
});
tagpro.socket.on('mapupdate', function(data) {
if(!(data instanceof Array)) data = [data];
for(var i = 0; i < data.length; i++)
{
data[i].x = parseInt(data[i].x);
data[i].y = parseInt(data[i].y);
var which = parseFloat(data[i].v);
if(which == 5 || which == 15 || which == 14 || which == 10 || which == 6.1 || which == 6.2 || which == 6.3 || which == 6.4 )
{
if(timers[data[i].x] && timers[data[i].x][data[i].y])
{
tr.layers.timers.removeChild(timers[data[i].x][data[i].y][0]);
clearInterval(timers[data[i].x][data[i].y][4]);
delete timers[data[i].x][data[i].y]
}
}
else
{
switch(which)
{
case 5.1:
createTimer(data[i].x, data[i].y, 10000, 0xFFFF00);
break;
case 14.1:
createTimer(data[i].x, data[i].y, 10000, 0xFF0000);
break;
case 15.1:
createTimer(data[i].x, data[i].y, 10000, 0x0000FF);
break;
case 10.1:
createTimer(data[i].x, data[i].y, 30000, 0x696969);
break;
case 6.12:
case 6.22:
case 6.32:
case 6.42:
createTimer(data[i].x, data[i].y, 60000, 0xFFFFFF);
updatePupTime(data[i].x, data[i].y)
break;
default:
break;
}
}
}
});
tagpro.socket.on('splat', function(data) {
if(tagpro.playerId && !tagpro.spectator)
{
var me = tagpro.players[tagpro.playerId];
if(data.t != me.team && !me.flag && (me.tagpro || me.bomb))
{
var theirflag = data.t == 1 ? redflag : blueflag;
if (theirflag)
{
if(timers[theirflag.x] && timers[theirflag.x][theirflag.y])
{
tr.layers.timers.removeChild(timers[theirflag.x][theirflag.y][0]);
clearInterval(timers[theirflag.x][theirflag.y][4]);
delete timers[theirflag.x][theirflag.y];
}
createTimer(theirflag.x, theirflag.y, spawntime || 3000, 0x00FF00, 1)
}
}
}
});
tagpro.socket.on('spawn', function(data) {
spawntime = parseFloat(data.w);
var locx = parseInt(data.x / 40);
var locy = parseInt(data.y / 40);
if(timers[locx] && timers[locx][locy])
{
tr.layers.timers.removeChild(timers[locx][locy][0]);
clearInterval(timers[locx][locy][4]);
delete timers[locx][locy];
}
createTimer(locx, locy, spawntime || 3000, 0x00FF00, 1);
});
var waitOne = false;
tagpro.socket.on('spectator', function(data) {
waitOne = true;
});
tagpro.socket.on('time', function(data) {
if(data.state && data.state == 5) //game going to overtime
{
updateOvertimePupTimes();
}
});
function drawPups()
{
var me = tagpro.players[tagpro.playerId];
if(!me || !me.sprites || !me.sprites.info)
{
setTimeout(drawPups, 50);
return
}
me.sprites.timers = new PIXI.DisplayObjectContainer();
var list = ['JJ', 'RB', 'TP', 'SP'];
for(var i = 0; i < 4; i++)
{
if(powerups[i] && powerups[i][0])
{
powerups[i][0].alpha = 0;
delete powerups[i][0]
}
powerups[i] = [tr.prettyText(''), list[i]];
me.sprites.timers.addChild(powerups[i][0]);
powerups[i][0].x = 40;
powerups[i][0].y = 5 + i * 10;
powerups[i][0].alpha = 0;
}
me.sprites.info.addChild(me.sprites.timers);
tagpro.socket.on('p',function(data) {
data = data.u || data;
for(var i = 0;i < data.length;i++)
{
if(data[i].id===tagpro.playerId && data[i].bomb === false)
{
powerups[1][0].setStyle({
font: "bold 8pt Arial",
fill: '#ffffff',
stroke: "#000000",
strokeThickness: 3
});
powerups[1][0].alpha = 0;
if (powerups[1][3])
{
clearInterval(powerups[1][3]);
delete powerups[1][3]
}
}
}
});
enableDisable();
}
function ifSpec()
{
if (!tagpro.spectator)
{
if (!waitOne)
{
waitOne = true;
setTimeout(ifSpec, 500);
return
}
drawPups();
tagpro.socket.on('sound', function(sound) {
pup = sound.s === 'powerup' ? (new Date()) : false
});
tagpro.socket.on('mapupdate', function(data) {
if(!(data instanceof Array)) data = [data];
for(var i = 0; i < data.length; i++)
{
try
{
if(data[i].v == 6 && (new Date).getTime() - pup <= 10)
{
var me = tagpro.players[tagpro.playerId];
if(!me) break;
data[i].v = parseFloat(data[i].v);
data[i].x = parseInt(data[i].x);
data[i].y = parseInt(data[i].y);
if(!me.sprites.timers)
drawPups();
if(!me.sprites.timers.parent)
me.sprites.info.addChild(me.sprites.timers);
pup = false;
if(pups[data[i].x] && pups[data[i].x][data[i].y])
{
var was = pups[data[i].x][data[i].y],
index = Math.round((was - 6.1) * 10);
if(powerups[index][3])
{
clearInterval(powerups[index][3]);
delete powerups[index][3]
}
powerups[index][0].setStyle({
font: "bold 8pt Arial",
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 3
});
powerups[index][0].setText(powerups[index][1] + ': 20');
powerups[index][0].alpha = 1;
powerups[index][2] = new Date((new Date).getTime() + 20000);
powerups[index][3] = setInterval(updateSelf, 500, index);
}
}
else if(data[i].v > 6 && data[i].v <= 6.4)
{
if(!pups[data[i].x]) pups[data[i].x] = [];
pups[data[i].x][data[i].y] = data[i].v;
}
}
catch(e)
{
console.log("Error: "+e);
}
}
});
function updateSelf(index)
{
var me = tagpro.players[tagpro.playerId];
if(!me.sprites.timers)
drawPups();
if(!me.sprites.timers.parent)
me.sprites.info.addChild(me.sprites.timers);
var timeleft = powerups[index][2] - (new Date).getTime();
if(timeleft <= 0)
{
powerups[index][0].setStyle({
font: "bold 8pt Arial",
fill: '#ffffff',
stroke: "#000000",
strokeThickness: 3
});
powerups[index][0].alpha = 0;
clearInterval(powerups[index][3]);
delete powerups[index][3];
return;
}
var color = '#ffffff';
if(timeleft <= 10000)
{
color = (255 * (timeleft / 10000) + 0x100).toString(16).substring(1, 3);
color = '#ff' + color + '00'
}
else if(timeleft <= 15000)
{
color = '#ffff' + (255 * ((timeleft - 10000) / 10000) + 0x100).toString(16).substring(1, 3)
}
powerups[index][0].setStyle({
font: "bold 8pt Arial",
fill: color,
stroke: "#000000",
strokeThickness: 3
});
powerups[index][0].setText(powerups[index][1] + ': ' + (Math.ceil(timeleft / 1000)));
}
}
}
ifSpec();
function updateItems(x, y)
{
if(tr.gameContainer && !tr.layers.timers.parent)
tr.gameContainer.addChildAt(tr.layers.timers, 2);
if(tr.gameContainer && tr.gameContainer.getChildAt(2) != tr.layers.timers)
tr.gameContainer.setChildIndex(tr.layers.timers, 2);
if(!timers[x][y]) return //i don't know why this happens sometimes
var curr = timers[x][y][0],
end = timers[x][y][1],
length = timers[x][y][2],
color = timers[x][y][3],
isSpawn = timers[x][y][5],
time = curr.getChildAt(0),
timeleft = end - (new Date).getTime(),
radius = 15;
if(timeleft <= 0)
{
tr.layers.timers.removeChild(timers[x][y][0]);
clearInterval(timers[x][y][4]);
delete timers[x][y];
return;
}
time.setText(Math.ceil(timeleft / 1000))
}
function onScreen(x, y)
{
var me = tagpro.players[tagpro.playerId];
if(!me) return false;
return tagpro.spectator ? true : (Math.abs(me.x / 40 - x) < 16.25 && Math.abs(me.y / 40 - y) < 10.25)
}
function createTimer(x, y, timeout, color, force)
{
if (tr.gameContainer && !tr.layers.timers.parent)
tr.gameContainer.addChildAt(tr.layers.timers, 2);
if(tr.gameContainer && tr.gameContainer.getChildAt(2) != tr.layers.timers)
tr.gameContainer.setChildIndex(tr.layers.timers, 2);
if(!(force || onScreen(x,y)))
return;
var radius = 15,
timer = new PIXI.DisplayObjectContainer(),
time = new PIXI.Text((timeout / 1000).toString(), {
font: '17.5pt Arial',
fill: ((force || onScreen(x, y)) ? 'black' : 'brown'),
stroke: 'white',
strokeThickness: 3,
});
time.x = time.y = 20;
time.anchor.x = time.anchor.y = .5;
time.alpha = .9;
timer.addChild(time);
timer.x = Math.round(x * 40);
timer.y = Math.round(y * 40);
tr.layers.timers.addChild(timer);
if(!timers[x]) timers[x] = [];
timers[x][y] = [timer, new Date((new Date).getTime() + timeout), timeout, color, setInterval(updateItems, 500 - (force ? 250 : 0), x, y), force || 0];
}
function getSecond()
{
const date = new Date();
var time = date.getTime();
if(tagpro.state == 1) //game is in active state
{
var timeLeft = (tagpro.gameEndsAt - time)/1000;
var second = 0;
second = Math.floor(timeLeft % 60);
return second;
}
else if(tagpro.state == 5)//game is in overtime state
{
var timeSinceOT = (time - tagpro.overtimeStartedAt )/1000;
return Math.floor(timeSinceOT % 60);
}
return 0;
}
function updatePupTime(x, y)
{
if(!onScreen(x,y))
{
return;
}
var second = getSecond();
if (tr.gameContainer && !tr.layers.pupTimes.parent)
tr.gameContainer.addChildAt(tr.layers.pupTimes, 3);
if(tr.gameContainer && tr.gameContainer.getChildAt(3) != tr.layers.pupTimes)
tr.gameContainer.setChildIndex(tr.layers.pupTimes, 3);
if(lastTime[x] && lastTime[x][y])
{
tr.layers.pupTimes.removeChild(lastTime[x][y]);
}
var timer = new PIXI.DisplayObjectContainer(),
time = new PIXI.Text((second).toString(), {
font: '11pt Arial',
fill: 'black',
stroke: 'blue',
strokeThickness: 0.5,
});
time.x = time.y = 35;
time.anchor.x = time.anchor.y = .5;
time.alpha = .9;
timer.addChild(time);
timer.x = Math.round(x * 40);
timer.y = Math.round(y * 40);
tr.layers.pupTimes.addChild(timer);
if(!lastTime[x]) lastTime[x] = [];
lastTime[x][y] = timer;
}
function updateOvertimePupTimes()
{
for(var x = 0; x < lastTime.length; x++)
{
if(!lastTime[x]) continue;
for(var y = 0; y <lastTime[x].length; y++)
{
if(!lastTime[x][y]) continue;
var time = lastTime[x][y].getChildAt(0);
var newTime = (60 - parseInt(time.text)) % 60;
time.setText(Math.floor(newTime))
}
}
}
function findFlagsAndPups()
{
if(!tagpro.map)
{
setTimeout(findFlagsAndPups, 50);
return
}
for(var i = 0; i < tagpro.map.length; i++)
{
var flags = [3, 19, 4, 20],
powerups = [6.1, 6.2, 6.3, 6.4];
for(var j = 0; j < flags.length; j++)
{
var found = tagpro.map[i].indexOf(flags[j]);
if(found > -1)
{
if (flags[j] == 3 || flags[j] == 19) {
redflag = {
x: i,
y: found
}
} else {
blueflag = {
x: i,
y: found
}
}
}
found = tagpro.map[i].indexOf(powerups[j]);
while(found > -1)
{
if (!pups[i]) pups[i] = [];
pups[i][found] = powerups[j];
found = tagpro.map[i].indexOf(powerups[j], found + 1)
}
}
}
}
findFlagsAndPups();
});