Last active
October 27, 2024 02:05
-
-
Save nabbynz/1e8e6bc50346d5002dab5bca8c55a4d6 to your computer and use it in GitHub Desktop.
Random_Zombie_Balls.user.js
This file contains hidden or 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 Random Zombie Balls | |
// @description Apply Different Random Skins to Zombies | |
// @version 0.0.1 | |
// @match https://*.koalabeast.com/game | |
// @match https://*.koalabeast.com/game?* | |
// @updateURL https://gist.github.com/nabbynz/1e8e6bc50346d5002dab5bca8c55a4d6/Random_Zombie_Balls.user.js | |
// @downloadURL https://gist.github.com/nabbynz/1e8e6bc50346d5002dab5bca8c55a4d6/Random_Zombie_Balls.user.js | |
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html | |
// @grant none | |
// @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, PIXI */ | |
/* eslint-disable no-multi-spaces */ | |
/* eslint-disable dot-notation */ | |
// --- Options --- | |
const SPIN_ZOMBIES = false; | |
// --------------- | |
const ballskins_url = 'https://i.imgur.com/wOsbD2r.png'; | |
const canvas_size = 128; | |
let skins_image = new Image; | |
let randomBallsTexture; | |
let skipTextures = []; | |
let maxSkipTextures = 0; | |
let createZombieTextures = function() { | |
let skins_canvas = createCanvas(skins_image.width, skins_image.height); | |
let skins_ctx = skins_canvas.getContext('2d'); | |
skins_ctx.filter = 'blur(9px) brightness(140%) contrast(250%) saturate(250%)'; | |
skins_ctx.drawImage(skins_image, 0, 0); | |
skins_ctx.filter = 'none'; | |
skins_ctx.drawImage(skins_image, 0, 0); | |
randomBallsTexture = new PIXI.Texture.from(skins_canvas); | |
maxSkipTextures = randomBallsTexture.width / canvas_size * randomBallsTexture.height / canvas_size; | |
}; | |
let addBallSkin = function(player) { | |
let sX, sY, key; | |
if (skipTextures.length >= maxSkipTextures) { | |
skipTextures.length = 0; | |
} | |
while (!key || skipTextures.indexOf(key) >= 0) { | |
sX = getRandomInt(0, (randomBallsTexture.width - canvas_size) / canvas_size); | |
sY = getRandomInt(0, (randomBallsTexture.height - canvas_size) / canvas_size); | |
key = '' + (sX < 10 ? '0' + sX : sX) + (sY < 10 ? '0' + sY : sY); | |
} | |
skipTextures.push(key); // only use each texture once | |
let texture = new PIXI.Texture(randomBallsTexture, new PIXI.Rectangle(sX * canvas_size, sY * canvas_size, canvas_size, canvas_size)); | |
player.sprites.ballskin = new PIXI.Sprite(texture); | |
player.sprites.ballskin.scale.set(0.9, 0.9); | |
player.sprites.actualBall.texture = PIXI.Texture.EMPTY; // clears the texture pack ball texture, but still leaves it visible | |
player.sprites.actualBall.width = 1; | |
player.sprites.actualBall.height = 1; | |
player.sprites.ballskin.anchor.set(0.5, 0.5); | |
if (SPIN_ZOMBIES) { | |
player.sprites.ballskin.position.set(0, 0); | |
player.sprites.actualBall.pivot.set(0, 0); | |
player.sprites.actualBall.anchor.set(0.5, 0.5); | |
player.sprites.actualBall.addChild(player.sprites.ballskin); | |
} else { | |
player.sprites.ballskin.position.set(20, 20); | |
player.sprites.ball.addChildAt(player.sprites.ballskin, 1); | |
} | |
}; | |
let applyBallSkins = function() { | |
for (let playerId in tagpro.players) { | |
let player = tagpro.players[playerId]; | |
if (!player.sprites || !player.sprites.actualBall) { | |
continue; | |
} | |
if (player.team === 2 && !player.sprites.ballskin) { | |
addBallSkin(player); | |
} | |
} | |
}; | |
let modifyTagProFunctions = function() { | |
tagpro.renderer.createBallSprite = function(player) { | |
let tileId = player.team === 1 ? 'redball' : 'blueball'; | |
player.sprites.actualBall = tagpro.tiles.draw(player.sprites.ball, tileId, {x: 0, y: 0}); | |
player.sprites.actualBall.position = new PIXI.Point(20, 20); | |
player.sprites.actualBall.pivot = new PIXI.Point(20, 20); | |
player.sprites.actualBall.tileId = tileId; | |
if (player.team === 2) { | |
addBallSkin(player); | |
} | |
}; | |
tagpro.renderer.updatePlayerColor = function(player) { | |
let tileId = player.team === 1 ? 'redball' : 'blueball'; | |
if (player.sprites.actualBall.tileId !== tileId) { | |
let baseTexture = tagpro.tiles.getTexture(tileId); | |
let texture = new PIXI.Texture(baseTexture); | |
player.sprites.actualBall.texture = texture; | |
player.sprites.actualBall.tileId = tileId; | |
if (player.sprites.ballskin) { | |
player.sprites.ballskin.parent.removeChild(player.sprites.ballskin); | |
} | |
if (player.team === 2) { | |
addBallSkin(player); | |
} | |
} | |
}; | |
}; | |
/***** CHECK FOR HALLOWEEN EVENT - START *****/ | |
let isEvent = false; | |
let isHalloween = false; | |
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']; // run only for halloween events | |
for (let scriptName of scriptNames) { | |
if (scriptSrcs.some(e => e.includes(scriptName))) { //eg: https://static.koalabeast.com/events/halloween-2019.js | |
isEvent = true; | |
if (scriptName === 'halloween') isHalloween = true; | |
break; | |
} | |
} | |
} | |
console.log(GM_info.script.name + ':: checkForEvent() isEvent:'+isEvent, 'isHalloween:'+isHalloween); | |
}; | |
/***** CHECK FOR EVENT - END *****/ | |
tagpro.ready(function() { | |
checkForEvent(); | |
if (!isHalloween) { | |
return; | |
} | |
let readyToDraw = function() { | |
return tagpro.tiles && tagpro.tiles.image && tagpro.playerId; | |
}; | |
let init = function() { | |
createZombieTextures(); | |
if (document.visibilityState === 'hidden') { | |
document.addEventListener('visibilitychange', start); | |
} else { | |
start(); | |
} | |
}; | |
let start = function() { | |
if (!readyToDraw()) { | |
setTimeout(() => { | |
start(); | |
}, 20); | |
return false; | |
} else { | |
document.removeEventListener('visibilitychange', start); | |
setTimeout(() => { | |
modifyTagProFunctions(); | |
applyBallSkins(); | |
}, 200); | |
} | |
}; | |
skins_image.onload = init; | |
skins_image.crossOrigin = 'Anonymous'; | |
skins_image.src = ballskins_url; | |
}); | |
function createCanvas(width, height, forceDOM = false) { | |
if (typeof OffscreenCanvas !== 'undefined' && !forceDOM) { | |
return new OffscreenCanvas(width, height); | |
} else { | |
let canvas = document.createElement('canvas'); | |
canvas.width = width; | |
canvas.height = height; | |
return canvas; | |
} | |
} | |
function getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment