Skip to content

Instantly share code, notes, and snippets.

@nabbynz
Last active April 25, 2024 23:12
Show Gist options
  • Save nabbynz/1cf5e67c0e048758f5a1912e0547fc72 to your computer and use it in GitHub Desktop.
Save nabbynz/1cf5e67c0e048758f5a1912e0547fc72 to your computer and use it in GitHub Desktop.
Mars Ball Rotator & Particles
// ==UserScript==
// @name Mars Ball Rotator & Particles
// @description .
// @version 0.0.3
// @match https://*.koalabeast.com/game
// @match https://*.koalabeast.com/game?*
// @updateURL https://gist.github.com/nabbynz/1cf5e67c0e048758f5a1912e0547fc72/raw/Mars_Ball_Rotator_&_Particles.user.js
// @downloadURL https://gist.github.com/nabbynz/1cf5e67c0e048758f5a1912e0547fc72/raw/Mars_Ball_Rotator_&_Particles.user.js
// @grant none
// @author nabby
// ==/UserScript==
/* eslint-env jquery */
/* globals tagpro, PIXI */
'use strict';
console.log('START: ' + GM_info.script.name + ' (v' + GM_info.script.version + ' by ' + GM_info.script.author + ')');
const SHOW_PARTICLES = true; // particles will show even if the "Disable Particles" setting is on
tagpro.ready(function() {
let tr = tagpro.renderer;
if (SHOW_PARTICLES) {
// smoke...
tagpro.particleDefinitions.marsball1 = {
alpha: { start: 0.75, end: 0 },
scale: { start: 0, end: 1.25, minimumScaleMultiplier: 1 },
color: { start: '#ffffff', end: '#000000' },
speed: { start: 50, end: 50, minimumSpeedMultiplier: 1 },
acceleration: { x: 0, y: 0 },
maxSpeed: 0,
startRotation: { min: 0, max: 360 },
noRotation: true,
rotationSpeed: { min: 0, max: 0 },
lifetime: { min: 0.1, max: 1.9 },
frequency: 0.01,
emitterLifetime: -1,
maxParticles: 50,
pos: { x: 40, y: 40 },
addAtBack: false,
spawnType: 'point'
};
// slow trail...
tagpro.particleDefinitions.marsball2 = {
alpha: { start: 0.8, end: 0.2 },
scale: { start: 0.75, end: 0.1, minimumScaleMultiplier: 1 },
color: { start: '#ff00ff', end: '#000000' },
speed: { start: 0, end: 0, minimumSpeedMultiplier: 1 },
acceleration: { x: 0, y: 0 },
maxSpeed: 0,
startRotation: { min: 0, max: 360 },
noRotation: true,
rotationSpeed: { min: 0, max: 0 },
lifetime: { min: 1, max: 3 },
frequency: 0.001,
emitterLifetime: -1,
maxParticles: 50,
pos: { x: 40, y: 40 },
addAtBack: false,
spawnType: 'point'
};
// blue edge burst...
tagpro.particleDefinitions.marsball3 = {
alpha: { start: 1, end: 0.8 },
scale: { start: 0.05, end: 0.1, minimumScaleMultiplier: 0.5 },
color: { start: '#ffffff', end: '#00ff80' },
speed: { start: 60, end: 220, minimumSpeedMultiplier: 1 },
acceleration: { x: 0, y: 0 },
maxSpeed: 0,
startRotation: { min: 0, max: 360 },
noRotation: true,
rotationSpeed: { min: 0, max: 0 },
lifetime: { min: 0.25, max: 0.35 },
frequency: 0.008,
emitterLifetime: -1,
maxParticles: 100,
pos: { x: 40, y: 40 },
addAtBack: false,
spawnType: 'burst',
particlesPerWave: 50,
particleSpacing: 0,
angleStart: 0,
};
// bubbles...
tagpro.particleDefinitions.marsball4 = {
alpha: { start: 0.8, end: 0.2 },
scale: { start: 0.02, end: 0.2, minimumScaleMultiplier: 1 },
color: { start: '#ffff00', end: '#78ff7f' },
speed: { start: 10, end: 30, minimumSpeedMultiplier: 3 },
acceleration: { x: 0, y: 0 },
maxSpeed: 0,
startRotation: { min: 0, max: 360 },
noRotation: true,
rotationSpeed: { min: 0, max: 0 },
lifetime: { min: 0.1, max: 0.3 },
frequency: 0.001,
emitterLifetime: -1,
maxParticles: 80,
pos: { x: 40, y: 40 },
addAtBack: false,
spawnType: 'circle',
spawnCircle: { x: 0, y: 0, r: 45 },
};
}
let orig_drawMarsball = tr.drawMarsball;
let orig_updateMarsBall = tr.updateMarsBall;
let marsballEmitters = [];
let renderDelta;
let updateMarsBallEmitter = function() {
const now = performance.now();
if (!renderDelta) {
renderDelta = now;
}
let toRemove = [];
marsballEmitters.forEach((emitter) => {
if (emitter.emit || emitter.particleCount > 0) {
emitter.update((now - renderDelta) * 0.001);
} else if (!emitter.keep) {
toRemove.push(emitter);
}
});
toRemove.forEach((emitter) => {
let index = marsballEmitters.indexOf(emitter);
if (index !== -1) {
marsballEmitters.splice(index, 1);
}
});
renderDelta = performance.now();
requestAnimationFrame(updateMarsBallEmitter);
};
tr.drawMarsball = function(object, position) {
if (object.type !== 'marsball') { // in case of egg
return orig_drawMarsball(object, position);
}
if (tagpro.spectator) {
object.draw = true;
}
object.sprite = tagpro.tiles.draw(tr.layers.foreground, "marsball", { x: position.x + 40, y: position.y + 40 }, 80, 80); // `foreground` so the marsball is always on top (mostly because of the emitter)
object.sprite.anchor.set(0.5, 0.5);
object.sprite.keep = true; // this does nothing? maybe for certain events?
if (!object.draw) {
object.sprite.visible = false;
}
if (SHOW_PARTICLES) {
object.emitter = new PIXI.particles.Emitter(tr.layers.midground, [tr.particleTexture], tagpro.particleDefinitions.marsball4); // can use the .marsball1, .marsball2, .marsball3 or .marsball4 definition
object.emitter.emit = true;
object.emitter.keep = true;
object.emitter.emitterId = object.id;
marsballEmitters.push(object.emitter);
}
};
tr.updateMarsBall = function(object, position) {
if (object.type !== 'marsball') { // in case of egg
return orig_updateMarsBall(object, position);
}
if (!object.sprite) {
tr.drawMarsball(object, position);
}
if (object.draw) {
object.sprite.visible = true;
} else {
object.sprite.visible = !!tagpro.spectator;
}
object.emitter.emit = object.sprite.visible;
object.sprite.position.x = position.x + 40;
object.sprite.position.y = position.y + 40;
object.sprite.rotation += Math.random() / (object.id % 2 === 0 ? 20 : -20);
if (SHOW_PARTICLES && object.emitter) {
object.emitter.updateOwnerPos(position.x, position.y);
}
};
updateMarsBallEmitter();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment