// ==UserScript== // @name 9mm [MooMoo.io] // @name:ru 9mm [MooMoo.io] // @namespace https://github.com/Nudo-o // @version 1.0.0 // @description It's a good script for the game, it's not the best, but I'll try to make it as good as possible. M - Auto mills. Q/F/V/N/H - Macro placers. Everything else works automatically! You don't need to buy anything in the store, the script will buy everything by itself! // @description:ru Это хороший сценарий для игры, не самый лучший, но я постараюсь сделать его как можно лучше. M - Автоматические мельницы. Q/F/V/N/H - Макросы. Всё остальное работает автоматически! Вам не нужно ничего покупать в магазине, скрипт все купит сам! // @author @nudoo // @match *://moomoo.io/* // @match *://*.moomoo.io/* // @icon https://www.google.com/s2/favicons?sz=64&domain=moomoo.io // @require https://update.greasyfork.icu/scripts/480301/1320686/CowJS.js // @license MIT // @grant none // @run-at document-start // @updateURL // @installURL // @downloadURL // @downloadURL none // ==/UserScript== // LICENSE (MIT): https://www.tldrlegal.com/license/mit-license // The creation uses my library designed to simplify the work in creating scripts on MooMoo.io. You can get acquainted with it by following the link. // Cow.js - https://update.greasyfork.icu/scripts/480301/1320686/CowJS.js /* - 02.02.2024 (v1.0.0): 1. RELEASE. */ (function() { "use strict" const { Cow, CowUtils } = window const { packets, items } = Cow.config.designations const _placeItem = Cow.placeItem const _roundRect = CanvasRenderingContext2D.prototype.roundRect let nearEnemy = null let preplaceObjects = [] let lastPreplaceClear = 0 class AutoHeal { constructor() { this.checkIsHealed = false this.lastHeal = 0 } doFullHeal() { const { player } = Cow if (player.health === player.maxHealth) return const amount = player.items[0] === 0 ? 20 : player.items[0] === 1 ? 30 : 25 for (let i = player.health; i < player.maxHealth; i += amount) { this.doHeal() } } doHeal() { const { player } = Cow if (player.health === player.maxHealth) return const timeSinceHeal = Cow.ticker.ticks - (this.lastHeal || 0) if (timeSinceHeal >= 0) { Cow.delayedPlaceItem(() => Cow.placeItem(items.FOOD)) this.lastHeal = Cow.ticker.ticks } } update() { const { player } = Cow if (!player?.alive || player?.skinIndex === 45) return if (player.health === player.maxHealth) { if (player.shameCount >= 2) { tailor.autoBullTick = true } return } if (player.health <= 85 && nearEnemy) { const distance = CowUtils.getDistance(nearEnemy, player) if (distance <= 500) { tailor.autoEmpHat = true } } const timeSinceHit = Cow.ticker.ticks - (player.hitTime || 0) const timeSinceHeal = Cow.ticker.ticks - (this.lastHeal || 0) if (player.shameCount < 5) { if (timeSinceHeal >= 8) { this.doHeal() } else { if (timeSinceHit >= ((player.health <= 30) ? 0 : 2)) { if (player.health <= 40) { this.doFullHeal() } else if (timeSinceHit >= 1 && timeSinceHit >= 1) { this.doHeal() } if (player.health >= 65) { this.doHeal() } else if (player.health > 40 && player.health < 65) { this.doFullHeal() } } else if (timeSinceHit === 1) { if (player.health <= 30) { this.doHeal() this.doFullHeal() } } } } else { if (player.health < 40 && timeSinceHit >= 2) { this.doHeal() this.doHeal() } else if (player.health >= 40 && timeSinceHit >= 3 && timeSinceHeal >= 2) { this.doFullHeal() this.doHeal() } } } } class AntiInsta { constructor() { this.targetHealth = 35 this.lastHeal = 0 } doFullHeal() { const { player } = Cow if (player.health === player.maxHealth) return const amount = player.items[0] === 0 ? 20 : player.items[0] === 1 ? 30 : 25 for (let i = player.health; i < player.maxHealth; i += amount) { this.doHeal() } } doHeal() { const { player } = Cow if (player.health === player.maxHealth) return const timeSinceHeal = Cow.ticker.ticks - (this.lastHeal || 0) if (timeSinceHeal >= 0) { Cow.placeItem(items.FOOD) this.lastHeal = Cow.ticker.ticks } } update() { const { player } = Cow if (!player?.alive || player?.skinIndex === 45) return if (player.health > this.targetHealth || !nearEnemy) return const timeSinceHit = Cow.ticker.ticks - (player.hitTime || 0) const timeSinceHeal = Cow.ticker.ticks - (this.lastHeal || 0) if (player.shameCount <= 4) { if (timeSinceHeal >= 8) { this.doHeal() if (player.health <= 20) { this.doFullHeal() } this.doHeal() } else { if (timeSinceHit >= ((player.health <= 20) ? 0 : 1)) { if (player.health <= (this.targetHealth - 10)) { this.doHeal() this.doHeal() } else if (timeSinceHit >= 1 && timeSinceHit >= 1) { this.doHeal() this.doFullHeal() } if (player.health >= (this.targetHealth - 10)) { this.doHeal() this.doHeal() } else if (player.health > 5 && player.health < 15) { this.doFullHeal() this.doHeal() } } else if (timeSinceHit === 1) { this.doHeal() this.doHeal() } } if (player.health <= Math.max(this.targetHealth - 15, 10)) { this.doFullHeal() } else if (timeSinceHit >= 1 && timeSinceHeal >= 1) { this.doHeal() this.doHeal() } else { this.doHeal() } } else { if (player.health < (this.targetHealth - 5) && timeSinceHit >= 1) { this.doHeal() this.doHeal() } else if (player.health >= (this.targetHealth - 5) && timeSinceHit >= 2 && timeSinceHeal >= 1) { this.doHeal() } } } } class Tailor { constructor() { this.hatTicks = [] this.hasHats = [ 0 ] this.hasAccs = [ 0 ] this.lastHatTick = 0 this.lastHatID = null this.lastAccID = null this.autoEmpCD = null this.attackHatsCD = null this.autoEmpSoldier = false this.autoSoldierEmp = false this.autoEmpHat = false this.autoBullTick = false this.autoTankHat = false this.autoBullTickTimeout = null Cow.onPacket(packets.ADD_PLAYER, (_, isYou) => { if (!isYou) return this.attackHatActive = false this.autoAttackState = false this.autoAttackHatTick = 0 }) } isHasTick(key) { return Boolean(this.hatTicks.filter((tick) => tick.key == key).length) } equipHat(id) { const { player } = Cow if (!this.hasHats.includes(id) && id !== 0) { if (player.points >= Cow.items.hats.searchById(id).price) { Cow.sendPacket(packets.STORE_EQUIP, 1, id, 0) return this.hasHats.push(id) } } if (this.hasHats.includes(id) && player.skinIndex !== id) { Cow.sendPacket(packets.STORE_EQUIP, 0, id, 0) this.lastHatID = id } } equipAcc(id) { const { player } = Cow if (!this.hasAccs.includes(id) && id !== 0) { if (player.points >= Cow.items.accessories.searchById(id).price) { Cow.sendPacket(packets.STORE_EQUIP, 1, id, 1) return this.hasAccs.push(id) } } if (this.hasAccs.includes(id) && player.tailIndex !== id) { Cow.sendPacket(packets.STORE_EQUIP, 0, id, 1) this.lastAccID = id } } equipBiomeHat() { const { player } = Cow let hatID = 0 if (player.y2 > 6850 && player.y2 < 7550) { hatID = 31 } else if (player.y2 < 2400) { hatID = 15 } else { hatID = 12 } if (!this.isHasTick("auto-biome")) { this.hatTicks.push({ key: "auto-biome", callback: () => { this.equipHat(hatID) this.equipAcc(11) } }) } } unknownTicks(amount) { while (amount--) { this.hatTicks.push({ key: "unknown", callback: () => {} }) } } autoHats() { const { player } = Cow const dangerBuildings = calculator.getDangerBuildings(player) if (nearEnemy && player.health < player.maxHealth) { const isPolearm = nearEnemy.weaponIndex === 4 const isSword = nearEnemy.weaponIndex === 3 const isKatana = nearEnemy.weaponIndex === 4 if (isPolearm || isSword || isKatana) { if (nearEnemy.weapons[1] === 10) { if (this.autoEmpSoldier) return this.autoEmpSoldier = true this.hatTicks = [] this.equipHat(22) setTimeout(() => { this.equipHat(6) setTimeout(() => { this.autoEmpSoldier = false }, 25) }, 90) } else { if (this.autoSoldierEmp) return this.autoSoldierEmp = true this.hatTicks = [] this.equipHat(6) setTimeout(() => { this.equipHat(22) setTimeout(() => { this.autoEmpSoldier = false }, 25) }, 90) } return } } /*if (this.autoBullTick) { this.hatTicks = [] this.equipHat(7) if (!this.autoBullTickTimeout) { this.autoBullTickTimeout = setTimeout(() => { this.autoBullTick = false this.autoBullTickTimeout = null }, 111.111) } return }*/ if (this.autoEmpHat && (!this.autoEmpCD || Date.now() - this.autoEmpCD >= 500)) { this.equipHat(22) if (!this.isHasTick("uneqip-hats")) { this.unknownTicks(1) this.hatTicks.push({ key: "uneqip-hats", callback: () => { this.autoEmpHat = false this.autoEmpCD = null } }) } this.autoEmpCD = Date.now() } else if (this.autoTankHat) { this.equipHat(40) if (!this.isHasTick("uneqip-hats")) { this.unknownTicks(4) this.hatTicks.push({ key: "uneqip-hats", callback: () => { this.autoTankHat = false } }) } this.attackHatsCD = Date.now() } else if (dangerBuildings.length || nearEnemy) { if (dangerBuildings.length) { this.equipHat(6) } else if (nearEnemy) { const weaponIndex = nearEnemy.weaponIndex const angle = CowUtils.getDirection(nearEnemy, player) const distance = CowUtils.getDistance(nearEnemy, player) - player.scale const isMeInAngle = true//getAngleDist(angle, tmpValues.nearEnemy.dir) <= Math.PI / 1.25 const weapon = Cow.items.weapons[weaponIndex] if (!weapon) return const isMeInRange = distance <= weapon.range * 3.25 if (isMeInRange && isMeInAngle) { if (nearEnemy.skinIndex === 7 && nearEnemy.tailIndex !== 11) { if (!this.isHasTick("auto-spike")) { this.equipHat(6) this.unknownTicks(2) this.hatTicks.push({ key: "auto-spike", callback: () => { this.equipHat(11) } }) } return } else { this.equipHat(6) return } } else { return this.equipBiomeHat() } } } else { return this.equipBiomeHat() } } update() { this.autoHats() const { player } = Cow const timeSinceHatTick = Cow.ticker.ticks - (this.lastHatTick || 0) if (timeSinceHatTick >= 0 && this.hatTicks.length) { const hatTick = this.hatTicks[0] typeof hatTick?.callback === 'function' && hatTick.callback() this.hatTicks.shift() this.lastHatTick = Cow.ticker.ticks } } } class AutoPlacer { constructor() { this.delay = 0 this.lastUpdate = null } update() { const { player } = Cow if (!player?.alive || !nearEnemy?.visible) return if (Date.now() - this.lastUpdate < this.delay) return const trapConfig = Cow.items.list[player.items[items.TRAP]] const spikeConfig = Cow.items.list[player.items[items.SPIKE]] if (!trapConfig || !spikeConfig) return const visibleObjects = Cow.objectsManager.list.filter((gameObject) => gameObject.visible && gameObject.active) const angle = CowUtils.getDistance(nearEnemy, player) const placeSpikeDistance = player.scale + spikeConfig.scale * 1.4 const distance = CowUtils.getDistance(player, nearEnemy) let distanceToPlace = distance nearEnemy.inTrap = false for (let i = 0; i < visibleObjects.length; i++) { const gameObject = visibleObjects[i] if (!gameObject.isItem || gameObject.id !== 15 || gameObject.owner?.sid === nearEnemy.sid) continue const scale = gameObject.scale || gameObject.getScale() const enemyDistanceToTrap = CowUtils.getDistance(nearEnemy, gameObject) - scale + window.config.collisionDepth const angleTrapToEnemy = CowUtils.getDirection(nearEnemy, gameObject) if (enemyDistanceToTrap > 0) continue nearEnemy.inTrap = true const offset = scale - Math.abs(enemyDistanceToTrap) + nearEnemy.scale / 2 + spikeConfig.scale const placeX = gameObject.x + offset * Math.cos(angleTrapToEnemy) const placeY = gameObject.y + offset * Math.sin(angleTrapToEnemy) distanceToPlace = CowUtils.getDistance(placeX, placeY, player.x, player.y) if (distanceToPlace <= placeSpikeDistance) { const angleToPlace = CowUtils.getDirection(placeX, placeY, player.x, player.y) Cow.placeItem(items.SPIKE, { angle: angleToPlace }) } break } const distanceToEnemy = CowUtils.getDistance(player, nearEnemy) - nearEnemy.scale const placeDistance = trapConfig.scale * 1.2 + player.scale if (!nearEnemy.inTrap) { if (trapConfig) { if (distanceToEnemy <= placeDistance && player.items[items.TRAP] === 15) { const angle = CowUtils.getDirection(nearEnemy, player) Cow.placeItem(items.TRAP, { angle }) } } } else if (distanceToPlace > placeSpikeDistance && distanceToEnemy <= 275) { if (player.items[items.TRAP] === 15) { Cow.placeItem(items.TRAP, { angle: angle }) } Cow.placeItem(items.SPIKE, { angle: -angle }) } this.lastUpdate = Date.now() } } class Macro { constructor() { this.assistPlaceX = null this.assistPlaceY = null this.lastAssistActive = null this.keys = { FOOD: "KeyQ", TRAP: "KeyF", SPIKE: "KeyV", MILL: "KeyN", TURRET: "KeyH" } } resetAssist() { this.assistPlaceX = null this.assistPlaceY = null this.lastAssistActive = Date.now() } update() { const { player } = Cow if (!player?.alive || isInputFocused()) return if (Date.now() - this.lastAssistActive >= 500) this.resetAssist() for (const key in this.keys) { if (!Cow.input.keyboard.activeKeys.get(this.keys[key])) continue const placeItemIndex = items[key.replace(/wind/, "").toUpperCase()] const placeItem = Cow.items.list[player.items[placeItemIndex]] if (!placeItem) continue let placeAngle = player.lookAngle if (placeItem?.scale) { const generalScale = (player.scale + placeItem.scale + (placeItem.placeOffset || 0)) const placeX = player.x + (generalScale * Math.cos(placeAngle)) const placeY = player.y + (generalScale * Math.sin(placeAngle)) const placePosition = { x: placeX, y: placeY } const interferingObject = Cow.objectsManager.checkItemLocation(placeX, placeY, placeItem.scale, 0.6, placeItem.id, false, true) if (interferingObject) { let nearObjects = Cow.objectsManager.list.filter((gameObject) => { const generalScale = placeItem.scale + (gameObject.isItem ? gameObject.scale : gameObject.getScale(0.6, false)) const inPlace = CowUtils.getDistance(gameObject, player) <= generalScale + player.scale * 2 + (placeItem.placeOffset || 0) return gameObject.visible && gameObject.active && inPlace }) nearObjects = nearObjects.sort((a, b) => { a = CowUtils.getDistance(a, placePosition) b = CowUtils.getDistance(b, placePosition) return a - b }) if (nearObjects.length) { let newPlaceX = placeX let newPlaceY = placeY for (const nearObject of nearObjects) { const angle = CowUtils.getDirection(player, nearObject) const scale = nearObject.isItem ? nearObject.scale : nearObject.getScale(.6, false) const offsetScale = scale / 2 + placeItem.scale / 2 * 1.25 const _x = newPlaceX + offsetScale const _y = newPlaceY + offsetScale newPlaceX = _x * Math.cos(angle - Math.atan(player.x - _x)) newPlaceY = _y * Math.sin(angle - Math.atan(player.y - _y)) const isCanPlace = Cow.objectsManager.checkItemLocation(newPlaceX, newPlaceY, placeItem.scale, 0.6, placeItem.id, false) if (isCanPlace) break nearObjects = nearObjects.sort((a, b) => { const newPlacePosition = { x: newPlaceX, y: newPlaceY } a = CowUtils.getDistance(a, newPlacePosition) b = CowUtils.getDistance(b, newPlacePosition) return a - b }) } this.assistPlaceX = newPlaceX this.assistPlaceY = newPlaceY this.lastAssistActive = Date.now() placeAngle = CowUtils.getDirection(player.x, player.y, newPlaceX, newPlaceY) } } } //Cow.delayedPlaceItem(() => { Cow.placeItem(placeItemIndex, { angle: placeAngle }) //}) } } } class AutoMills { constructor() { this.gaps = [ 1.115820407, 1.141422642 ] this.lastPlace = null this.isActive = false Cow.onKeyboard("KeyM", () => { if (isInputFocused()) return this.isActive = !this.isActive if (!this.isActive) this.lastPlace = null }, { repeat: false }) } get gap() { const { player } = Cow return this.gaps[Number(player.items[items.MILL] !== 10)] } update() { const { player } = Cow if (!player?.alive || !this.isActive) return if (this.lastPlace) { const millConfig = Cow.items.list[player.items[items.MILL]] const distance = CowUtils.getDistance(player, this.lastPlace) - player.scale const placeDistance = millConfig.scale * 1.6 if (distance < placeDistance) return } //Cow.delayedPlaceItem(() => { Cow.placeItem(items.MILL, { angle: player.moveDir + this.gap }) Cow.placeItem(items.MILL, { angle: player.moveDir }) Cow.placeItem(items.MILL, { angle: player.moveDir - this.gap }) this.lastPlace = { x: player.x, y: player.y } //}) } } class ReloadBars { constructor() { this.colors = { 1: [ "#cc5151", "#8ecc51" ], 2: "#accd51", 3: "#c4cd51", 4: "#cdae51", 5: "#cd8251", 6: "#cd5d51" } } getColor(reloadValue, isAlly) { let color = "" if (reloadValue >= 0.8 && reloadValue < 1) { color = this.colors[2] } else if (reloadValue >= 0.6 && reloadValue < 0.8) { color = this.colors[3] } else if (reloadValue >= 0.4 && reloadValue < 0.6) { color = this.colors[4] } else if (reloadValue >= 0.2 && reloadValue < 0.4) { color = this.colors[5] } else if (reloadValue < 0.2) { color = this.colors[6] } else { color = this.colors[1][Number(isAlly)] } return color } drawBar(widthMult, color, object, offsetX, offsetY, _width, radii) { const { healthBarWidth, healthBarPad } = window.config const { context } = Cow.renderer const width = _width || (healthBarWidth / 2 - healthBarPad / 2) const height = 17 context._roundRect = _roundRect context.save() context.fillStyle = "#3d3f42" context.translate(object.renderX + offsetX, object.renderY + offsetY) context.beginPath() context._roundRect(-width - healthBarPad, -height / 2, 2 * width + 2 * healthBarPad, height, Array.isArray(radii) ? radii[0] : radii) context.fill() context.restore() context.save() context.fillStyle = color context.translate(object.renderX + offsetX, object.renderY + offsetY) context.beginPath() context._roundRect(-width, -height / 2 + healthBarPad, 2 * width * widthMult, height - 2 * healthBarPad, Array.isArray(radii) ? radii[1] : radii - 1) context.fill() context.restore() } drawPrimaryBar(entity) { const primaryReload = Math.min(Math.max(entity.reloads.primary.count / entity.reloads.primary.max, 0), 1) const isAlly = entity.isMe || entity.isAlly const { healthBarWidth, healthBarPad } = window.config const width = (healthBarWidth / 2 - healthBarPad / 2) const addWidth = 0 const color = this.getColor(primaryReload, isAlly) const offset = -width * 1.19 + addWidth const radius = 8 const radii = [[ radius, 0, 0, radius ], [ radius - 1, 0, 0, radius - 1 ]] this.drawBar(primaryReload, color, entity, offset, entity.scale + window.config.nameY - 5, width + addWidth, radii) } drawSecondaryBar(entity) { const secondaryReload = Math.min(Math.max(entity.reloads.secondary.count / entity.reloads.secondary.max, 0), 1) const isAlly = entity.isMe || entity.isAlly const { healthBarWidth, healthBarPad } = window.config const width = (healthBarWidth / 2 - healthBarPad / 2) const addWidth = 0 const color = this.getColor(secondaryReload, isAlly) const offset = width * 1.19 - addWidth const radius = 8 const radii = [[ 0, radius, radius, 0 ], [ 0, radius - 1, radius - 1, 0 ]] this.drawBar(secondaryReload, color, entity, offset, entity.scale + window.config.nameY - 5, width + addWidth, radii) } drawTurretHatBar(entity) { const turretReload = Math.min(Math.max(entity.reloads.turret.count / entity.reloads.turret.max, 0), 1) const isAlly = entity.isMe || entity.isAlly const { healthBarWidth } = window.config const color = this.getColor(turretReload, isAlly) const radius = 8 this.drawBar(turretReload, color, entity, 0, entity.scale + window.config.nameY * 1.75 - 3, healthBarWidth, radius) } update() { const { player } = Cow if (!player?.alive) return Cow.playersManager.eachVisible((player) => { this.drawPrimaryBar(player) this.drawSecondaryBar(player) this.drawTurretHatBar(player) }) } } class Calculator { constructor() {} getLength(x, y) { const math = (Math.pow, Math.sqrt) return math(x * x + y * y) } findBuildingOnPosition(target, other) { const dx = target.x - other.x const dy = target.y - other.y const scale = target.scale + (other.getScale ? other.getScale() : other.scale) const length = this.getLength(dx, dy) return length - scale < 0 } getPredictor(target) { return { x: target.x2 + target.speed * Math.cos(target.moveDir - Math.PI), y: target.y2 + target.speed * Math.sin(target.moveDir - Math.PI), scale: target.scale } } getDangerBuildings(target) { const { player } = Cow if (!player?.alive || !target?.visible) return [] const predictor = this.getPredictor(target) return Cow.objectsManager.list.filter((gameObject) => { if (!gameObject.visible || !gameObject.isItem || !gameObject.visible) return const isSpike = [6, 7, 8, 9].includes(gameObject.id) return isSpike && !Cow.isAllianceMember(gameObject.owner?.sid) && this.findBuildingOnPosition(predictor, gameObject) }) } } class AutoBreak { constructor() { this.isBreaking = false } stopBreaking() { if (!this.isBreaking) return this.isBreaking = false tailor.autoTankHat = false aimControl.stopAiming() } async update() { const { player } = Cow player.inTrap = false const nearTrap = Cow.objectsManager.list .filter((gameObject) => gameObject.visible && gameObject.active && gameObject.id === 15 && !Cow.isAllianceMember(gameObject.owner?.sid)) .sort((a, b) => { a = CowUtils.getDistance(a, player) b = CowUtils.getDistance(b, player) return a - b })[0] if (!nearTrap) return this.stopBreaking() const distance = CowUtils.getDistance(nearTrap, player) - nearTrap.scale + window.config.collisionDepth player.inTrap = distance <= 0 if (!player.inTrap) return this.stopBreaking() this.isBreaking = true tailor.autoTankHat = true const breakWeapon = player.weapons[1] === 10 ? player.weapons[1] : player.weapons[0] if (player.weaponIndex !== breakWeapon) Cow.sendPacket(packets.SELECT_BUILD, breakWeapon, true) aimControl.startAiming(nearTrap) Cow.sendPacket(packets.ATTACK_STATE, 1, aimControl.aimAngle) Cow.sendPacket(packets.ATTACK_STATE, 0, aimControl.aimAngle) } } class AntiTrap extends AutoBreak { constructor() { super() } update() { super.update() } } class AimControl { constructor() { this.aimTarget = null this.isAiming = false this._aimAngle = null this.isSent = false } get aimAngle() { this.updateAimToTarget() return this._aimAngle } set aimAngle(_angle) { this._aimAngle = _angle } onSent() { this.isSent = true } updateAimToTarget() { if (!this.isAiming) return const { player } = Cow const angle = typeof this.aimTarget === 'number' ? this.aimTarget : CowUtils.getDirection(this.aimTarget, player) this.aimAngle = angle } startAiming(point) { this.aimTarget = point this.isAiming = true this.isSent = false this.updateAimToTarget() } stopAiming() { this.aimTarget = null this.isAiming = false this.aimAngle = null } } CowUtils.delay = function(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } Cow.placeItem = function() { const lastWeapon = Number(this.player.weaponIndex > 8) if (arguments[0] !== 0) { preplaceObjects.push({ id: arguments[0], angle: arguments[1]?.angle || this.player.dir }) } _placeItem.apply(this, arguments) const weaponId = this.player.weapons[lastWeapon] if (this.player.weaponIndex !== weaponId) this.sendPacket(packets.SELECT_BUILD, weaponId, true) } Cow.delayedPlaceItem = function(callback) { this.lastPlaceItem ??= 0 if (this.lastPlaceItem && (this.ticker.ticks - this.lastPlaceItem) < 1) return callback() this.lastPlaceItem = this.ticker.ticks } Cow.isAllianceMember = function(sid) { const { player } = Cow if (player && player.sid == sid) return true if (!player.team || sid < 0) return false for (var i = 0; i < Cow.alliancePlayers.length; i += 2) { if (sid !== Cow.alliancePlayers[i]) continue return true } return false } Cow.isCanGather = function(doer, other) { const distance = CowUtils.getDistance(doer, other) - other.scale const angle = CowUtils.getDirection(other, doer) const angleDistance = CowUtils.getAngleDist(angle, doer.dir2) const isInAngle = angleDistance <= window.config.gatherAngle const isInRange = distance <= doer.weapon.range return { range: isInRange, angle: isInAngle, both: isInRange && isInAngle } } Cow.onPacket(packets.INIT_DATA, (initData) => { Cow.alliances = initData.teams }) Cow.onPacket(packets.ADD_ALLIANCE, (alliance) => { Cow.alliances.push(alliance) }) Cow.onPacket(packets.DELETE_ALLIANCE, (sid) => { for (let i = Cow.alliances.length - 1; i >= 0; i--) { if (Cow.alliances[i].sid !== sid) continue Cow.alliances.splice(i, 1) } }) Cow.onPacket(packets.SET_ALLIANCE_PLAYERS, (players) => { Cow.alliancePlayers = players }) Cow.onPacket(packets.UPDATE_PLAYERS, () => { const { player } = Cow if (Cow.ticker.ticks - lastPreplaceClear >= 1) { preplaceObjects = [] lastPreplaceClear = Cow.ticker.ticks } }) const macro = new Macro() const calculator = new Calculator() const autoPlacer = new AutoPlacer() const tailor = new Tailor() const autoHeal = new AutoHeal() const antiInsta = new AntiInsta() const autoMills = new AutoMills() const reloadBars = new ReloadBars() const antiTrap = new AntiTrap() const aimControl = new AimControl() Cow.addRender("global", () => { const { context } = Cow.renderer const { player } = Cow nearEnemy = Cow.getNearEnemy() for (const preplaceObject of preplaceObjects) { renderPreplace(preplaceObject, context) } macro.update() autoPlacer.update() tailor.update() autoHeal.update() antiInsta.update() autoMills.update() reloadBars.update() antiTrap.update() }) const oldSend = WebSocket.prototype.send WebSocket.prototype.send = function(data) { const binary = new Uint8Array(data) const decoded = Cow.codec.decoder.decode(binary) if (decoded[0] === packets.SPAWN) { decoded[1][0].moofoll = true decoded[1][0].name = "9-".concat(decoded[1][0].name) return oldSend.call(this, Cow.codec.encoder.encode(decoded)) } if (decoded[0] === packets.LOOK_DIR && aimControl.isAiming) { aimControl.updateAimToTarget() decoded[1][0] = aimControl.aimAngle oldSend.call(this, Cow.codec.encoder.encode(decoded)) return aimControl.onSent() } oldSend.apply(this, arguments) } function isInputFocused() { return document.activeElement.tagName === "INPUT" } function renderPreplace(preplaceObject, context) { const { player } = Cow const item = Cow.items.list[Cow.player.items[preplaceObject.id]] const sprite = getItemSprite(item) const x = (player.scale + item.scale) * Math.cos(preplaceObject.angle) const y = (player.scale + item.scale) * Math.sin(preplaceObject.angle) const isCanPlace = Cow.objectsManager.checkItemLocation(player.x + x, player.y + y, item.scale, 0.6, item.id, false) if (!isCanPlace) return context.save() context.globalAlpha = .3 context.translate(player.renderX + x, player.renderY + y) context.rotate(preplaceObject.angle) context.drawImage(sprite, -(sprite.width / 2), -(sprite.height / 2)) context.restore() } const itemSprites = {} function renderStar(ctxt, spikes, outer, inner) { const step = Math.PI / spikes let rot = Math.PI / 2 * 3 let x = 0 let y = 0 ctxt.beginPath() ctxt.moveTo(0, -outer) for (let i = 0; i < spikes; i++) { x = Math.cos(rot) * outer y = Math.sin(rot) * outer ctxt.lineTo(x, y) rot += step x = Math.cos(rot) * inner y = Math.sin(rot) * inner ctxt.lineTo(x, y) rot += step } ctxt.lineTo(0, -outer) ctxt.closePath() } function renderCircle(x, y, scale, tmpContext, dontStroke, dontFill) { tmpContext = tmpContext || Cow.renderer.context tmpContext.beginPath() tmpContext.arc(x, y, scale, 0, 2 * Math.PI) if (!dontFill) tmpContext.fill() if (!dontStroke) tmpContext.stroke() } function renderRect(x, y, w, h, ctxt, stroke) { ctxt.fillRect(x - (w / 2), y - (h / 2), w, h) if (!stroke) ctxt.strokeRect(x - (w / 2), y - (h / 2), w, h) } function renderRectCircle(x, y, s, sw, seg, ctxt, stroke) { ctxt.save() ctxt.translate(x, y) seg = Math.ceil(seg / 2) for (var i = 0; i < seg; i++) { renderRect(0, 0, s * 2, sw, ctxt, stroke) ctxt.rotate(Math.PI / seg) } ctxt.restore() } function renderTriangle(s, ctx) { ctx = ctx || Cow.renderer.context const h = s * (Math.sqrt(3) / 2) ctx.beginPath() ctx.moveTo(0, -h / 2) ctx.lineTo(-s / 2, h / 2) ctx.lineTo(s / 2, h / 2) ctx.lineTo(0, -h / 2) ctx.fill() ctx.closePath() } function getItemSprite(obj) { let tmpSprite = itemSprites[obj.id]; if (tmpSprite) return tmpSprite const tmpCanvas = document.createElement("canvas") const tmpContext = tmpCanvas.getContext("2d") const outlineWidth = 5.5 const outlineColor = "#525252" tmpCanvas.width = tmpCanvas.height = (obj.scale * 2.5) + outlineWidth + (Cow.items.list[obj.id].spritePadding || 0) tmpContext.strokeStyle = outlineColor tmpContext.lineWidth = outlineWidth tmpContext.translate((tmpCanvas.width / 2), (tmpCanvas.height / 2)) tmpContext.rotate(Math.PI / 2) if (/wall/.test(obj.name)) { const sides = (obj.name == "castle wall") ? 4 : 3 tmpContext.fillStyle = obj.name == "castle wall" ? "#83898e" : obj.name == "wood wall" ? "#a5974c" : "#939393" renderStar(tmpContext, sides, obj.scale * 1.1, obj.scale * 1.1) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = obj.name == "castle wall" ? "#9da4aa" : obj.name == "wood wall" ? "#c9b758" : "#bcbcbc" renderStar(tmpContext, sides, obj.scale * 0.65, obj.scale * 0.65) tmpContext.fill() } else if (/spikes/.test(obj.name)) { const tmpScale = (obj.scale * 0.6) tmpContext.fillStyle = obj.name == "poison spikes" ? "#7b935d" : "#939393" renderStar(tmpContext, (obj.name == "spikes") ? 5 : 6, obj.scale, tmpScale) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = "#a5974c" renderCircle(0, 0, tmpScale, tmpContext) tmpContext.fillStyle = "#c9b758" renderCircle(0, 0, tmpScale / 2, tmpContext, true) } else if (/mill/.test(obj.name)) { tmpContext.fillStyle = "#a5974c" renderCircle(0, 0, obj.scale, tmpContext) tmpContext.fillStyle = "#c9b758" renderRectCircle(0, 0, obj.scale * 1.5, 29, 4, tmpContext) tmpContext.fillStyle = "#a5974c" renderCircle(0, 0, obj.scale * 0.5, tmpContext) } else if (/mine/.test(obj.name)) { tmpContext.fillStyle = "#939393" renderStar(tmpContext, 3, obj.scale, obj.scale) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = "#bcbcbc" renderStar(tmpContext, 3, obj.scale * 0.55, obj.scale * 0.65) tmpContext.fill() } else if (/sapling/.test(obj.name)) { for (let i = 0; i < 2; ++i) { const tmpScale = obj.scale * (!i ? 1 : 0.5) renderStar(tmpContext, 7, tmpScale, tmpScale * 0.7) tmpContext.fillStyle = (!i ? "#9ebf57" : "#b4db62") tmpContext.fill() !i && tmpContext.stroke() } } else if (/trap/.test(obj.name)) { tmpContext.fillStyle = "#a5974c" renderStar(tmpContext, 3, obj.scale * 1.1, obj.scale * 1.1) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = outlineColor renderStar(tmpContext, 3, obj.scale * 0.65, obj.scale * 0.65) tmpContext.fill() } else if (/boost/.test(obj.name)) { tmpContext.fillStyle = "#7e7f82" renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = "#dbd97d" renderTriangle(obj.scale * 1, tmpContext) } else if (/turret/.test(obj.name)) { const tmpLen = 50 tmpContext.fillStyle = "#a5974c" renderCircle(0, 0, obj.scale, tmpContext) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = "#939393" renderRect(0, -tmpLen / 2, obj.scale * 0.9, tmpLen, tmpContext) renderCircle(0, 0, obj.scale * 0.6, tmpContext) tmpContext.fill() tmpContext.stroke() } else if (/platform/.test(obj.name)) { const tmpCount = 4; const tmpS = obj.scale * 2 const tmpW = tmpS / tmpCount let tmpX = -(obj.scale / 2) tmpContext.fillStyle = "#cebd5f" for (let i = 0; i < tmpCount; ++i) { renderRect(tmpX - (tmpW / 2), 0, tmpW, obj.scale * 2, tmpContext) tmpContext.fill() tmpContext.stroke() tmpX += tmpS / tmpCount } } else if (/spawn/.test(obj.name)) { tmpContext.fillStyle = "#7e7f82" renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext) tmpContext.fill() tmpContext.stroke() tmpContext.fillStyle = "#71aad6" renderCircle(0, 0, obj.scale * 0.6, tmpContext) } else if (/blocker/.test(obj.name)) { tmpContext.fillStyle = "#7e7f82" renderCircle(0, 0, obj.scale, tmpContext) tmpContext.fill() tmpContext.stroke() tmpContext.rotate(Math.PI / 4) tmpContext.fillStyle = "#db6e6e" renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true) } else if (/teleport/.test(obj.name)) { tmpContext.fillStyle = "#7e7f82" renderCircle(0, 0, obj.scale, tmpContext) tmpContext.fill() tmpContext.stroke() tmpContext.rotate(Math.PI / 4) tmpContext.fillStyle = "#d76edb" renderCircle(0, 0, obj.scale * 0.5, tmpContext, true) } tmpSprite = tmpCanvas itemSprites[obj.id] = tmpSprite return tmpSprite } function removeButton(buttonId) { const button = document.querySelector(buttonId) button.style.visibility = "hidden" } const checkButtons = setInterval(() => { const storeButton = document.getElementById("storeButton") if (!storeButton?.style) return createCustomHtmlAndCss() removeButton("#storeButton") removeButton("#chatButton") clearInterval(checkButtons) }) function createCustomHtmlAndCss() { const style = document.createElement("style") style.insertAdjacentHTML("beforeend", ` #gameName::after { content: "9mm"; display: inline-block; position: absolute; font-size: 40px; transform: rotate(45deg) translate(-10px, 60px) scale(1); text-shadow: 0 1px 0 #c4c4c4, 0 2px 0 #c4c4c4, 0 3px 0 #c4c4c4; animation: scale-anim 3s infinite ease-in-out; } @keyframes scale-anim { 0% { transform: rotate(45deg) translate(-10px, 60px) scale(1); } 50% { transform: rotate(45deg) translate(-10px, 60px) scale(1.1); } 100% { transform: rotate(45deg) translate(-10px, 60px) scale(1); } } `) document.head.appendChild(style) } })()