Skip to content

Instantly share code, notes, and snippets.

@nabbynz
Last active October 27, 2024 02:05
Show Gist options
  • Save nabbynz/1e8e6bc50346d5002dab5bca8c55a4d6 to your computer and use it in GitHub Desktop.
Save nabbynz/1e8e6bc50346d5002dab5bca8c55a4d6 to your computer and use it in GitHub Desktop.
Random_Zombie_Balls.user.js
// ==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