// ==UserScript==
// @name Movement particles
// @namespace -
// @version 0.1.2
// @description Adds particles when walking
// @author Devil D. Nudo#7346
// @match *://*.moomoo.io/*
// @match *://moomoo.io/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=moomoo.io
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
function particles() {
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min)) + min
}
function getRandomRGBA(alpha) {
const r = Math.round(255 * Math.random())
const g = Math.round(255 * Math.random())
const b = Math.round(255 * Math.random())
const a = alpha ?? 1
return `rgba(${r}, ${g}, ${b}, ${a})`
}
let lastX = 0
let lastY = 0
class Vector {
constructor(x = 0, y = 0) {
this.x = x
this.y = y
}
static random2D(angle, length = 1) {
return new Vector(length * Math.cos(angle), length * Math.sin(angle))
}
get magnitude() {
return Math.sqrt(this.x ** 2 + this.y ** 2)
}
setMag(length) {
return this.normalize().mult(length)
}
add(x, y) {
const vector = new Vector(x, y)
this.x += vector.x
this.y += vector.y
return this
}
sub(vector) {
this.x -= vector.x
this.y -= vector.y
return this
}
mult(scalar) {
this.x *= scalar
this.y *= scalar
return this
}
div(divisor) {
this.x /= divisor
this.y /= divisor
return this
}
normalize() {
const mag = this.magnitude
if (mag > 0) {
this.div(mag)
}
return this
}
}
class Physics {
constructor(x, y, mass = 5, time = 0.9) {
this.mass = mass
this.time = time
this.position = new Vector(x, y)
this.velocity = new Vector()
this.acceleration = new Vector()
this.force = new Vector()
}
updatePhysics() {
this.force.div(this.mass)
this.acceleration.add(this.force.x, this.force.y)
this.acceleration.mult(this.time)
this.velocity.add(this.acceleration.x, this.acceleration.y)
this.velocity.mult(this.time)
this.position.add(this.velocity.x, this.velocity.y)
}
}
class Particle extends Physics {
constructor({ id, scale, color }, context, xOffset, yOffset, myPlayer) {
super(myPlayer.x, myPlayer.y)
this.id = id
this.maxScale = scale
this.color = color
this.context = context
this.xOffset = xOffset
this.yOffset = yOffset
this.scale = 0
this.alpha = 0
this.maxAlpha = 1
this.liveTime = getRandom(350, 600)
this.liveDate = Date.now()
let mag = getRandom(1, 10)
const speed = Math.hypot(lastY - myPlayer.y, lastX - myPlayer.x)
const direction = Math.atan2(lastY - myPlayer.y, lastX - myPlayer.x)
const point = new Physics(myPlayer.x, myPlayer.y)
point.velocity.add(speed * Math.cos(direction), speed * Math.sin(direction))
point.updatePhysics()
this.moveDir = Math.atan2(point.position.y - myPlayer.y, point.position.x - myPlayer.x)
if (speed <= 0.15) {
mag = 0
this.moveDir = 0
}
this.velocity = Vector.random2D((this.moveDir - Math.PI / 6) + Math.random() * Math.PI * .35).setMag(mag)
lastX = myPlayer.x
lastY = myPlayer.y
}
get liveTimer() {
return Date.now() - this.liveDate
}
render() {
this.context.save()
this.context.fillStyle = this.color
this.context.globalAlpha = this.alpha
this.context.beginPath()
this.context.arc(this.position.x - this.xOffset, this.position.y - this.yOffset, this.scale, 0, 2 * Math.PI)
this.context.fill()
this.context.restore()
}
update() {
this.updatePhysics()
this.scale = (this.liveTimer / this.liveTime) * this.maxScale
this.alpha = (this.liveTimer / this.liveTime) * this.maxAlpha
this.render()
if (this.liveTimer >= this.liveTime) {
_particles.remove(this.id)
}
}
}
class Particles {
constructor() {
this.particles = {}
}
get list() {
return Object.values(this.particles)
}
create(be, f, d, R) {
const id = Date.now() / 111
this.particles[id] = new Particle({
id: id,
scale: getRandom(5, 12),
color: getRandomRGBA()
}, be, f, d, R)
}
remove(id) {
delete this.particles[id]
}
update(be, f, d, R) {
this.create(be, f, d, R)
let i = this.list.length
while (i--) {
this.list[i].update()
}
}
}
return new Particles()
}
function applyRegex(code) {
code = code.replace(/\,._blank.\)\}/, `,"_blank")};\n${particles.toString()};\n const _particles = particles();\n`)
const { index } = code.match(/\.drawImage\(\w+\.skull\,/)
const contextVariable = code.slice(index - 2, index)
code = code.replace(/\_\.health\>\d/, `;_particles.update(${contextVariable}, f, d, R);_.health>0`)
return code
}
async function loadScript(script) {
const response = await fetch(script.src)
let code = await response.text()
code = applyRegex(code)
eval(code)
}
const observer = new MutationObserver(function(mutations) {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.tagName === "SCRIPT" && /bundle\.js$/.test(node.src)) {
observer.disconnect()
loadScript(node)
node.remove()
}
}
}
})
observer.observe(document, {
childList: true,
subtree: true
})
})()