Professional Documents
Culture Documents
// @name MooVisuals
// @namespace https://github.com/Nudo-o
// @version 1
// @description best visual extension for moomoo.io with open source code
// @author @nudoo
// @match *://moomoo.io/*
// @match *://*.moomoo.io/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=moomoo.io
// @require https://context.werkors.repl.co/index.js
// @require
https://raw.githubusercontent.com/Nudo-o/MooUI/main/dist/mooui.min.js
// @license MIT
// @grant none
// ==/UserScript==
// If you are a coder and you read this code, then MooUI is my new library for
quick and easy menu creation in moomoo.io or other games. Try now:
https://github.com/Nudo-o/MooUI
! function() {
const allScript = document.getElementsByTagName("script")
let scriptIndex = 0
do {
scriptIndex++
script.remove()
} while (scriptIndex < allScript.length)
}()
!function(e) {
var t = {};
function i(n) {
if (t[n])
return t[n].exports;
var s = t[n] = {
i: n,
l: !1,
exports: {}
};
return e[n].call(s.exports, s, s.exports, i),
s.l = !0,
s.exports
}
i.m = e,
i.c = t,
i.d = function(e, t, n) {
i.o(e, t) || Object.defineProperty(e, t, {
enumerable: !0,
get: n
})
}
,
i.r = function(e) {
"undefined" != typeof Symbol && Symbol.toStringTag &&
Object.defineProperty(e, Symbol.toStringTag, {
value: "Module"
}),
Object.defineProperty(e, "__esModule", {
value: !0
})
}
,
i.t = function(e, t) {
if (1 & t && (e = i(e)),
8 & t)
return e;
if (4 & t && "object" == typeof e && e && e.__esModule)
return e;
var n = Object.create(null);
if (i.r(n),
Object.defineProperty(n, "default", {
enumerable: !0,
value: e
}),
2 & t && "string" != typeof e)
for (var s in e)
i.d(n, s, function(t) {
return e[t]
}
.bind(null, s));
return n
}
,
i.n = function(e) {
var t = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return i.d(t, "a", t),
t
}
,
i.o = function(e, t) {
return Object.prototype.hasOwnProperty.call(e, t)
}
,
i.p = "",
i(i.s = 2)
}([function(e, t, i) {
(function(t) {
e.exports.maxScreenWidth = 1920,
e.exports.maxScreenHeight = 1080,
e.exports.serverUpdateRate = 9,
e.exports.maxPlayers = t && -1 != t.argv.indexOf("--largeserver") ? 80 :
50,
e.exports.maxPlayersHard = e.exports.maxPlayers + 10,
e.exports.collisionDepth = 6,
e.exports.minimapRate = 3e3,
e.exports.colGrid = 10,
e.exports.clientSendRate = 5,
e.exports.healthBarWidth = 50,
e.exports.healthBarPad = 4.5,
e.exports.iconPadding = 15,
e.exports.iconPad = .9,
e.exports.deathFadeout = 3e3,
e.exports.crownIconScale = 60,
e.exports.crownPad = 35,
e.exports.chatCountdown = 3e3,
e.exports.chatCooldown = 500,
window.inSandbox = /sandbox\./.test(location.href),
e.exports.inSandbox = t && "mm_exp" === t.env.VULTR_SCHEME,
e.exports.maxAge = 100,
e.exports.gatherAngle = Math.PI / 2.6,
e.exports.gatherWiggle = 10,
e.exports.hitReturnRatio = .25,
e.exports.hitAngle = Math.PI / 2,
e.exports.playerScale = 35,
e.exports.playerSpeed = .0016,
e.exports.playerDecel = .993,
e.exports.nameY = 34,
e.exports.skinColors = ["#bf8f54", "#cbb091", "#896c4b", "#fadadc",
"#ececec", "#c37373", "#4c4c4c", "#ecaff7", "#738cc3", "#8bc373"],
e.exports.animalCount = 7,
e.exports.aiTurnRandom = .06,
e.exports.cowNames = ["Sid", "Steph", "Bmoe", "Romn", "Jononthecool",
"Fiona", "Vince", "Nathan", "Nick", "Flappy", "Ronald", "Otis", "Pepe", "Mc
Donald", "Theo", "Fabz", "Oliver", "Jeff", "Jimmy", "Helena", "Reaper", "Ben",
"Alan", "Naomi", "XYZ", "Clever", "Jeremy", "Mike", "Destined", "Stallion",
"Allison", "Meaty", "Sophia", "Vaja", "Joey", "Pendy", "Murdoch", "Theo", "Jared",
"July", "Sonia", "Mel", "Dexter", "Quinn", "Milky"],
e.exports.shieldAngle = Math.PI / 3,
e.exports.weaponVariants = [{
id: 0,
src: "",
xp: 0,
val: 1
}, {
id: 1,
src: "_g",
xp: 3e3,
val: 1.1
}, {
id: 2,
src: "_d",
xp: 7e3,
val: 1.18
}, {
id: 3,
src: "_r",
poison: !0,
xp: 12e3,
val: 1.18
}],
e.exports.fetchVariant = function(t) {
for (var i = t.weaponXP[t.weaponIndex] || 0, n =
e.exports.weaponVariants.length - 1; n >= 0; --n)
if (i >= e.exports.weaponVariants[n].xp)
return e.exports.weaponVariants[n]
}
,
e.exports.resourceTypes = ["wood", "food", "stone", "points"],
e.exports.areaCount = 7,
e.exports.treesPerArea = 9,
e.exports.bushesPerArea = 3,
e.exports.totalRocks = 32,
e.exports.goldOres = 7,
e.exports.riverWidth = 724,
e.exports.riverPadding = 114,
e.exports.waterCurrent = .0011,
e.exports.waveSpeed = 1e-4,
e.exports.waveMax = 1.3,
e.exports.treeScales = [150, 160, 165, 175],
e.exports.bushScales = [80, 85, 95],
e.exports.rockScales = [80, 85, 90],
e.exports.snowBiomeTop = 2400,
e.exports.snowSpeed = .75,
e.exports.maxNameLength = 15,
e.exports.mapScale = 14400,
e.exports.mapPingScale = 40,
e.exports.mapPingTime = 2200
}
).call(this, i(5))
}
, function(e, t) {
var i = {
utf8: {
stringToBytes: function(e) {
return i.bin.stringToBytes(unescape(encodeURIComponent(e)))
},
bytesToString: function(e) {
return decodeURIComponent(escape(i.bin.bytesToString(e)))
}
},
bin: {
stringToBytes: function(e) {
for (var t = [], i = 0; i < e.length; i++)
t.push(255 & e.charCodeAt(i));
return t
},
bytesToString: function(e) {
for (var t = [], i = 0; i < e.length; i++)
t.push(String.fromCharCode(e[i]));
return t.join("")
}
}
};
e.exports = i
}
, function(e, t, i) {
"use strict";
window.loadedScript = !0;
var n = "127.0.0.1" !== location.hostname && !
location.hostname.startsWith("192.168.");
i(3);
var s = i(4)
, o = i(6)
, a = i(7)
, r = i(0)
, c = i(8)
, l = i(9)
, h = (i(10),
i(11))
, u = i(12)
, d = i(19)
, f = i(20)
, p = i(21)
, g = i(22).obj
, m = new a.TextManager
, y = new (i(23))("moomoo.io",3e3,r.maxPlayers,5,!1);
y.debugLog = !1;
var k = !1;
function w() {
lt && ht && (k = !0,
n ? window.grecaptcha.execute("6LevKusUAAAAAAFknhlV8sPtXAk5Z5dGP5T2FYIZ", {
action: "homepage"
}).then((function(e) {
v(e)
}
)) : v(null))
}
function v(e) {
y.start((function(t, i, a) {
var c = (n ? "wss" : "ws") + "://" + t + ":8008/?gameIndex=" + a;
e && (c += "&token=" + encodeURIComponent(e)),
s.connect(c, (function(e) {
Mn(),
setInterval(()=>Mn(), 2500),
e ? ut(e) : (he.onclick = o.checkTrusted((function() {
!function() {
var e = ++yt > 1
, t = Date.now() - mt > gt;
e && t ? (mt = Date.now(),
kt()) : ki()
}()
}
)),
o.hookTouchEvents(he),
ue.onclick = o.checkTrusted((function() {
Pn("https://krunker.io/?play=Plundur.io")
}
)),
o.hookTouchEvents(ue),
fe.onclick = o.checkTrusted((function() {
setTimeout((function() {
!function() {
var e = be.value
, t = prompt("party key", e);
t && (window.onbeforeunload = void 0,
window.location.href = "/?server=" + t)
}()
}
), 10)
}
)),
o.hookTouchEvents(fe),
pe.onclick = o.checkTrusted((function() {
Ce.classList.contains("showing") ?
(Ce.classList.remove("showing"),
ge.innerText = "Settings") : (Ce.classList.add("showing"),
ge.innerText = "Close")
}
)),
o.hookTouchEvents(pe),
me.onclick = o.checkTrusted((function() {
ui(),
"block" != qe.style.display ? Bt() : qe.style.display = "none"
}
)),
o.hookTouchEvents(me),
ye.onclick = o.checkTrusted((function() {
"block" != Je.style.display ? (Je.style.display = "block",
qe.style.display = "none",
ei(),
qt()) : Je.style.display = "none"
}
)),
o.hookTouchEvents(ye),
ke.onclick = o.checkTrusted((function() {
$t()
}
)),
o.hookTouchEvents(ke),
Ge.onclick = o.checkTrusted((function() {
mi()
}
)),
o.hookTouchEvents(Ge),
function() {
for (var e = 0; e < Pi.length; ++e) {
var t = new Image;
t.onload = function() {
this.isLoaded = !0
}
,
t.src = ".././img/icons/" + Pi[e] + ".png",
Ci[Pi[e]] = t
}
}(),
Pe.style.display = "none",
Me.style.display = "block",
Le.value = M("moo_name") || "",
function() {
var e = M("native_resolution");
Yt(e ? "true" == e : "undefined" != typeof cordova),
P = "true" == M("show_ping"),
Ie.hidden = !P,
M("moo_moosic"),
setInterval((function() {
window.cordova &&
(document.getElementById("downloadButtonContainer").classList.add("cordova"),
document.getElementById("mobileDownloadButtonContainer").classList.add("cordova"))
}
), 1e3),
Kt(),
o.removeAllChildren(Oe);
for (var t = 0; t < l.weapons.length + l.list.length; ++t)
!function(e) {
o.generateElement({
id: "actionBarItem" + e,
class: "actionBarItem",
style: "display:none",
onmouseout: function() {
wt()
},
parent: Oe
})
Oe.style.display = "flex"
Oe.style.justifyContent = "center"
const id = e - 16
const actionBarItem =
document.getElementById(`actionBarItem${e}`)
const limit = window.inSandbox ? Math.max(3 *
l.list[id].group.limit, 99) : l.list[id].group.limit
actionBarItem.insertAdjacentHTML("beforeend", `<span
class="item-count" id="itemCount_${id}" style="display: none; color: #fff; font-
size: 14px;">${menu.getModelActive("item-counts") ? `0/${limit}` : ""}</span>`)
window.toggleItemCounts()
}(t);
for (t = 0; t < l.list.length + l.weapons.length; ++t)
!function(e) {
var t = document.createElement("canvas");
t.width = t.height = 66;
var i = t.getContext("2d");
if (i.translate(t.width / 2, t.height / 2),
i.imageSmoothingEnabled = !1,
i.webkitImageSmoothingEnabled = !1,
i.mozImageSmoothingEnabled = !1,
l.weapons[e]) {
i.rotate(Math.PI / 4 + Math.PI);
var n = new Image;
Yi[l.weapons[e].src] = n,
n.onload = function() {
this.isLoaded = !0;
var n = 1 / (this.height / this.width)
, s = l.weapons[e].iPad || 1;
i.drawImage(this, -t.width * s * r.iconPad *
n / 2, -t.height * s * r.iconPad / 2, t.width * s * n * r.iconPad, t.height * s *
r.iconPad),
i.fillStyle = "rgba(0, 0, 70, 0.1)",
i.globalCompositeOperation = "source-atop",
i.fillRect(-t.width / 2, -t.height / 2,
t.width, t.height),
document.getElementById("actionBarItem" +
e).style.backgroundImage = "url(" + t.toDataURL() + ")"
}
,
n.src = ".././img/weapons/" + l.weapons[e].src +
".png",
(s = document.getElementById("actionBarItem" +
e)).onmouseover = o.checkTrusted((function() {
wt(l.weapons[e], !0)
}
)),
s.onclick = o.checkTrusted((function() {
yi(e, !0)
}
)),
o.hookTouchEvents(s)
} else {
n = Zi(l.list[e - l.weapons.length], !0);
var s, a = Math.min(t.width - r.iconPadding,
n.width);
i.globalAlpha = 1,
i.drawImage(n, -a / 2, -a / 2, a, a),
i.fillStyle = "rgba(0, 0, 70, 0.1)",
i.globalCompositeOperation = "source-atop",
i.fillRect(-a / 2, -a / 2, a, a),
document.getElementById("actionBarItem" +
e).style.backgroundImage = "url(" + t.toDataURL() + ")",
(s = document.getElementById("actionBarItem" +
e)).onmouseover = o.checkTrusted((function() {
wt(l.list[e - l.weapons.length])
}
)),
s.onclick = o.checkTrusted((function() {
yi(e - l.weapons.length)
}
)),
o.hookTouchEvents(s)
}
}(t);
Le.ontouchstart = o.checkTrusted((function(e) {
e.preventDefault();
var t = prompt("enter name", e.currentTarget.value);
t && (e.currentTarget.value = t.slice(0, 15))
}
)),
xe.checked = C,
xe.onchange = o.checkTrusted((function(e) {
Yt(e.target.checked)
}
)),
Se.checked = P,
Se.onchange = o.checkTrusted((function(e) {
P = Se.checked,
Ie.hidden = !P,
T("show_ping", P ? "true" : "false")
}
))
}())
}
), {
id: st,
d: ut,
1: vi,
2: gn,
4: mn,
33: updatePlayers,
5: ji,
6: on,
a: un,
aa: hn,
7: gatherAnimation,
8: an,
sp: rn,
9: kn,
h: updateHealth,
11: Si,
12: Ti,
13: Ii,
14: yn,
15: Bi,
16: Oi,
17: Nt,
18: cn,
19: ln,
20: Cn,
ac: Ct,
ad: Ot,
an: Tt,
st: Pt,
sa: Et,
us: Vt,
ch: si,
mm: Ft,
t: bi,
p: _t,
pp: Tn
}),
ft(),
setTimeout(()=>pt(), 3e3)
}
), (function(e) {
console.error("Vultr error:", e),
alert("Error:\n" + e),
ut("disconnected")
}
))
}
var b, x = new g(r,o), S = Math.PI, I = 2 * S;
function T(e, t) {
b && localStorage.setItem(e, t)
}
function M(e) {
return b ? localStorage.getItem(e) : null
}
Math.lerpAngle = function(e, t, i) {
Math.abs(t - e) > S && (e > t ? t += I : e += I);
var n = t + (e - t) * i;
return n >= 0 && n <= I ? n : n % I
}
,
CanvasRenderingContext2D.prototype.roundRect = function(e, t, i, n, s) {
return i < 2 * s && (s = i / 2),
n < 2 * s && (s = n / 2),
s < 0 && (s = 0),
this.beginPath(),
this.moveTo(e + s, t),
this.arcTo(e + i, t, e + i, t + n, s),
this.arcTo(e + i, t + n, e, t + n, s),
this.arcTo(e, t + n, e, t, s),
this.arcTo(e, t, e + i, t, s),
this.closePath(),
this
}
,
"undefined" != typeof Storage && (b = !0);
var C, P, E, O, B, j, A, D, U, R, L, z, _, F, H = M("moofoll"), V = 1, q =
Date.now(), W = [], X = [], G = [], N = [], Y = [], K = new p(f,Y,X,W,tt,l,r,o), J
= i(35), Q = i(36), $ = new J(W,Q,X,l,null,r,o), Z = 1, ee = 0, te = 0, ie = 0, ne
= {
id: -1,
startX: 0,
startY: 0,
currentX: 0,
currentY: 0
}, se = {
id: -1,
startX: 0,
startY: 0,
currentX: 0,
currentY: 0
}, oe = 0, maxScreenWidth = r.maxScreenWidth, maxScreenHeight =
r.maxScreenHeight, ce = !1, le = (document.getElementById("ad-container"),
document.getElementById("mainMenu")), he =
document.getElementById("enterGame"), ue = document.getElementById("promoImg"), de
= document.getElementById("partyButton"), fe =
document.getElementById("joinPartyButton"), pe =
document.getElementById("settingsButton"), ge = pe.getElementsByTagName("span")[0],
me = document.getElementById("allianceButton"), ye =
document.getElementById("storeButton"), ke = document.getElementById("chatButton"),
we = document.getElementById("gameCanvas"), ve = we.getContext("2d"), be =
document.getElementById("serverBrowser"), xe =
document.getElementById("nativeResolution"), Se =
document.getElementById("showPing"), Ie = (document.getElementById("playMusic"),
document.getElementById("pingDisplay")), Te =
document.getElementById("shutdownDisplay"), Me =
document.getElementById("menuCardHolder"), Ce =
document.getElementById("guideCard"), Pe = document.getElementById("loadingText"),
Ee = document.getElementById("gameUI"), Oe = document.getElementById("actionBar"),
Be = document.getElementById("scoreDisplay"), je =
document.getElementById("foodDisplay"), Ae =
document.getElementById("woodDisplay"), De =
document.getElementById("stoneDisplay"), Ue =
document.getElementById("killCounter"), Re =
document.getElementById("leaderboardData"), Le =
document.getElementById("nameInput"), ze =
document.getElementById("itemInfoHolder"), _e = document.getElementById("ageText"),
Fe = document.getElementById("ageBarBody"), He =
document.getElementById("upgradeHolder"), Ve =
document.getElementById("upgradeCounter"), qe =
document.getElementById("allianceMenu"), We =
document.getElementById("allianceHolder"), Xe =
document.getElementById("allianceManager"), Ge =
document.getElementById("mapDisplay"), Ne = document.getElementById("diedText"), Ye
= document.getElementById("skinColorHolder"), Ke = Ge.getContext("2d");
Ge.width = 300,
Ge.height = 300;
var Je = document.getElementById("storeMenu")
, Qe = document.getElementById("storeHolder")
, $e = document.getElementById("noticationDisplay")
, Ze = d.hats
, et = d.accessories
, tt = new h(c,N,o,r)
, it = "#525252"
, nt = "#3d3f42";
window._maxScreenWidth = maxScreenWidth
window._maxScreenHeight = maxScreenHeight
if (document.getElementById("promoImgHolder")) {
document.getElementById("promoImgHolder").remove()
}
let settings = {
"attack-animation": false,
"health-animation": true,
"health-particles": false,
"health-particles-color": "#579d0c",
"blood-particles": false,
"blood-particles-color": "#9d0c0c",
"shame-indicators": true,
"shame-counter": false,
"shame-counter-color": "#ffffff",
"shame-hat": true,
"tracers-to-players": false,
"tracers-players-use-arrows": false,
"tracers-players-dashline": false,
"tracers-color-ally": "#8ecc51",
"tracers-color-enemy": "#cc5151",
"reload-bars": true,
"reload-bars-primary": true,
"reload-bars-secondary": true,
"reload-bars-color-ally": "#8ecc51",
"reload-bars-color-enemy": "#cc5151",
"player-health-text": false,
"movement-tail": false,
"movement-tail-all-players": false,
"movement-tail-scale": "4",
"hack-detector": false,
"tracers-to-animals": false,
"tracers-animals-use-arrows": false,
"tracers-animals-dashline": false,
"tracers-color-animal": "#cd9d51",
"animals-health-text": true,
"building-health-bar": true,
"building-health-bar-use-round": true,
"building-health-bar-range": "3",
"turret-reload-bar": true,
"turret-reload-bar-color": "#a5974c",
"turret-range-indicator": false,
"destroy-animation": true,
"disable-buildings-turn": true,
"buildings-health-text": false,
"place-helper": false,
"smooth-camera": false,
"smooth-chat": true,
"wheel-zoom": false,
"coastlines": true,
"snow-coast": true,
"desert-coast": true,
"disable-game-grid": false,
"disable-river-waves": false,
"disable-damage-text": false,
"disable-object-wiggle": false,
"nickname": true,
"nickname-float-left": false,
"nickname-offset-x": 0,
"nickname-offset-y": 0,
"nickname-color": "#ffffff",
"minimap": true,
"minimap-biomes": true,
"minimap-resources": false,
"item-counts": true,
"show-stats": true
}
const settingsMap = Object.entries(settings)
localStorage.setItem("visual-settings", JSON.stringify(settings))
}
if (!visualSettings) {
localStorage.setItem("visual-settings", JSON.stringify(settings))
break
}
if (!visualSettings.hasOwnProperty(settingsMap[i][0])) {
setVisualSetting(settingsMap[i][0], settingsMap[i][1])
}
}
settings = JSON.parse(localStorage.getItem("visual-settings"))
playersVisual.setHeaderText("Players")
animalsVisual.setHeaderText("Animals")
buildingsVisual.setHeaderText("Buildings")
gameVisual.setHeaderText("Game")
guiVisual.setHeaderText("GUI")
playersVisual.add(new window.MooUI.Checkbox({
key: "attack-animation",
name: "Attack Animation",
description: "Creating particulars when attacking and around players",
isActive: settings["attack-animation"]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "health-animation",
name: "Health Animation",
description: "Smoothly reduces and increases the health of players",
isActive: settings["health-animation"]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "health-particles",
name: "Health Particles",
description: "When a player heals, particles fly out of him",
isActive: settings["health-particles"],
options: [
new window.MooUI.OptionIColor({
key: "health-particles-color",
name: "Color",
description: "Color of health particles",
value: settings["health-particles-color"]
}),
]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "blood-particles",
name: "Blood Particles",
description: "When a player takes damage, particles fly out of him",
isActive: settings["blood-particles"],
options: [
new window.MooUI.OptionIColor({
key: "blood-particles-color",
name: "Color",
description: "Color of blood particles",
value: settings["blood-particles-color"]
})
]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "shame-indicators",
name: "Shame Indicators",
description: "Draws the selected shame designators",
isActive: settings["shame-indicators"],
options: [
new window.MooUI.OptionCheckbox({
key: "shame-counter",
name: "Shame Counter",
description: "Draws a shame counter after the player's nickname",
isActive: settings["shame-counter"]
}),
new window.MooUI.OptionCheckbox({
key: "shame-hat",
name: "Shame Hat",
description: "Gradually increases the visibility of the shame cap
depending on the amount of shame",
isActive: settings["shame-hat"]
}),
new window.MooUI.OptionIColor({
key: "shame-counter-color",
name: "Shame Counter Color",
description: "Color of shame counter text",
value: settings["shame-counter-color"]
})
]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "tracers-to-players",
name: "Tracers",
description: "Draws tracers to players",
isActive: settings["tracers-to-players"],
options: [
new window.MooUI.OptionCheckbox({
key: "tracers-players-use-arrows",
name: "Use Arrows",
description: "Uses an arrow instead of a line",
isActive: settings["tracers-players-use-arrows"]
}),
new window.MooUI.OptionCheckbox({
key: "tracers-players-dashline",
name: "Dash Line",
description: "Makes a tracer in the form of dotted lines",
isActive: settings["tracers-players-dashline"]
}),
new window.MooUI.OptionIColor({
key: "tracers-color-ally",
name: "Ally Color",
description: "Tracer color for Allies",
value: settings["tracers-color-ally"]
}),
new window.MooUI.OptionIColor({
key: "tracers-color-enemy",
name: "Enemy Color",
description: "Trace color for enemies",
value: settings["tracers-color-enemy"]
})
]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "reload-bars",
name: "Reload Bars",
description: "Shows how loaded the weapon is and ready to attack",
isActive: settings["reload-bars"],
options: [
new window.MooUI.OptionCheckbox({
key: "reload-bars-primary",
name: "Primary Bar",
description: "Melee weapon bar",
isActive: settings["reload-bars-primary"]
}),
new window.MooUI.OptionCheckbox({
key: "reload-bars-secondary",
name: "Secondary Bar",
description: "Long-range weapon bar",
isActive: settings["reload-bars-secondary"]
}),
new window.MooUI.OptionIColor({
key: "reload-bars-color-ally",
name: "Ally Color",
description: "The color of the bars for the ally",
value: settings["reload-bars-color-ally"]
}),
new window.MooUI.OptionIColor({
key: "reload-bars-color-enemy",
name: "Enemy Color",
description: "The color of the bars for the enemies",
value: settings["reload-bars-color-enemy"]
})
]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "player-health-text",
name: "Health Text",
description: "Draws the value of health",
isActive: settings["player-health-text"]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "movement-tail",
name: "Movement Tail",
description: "Draws a tail behind you",
isActive: settings["movement-tail"],
options: [
new window.MooUI.OptionCheckbox({
key: "movement-tail-all-players",
name: "All Players",
description: "If enabled, the movement tail will be drawn for all
players",
isActive: settings["movement-tail-all-players"]
}),
new window.MooUI.OptionIRange({
key: "movement-tail-scale",
name: "Scale",
description: "Particle scale",
min: 1,
max: 10,
value: settings["movement-tail-scale"]
})
]
}))
playersVisual.add(new window.MooUI.Checkbox({
key: "hack-detector",
name: "Hack Detector (Beta)",
description: "Shows how many percent a player can be a cheater",
isActive: settings["hack-detector"]
}))
animalsVisual.add(new window.MooUI.Checkbox({
key: "tracers-to-animals",
name: "Tracers",
description: "Draws tracers to animals",
isActive: settings["tracers-to-animals"],
options: [
new window.MooUI.OptionCheckbox({
key: "tracers-animals-use-arrows",
name: "Use Arrows",
description: "Uses an arrow instead of a line",
isActive: settings["tracers-animals-use-arrows"]
}),
new window.MooUI.OptionCheckbox({
key: "tracers-animals-dashline",
name: "Dash Line",
description: "Makes a tracer in the form of dotted lines",
isActive: settings["tracers-animals-dashline"]
}),
new window.MooUI.OptionIColor({
key: "tracers-color-animal",
name: "Color",
description: "Tracer color for animals",
value: settings["tracers-color-animal"]
})
]
}))
animalsVisual.add(new window.MooUI.Checkbox({
key: "animals-health-text",
name: "Health Text",
description: "Draws the value of health",
isActive: settings["animals-health-text"]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "building-health-bar",
name: "Health Bar",
description: "Shows the health of buildings in the form of a rectangular
bar",
isActive: settings["building-health-bar"],
options: [
new window.MooUI.OptionCheckbox({
key: "building-health-bar-use-round",
name: "Use Round Bar",
description: "Use round bar instead of rectangular bar",
isActive: settings["building-health-bar-use-round"]
}),
new window.MooUI.OptionIRange({
key: "building-health-bar-range",
name: "Target Radius",
description: "The radius in which health bars is displayed",
min: 1,
max: 8,
value: settings["building-health-bar-range"]
})
]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "turret-reload-bar",
name: "Turret Reload Bar",
description: "Shows after how long the turret will shoot in the form of a
bar",
isActive: settings["turret-reload-bar"],
options: [
new window.MooUI.OptionIColor({
key: "turret-reload-bar-color",
name: "Color",
description: "Color of bars for turrets",
value: settings["turret-reload-bar-color"]
})
]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "turret-range-indicator",
name: "Turret Range Indicator",
description: "Draws a line where the turret will react and shoot",
isActive: settings["turret-range-indicator"]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "destroy-animation",
name: "Destroy Animation",
description: "Smooth removal of a building after it is destroyed",
isActive: settings["destroy-animation"]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "disable-buildings-turn",
name: "Disable Turn",
description: "Buildings will no longer rotate",
isActive: settings["disable-buildings-turn"]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "buildings-health-text",
name: "Health Text",
description: "Draws the value of health",
isActive: settings["buildings-health-text"]
}))
buildingsVisual.add(new window.MooUI.Checkbox({
key: "place-helper",
name: "Place Helper (Beta)",
description: "Shows the places where buildings can be placed",
isActive: settings["place-helper"]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "smooth-camera",
name: "Smooth Camera",
description: "The camera moves more smoothly",
isActive: settings["smooth-camera"]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "smooth-chat",
name: "Smooth Chat",
description: "Chat smoothly appears and disappears",
isActive: settings["smooth-chat"]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "wheel-zoom",
name: "Wheel Zoom",
description: "Changes the scale of the game if you turn the mouse wheel.",
isActive: settings["wheel-zoom"]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "coastlines",
name: "Coastlines",
description: "Creates a smooth transition",
isActive: settings["coastlines"],
options: [
new window.MooUI.OptionCheckbox({
key: "snow-coast",
name: "Snow Coast",
description: "Creates a smooth transition between snow and grass",
isActive: settings["snow-coast"]
}),
new window.MooUI.OptionCheckbox({
key: "desert-coast",
name: "Desert Coast",
description: "Creates a smooth transition between desert and
grass",
isActive: settings["desert-coast"]
})
]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "disable-game-visuals",
name: "Disable Visuals",
description: "Disables the rendering of the game visuals",
isDisabled: true,
options: [
new window.MooUI.OptionCheckbox({
key: "disable-game-grid",
name: "Disable Game Grid",
description: "Disables the rendering of the game grid",
isActive: settings["disable-game-grid"]
}),
new window.MooUI.OptionCheckbox({
key: "disable-river-waves",
name: "Disable River Waves",
description: "Disables the rendering of the river waves",
isActive: settings["disable-river-waves"]
}),
new window.MooUI.OptionCheckbox({
key: "disable-damage-text",
name: "Disable Damage Text",
description: "Disable the text that flies out of the player when he
takes damage or heals",
isActive: settings["disable-damage-text"]
}),
new window.MooUI.OptionCheckbox({
key: "disable-object-wiggle",
name: "Disable Object Wiggle",
description: "Disables the object's repulsion when it is hit or it
shoots",
isActive: settings["disable-object-wiggle"]
})
]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "nickname",
name: "Nickname",
description: "Setting up a nickname",
isActive: settings["nickname"],
options: [
new window.MooUI.OptionCheckbox({
key: "nickname-float-left",
name: "Float Left",
description: "Changes the direction of displacement along the X
axis",
isActive: settings["nickname-float-left"]
}),
new window.MooUI.OptionIRange({
key: "nickname-offset-x",
name: "Offset X",
description: "Nickname X-axis offset",
min: 0,
max: 225,
value: settings["nickname-offset-x"]
}),
new window.MooUI.OptionIRange({
key: "nickname-offset-y",
name: "Offset Y",
description: "Nickname Y-axis offset",
min: 0,
max: 225,
value: settings["nickname-offset-y"]
}),
new window.MooUI.OptionIColor({
key: "nickname-color",
name: "Color",
description: "Nickname color",
value: settings["nickname-color"]
})
]
}))
gameVisual.add(new window.MooUI.Checkbox({
key: "minimap",
name: "Minimap",
description: "Setting up a minimap",
isActive: settings["minimap"],
options: [
new window.MooUI.OptionCheckbox({
key: "minimap-biomes",
name: "Biomes",
description: "Draws biomes on a minimap",
isActive: settings["minimap-biomes"]
}),
new window.MooUI.OptionCheckbox({
key: "minimap-resources",
name: "Resources",
description: "Draws submerged trees, bushes, and rocks on a
minimap",
isActive: settings["minimap-resources"]
})
]
}))
guiVisual.add(new window.MooUI.Checkbox({
key: "item-counts",
name: "Item Counts",
description: "Shows the number of specific buildings delivered",
isActive: settings["item-counts"]
}))
guiVisual.add(new window.MooUI.Checkbox({
key: "show-stats",
name: "Show Stats",
description: "Shows Ping (data transfer delay) and fps (frame per second)",
isActive: settings["show-stats"]
}))
menu.onModelsAction(setVisualSetting)
menu.getModel("show-stats").on("click", () => {
window.togglePingDisplay && window.togglePingDisplay()
})
window.toggleItemCounts = function() {
const itemCounts = Object.values(document.querySelectorAll(".item-count"))
continue
}
itemCount.style.display = "none"
}
}
menu.getModel("item-counts").on("click", window.toggleItemCounts)
if (!menu.getModelActive("wheel-zoom") || !player?.alive ||
document.activeElement.tagName === "INPUT") return
if (event.deltaY > 0) {
if (maxScreenWidth <= 50000) {
for (let i = 0; i < 25; i += 1) {
setTimeout(() => {
if (maxScreenWidth > 50000) return
maxScreenWidth *= power
maxScreenHeight *= power
oi()
}, i * 5)
}
}
} else {
if (maxScreenWidth >= 500) {
for (let i = 0; i < 25; i += 1) {
setTimeout(() => {
if (maxScreenWidth < 500) return
maxScreenWidth /= power
maxScreenHeight /= power
oi()
}, i * 5)
}
}
}
})
function st(e) {
G = e.teams
}
const ot = document.getElementById("featuredYoutube")
ot.innerHTML = `
<a target="_blank" class="ytLink"
href="https://www.youtube.com/@nudo1050/featured">
<i class='material-icons' style='vertical-align: top;'></i> Nudo
</a>
`
var ct = !0
, lt = !1
, ht = !1;
function ut(e) {
s.close(),
dt(e)
}
function dt(e) {
le.style.display = "block",
Ee.style.display = "none",
Me.style.display = "none",
Ne.style.display = "none",
Pe.style.display = "block",
Pe.innerHTML = e + "<a
href='javascript:window.location.href=window.location.href'
class='ytLink'>reload</a>"
}
window.onblur = function() {
ct = !1
}
window.onfocus = function() {
ct = !0
window.onload = function() {
window.follmoo()
shameImg.onload = function() {
this.isLoaded = true
this.onload = null
}
shameImg.src = `.././img/hats/hat_${shameHat.id}.png`
shameImg.scale = shameHat.scale
Wi.shameImg = shameImg
lt = !0
w()
setTimeout(() => {
k || (alert("Captcha failed to load"), window.location.reload())
}, 2e4)
}
window.captchaCallback = function() {
ht = !0
w()
}
we.oncontextmenu = function() {
return !1
}
function ft() {
var e, t, i = "", n = 0;
for (var s in y.servers) {
for (var o = y.servers[s], a = 0, c = 0; c < o.length; c++)
for (var l = 0; l < o[c].games.length; l++)
a += o[c].games[l].playerCount;
n += a;
var h = y.regionInfo[s].name;
i += "<option disabled>" + h + " - " + a + " players</option>";
for (var u = 0; u < o.length; u++)
for (var d = o[u], f = 0; f < d.games.length; f++) {
var p = d.games[f]
, g = 1 * d.index + f + 1
, m = y.server && y.server.region === d.region &&
y.server.index === d.index && y.gameIndex == f
, k = h + " " + g + " [" + Math.min(p.playerCount,
r.maxPlayers) + "/" + r.maxPlayers + "]";
let e = y.stripRegion(s) + ":" + u + ":" + f;
m && (de.getElementsByTagName("span")[0].innerText = e),
i += "<option value='" + e + "' " + (m ? "selected" : "") + ">"
+ k + "</option>"
}
i += "<option disabled></option>"
}
i += "<option disabled>All Servers - " + n + " players</option>",
be.innerHTML = i,
"sandbox.moomoo.io" == location.hostname ? (e = "Back to MooMoo",
t = "//moomoo.io/") : (e = "Try the sandbox",
t = "//sandbox.moomoo.io/"),
document.getElementById("altServer").innerHTML = "<a href='" + t + "'>" + e
+ "<i class='material-icons' style='font-size:10px;vertical-
align:middle'>arrow_forward_ios</i></a>"
}
function pt() {
var e = new XMLHttpRequest;
e.onreadystatechange = function() {
4 == this.readyState && (200 == this.status ? (window.vultr =
JSON.parse(this.responseText),
(y.processServers instanceof Function &&
y.processServers(vultr.servers)),
ft()) : console.error("Failed to load server data with status code:",
this.status))
}
,
e.open("GET", "/serverData", !0),
e.send()
}
be.addEventListener("change", o.checkTrusted((function() {
let e = be.value.split(":");
y.switchServer(e[0], e[1], e[2])
}
)));
var gt = 3e5
, mt = 0
, yt = 0;
function kt() {
if (!window.adsbygoogle)
return console.log("Failed to load video ad API"),
void ki();
window.adsbygoogle.push({
type: "next",
adBreakDone: ()=>{
ki()
}
})
}
function wt(e, t, i) {
if (A && e)
if (o.removeAllChildren(ze),
ze.classList.add("visible"),
o.generateElement({
id: "itemInfoName",
text: o.capitalizeFirst(e.name),
parent: ze
}),
o.generateElement({
id: "itemInfoDesc",
text: e.desc,
parent: ze
}),
i)
;
else if (t)
o.generateElement({
class: "itemInfoReq",
text: e.type ? "secondary" : "primary",
parent: ze
});
else {
for (var n = 0; n < e.req.length; n += 2)
o.generateElement({
class: "itemInfoReq",
html: e.req[n] + "<span class='itemInfoReqVal'> x" +
e.req[n + 1] + "</span>",
parent: ze
});
e.group.limit && o.generateElement({
class: "itemInfoLmt",
text: (A.itemCounts[e.group.id] || 0) + "/" + e.group.limit,
parent: ze
})
}
else
ze.classList.remove("visible")
}
window.adsbygoogle && adsbygoogle.push({
preloadAdBreaks: "on"
}),
window.showPreAd = kt;
var vt, bt, xt, St = [], It = [];
function Tt(e, t) {
St.push({
sid: e,
name: t
}),
Mt()
}
function Mt() {
if (St[0]) {
var e = St[0];
o.removeAllChildren($e),
$e.style.display = "block",
o.generateElement({
class: "notificationText",
text: e.name,
parent: $e
}),
o.generateElement({
class: "notifButton",
html: "<i class='material-icons' style='font-
size:28px;color:#cc5151;'></i>",
parent: $e,
onclick: function() {
jt(0)
},
hookTouch: !0
}),
o.generateElement({
class: "notifButton",
html: "<i class='material-icons' style='font-
size:28px;color:#8ecc51;'></i>",
parent: $e,
onclick: function() {
jt(1)
},
hookTouch: !0
})
} else
$e.style.display = "none"
}
function Ct(e) {
G.push(e),
"block" == qe.style.display && Bt()
}
function Pt(e, t) {
A && (A.team = e,
A.isOwner = t,
"block" == qe.style.display && Bt())
}
function Et(e) {
It = e,
"block" == qe.style.display && Bt()
}
function Ot(e) {
for (var t = G.length - 1; t >= 0; t--)
G[t].sid == e && G.splice(t, 1);
"block" == qe.style.display && Bt()
}
function Bt() {
if (A && A.alive) {
if (ei(),
Je.style.display = "none",
qe.style.display = "block",
o.removeAllChildren(We),
A.team)
for (var e = 0; e < It.length; e += 2)
!function(e) {
var t = o.generateElement({
class: "allianceItem",
style: "color:" + (It[e] == A.sid ? "#fff" :
"rgba(255,255,255,0.6)"),
text: It[e + 1],
parent: We
});
A.isOwner && It[e] != A.sid && o.generateElement({
class: "joinAlBtn",
text: "Kick",
onclick: function() {
At(It[e])
},
hookTouch: !0,
parent: t
})
}(e);
else if (G.length)
for (e = 0; e < G.length; ++e)
!function(e) {
var t = o.generateElement({
class: "allianceItem",
style: "color:" + (G[e].sid == A.team ? "#fff" :
"rgba(255,255,255,0.6)"),
text: G[e].sid,
parent: We
});
o.generateElement({
class: "joinAlBtn",
text: "Join",
onclick: function() {
Dt(e)
},
hookTouch: !0,
parent: t
})
}(e);
else
o.generateElement({
class: "allianceItem",
text: "No Tribes Yet",
parent: We
});
o.removeAllChildren(Xe),
A.team ? o.generateElement({
class: "allianceButtonM",
style: "width: 360px",
text: A.isOwner ? "Delete Tribe" : "Leave Tribe",
onclick: function() {
Rt()
},
hookTouch: !0,
parent: Xe
}) : (o.generateElement({
tag: "input",
type: "text",
id: "allianceInput",
maxLength: 7,
placeholder: "unique name",
ontouchstart: function(e) {
e.preventDefault();
var t = prompt("unique name", e.currentTarget.value);
e.currentTarget.value = t.slice(0, 7)
},
parent: Xe
}),
o.generateElement({
tag: "div",
class: "allianceButtonM",
style: "width: 140px;",
text: "Create",
onclick: function() {
Ut()
},
hookTouch: !0,
parent: Xe
}))
}
}
function jt(e) {
s.send("11", St[0].sid, e),
St.splice(0, 1),
Mt()
}
function At(e) {
s.send("12", e)
}
function Dt(e) {
s.send("10", G[e].sid)
}
function Ut() {
s.send("8", document.getElementById("allianceInput").value)
}
function Rt() {
St = [],
Mt(),
s.send("9")
}
window.socket = s
we.width = _ * V
we.height = F * V
we.style.width = _ + "px"
we.style.height = F + "px"
ve.setTransform(scale, 0, 0, scale, (_ * V - maxScreenWidth * scale) / 2,
(F * V - maxScreenHeight * scale) / 2)
window._maxScreenWidth = maxScreenWidth
window._maxScreenHeight = maxScreenHeight
}
function ai(e) {
(ti = e) ? Ce.classList.add("touch") : Ce.classList.remove("touch")
}
function ri(e) {
e.preventDefault(),
e.stopPropagation(),
ai(!0);
for (var t = 0; t < e.changedTouches.length; t++) {
var i = e.changedTouches[t];
i.identifier == ne.id ? (ne.id = -1,
gi()) : i.identifier == se.id && (se.id = -1,
A.buildIndex >= 0 && (j = 1,
fi()),
j = 0,
fi())
}
}
function ci() {
if (!A) return 0
window.addEventListener("resize", o.checkTrusted(oi)),
oi(),
ai(!1),
window.setUsingTouch = ai,
we.addEventListener("touchmove", o.checkTrusted((function(e) {
e.preventDefault(),
e.stopPropagation(),
ai(!0);
for (var t = 0; t < e.changedTouches.length; t++) {
var i = e.changedTouches[t];
i.identifier == ne.id ? (ne.currentX = i.pageX,
ne.currentY = i.pageY,
gi()) : i.identifier == se.id && (se.currentX = i.pageX,
se.currentY = i.pageY,
j = 1)
}
}
)), !1),
we.addEventListener("touchstart", o.checkTrusted((function(e) {
if (!ce)
return e.preventDefault(),
!1;
e.preventDefault(),
e.stopPropagation(),
ai(!0);
for (var t = 0; t < e.changedTouches.length; t++) {
var i = e.changedTouches[t];
i.pageX < document.body.scrollWidth / 2 && -1 == ne.id ? (ne.id =
i.identifier,
ne.startX = ne.currentX = i.pageX,
ne.startY = ne.currentY = i.pageY,
gi()) : i.pageX > document.body.scrollWidth / 2 && -1 == se.id &&
(se.id = i.identifier,
se.startX = se.currentX = i.pageX,
se.startY = se.currentY = i.pageY,
A.buildIndex < 0 && (j = 1,
fi()))
}
}
)), !1),
we.addEventListener("touchend", o.checkTrusted(ri), !1),
we.addEventListener("touchcancel", o.checkTrusted(ri), !1),
we.addEventListener("touchleave", o.checkTrusted(ri), !1),
we.addEventListener("mousemove", (function(e) {
e.preventDefault(),
e.stopPropagation(),
ai(!1),
te = e.clientX,
ie = e.clientY
}
), !1),
we.addEventListener("mousedown", (function(e) {
ai(!1),
1 != j && (j = 1,
fi())
}
), !1),
we.addEventListener("mouseup", (function(e) {
ai(!1),
0 != j && (j = 0,
fi())
}
), !1);
var li = {}
, hi = {
87: [0, -1],
38: [0, -1],
83: [0, 1],
40: [0, 1],
65: [-1, 0],
37: [-1, 0],
68: [1, 0],
39: [1, 0]
};
function ui() {
li = {},
s.send("rmd")
}
function di() {
return "block" != qe.style.display && "block" != Qt.style.display
}
function fi() {
A && A.alive && s.send("c", j, A.buildIndex >= 0 ? ci() : null)
}
window.addEventListener("keydown", o.checkTrusted((function(e) {
if (document.activeElement.tagName === "INPUT" && e.keyCode !== 13 &&
e.keyCode !== 27) return
if (A && A.alive) {
var t = e.which || e.keyCode || 0;
13 == t ? $t() : di() && li[t] && (li[t] = 0,
hi[t] ? gi() : 32 == t && (j = 0,
fi()))
}
}
)));
var pi = void 0;
function gi() {
var e = function() {
var e = 0
, t = 0;
if (-1 != ne.id)
e += ne.currentX - ne.startX,
t += ne.currentY - ne.startY;
else
for (var i in hi) {
var n = hi[i];
e += !!li[i] * n[0],
t += !!li[i] * n[1]
}
return 0 == e && 0 == t ? void 0 : o.fixTo(Math.atan2(t, e), 2)
}();
(null == pi || null == e || Math.abs(e - pi) > .3) && (s.send("33", e),
pi = e)
}
function mi() {
s.send("14", 1)
}
function yi(e, t) {
s.send("5", e, t)
}
function ki() {
window.FRVR && window.FRVR.tracker.levelStart("game_start"),
T("moo_name", Le.value),
!ce && s.connected && (ce = !0,
x.stop("menu"),
dt("Loading..."),
s.send("sp", {
name: Le.value,
moofoll: H,
skin: oe
})),
function() {
var e = document.getElementById("ot-sdk-btn-floating");
e && (e.style.display = "none")
}()
}
var wi = !0;
function vi(e) {
Pe.style.display = "none",
Me.style.display = "block",
le.style.display = "none",
li = {},
D = e,
j = 0,
ce = !0,
wi && (wi = !1,
N.length = 0)
}
function bi(e, t, i, n) {
if (menu.getModelActive("disable-damage-text")) return
var xi = 99999;
function Si() {
ce = !1
Ee.style.display = "none"
Gt()
vt = {
x: A.x,
y: A.y
}
Pe.style.display = "none"
Ne.style.display = "block"
Ne.style.fontSize = "0px"
xi = 0
setTimeout(() => {
Me.style.display = "block",
le.style.display = "block",
Ne.style.display = "none"
A.resetHealthAnim()
pt()
}
function Ii(e) {
A && tt.removeAllItems(e)
}
function Ti(sid) {
const tmpObject = tt.objects.filter((object) => object.sid === sid)[0]
if (!tmpObject) return
function Bi(e, t, i) {
null != e && (A.XP = e),
null != t && (A.maxXP = t),
null != i && (A.age = i),
i == r.maxAge ? (_e.innerHTML = "MAX AGE",
Fe.style.width = "100%") : (_e.innerHTML = "AGE " + A.age,
Fe.style.width = A.XP / A.maxXP * 100 + "%")
}
function ji(e) {
o.removeAllChildren(Re);
for (var t = 1, i = 0; i < e.length; i += 3)
!function(i) {
o.generateElement({
class: "leaderHolder",
parent: Re,
children: [o.generateElement({
class: "leaderboardItem",
style: "color:" + (e[i] == D ? "#fff" :
"rgba(255,255,255,0.6)"),
text: t + ". " + ("" != e[i + 1] ? e[i + 1] : "unknown")
}), o.generateElement({
class: "leaderScore",
text: o.kFormat(e[i + 2]) || "0"
})]
})
}(i),
t++
}
let Ai = null
function Di(e, t, i, n) {
ve.save(),
ve.setTransform(1, 0, 0, 1, 0, 0),
ve.scale(V, V);
var s = 50;
ve.beginPath(),
ve.arc(e, t, s, 0, 2 * Math.PI, !1),
ve.closePath(),
ve.fillStyle = "rgba(255, 255, 255, 0.3)",
ve.fill(),
s = 50;
var o = i - e
, a = n - t
, r = Math.sqrt(Math.pow(o, 2) + Math.pow(a, 2))
, c = r > s ? r / s : 1;
o /= c,
a /= c,
ve.beginPath(),
ve.arc(e + o, t + a, .5 * s, 0, 2 * Math.PI, !1),
ve.closePath(),
ve.fillStyle = "white",
ve.fill(),
ve.restore()
}
function Ui(e, t, i) {
for (var n = 0; n < Y.length; ++n)
(U = Y[n]).active && U.layer == e && (U.update(E),
U.active && isOnScreen(U.x - t, U.y - i, U.scale) && (ve.save(),
ve.translate(U.x - t, U.y - i),
ve.rotate(U.dir),
Li(0, 0, U, ve, 1),
ve.restore()))
}
var Ri = {};
function Li(e, t, i, n, s) {
if (i.src) {
var o = l.projectiles[i.indx].src
, a = Ri[o];
a || ((a = new Image).onload = function() {
this.isLoaded = !0
}
,
a.src = ".././img/weapons/" + o + ".png",
Ri[o] = a),
a.isLoaded && n.drawImage(a, e - i.scale / 2, t - i.scale / 2, i.scale,
i.scale)
} else
1 == i.indx && (n.fillStyle = "#939393",
en(e, t, i.scale, n))
}
function zi(e, t, i, n) {
var s = r.riverWidth + n
, o = r.mapScale / 2 - t - s / 2;
o < maxScreenHeight && o + s > 0 && i.fillRect(0, o, maxScreenWidth, s)
}
function renderGameObjects(e, t, i) {
for (let n, s, o, a = 0; a < N.length; ++a) {
U = N[a]
if (!U.active) continue
s = U.x + U.xWiggle - t
o = U.y + U.yWiggle - i
0 == e && U.update(E)
ve.globalAlpha = menu.getModelActive("destroy-animation") ?
U.isDestroying ? 1 - U.getDestroyAlpha() : defaultAlpha : defaultAlpha
if (U.isItem) {
n = Zi(U)
ve.save()
ve.strokeStyle = color
ve.lineWidth = 2
ve.globalAlpha = 1
ve.lineCap = "round"
ve.beginPath()
ve.moveTo(s, o)
ve.lineTo(s + range * Math.cos(U.dir), o + range *
Math.sin(U.dir))
ve.stroke()
ve.beginPath()
ve.arc(s + range * Math.cos(U.dir), o + range *
Math.sin(U.dir), U.scale / 2, 0, Math.PI * 2)
ve.closePath()
ve.stroke()
ve.restore()
}
}
ve.save()
ve.translate(s, o)
ve.rotate(U.dir)
ve.drawImage(n, -n.width / 2, -n.height / 2)
if (U.blocker) {
ve.strokeStyle = "#db6e6e"
ve.globalAlpha = .3
ve.lineWidth = 6
en(0, 0, U.blocker, ve, !1, !0)
}
ve.restore()
ve.save()
ve.fillStyle = nt
ve.roundRect(s - width - r.healthBarPad, o + U.scale +
yOffset, 2 * width + 2 * r.healthBarPad, 17, 8)
ve.fill()
ve.fillStyle = menu.getModelValue("turret-reload-bar-
color")
ve.roundRect(s - width, o + U.scale + yOffset +
r.healthBarPad, 2 * width * shootReload, 17 - 2 * r.healthBarPad, 7)
ve.fill()
ve.restore()
}
}
if (!U.isDestroying) {
for (const player of X) {
if (!player.alive || !player.active) continue
if (menu.getModelActive("building-health-bar")) {
if (menu.getModelActive("building-health-bar-use-
round")) {
const endAngle = ((U.health / U.maxHealth) *
360) * (Math.PI / 180)
const width = 14
const scale = 22
ve.save()
ve.strokeStyle = nt
ve.lineWidth = width
ve.lineCap = "round"
ve.translate(s, o)
ve.rotate(U.dir)
ve.beginPath()
ve.arc(0, 0, scale, 0, endAngle)
ve.stroke()
ve.restore()
ve.save()
ve.strokeStyle = isClanMember(U.owner.sid) ?
"#8ecc51" : "#cc5151"
ve.lineWidth = width / 2.5
ve.lineCap = "round"
ve.translate(s, o)
ve.rotate(U.dir)
ve.beginPath()
ve.arc(0, 0, scale, 0, endAngle)
ve.stroke()
ve.restore()
} else {
const width = r.healthBarWidth / 2 -
r.healthBarPad / 2
const height = 17
const radius = 8
const color = isClanMember(U.owner.sid) ?
"#8ecc51" : "#cc5151"
ve.save()
ve.fillStyle = nt
ve.roundRect(s - width - r.healthBarPad, o -
height / 2, 2 * width + 2 * r.healthBarPad, height, radius)
ve.fill()
ve.fillStyle = color
ve.roundRect(s - width, o - height / 2 +
r.healthBarPad, 2 * width * (U.health / U.maxHealth), height - 2 * r.healthBarPad,
radius - 1)
ve.fill()
ve.restore()
}
}
if (menu.getModelActive("buildings-health-text") &&
U.maxHealth) {
ve.save()
ve.font = "18px Hammersmith One"
ve.fillStyle = "#fff"
ve.textBaseline = "middle"
ve.textAlign = "center"
ve.lineWidth = 8
ve.lineJoin = "round"
ve.strokeText(`${~~U.health}/${~~U.maxHealth}`, s,
o)
ve.fillText(`${~~U.health}/${~~U.maxHealth}`, s, o)
ve.restore()
}
}
}
} else {
n = Qi(U)
function getPosition(position) {
return position / r.mapScale * ((Ge.width +
Ge.height) / 2)
}
context.save()
context.translate(getPosition(this.target.x),
getPosition(this.target.y))
context.strokeStyle = "#525252"
context.lineWidth = 1
switch (this.target.type) {
case 0: {
const color = biomeID ? i ? "#fff" :
"#e3f1f4" : i ? "#b4db62" : "#9ebf57"
tn(context, 7, scale, .7 *
scale) // render star
context.fillStyle = color
context.fill()
if (!i) context.stroke()
}
} break
case 1: {
const scale = 8.25
if (biomeID === 2) {
context.fillStyle = "#606060"
tn(context, 6, .3 * scale, .71 *
scale)
context.fill()
context.stroke()
context.fillStyle = "#89a54c"
en(0, 0, .55 * scale, context)
context.fillStyle = "#a5c65b"
en(0, 0, .3 * scale, context, !0)
} else {
const spikes = 6
const blobSteps = Math.PI / spikes
context.beginPath()
context.moveTo(0, -(.7 * scale))
context.quadraticCurveTo(
Math.cos(blobRotate +
blobSteps) * blobOuter, Math.sin(blobRotate + blobSteps) * blobOuter,
Math.cos(blobRotate +
(blobSteps * 2)) * .7 * scale, Math.sin(blobRotate + (blobSteps * 2)) * .7 * scale
)
blobRotate += blobSteps * 2
}
context.fillStyle = biomeID ?
"#e3f1f4" : "#89a54c"
context.fill()
context.stroke()
context.fillStyle = biomeID ?
"#6a64af" : "#c15555"
const rotateValue = I / 4
en(range * Math.cos(rotateValue
* i), range * Math.sin(rotateValue * i), scale / range, context)
}
}
} break
case 2:
case 3: {
const scale = 5.5
const color1 = 2 == this.target.type ?
2 == biomeID ? "#938d77" : "#939393" : "#e0c655"
const color2 = 2 == this.target.type ?
2 == biomeID ? "#b2ab90" : "#bcbcbc" : "#ebdca3"
context.fillStyle = color1
tn(context, 3, scale, scale)
context.fill()
context.stroke()
context.fillStyle = color2
tn(context, 3, .55 * scale, .65 *
scale)
context.fill()
} break
}
context.restore()
}
})
}
}
function gatherAnimation(e, t, i) {
U = bn(e)
if (!U) return
if (menu.getModelActive("attack-animation")) {
particles.particles.forEach((particle) => {
if (particle.type !== "attack") return
particle.angle = U.dir
particle.power = 3 + Math.random()
})
}
gameObject.changeHealth(-damage)
}
if (menu.getModelActive("hack-detector")) {
if (Math.abs(U.dir - angle) <= .013) {
U.hackCount = (U.hackCount || 0) + 15
} else {
U.hackCount = (U.hackCount || 0) - .25
}
if (menu.getModelActive("hack-detector")) {
if (Math.abs(U.dir - angle) <= .013) {
U.hackCount = (U.hackCount || 0) + 15
} else {
U.hackCount = (U.hackCount || 0) - .25
}
U.startAnim(t, i)
}
function Hi(e, t, i) {
ve.globalAlpha = 1;
if (!U.visible) continue
U.skinRot += .002 * E
ve.save()
ve.globalAlpha = shameCountAlpha
ve.translate(U.x - e, U.y - t)
ve.rotate(z + Math.PI / 2)
ve.drawImage(Wi.shameImg, -Wi.shameImg.scale / 2, -
Wi.shameImg.scale / 2, Wi.shameImg.scale, Wi.shameImg.scale)
ve.restore()
}
}
}
function Vi(e, t) {
(t = t || ve).lineWidth = 5.5,
t.lineJoin = "miter";
var i = Math.PI / 4 * (l.weapons[e.weaponIndex].armS || 1)
, n = e.buildIndex < 0 && l.weapons[e.weaponIndex].hndS || 1
, s = e.buildIndex < 0 && l.weapons[e.weaponIndex].hndD || 1;
if (e.tailIndex > 0 && function(e, t, i) {
if (!(qi = Gi[e])) {
var n = new Image;
n.onload = function() {
this.isLoaded = !0,
this.onload = null
}
,
n.src = ".././img/accessories/access_" + e + ".png",
Gi[e] = n,
qi = n
}
var s = Ni[e];
if (!s) {
for (var o = 0; o < et.length; ++o)
if (et[o].id == e) {
s = et[o];
break
}
Ni[e] = s
}
qi.isLoaded && (t.save(),
t.translate(-20 - (s.xOff || 0), 0),
s.spin && t.rotate(i.skinRot),
t.drawImage(qi, -s.scale / 2, -s.scale / 2, s.scale, s.scale),
t.restore())
}(e.tailIndex, t, e),
e.buildIndex < 0 && !l.weapons[e.weaponIndex].aboveHand &&
(Ki(l.weapons[e.weaponIndex], r.weaponVariants[e.weaponVariant].src, e.scale, 0,
t),
null == l.weapons[e.weaponIndex].projectile ||
l.weapons[e.weaponIndex].hideProjectile || Li(e.scale, 0,
l.projectiles[l.weapons[e.weaponIndex].projectile], ve)),
t.fillStyle = r.skinColors[e.skinColor],
en(e.scale * Math.cos(i), e.scale * Math.sin(i), 14),
en(e.scale * s * Math.cos(-i * n), e.scale * s * Math.sin(-i * n), 14),
e.buildIndex < 0 && l.weapons[e.weaponIndex].aboveHand &&
(Ki(l.weapons[e.weaponIndex], r.weaponVariants[e.weaponVariant].src, e.scale, 0,
t),
null == l.weapons[e.weaponIndex].projectile ||
l.weapons[e.weaponIndex].hideProjectile || Li(e.scale, 0,
l.projectiles[l.weapons[e.weaponIndex].projectile], ve)),
e.buildIndex >= 0) {
var o = Zi(l.list[e.buildIndex]);
t.drawImage(o, e.scale - l.list[e.buildIndex].holdOffset, -o.width / 2)
}
en(0, 0, e.scale, t),
e.skinIndex > 0 && (t.rotate(Math.PI / 2),
function e(t, i, n, s) {
if (!(qi = Wi[t])) {
var o = new Image;
o.onload = function() {
this.isLoaded = !0,
this.onload = null
}
,
o.src = ".././img/hats/hat_" + t + ".png",
Wi[t] = o,
qi = o
}
var a = n || Xi[t];
if (!a) {
for (var r = 0; r < Ze.length; ++r)
if (Ze[r].id == t) {
a = Ze[r];
break
}
Xi[t] = a
}
qi.isLoaded && i.drawImage(qi, -a.scale / 2, -a.scale / 2, a.scale,
a.scale),
!n && a.topSprite && (i.save(),
i.rotate(s.skinRot),
e(t + "_top", i, a, s),
i.restore())
}(e.skinIndex, t, null, e))
}
var qi, Wi = {}, Xi = {}, Gi = {}, Ni = {}, Yi = {};
function Ki(e, t, i, n, s) {
var o = e.src + (t || "")
, a = Yi[o];
a || ((a = new Image).onload = function() {
this.isLoaded = !0
}
,
a.src = ".././img/weapons/" + o + ".png",
Yi[o] = a),
a.isLoaded && s.drawImage(a, i + e.xOff - e.length / 2, n + e.yOff -
e.width / 2, e.length, e.width)
}
var Ji = {};
function Qi(e) {
var t = e.y >= r.mapScale - r.snowBiomeTop ? 2 : e.y <= r.snowBiomeTop ?
1 : 0 // biomeID
, i = e.type + "_" + e.scale + "_" + t
, n = Ji[i];
if (!n) {
var s = document.createElement("canvas");
s.width = s.height = 2.1 * e.scale + 5.5;
var a = s.getContext("2d");
if (a.translate(s.width / 2, s.height / 2),
a.rotate(o.randFloat(0, Math.PI)),
a.strokeStyle = it,
a.lineWidth = 5.5,
0 == e.type)
for (var c, l = 0; l < 2; ++l)
tn(a, 7, c = U.scale * (l ? .5 : 1), .7 * c),
a.fillStyle = t ? l ? "#fff" : "#e3f1f4" : l ? "#b4db62" :
"#9ebf57",
a.fill(),
l || a.stroke();
else if (1 == e.type)
if (2 == t)
a.fillStyle = "#606060",
tn(a, 6, .3 * e.scale, .71 * e.scale),
a.fill(),
a.stroke(),
a.fillStyle = "#89a54c",
en(0, 0, .55 * e.scale, a),
a.fillStyle = "#a5c65b",
en(0, 0, .3 * e.scale, a, !0);
else {
var h;
!function(e, t, i, n) {
var s, a = Math.PI / 2 * 3, r = Math.PI / 6;
e.beginPath(),
e.moveTo(0, -n);
for (var c = 0; c < 6; c++)
s = o.randInt(i + .9, 1.2 * i),
e.quadraticCurveTo(Math.cos(a + r) * s, Math.sin(a + r)
* s, Math.cos(a + 2 * r) * n, Math.sin(a + 2 * r) * n),
a += 2 * r;
e.lineTo(0, -n),
e.closePath()
}(a, 0, U.scale, .7 * U.scale),
a.fillStyle = t ? "#e3f1f4" : "#89a54c",
a.fill(),
a.stroke(),
a.fillStyle = t ? "#6a64af" : "#c15555";
var u = I / 4;
for (l = 0; l < 4; ++l)
en((h = o.randInt(U.scale / 3.5, U.scale / 2.3)) *
Math.cos(u * l), h * Math.sin(u * l), o.randInt(10, 12), a)
}
else
2 != e.type && 3 != e.type || (a.fillStyle = 2 == e.type ? 2 == t ?
"#938d77" : "#939393" : "#e0c655",
tn(a, 3, e.scale, e.scale),
a.fill(),
a.stroke(),
a.fillStyle = 2 == e.type ? 2 == t ? "#b2ab90" : "#bcbcbc" :
"#ebdca3",
tn(a, 3, .55 * e.scale, .65 * e.scale),
a.fill());
n = s,
Ji[i] = n
}
return n
}
var $i = [];
function Zi(e, t) {
var i = $i[e.id];
if (!i || t) {
var n = document.createElement("canvas");
n.width = n.height = 2.5 * e.scale + 5.5 + (l.list[e.id].spritePadding
|| 0);
var s = n.getContext("2d");
if (s.translate(n.width / 2, n.height / 2),
s.rotate(t ? 0 : Math.PI / 2),
s.strokeStyle = it,
s.lineWidth = 5.5 * (t ? n.width / 81 : 1),
"apple" == e.name) {
s.fillStyle = "#c15555",
en(0, 0, e.scale, s),
s.fillStyle = "#89a54c";
var a = -Math.PI / 2;
!function(e, t, i, n, s) {
var o = e + 25 * Math.cos(n)
, a = t + 25 * Math.sin(n);
s.moveTo(e, t),
s.beginPath(),
s.quadraticCurveTo((e + o) / 2 + 10 * Math.cos(n + Math.PI /
2), (t + a) / 2 + 10 * Math.sin(n + Math.PI / 2), o, a),
s.quadraticCurveTo((e + o) / 2 - 10 * Math.cos(n + Math.PI /
2), (t + a) / 2 - 10 * Math.sin(n + Math.PI / 2), e, t),
s.closePath(),
s.fill(),
s.stroke()
}(e.scale * Math.cos(a), e.scale * Math.sin(a), 0, a + Math.PI / 2,
s)
} else if ("cookie" == e.name) {
s.fillStyle = "#cca861",
en(0, 0, e.scale, s),
s.fillStyle = "#937c4b";
for (var r = I / (h = 4), c = 0; c < h; ++c)
en((u = o.randInt(e.scale / 2.5, e.scale / 1.7)) * Math.cos(r *
c), u * Math.sin(r * c), o.randInt(4, 5), s, !0)
} else if ("cheese" == e.name) {
var h, u;
for (s.fillStyle = "#f4f3ac",
en(0, 0, e.scale, s),
s.fillStyle = "#c3c28b",
r = I / (h = 4),
c = 0; c < h; ++c)
en((u = o.randInt(e.scale / 2.5, e.scale / 1.7)) * Math.cos(r *
c), u * Math.sin(r * c), o.randInt(4, 5), s, !0)
} else if ("wood wall" == e.name || "stone wall" == e.name || "castle
wall" == e.name) {
s.fillStyle = "castle wall" == e.name ? "#83898e" : "wood wall" ==
e.name ? "#a5974c" : "#939393";
var d = "castle wall" == e.name ? 4 : 3;
tn(s, d, 1.1 * e.scale, 1.1 * e.scale),
s.fill(),
s.stroke(),
s.fillStyle = "castle wall" == e.name ? "#9da4aa" : "wood wall" ==
e.name ? "#c9b758" : "#bcbcbc",
tn(s, d, .65 * e.scale, .65 * e.scale),
s.fill()
} else if ("spikes" == e.name || "greater spikes" == e.name || "poison
spikes" == e.name || "spinning spikes" == e.name) {
s.fillStyle = "poison spikes" == e.name ? "#7b935d" : "#939393";
var f = .6 * e.scale;
tn(s, "spikes" == e.name ? 5 : 6, e.scale, f),
s.fill(),
s.stroke(),
s.fillStyle = "#a5974c",
en(0, 0, f, s),
s.fillStyle = "#c9b758",
en(0, 0, f / 2, s, !0)
} else if ("windmill" == e.name || "faster windmill" == e.name ||
"power mill" == e.name)
s.fillStyle = "#a5974c",
en(0, 0, e.scale, s),
s.fillStyle = "#c9b758",
sn(0, 0, 1.5 * e.scale, 29, 4, s),
s.fillStyle = "#a5974c",
en(0, 0, .5 * e.scale, s);
else if ("mine" == e.name)
s.fillStyle = "#939393",
tn(s, 3, e.scale, e.scale),
s.fill(),
s.stroke(),
s.fillStyle = "#bcbcbc",
tn(s, 3, .55 * e.scale, .65 * e.scale),
s.fill();
else if ("sapling" == e.name)
for (c = 0; c < 2; ++c)
tn(s, 7, f = e.scale * (c ? .5 : 1), .7 * f),
s.fillStyle = c ? "#b4db62" : "#9ebf57",
s.fill(),
c || s.stroke();
else if ("pit trap" == e.name)
s.fillStyle = "#a5974c",
tn(s, 3, 1.1 * e.scale, 1.1 * e.scale),
s.fill(),
s.stroke(),
s.fillStyle = it,
tn(s, 3, .65 * e.scale, .65 * e.scale),
s.fill();
else if ("boost pad" == e.name)
s.fillStyle = "#7e7f82",
nn(0, 0, 2 * e.scale, 2 * e.scale, s),
s.fill(),
s.stroke(),
s.fillStyle = "#dbd97d",
function(e, t) {
t = t || ve;
var i = e * (Math.sqrt(3) / 2);
t.beginPath(),
t.moveTo(0, -i / 2),
t.lineTo(-e / 2, i / 2),
t.lineTo(e / 2, i / 2),
t.lineTo(0, -i / 2),
t.fill(),
t.closePath()
}(1 * e.scale, s);
else if ("turret" == e.name)
s.fillStyle = "#a5974c",
en(0, 0, e.scale, s),
s.fill(),
s.stroke(),
s.fillStyle = "#939393",
nn(0, -25, .9 * e.scale, 50, s),
en(0, 0, .6 * e.scale, s),
s.fill(),
s.stroke();
else if ("platform" == e.name) {
s.fillStyle = "#cebd5f";
var p = 2 * e.scale
, g = p / 4
, m = -e.scale / 2;
for (c = 0; c < 4; ++c)
nn(m - g / 2, 0, g, 2 * e.scale, s),
s.fill(),
s.stroke(),
m += p / 4
} else
"healing pad" == e.name ? (s.fillStyle = "#7e7f82",
nn(0, 0, 2 * e.scale, 2 * e.scale, s),
s.fill(),
s.stroke(),
s.fillStyle = "#db6e6e",
sn(0, 0, .65 * e.scale, 20, 4, s, !0)) : "spawn pad" == e.name ?
(s.fillStyle = "#7e7f82",
nn(0, 0, 2 * e.scale, 2 * e.scale, s),
s.fill(),
s.stroke(),
s.fillStyle = "#71aad6",
en(0, 0, .6 * e.scale, s)) : "blocker" == e.name ? (s.fillStyle =
"#7e7f82",
en(0, 0, e.scale, s),
s.fill(),
s.stroke(),
s.rotate(Math.PI / 4),
s.fillStyle = "#db6e6e",
sn(0, 0, .65 * e.scale, 20, 4, s, !0)) : "teleporter" == e.name &&
(s.fillStyle = "#7e7f82",
en(0, 0, e.scale, s),
s.fill(),
s.stroke(),
s.rotate(Math.PI / 4),
s.fillStyle = "#d76edb",
en(0, 0, .5 * e.scale, s, !0));
i = n,
t || ($i[e.id] = i)
}
return i
}
function en(e, t, i, n, s, o) {
(n = n || ve).beginPath(),
n.arc(e, t, i, 0, 2 * Math.PI),
o || n.fill(),
s || n.stroke()
}
function tn(e, t, i, n) {
var s, o, a = Math.PI / 2 * 3, r = Math.PI / t;
e.beginPath(),
e.moveTo(0, -i);
for (var c = 0; c < t; c++)
s = Math.cos(a) * i,
o = Math.sin(a) * i,
e.lineTo(s, o),
a += r,
s = Math.cos(a) * n,
o = Math.sin(a) * n,
e.lineTo(s, o),
a += r;
e.lineTo(0, -i),
e.closePath()
}
function nn(e, t, i, n, s, o) {
s.fillRect(e - i / 2, t - n / 2, i, n),
o || s.strokeRect(e - i / 2, t - n / 2, i, n)
}
function sn(e, t, i, n, s, o, a) {
o.save(),
o.translate(e, t),
s = Math.ceil(s / 2);
for (var r = 0; r < s; r++)
nn(0, 0, 2 * i, n, o, a),
o.rotate(Math.PI / s);
o.restore()
}
function on(e) {
for (var t = 0; t < e.length; )
tt.add(e[t], e[t + 1], e[t + 2], e[t + 3], e[t + 4], e[t + 5],
l.list[e[t + 6]], !0, e[t + 7] >= 0 ? {
sid: e[t + 7]
} : null),
t += 8
}
function an(angle, sid) {
U = Sn(sid)
if (!U) return
if (!menu.getModelActive("disable-object-wiggle")) {
U.xWiggle += r.gatherWiggle * Math.cos(angle)
U.yWiggle += r.gatherWiggle * Math.sin(angle)
}
}
function rn(e, t) {
U = Sn(e)
if (!U) return
U.dir = t
if (!menu.getModelActive("disable-object-wiggle")) {
U.xWiggle += r.gatherWiggle * Math.cos(t + Math.PI)
U.yWiggle += r.gatherWiggle * Math.sin(t + Math.PI)
}
U.shootTime = Date.now()
}
if (!menu.getModelActive("reload-bars") || !menu.getModelActive("reload-
bars-secondary")) return
/*if (isTurret) {
if (player.skinIndex == 53 && distance <= 5) {
player.startTurretReload(item)
}
}*/
player.startSecondaryReload(item)
}
}
function ln(e, t) {
for (var i = 0; i < Y.length; ++i)
Y[i].sid == e && (Y[i].range = t)
}
function hn(e) {
(U = xn(e)) && U.startAnim()
}
function un(e) {
for (var t = 0; t < W.length; ++t)
W[t].forcePos = !W[t].visible,
W[t].visible = !1;
if (e) {
var i = Date.now();
for (t = 0; t < e.length;)
(U = xn(e[t])) ? (U.index = e[t + 1],
U.t1 = void 0 === U.t2 ? i : U.t2,
U.t2 = i,
U.x1 = U.x,
U.y1 = U.y,
U.x2 = e[t + 2],
U.y2 = e[t + 3],
U.d1 = void 0 === U.d2 ? e[t + 4] : U.d2,
U.d2 = e[t + 4],
U.health = e[t + 5],
U.dt = 0,
U.visible = !0) : ((U = $.spawn(e[t + 2], e[t +
3], e[t + 4], e[t + 1])).x2 = U.x,
U.y2 = U.y,
U.d2 = U.dir,
U.health = e[t + 5],
$.aiTypes[e[t + 1]].name ||
(U.name = r.cowNames[e[t + 6]]),
U.forcePos = !0,
U.sid = e[t],
U.visible = !0),
t += 7
}
}
var dn = {};
function fn(e, t) {
var i = e.index
, n = dn[i];
if (!n) {
var s = new Image;
s.onload = function() {
this.isLoaded = !0,
this.onload = null
}
,
s.src = ".././img/animals/" + e.src + ".png",
n = s,
dn[i] = n
}
if (n.isLoaded) {
var o = 1.2 * e.scale * (e.spriteMlt || 1);
t.drawImage(n, -o, -o, 2 * o, 2 * o)
}
}
function isOnScreen(x, y, s) {
return (x + s >= 0 && x - s <= maxScreenWidth && y + s >= 0 && y - s <=
maxScreenHeight)
}
function gn(e, t) {
var i = function(e) {
for (var t = 0; t < X.length; ++t)
if (X[t].id == e)
return X[t];
return null
}(e[0]);
i || (i = new u(e[0],e[1],r,o,K,tt,X,W,l,Ze,et),
X.push(i)),
i.spawn(t ? H : null),
i.visible = !1,
i.x2 = void 0,
i.y2 = void 0,
i.setData(e),
t && (R = (A = i).x,
L = A.y,
Nt(),
Mi(),
Bi(),
Oi(0),
Ee.style.display = "block")
}
function mn(e) {
for (var t = 0; t < X.length; t++)
if (X[t].id == e) {
X.splice(t, 1);
break
}
}
function yn(e, t) {
A && (A.itemCounts[e] = t)
}
function kn(e, t, i) {
if (!A) return
A[e] = t
if (i) {
Mi()
}
}
if (!U) return
U.newHealth = health
U.oldHealth = U.health
if (!menu.getModelActive("health-animation")) {
U.health = health
}
U.isHealing = true
if (menu.getModelActive("health-particles")) {
const amount = Math.abs(U.newHealth - U.oldHealth)
return
}
U.hitTime = window.ticks
U.isHealing = false
if (menu.getModelActive("blood-particles")) {
const amount = Math.abs(U.newHealth - U.oldHealth)
if (menu.getModelActive("health-animation")) {
U.lossHealth = Math.abs(U.oldHealth - health)
U.updateHealthTime = Date.now()
}
}
window.ticks = 0
window.fps = 0
this.radius = 2
this.color = "#479e00"
this.canBuild = true
this.obstacle = null
this.phantomObstacle = null
this.setTo = function(x, y) {
this.x = x
this.y = y
this.setTo(this.x, this.y)
this.render = function() {
ve.save()
ve.fillStyle = !this.canBuild ? "#b41d1d" : "#48b41d"
ve.beginPath()
ve.arc(this.x - window.xOffset, this.y - window.yOffset, this.radius,
0, Math.PI * 2)
ve.fill()
ve.restore()
ve.save()
ve.strokeStyle = !this.canBuild ? "#b41d1d" : "#48b41d"
ve.lineWidth = 1
ve.beginPath()
ve.moveTo(this.x - window.xOffset, this.y - window.yOffset)
ve.lineTo(this.buildX - window.xOffset, this.buildY - window.yOffset)
ve.stroke()
ve.restore()
ve.save()
ve.fillStyle = !this.canBuild ? "#b41d1d" : "#aeb238"
ve.beginPath()
ve.arc(this.buildX - window.xOffset, this.buildY - window.yOffset,
this.radius, 0, Math.PI * 2)
ve.fill()
ve.restore()
}
this.update = function() {
this.render()
if (!building.active) continue
building.isObstacle = false
continue
} else {
break
}
} else {
continue
}
}
continue
} else {
break
}
} else {
continue
}
}
this.canBuild = false
this.phantomObstacle = building
building.isObstacle = true
}
}
}
function updateBuildPosition() {
buildPositions.active = false
if (!building) return
if (!building.group.place) return
buildPositions.oldBuilding = building
if (buildPositions.has(i)) {
buildPositions.get(i).setTo(x, y)
continue
}
buildPositions.active = true
}
function renderFreeBuildPositions() {
const building = l.list[A.buildIndex]
if (!building) return
if (!building.group.place) return
const freePositions =
Array.from(buildPositions.values()).filter((buildPosition) =>
buildPosition.canBuild)
if (nearPosition) {
const distance = Math.hypot(nearPosition.buildY -
freePosition.buildY, nearPosition.buildX - freePosition.buildX)
if (isCanBuild) {
buildPositions.get(freePosition.id).isCanBuild = true
ve.save()
ve.fillStyle = "#3896ad"
ve.strokeStyle = "#2a7183"
ve.lineWidth = freePosition.radius
ve.beginPath()
ve.globalAlpha = .25
ve.arc(freePosition.buildX - window.xOffset, freePosition.buildY -
window.yOffset, freePosition.building.scale, 0, Math.PI * 2)
ve.fill()
ve.globalAlpha = .55
ve.arc(freePosition.buildX - window.xOffset, freePosition.buildY -
window.yOffset, freePosition.building.scale, 0, Math.PI * 2)
ve.stroke()
ve.restore()
} else {
buildPositions.get(freePosition.id).isCanBuild = false
}
}
}
function updatePlayers(e) {
for (var t = Date.now(), i = 0; i < X.length; ++i)
X[i].forcePos = !X[i].visible,
X[i].visible = !1;
for (i = 0; i < e.length;)
(U = bn(e[i])) && (U.t1 = void 0 === U.t2 ? t : U.t2,
U.t2 = t,
U.x1 = U.x,
U.y1 = U.y,
U.x2 = e[i + 1],
U.y2 = e[i + 2],
U.moveAngle = Math.atan2(U.y - U.y2, U.x - U.x2),
U.moveSpeed = Math.hypot(U.y1 - U.y2, U.x1 - U.x2),
U.d1 = void 0 === U.d2 ? e[i + 3] : U.d2,
U.d2 = e[i + 3],
U.dt = 0,
U.buildIndex = e[i + 4],
U.weaponIndex = e[i + 5],
U.weaponVariant = e[i + 6],
U.team = e[i + 7],
U.isLeader = e[i + 8],
U.skinIndex = e[i + 9],
U.tailIndex = e[i + 10],
U.iconIndex = e[i + 11],
U.zIndex = e[i + 12],
U.visible = !0,
U.isAlly = (U == A || U.team && U.team === A.team),
U.tick(window.delta)),
i += 13
window.ticks += 1
}
function isClanMember(sid) {
if (A && A.sid == sid) return true
return false
}
function bn(e) {
for (var t = 0; t < X.length; ++t)
if (X[t].sid == e)
return X[t];
return null
}
function xn(e) {
for (var t = 0; t < W.length; ++t)
if (W[t].sid == e)
return W[t];
return null
}
function Sn(e) {
for (var t = 0; t < N.length; ++t)
if (N[t].sid == e)
return N[t];
return null
}
var In = -1;
function Tn() {
let pingDisplay = document.getElementById("pingDisplay")
document.body.insertAdjacentHTML("beforeend", pingDisplay.outerHTML)
pingDisplay = document.getElementById("pingDisplay")
}
window.togglePingDisplay = function() {
if (menu.getModelActive("show-stats")) {
if (pingDisplay.style.display === "none" || !
pingDisplay.style.display) {
pingDisplay.style.display = "block"
}
} else if (pingDisplay.style.display === "block" || !
pingDisplay.style.display) {
pingDisplay.style.display = "none"
}
}
window.togglePingDisplay()
window.pingTime = ping
pingDisplay.style.textAlign = "center"
pingDisplay.style.pointerEvets = "none"
pingDisplay.style.zIndex = 1
function Mn() {
In = Date.now(),
s.send("pp")
}
function Cn(e) {
if (!(e < 0)) {
var t = Math.floor(e / 60)
, i = e % 60;
i = ("0" + i).slice(-2),
Te.innerText = "Server restarting in " + t + ":" + i,
Te.hidden = !1
}
}
function getAngleDist(a, b) {
const angle = Math.abs(b - a) % (Math.PI * 2)
this.alpha = 1
this.lifeTime = Date.now()
this.destroy = function() {
particles.particles.delete(this.id)
}
this.render = function() {
if (!this.isText) {
context.begin(this.x - window.xOffset, this.y - window.yOffset)
.setFillColor(this.color)
.setAlpha(this.alpha)
.circle(this.radius)
.end()
} else {
context.begin(this.x - window.xOffset, this.y - window.yOffset)
.setFillColor(this.color)
.setFont(`${this.radius}px Hammersmith One`)
.setJoin("round")
.setBaseLine("middle")
.setAlign("center")
.setAlpha(this.alpha)
.text(this.text)
.end()
}
}
this.update = function() {
if (Date.now() - this.lifeTime >= (this.deathCooldown -
Math.max(window.fps, window.delta))) return this.destroy()
const xVel = this.power * Math.cos(this.angle)
const yVel = this.power * Math.sin(this.angle)
this.x += xVel
this.y += yVel
this.render()
}
}
function Particles() {
this.particles = new Map()
this.particles.set(particle.id, particle)
}
return this
}
function fire(color) {
let pointsAround = new Array(~~(radius / Math.PI * 3)).fill([NaN, NaN])
let pointsAroundStep = 0
return [ _x, _y ]
})
return {
fire
}
}
this.generate = function() {
for (let i = 1; i <= this.amountPaths; i += 1) {
const offsetY = i % 2 === 0 ? this.distance : 0
const x = this.startX + this.distance * (i - 1)
const randomOffsetY = Math.floor(Math.random() * (45 - 10)) + 10
const y = this.startY + ((this.float === "down" ? offsetY : -
offsetY) + (i % 2 === 0 ? (Math.random() < .55 ? randomOffsetY : -randomOffsetY) :
0))
if (!player.canSeePoint({
x: oldPoint[0],
y: oldPoint[1],
scale: 10
})) continue
if (!player.canSeePoint({
x: currentPoint[0],
y: currentPoint[1],
scale: 10
})) continue
const pointOffset = this.distance / 2
const sidePoint1 = [ oldPoint[0] - pointOffset / 2, oldPoint[1] +
(oldPoint[2] === 0 ? pointOffset : -pointOffset) ]
const sidePoint2 = [ currentPoint[0] + pointOffset * 1.15,
currentPoint[1] + pointOffset * 1.2 ]
const sidePoint3 = [ currentPoint[0] + pointOffset * 1.35,
currentPoint[1] - pointOffset * 1.15 ]
const sidePoint4 = [ currentPoint[0] - pointOffset * 1.35,
currentPoint[1] + pointOffset * 1.15 ]
ve.save()
ve.fillStyle = this.color
ve.lineCap = "round"
ve.lineJoin = "round"
ve.beginPath()
ve.moveTo(oldPoint[0] - xOffset, oldPoint[1] - yOffset)
ve.lineTo(oldPoint[0] + this.distance * 2 - xOffset, this.startY -
yOffset)
ve.lineTo(currentPoint[0] - xOffset, currentPoint[1] - yOffset)
ve.fill()
ve.beginPath()
ve.moveTo(oldPoint[0] - xOffset, oldPoint[1] - yOffset)
ve.bezierCurveTo(
sidePoint1[0] - xOffset, sidePoint1[1] - yOffset,
sidePoint2[0] - xOffset, sidePoint2[1] - yOffset,
currentPoint[0] + (currentPoint[3] >= 10 ? 3.5 : 1) - xOffset,
currentPoint[1] - yOffset
)
ve.fill()
ve.beginPath()
ve.moveTo(currentPoint[0] - xOffset, currentPoint[1] - yOffset)
ve.bezierCurveTo(
sidePoint2[0] - xOffset, sidePoint2[1] - yOffset,
sidePoint3[0] - xOffset, sidePoint3[1] - yOffset,
currentPoint[0] + this.distance * 2 - xOffset, this.startY -
yOffset
)
ve.fill()
ve.restore()
}
}
return this.generate()
}
function Pn(e) {
window.open(e, "_blank")
}
let lineDashOffset = 0
if (dashLine) {
ve.setLineDash([ 10, 10 ])
ve.lineDashOffset = lineDashOffset
}
window.requestAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
function(e) {
window.setTimeout(e, 1e3 / 60)
}
,
function() {
const mapMiddle = r.mapScale / 2
let index = 0
index += 1
index += 1
index += 1
index += 1
O = Date.now()
E = O - q
q = O
window.delta = E
! function() {
// UPDATE DIRECTION:
if (A) {
if (!B || O - B >= (1000 / r.clientSendRate)) {
B = O
s.send("2", dir)
}
}
}
// DEATH TEXT:
if (xi < 120) {
xi += .1 * E
// MOVE CAMERA:
if (A) {
const distance = o.getDistance(R, L, A.x, A.y)
const angle = o.getDirection(A.x, A.y, R, L)
const tmpSpeed = menu.getModelActive("smooth-camera") ?
0.0045 : .01
const fixSpeed = Math.min(tmpSpeed * distance * E, distance)
U.dt += E
U.x = U.x1 + u * h
u = U.y2 - U.y1
U.y = U.y1 + u * h
U.dir = Math.lerpAngle(U.d2, U.d1, Math.min(1.2, l))
}
}
}
// RENDER CORDS:
const d = R - maxScreenWidth / 2
const f = L - maxScreenHeight / 2
// RENDER BACKGROUND:
if (r.snowBiomeTop - f <= 0 && r.mapScale - r.snowBiomeTop - f >=
maxScreenHeight) {
ve.fillStyle = "#b6db66"
ve.fillRect(0, 0, maxScreenWidth, maxScreenHeight)
} else if (r.mapScale - r.snowBiomeTop - f <= 0) {
ve.fillStyle = "#dbc666"
ve.fillRect(0, 0, maxScreenWidth, maxScreenHeight)
} else if (r.snowBiomeTop - f >= maxScreenHeight) {
ve.fillStyle = "#fff"
ve.fillRect(0, 0, maxScreenWidth, maxScreenHeight)
} else if (r.snowBiomeTop - f >= 0) {
ve.fillStyle = "#fff"
ve.fillRect(0, 0, maxScreenWidth, r.snowBiomeTop - f)
ve.fillStyle = "#b6db66"
ve.fillRect(0, r.snowBiomeTop - f, maxScreenWidth, maxScreenHeight
- (r.snowBiomeTop - f))
if (menu.getModelActive("coastlines")) {
if (menu.getModelActive("snow-coast")) {
snowPath.render(d, f)
}
}
} else {
ve.fillStyle = "#b6db66"
ve.fillRect(0, 0, maxScreenWidth, (r.mapScale - r.snowBiomeTop -
f))
ve.fillStyle = "#dbc666"
ve.fillRect(0, (r.mapScale - r.snowBiomeTop - f), maxScreenWidth,
maxScreenHeight - (r.mapScale - r.snowBiomeTop - f))
if (menu.getModelActive("coastlines")) {
if (menu.getModelActive("desert-coast")) {
desertPath.render(d, f)
}
}
}
if (Z >= r.waveMax) {
Z = r.waveMax
ee = -1
} else if (Z <= 1) {
Z = ee = 1
}
} else {
Z = ee = 1
}
ve.globalAlpha = 1
ve.fillStyle = "#dbc666"
zi(d, f, ve, r.riverPadding)
ve.fillStyle = "#91b2db"
zi(d, f, ve, 250 * (Z - 1))
}
// RENDER GRID:
if (!menu.getModelActive("disable-game-grid")) {
ve.lineWidth = 4
ve.strokeStyle = "#000"
ve.globalAlpha = 0.06
ve.beginPath()
ve.stroke()
}
// RENDER PROJECTILES:
ve.globalAlpha = 1
ve.lineWidth = 5.5
Ui(0, d, f)
// RENDER PLAYERS:
Hi(d, f, 0)
// RENDER AI:
ve.globalAlpha = 1
ve.save()
ve.translate(U.x - d, U.y - f)
ve.rotate(U.dir + U.dirPlus - Math.PI / 2)
fn(U, ve)
ve.restore()
}
}
// MAP BOUNDARIES:
ve.fillStyle = "#000"
ve.globalAlpha = 0.09
if (d <= 0) {
ve.fillRect(0, 0, -d, maxScreenHeight)
}
if (f <= 0) {
ve.fillRect(-d, 0, maxScreenWidth + d, -f);
}
let tmpMin = 0
if (U.visible) {
const nicknameWidth =
ve.measureText(nicknameValue).width
ve.fillStyle = menu.getModelValue("shame-counter-
color")
ve.textAlign = "left"
if (U.isPlayer) {
ve.strokeText(shameCounterValue, U.x +
nicknameWidth / 2 + (1 == U.iconIndex ? r.crownIconScale / 2 + r.crownPad / 2 : 0)
- d + offsetX, U.y - f - U.scale - r.nameY + offsetY)
ve.fillText(shameCounterValue, U.x +
nicknameWidth / 2 + (1 == U.iconIndex ? r.crownIconScale / 2 + r.crownPad / 2 : 0)
- d + offsetX, U.y - f - U.scale - r.nameY + offsetY)
}
k = U.x - d - b / 2 -
ve.measureText(nicknameValue).width / 2 - r.crownPad
window.xOffset = d
window.yOffset = f
window.cameraX = R
window.cameraY = L
window.ownPlayer = A
magic.fire(color)
}
if (U.isPlayer) {
if (U.alive && U.active) {
if (U.y <= r.snowBiomeTop) {
U.biomeColor = "#a2c4ec"
} else if (U.y >= (r.mapScale / 2) -
(r.riverWidth / 2) && U.y <= (r.mapScale / 2) + (r.riverWidth / 2)) {
U.biomeColor = "#486589"
} else if (U.y > r.snowBiomeTop && U.y < r.mapScale
- r.snowBiomeTop) {
U.biomeColor = "#8cb337"
} else {
U.biomeColor = "#a08e3b"
}
if (menu.getModelActive("movement-tail") &&
menu.getModelActive("movement-tail-all-players")) {
const scale = menu.getModelValue("movement-
tail-scale")
if (menu.getModelActive("tracers-to-players"))
{
if (menu.getModelActive("tracers-players-
use-arrows")) {
drawArrow(arrowX, arrowY, arrowWidth,
color, angle)
} else {
drawTracer(U.x, U.y, color, dashLine)
}
}
}
if (menu.getModelActive("health-animation")) {
U.updateHealthAnim()
} else {
U.resetHealthAnim()
}
}
} else {
const angle = Math.atan2(U.y - A.y, U.x - A.x)
const distance = Math.hypot(U.y - A.y, U.x - A.x)
const offset = Math.min(distance - A.scale, A.scale *
4)
const arrowX = A.x + offset * Math.cos(angle)
const arrowY = A.y + offset * Math.sin(angle)
const color = menu.getModelValue("tracers-color-
animal")
const dashLine = menu.getModelActive("tracers-animals-
dashline")
const arrowWidth = 8
if (menu.getModelActive("tracers-to-animals")) {
if (menu.getModelActive("tracers-animals-use-
arrows")) {
drawArrow(arrowX, arrowY, arrowWidth, color,
angle)
} else {
drawTracer(U.x, U.y, color, dashLine)
}
}
if (menu.getModelActive("animals-health-text")) {
const x = U.x - d
const y = U.y - f + U.scale + r.nameY * 2
const text = `${~~U.health}/${~~U.maxHealth}`
ve.save()
ve.font = "18px Hammersmith One"
ve.fillStyle = "#fff"
ve.textBaseline = "middle"
ve.textAlign = "center"
ve.lineWidth = 8
ve.lineJoin = "round"
ve.strokeText(text, x, y)
ve.fillText(text, x, y)
ve.restore()
}
}
if (U.health > 0) {
function renderBar({ width, innerWidth, xOffset,
yOffset, color }) {
const x = U.x - d - width + (xOffset || 0)
const y = U.y - f + U.scale + r.nameY + (yOffset ||
0)
const height = 17
const radius = 8
ve.save()
ve.fillStyle = nt
ve.roundRect(x - r.healthBarPad, y, 2 * width + 2 *
r.healthBarPad, height, radius)
ve.fill()
ve.fillStyle = color
ve.roundRect(x, y + r.healthBarPad, 2 * width *
innerWidth, height - 2 * r.healthBarPad, radius - 1)
ve.fill()
ve.restore()
}
renderBar({
width: r.healthBarWidth,
innerWidth: U.health / U.maxHealth,
color: U.isAlly ? "#8ecc51" : "#cc5151"
})
if (menu.getModelActive("reload-bars-primary")) {
renderBar({
width: r.healthBarWidth / 2 -
r.healthBarPad / 2,
innerWidth: U.primaryReloadCount || 1,
color: color,
get xOffset() {
return -(this.width + r.healthBarPad) *
Number(menu.getModelActive("reload-bars-secondary"))
},
yOffset: -r.nameY / 2
})
}
if (menu.getModelActive("reload-bars-secondary")) {
renderBar({
width: r.healthBarWidth / 2 -
r.healthBarPad / 2,
innerWidth: U.secondaryReloadCount || 1,
color: color,
get xOffset() {
return (this.width + r.healthBarPad) *
Number(menu.getModelActive("reload-bars-primary"))
},
yOffset: -r.nameY / 2
})
}
}
}
let downYOffset = 0
ve.save()
ve.font = "18px Hammersmith One"
ve.fillStyle = "#fff"
ve.textBaseline = "middle"
ve.textAlign = "center"
ve.lineWidth = 8
ve.lineJoin = "round"
ve.strokeText(text, x, y)
ve.fillText(text, x, y)
ve.restore()
downYOffset += r.nameY / 2 + 4
}
ve.save()
ve.font = "18px Hammersmith One"
ve.fillStyle = "#fff"
ve.textBaseline = "middle"
ve.textAlign = "center"
ve.lineWidth = 8
ve.lineJoin = "round"
ve.strokeText(text, x, y)
ve.fillText(text, x, y)
ve.restore()
downYOffset += r.nameY / 2 + 4
}
}
}
}
lineDashOffset -= .5
particles.update()
if (buildPositions.active) {
buildPositions.forEach((buildPosition) => {
buildPosition.update()
})
}
renderFreeBuildPositions()
}
if (menu.getModelActive("movement-tail") && !
menu.getModelActive("movement-tail-all-players")) {
const scale = menu.getModelValue("movement-tail-scale")
U.chatCountdown -= E
if (U.chatCountdown <= 0) {
U.chatCountdown = alpha = 0
} else if (menu.getModelActive("smooth-chat")) {
if (U.chatCountdown >= 2600) {
alpha = 1 - ((U.chatCountdown - 2600) / 400)
} else if (U.chatCountdown <= 400) {
alpha = (U.chatCountdown / 400)
}
}
ve.save()
ve.font = "32px Hammersmith One"
let x = ve.measureText(U.chatMessage)
ve.textBaseline = "middle"
ve.textAlign = "center"
k = U.x - d
y = U.y - U.scale - f - 90
let S = x.width + 17
ve.globalAlpha = alpha
ve.fillStyle = "rgba(0,0,0,0.2)"
ve.roundRect(k - S / 2, y - 23.5, S, 47, 6)
ve.fill()
ve.fillStyle = "#fff"
ve.fillText(U.chatMessage, k, y)
ve.restore()
}
}
// RENDER MINIMAP:
!function(e) {
if (!menu.getModelActive("minimap")) {
if (Ge.style.display !== "none") {
Ge.style.display = "none"
}
return
} else {
if (Ge.style.display === "none" || !Ge.style.display){
Ge.style.display = "block"
}
}
if (A && A.alive) {
Ke.clearRect(0, 0, Ge.width, Ge.height)
// RENDER BIOMES:
if (menu.getModelActive("minimap-biomes")) {
function getBiomePosition(position, diviser = 1) {
return position / r.mapScale * ((Ge.width +
Ge.height) / 2 / diviser)
}
Ke.save()
Ke.globalAlpha = .5
Ke.fillStyle = "#fff"
Ke.fillRect(0, 0, Ge.width, getBiomePosition(2400))
Ke.fillStyle = "#91b2db"
Ke.fillRect(0, getBiomePosition((r.mapScale / 2) - 362),
Ge.width, getBiomePosition((r.mapScale / 2) + 362, 10))
Ke.fillStyle = "#dbc666"
Ke.fillRect(0, getBiomePosition(r.mapScale - 2400),
Ge.width, Ge.height)
Ke.restore()
}
if (menu.getModelActive("minimap-resources")) {
minimapResources.forEach((resource) => {
resource.render(Ke, d, f)
})
}
// RENDER PINGS:
Ke.strokeStyle = "#fff"
Ke.lineWidth = 4
Lt.update(Ke, e)
}
// RENDER PLAYERS:
Ke.globalAlpha = 1
Ke.fillStyle = "#fff"
Ke.fillStyle = "rgba(255,255,255,0.35)"
t += 2;
}
}
// DEATH LOCATION:
if (vt) {
Ke.fillStyle = "#fc5553"
Ke.font = "34px Hammersmith One"
Ke.textBaseline = "middle"
Ke.textAlign = "center"
Ke.fillText("x", vt.x / r.mapScale * Ge.width, vt.y /
r.mapScale * Ge.height)
}
// MAP MARKER:
if (xt) {
Ke.fillStyle = "#fff"
Ke.font = "34px Hammersmith One"
Ke.textBaseline = "middle"
Ke.textAlign = "center"
Ke.fillText("x", xt.x / r.mapScale * Ge.width, xt.y /
r.mapScale * Ge.height)
}
}
}(E)
// RENDER CONTROLS:
if (-1 !== ne.id) {
Di(ne.startX, ne.startY, ne.currentX, ne.currentY)
}
window.requestAnimFrame(e)
}()
window.openLink = Pn
window.aJoinReq = jt
window.kickFromClan = At
window.sendJoin = Dt
window.leaveAlliance = Rt
window.createAlliance = Ut
window.storeBuy = Xt
window.storeEquip = Wt
window.showItemInfo = wt
window.config = r
window.follmoo = function() {
if (!H) return
H = !0
T("moofoll", 1)
}
window.selectSkinColor = function(e) {
oe = e
Kt()
}
window.changeStoreIndex = function(e) {
if (Ht == e) return
Ht = e
qt()
}
this.updateItemCount()
}
,
this.updateItemCount = function(isRemove) {
if (!this.owner) return
this.destroy = function() {
objectManager.disableBySid(this.sid)
}
}
,
this.getDestroyAlpha = function() {
if (!this.isDestroying) return 0
if (!window.menu.getModelActive("disable-buildings-turn")) {
this.turnSpeed && (this.dir += this.turnSpeed * e)
}
if (this.isDestroying) {
if (Date.now() - this.destroyTime >= this.destroyDelay) {
this.destroy()
}
}
}
}
}
, function(e, t) {
e.exports.groups = [{
id: 0,
name: "food",
layer: 0
}, {
id: 1,
name: "walls",
place: !0,
limit: 30,
layer: 0
}, {
id: 2,
name: "spikes",
place: !0,
limit: 15,
layer: 0
}, {
id: 3,
name: "mill",
place: !0,
limit: 7,
layer: 1
}, {
id: 4,
name: "mine",
place: !0,
limit: 1,
layer: 0
}, {
id: 5,
name: "trap",
place: !0,
limit: 6,
layer: -1
}, {
id: 6,
name: "booster",
place: !0,
limit: 12,
layer: -1
}, {
id: 7,
name: "turret",
place: !0,
limit: 2,
layer: 1
}, {
id: 8,
name: "watchtower",
place: !0,
limit: 12,
layer: 1
}, {
id: 9,
name: "buff",
place: !0,
limit: 4,
layer: -1
}, {
id: 10,
name: "spawn",
place: !0,
limit: 1,
layer: -1
}, {
id: 11,
name: "sapling",
place: !0,
limit: 2,
layer: 0
}, {
id: 12,
name: "blocker",
place: !0,
limit: 3,
layer: -1
}, {
id: 13,
name: "teleporter",
place: !0,
limit: 2,
layer: -1
}],
t.projectiles = [{
indx: 0,
layer: 0,
src: "arrow_1",
dmg: 25,
speed: 1.6,
scale: 103,
range: 1e3
}, {
indx: 1,
layer: 1,
dmg: 25,
scale: 20
}, {
indx: 0,
layer: 0,
src: "arrow_1",
dmg: 35,
speed: 2.5,
scale: 103,
range: 1200
}, {
indx: 0,
layer: 0,
src: "arrow_1",
dmg: 30,
speed: 2,
scale: 103,
range: 1200
}, {
indx: 1,
layer: 1,
dmg: 16,
scale: 20
}, {
indx: 0,
layer: 0,
src: "bullet_1",
dmg: 50,
speed: 3.6,
scale: 160,
range: 1400
}],
t.weapons = window.weaponsConfig = [{
id: 0,
type: 0,
name: "tool hammer",
desc: "tool for gathering all resources",
src: "hammer_1",
length: 140,
width: 140,
xOff: -3,
yOff: 18,
dmg: 25,
range: 65,
gather: 1,
speed: 300
}, {
id: 1,
type: 0,
age: 2,
name: "hand axe",
desc: "gathers resources at a higher rate",
src: "axe_1",
length: 140,
width: 140,
xOff: 3,
yOff: 24,
dmg: 30,
spdMult: 1,
range: 70,
gather: 2,
speed: 400
}, {
id: 2,
type: 0,
age: 8,
pre: 1,
name: "great axe",
desc: "deal more damage and gather more resources",
src: "great_axe_1",
length: 140,
width: 140,
xOff: -8,
yOff: 25,
dmg: 35,
spdMult: 1,
range: 75,
gather: 4,
speed: 400
}, {
id: 3,
type: 0,
age: 2,
name: "short sword",
desc: "increased attack power but slower move speed",
src: "sword_1",
iPad: 1.3,
length: 130,
width: 210,
xOff: -8,
yOff: 46,
dmg: 35,
spdMult: .85,
range: 110,
gather: 1,
speed: 300
}, {
id: 4,
type: 0,
age: 8,
pre: 3,
name: "katana",
desc: "greater range and damage",
src: "samurai_1",
iPad: 1.3,
length: 130,
width: 210,
xOff: -8,
yOff: 59,
dmg: 40,
spdMult: .8,
range: 118,
gather: 1,
speed: 300
}, {
id: 5,
type: 0,
age: 2,
name: "polearm",
desc: "long range melee weapon",
src: "spear_1",
iPad: 1.3,
length: 130,
width: 210,
xOff: -8,
yOff: 53,
dmg: 45,
knock: .2,
spdMult: .82,
range: 142,
gather: 1,
speed: 700
}, {
id: 6,
type: 0,
age: 2,
name: "bat",
desc: "fast long range melee weapon",
src: "bat_1",
iPad: 1.3,
length: 110,
width: 180,
xOff: -8,
yOff: 53,
dmg: 20,
knock: .7,
range: 110,
gather: 1,
speed: 300
}, {
id: 7,
type: 0,
age: 2,
name: "daggers",
desc: "really fast short range weapon",
src: "dagger_1",
iPad: .8,
length: 110,
width: 110,
xOff: 18,
yOff: 0,
dmg: 20,
knock: .1,
range: 65,
gather: 1,
hitSlow: .1,
spdMult: 1.13,
speed: 100
}, {
id: 8,
type: 0,
age: 2,
name: "stick",
desc: "great for gathering but very weak",
src: "stick_1",
length: 140,
width: 140,
xOff: 3,
yOff: 24,
dmg: 1,
spdMult: 1,
range: 70,
gather: 7,
speed: 400
}, {
id: 9,
type: 1,
age: 6,
name: "hunting bow",
desc: "bow used for ranged combat and hunting",
src: "bow_1",
req: ["wood", 4],
length: 120,
width: 120,
xOff: -6,
yOff: 0,
projectile: 0,
spdMult: .75,
speed: 600
}, {
id: 10,
type: 1,
age: 6,
name: "great hammer",
desc: "hammer used for destroying structures",
src: "great_hammer_1",
length: 140,
width: 140,
xOff: -9,
yOff: 25,
dmg: 10,
spdMult: .88,
range: 75,
sDmg: 7.5,
gather: 1,
speed: 400
}, {
id: 11,
type: 1,
age: 6,
name: "wooden shield",
desc: "blocks projectiles and reduces melee damage",
src: "shield_1",
length: 120,
width: 120,
shield: .2,
xOff: 6,
yOff: 0,
spdMult: .7
}, {
id: 12,
type: 1,
age: 8,
pre: 9,
name: "crossbow",
desc: "deals more damage and has greater range",
src: "crossbow_1",
req: ["wood", 5],
aboveHand: !0,
armS: .75,
length: 120,
width: 120,
xOff: -4,
yOff: 0,
projectile: 2,
spdMult: .7,
speed: 700
}, {
id: 13,
type: 1,
age: 9,
pre: 12,
name: "repeater crossbow",
desc: "high firerate crossbow with reduced damage",
src: "crossbow_2",
req: ["wood", 10],
aboveHand: !0,
armS: .75,
length: 120,
width: 120,
xOff: -4,
yOff: 0,
projectile: 3,
spdMult: .7,
speed: 230
}, {
id: 14,
type: 1,
age: 6,
name: "mc grabby",
desc: "steals resources from enemies",
src: "grab_1",
length: 130,
width: 210,
xOff: -8,
yOff: 53,
dmg: 0,
steal: 250,
knock: .2,
spdMult: 1.05,
range: 125,
gather: 0,
speed: 700
}, {
id: 15,
type: 1,
age: 9,
pre: 12,
name: "musket",
desc: "slow firerate but high damage and range",
src: "musket_1",
req: ["stone", 10],
aboveHand: !0,
rec: .35,
armS: .6,
hndS: .3,
hndD: 1.6,
length: 205,
width: 205,
xOff: 25,
yOff: 0,
projectile: 5,
hideProjectile: !0,
spdMult: .6,
speed: 1500
}],
e.exports.list = [{
group: e.exports.groups[0],
name: "apple",
desc: "restores 20 health when consumed",
req: ["food", 10],
consume: function(e) {
return e.changeHealth(20, e)
},
scale: 22,
holdOffset: 15
}, {
age: 3,
group: e.exports.groups[0],
name: "cookie",
desc: "restores 40 health when consumed",
req: ["food", 15],
consume: function(e) {
return e.changeHealth(40, e)
},
scale: 27,
holdOffset: 15
}, {
age: 7,
group: e.exports.groups[0],
name: "cheese",
desc: "restores 30 health and another 50 over 5 seconds",
req: ["food", 25],
consume: function(e) {
return !!(e.changeHealth(30, e) || e.health < 100) &&
(e.dmgOverTime.dmg = -10,
e.dmgOverTime.doer = e,
e.dmgOverTime.time = 5,
!0)
},
scale: 27,
holdOffset: 15
}, {
group: e.exports.groups[1],
name: "wood wall",
desc: "provides protection for your village",
req: ["wood", 10],
projDmg: !0,
health: 380,
scale: 50,
holdOffset: 20,
placeOffset: -5
}, {
age: 3,
group: e.exports.groups[1],
name: "stone wall",
desc: "provides improved protection for your village",
req: ["stone", 25],
health: 900,
scale: 50,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
pre: 1,
group: e.exports.groups[1],
name: "castle wall",
desc: "provides powerful protection for your village",
req: ["stone", 35],
health: 1500,
scale: 52,
holdOffset: 20,
placeOffset: -5
}, {
group: e.exports.groups[2],
name: "spikes",
desc: "damages enemies when they touch them",
req: ["wood", 20, "stone", 5],
health: 400,
dmg: 20,
scale: 49,
spritePadding: -23,
holdOffset: 8,
placeOffset: -5
}, {
age: 5,
group: e.exports.groups[2],
name: "greater spikes",
desc: "damages enemies when they touch them",
req: ["wood", 30, "stone", 10],
health: 500,
dmg: 35,
scale: 52,
spritePadding: -23,
holdOffset: 8,
placeOffset: -5
}, {
age: 9,
pre: 1,
group: e.exports.groups[2],
name: "poison spikes",
desc: "poisons enemies when they touch them",
req: ["wood", 35, "stone", 15],
health: 600,
dmg: 30,
pDmg: 5,
scale: 52,
spritePadding: -23,
holdOffset: 8,
placeOffset: -5
}, {
age: 9,
pre: 2,
group: e.exports.groups[2],
name: "spinning spikes",
desc: "damages enemies when they touch them",
req: ["wood", 30, "stone", 20],
health: 500,
dmg: 45,
turnSpeed: .003,
scale: 52,
spritePadding: -23,
holdOffset: 8,
placeOffset: -5
}, {
group: e.exports.groups[3],
name: "windmill",
desc: "generates gold over time",
req: ["wood", 50, "stone", 10],
health: 400,
pps: 1,
turnSpeed: .0016,
spritePadding: 25,
iconLineMult: 12,
scale: 45,
holdOffset: 20,
placeOffset: 5
}, {
age: 5,
pre: 1,
group: e.exports.groups[3],
name: "faster windmill",
desc: "generates more gold over time",
req: ["wood", 60, "stone", 20],
health: 500,
pps: 1.5,
turnSpeed: .0025,
spritePadding: 25,
iconLineMult: 12,
scale: 47,
holdOffset: 20,
placeOffset: 5
}, {
age: 8,
pre: 1,
group: e.exports.groups[3],
name: "power mill",
desc: "generates more gold over time",
req: ["wood", 100, "stone", 50],
health: 800,
pps: 2,
turnSpeed: .005,
spritePadding: 25,
iconLineMult: 12,
scale: 47,
holdOffset: 20,
placeOffset: 5
}, {
age: 5,
group: e.exports.groups[4],
type: 2,
name: "mine",
desc: "allows you to mine stone",
req: ["wood", 20, "stone", 100],
iconLineMult: 12,
scale: 65,
holdOffset: 20,
placeOffset: 0
}, {
age: 5,
group: e.exports.groups[11],
type: 0,
name: "sapling",
desc: "allows you to farm wood",
req: ["wood", 150],
iconLineMult: 12,
colDiv: .5,
scale: 110,
holdOffset: 50,
placeOffset: -15
}, {
age: 4,
group: e.exports.groups[5],
name: "pit trap",
desc: "pit that traps enemies if they walk over it",
req: ["wood", 30, "stone", 30],
trap: !0,
ignoreCollision: !0,
hideFromEnemy: !0,
health: 500,
colDiv: .2,
scale: 50,
holdOffset: 20,
placeOffset: -5
}, {
age: 4,
group: e.exports.groups[6],
name: "boost pad",
desc: "provides boost when stepped on",
req: ["stone", 20, "wood", 5],
ignoreCollision: !0,
boostSpeed: 1.5,
health: 150,
colDiv: .7,
scale: 45,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: e.exports.groups[7],
doUpdate: !0,
name: "turret",
desc: "defensive structure that shoots at enemies",
req: ["wood", 200, "stone", 150],
health: 800,
projectile: 1,
shootRange: 700,
shootRate: 2200,
scale: 43,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: e.exports.groups[8],
name: "platform",
desc: "platform to shoot over walls and cross over water",
req: ["wood", 20],
ignoreCollision: !0,
zIndex: 1,
health: 300,
scale: 43,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: e.exports.groups[9],
name: "healing pad",
desc: "standing on it will slowly heal you",
req: ["wood", 30, "food", 10],
ignoreCollision: !0,
healCol: 15,
health: 400,
colDiv: .7,
scale: 45,
holdOffset: 20,
placeOffset: -5
}, {
age: 9,
group: e.exports.groups[10],
name: "spawn pad",
desc: "you will spawn here when you die but it will dissapear",
req: ["wood", 100, "stone", 100],
health: 400,
ignoreCollision: !0,
spawnPoint: !0,
scale: 45,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: e.exports.groups[12],
name: "blocker",
desc: "blocks building in radius",
req: ["wood", 30, "stone", 25],
ignoreCollision: !0,
blocker: 300,
health: 400,
colDiv: .7,
scale: 45,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: e.exports.groups[13],
name: "teleporter",
desc: "teleports you to a random point on the map",
req: ["wood", 60, "stone", 60],
ignoreCollision: !0,
teleport: !0,
health: 200,
colDiv: .7,
scale: 45,
holdOffset: 20,
placeOffset: -5
}];
for (var i = 0; i < e.exports.list.length; ++i)
e.exports.list[i].id = i,
e.exports.list[i].pre && (e.exports.list[i].pre = i -
e.exports.list[i].pre)
}
, function(e, t) {
e.exports = {}
}
, function(e, t) {
var i = Math.floor
, n = Math.abs
, s = Math.cos
, o = Math.sin
, a = (Math.pow,
Math.sqrt);
e.exports = function(e, t, r, c, l, h) {
var u, d;
this.objects = t,
this.grids = {},
this.updateObjects = [];
var f = c.mapScale / c.colGrid;
this.setObjectGrids = function(e) {
for (var t = Math.min(c.mapScale, Math.max(0, e.x)), i =
Math.min(c.mapScale, Math.max(0, e.y)), n = 0; n < c.colGrid; ++n) {
u = n * f;
for (var s = 0; s < c.colGrid; ++s)
d = s * f,
t + e.scale >= u && t - e.scale <= u + f && i + e.scale >= d &&
i - e.scale <= d + f && (this.grids[n + "_" + s] || (this.grids[n + "_" + s] = []),
this.grids[n + "_" + s].push(e),
e.gridLocations.push(n + "_" + s))
}
}
,
this.removeObjGrid = function(e) {
for (var t, i = 0; i < e.gridLocations.length; ++i)
(t = this.grids[e.gridLocations[i]].indexOf(e)) >= 0 &&
this.grids[e.gridLocations[i]].splice(t, 1)
}
,
this.disableObj = function(e) {
if (e.active = !1,
h) {
e.owner && e.pps && (e.owner.pps -= e.pps),
this.removeObjGrid(e);
var t = this.updateObjects.indexOf(e);
t >= 0 && this.updateObjects.splice(t, 1)
}
}
,
this.hitObj = function(e, t) {
for (var i = 0; i < l.length; ++i)
l[i].active && (e.sentTo[l[i].id] && (e.active ? l[i].canSee(e) &&
h.send(l[i].id, "8", r.fixTo(t, 1), e.sid) : h.send(l[i].id, "12", e.sid)),
e.active || e.owner != l[i] || l[i].changeItemCount(e.group.id, -
1))
}
;
var p, g, m = [];
this.getGridArrays = function(e, t, n) {
u = i(e / f),
d = i(t / f),
m.length = 0;
try {
this.grids[u + "_" + d] && m.push(this.grids[u + "_" + d]),
e + n >= (u + 1) * f && ((p = this.grids[u + 1 + "_" + d]) &&
m.push(p),
d && t - n <= d * f ? (p = this.grids[u + 1 + "_" + (d - 1)]) &&
m.push(p) : t + n >= (d + 1) * f && (p = this.grids[u + 1 + "_" + (d + 1)]) &&
m.push(p)),
u && e - n <= u * f && ((p = this.grids[u - 1 + "_" + d]) &&
m.push(p),
d && t - n <= d * f ? (p = this.grids[u - 1 + "_" + (d - 1)]) &&
m.push(p) : t + n >= (d + 1) * f && (p = this.grids[u - 1 + "_" + (d + 1)]) &&
m.push(p)),
t + n >= (d + 1) * f && (p = this.grids[u + "_" + (d + 1)]) &&
m.push(p),
d && t - n <= d * f && (p = this.grids[u + "_" + (d - 1)]) &&
m.push(p)
} catch (e) {}
return m
}
,
this.add = function(i, n, s, o, a, r, c, l, u) {
g = null;
for (var d = 0; d < t.length; ++d)
if (t[d].sid == i) {
g = t[d];
break
}
if (!g)
for (d = 0; d < t.length; ++d)
if (!t[d].active) {
g = t[d];
break
}
g || (g = new e(i),
t.push(g)),
l && (g.sid = i),
g.init(n, s, o, a, r, c, u),
h && (this.setObjectGrids(g),
g.doUpdate && this.updateObjects.push(g))
}
,
this.disableBySid = function(e) {
for (var i = 0; i < t.length; ++i)
if (t[i].sid == e) {
this.disableObj(t[i]);
break
}
}
,
this.removeAllItems = function(e, i) {
for (var n = 0; n < t.length; ++n)
t[n].active && t[n].owner && t[n].owner.sid == e &&
this.disableObj(t[n]);
i && i.broadcast("13", e)
}
,
this.fetchSpawnObj = function(e) {
for (var i = null, n = 0; n < t.length; ++n)
if ((g = t[n]).active && g.owner && g.owner.sid == e &&
g.spawnPoint) {
i = [g.x, g.y],
this.disableObj(g),
h.broadcast("12", g.sid),
g.owner && g.owner.changeItemCount(g.group.id, -1);
break
}
return i
}
,
this.checkItemLocation = function(e, i, n, s, o, a, l) {
for (var h = 0; h < t.length; ++h) {
var u = t[h].blocker ? t[h].blocker : t[h].getScale(s,
t[h].isItem);
if (t[h].active && r.getDistance(e, i, t[h].x, t[h].y) < n + u)
return !1
}
return !(!a && 18 != o && i >= c.mapScale / 2 - c.riverWidth / 2 && i
<= c.mapScale / 2 + c.riverWidth / 2)
}
,
this.addProjectile = function(e, t, i, n, s) {
for (var o, a = items.projectiles[s], c = 0; c < projectiles.length; +
+c)
if (!projectiles[c].active) {
o = projectiles[c];
break
}
o || (o = new Projectile(l,r),
projectiles.push(o)),
o.init(s, e, t, i, a.speed, n, a.scale)
}
,
this.checkCollision = function(e, t, i) {
i = i || 1;
var l = e.x - t.x
, h = e.y - t.y
, u = e.scale + t.scale;
if (n(l) <= u || n(h) <= u) {
u = e.scale + (t.getScale ? t.getScale() : t.scale);
var d = a(l * l + h * h) - u;
if (d <= 0) {
if (t.ignoreCollision)
!t.trap || e.noTrap || t.owner == e || t.owner &&
t.owner.team && t.owner.team == e.team ? t.boostSpeed ? (e.xVel += i * t.boostSpeed
* (t.weightM || 1) * s(t.dir),
e.yVel += i * t.boostSpeed * (t.weightM || 1) * o(t.dir)) :
t.healCol ? e.healCol = t.healCol : t.teleport && (e.x = r.randInt(0, c.mapScale),
e.y = r.randInt(0, c.mapScale)) : (e.lockMove = !0,
t.hideFromEnemy = !1);
else {
var f = r.getDirection(e.x, e.y, t.x, t.y);
if (r.getDistance(e.x, e.y, t.x, t.y),
t.isPlayer ? (d = -1 * d / 2,
e.x += d * s(f),
e.y += d * o(f),
t.x -= d * s(f),
t.y -= d * o(f)) : (e.x = t.x + u * s(f),
e.y = t.y + u * o(f),
e.xVel *= .75,
e.yVel *= .75),
t.dmg && t.owner != e && (!t.owner || !t.owner.team ||
t.owner.team != e.team)) {
e.changeHealth(-t.dmg, t.owner, t);
var p = 1.5 * (t.weightM || 1);
e.xVel += p * s(f),
e.yVel += p * o(f),
!t.pDmg || e.skin && e.skin.poisonRes ||
(e.dmgOverTime.dmg = t.pDmg,
e.dmgOverTime.time = 5,
e.dmgOverTime.doer = t.owner),
e.colDmg && t.health && (t.changeHealth(-e.colDmg) &&
this.disableObj(t),
this.hitObj(t, r.getDirection(e.x, e.y, t.x, t.y)))
}
}
return t.zIndex > e.zIndex && (e.zIndex = t.zIndex),
!0
}
}
return !1
}
}
}
, function(e, t, i) {
var n = new (i(13));
n.addWords("jew", "black", "baby", "child", "white", "porn", "pedo", "trump",
"clinton", "hitler", "nazi", "gay", "pride", "sex", "pleasure", "touch", "poo",
"kids", "rape", "white power", "nigga", "nig nog", "doggy", "rapist", "boner",
"nigger", "nigg", "finger", "nogger", "nagger", "nig", "fag", "gai", "pole",
"stripper", "penis", "vagina", "pussy", "nazi", "hitler", "stalin", "burn",
"chamber", "cock", "peen", "dick", "spick", "nieger", "die", "satan", "n|ig",
"nlg", "cunt", "c0ck", "fag", "lick", "condom", "anal", "shit", "phile", "little",
"kids", "free KR", "tiny", "sidney", "ass", "kill", ".io", "(dot)", "[dot]",
"mini", "whiore", "whore", "faggot", "github", "1337", "666", "satan", "senpa",
"discord", "d1scord", "mistik", ".io", "senpa.io", "sidney", "sid", "senpaio",
"vries", "asa");
var s = Math.abs
, o = Math.cos
, a = Math.sin
, r = Math.pow
, c = Math.sqrt;
e.exports = function(e, t, i, l, h, u, d, f, p, g, m, y, k, w) {
this.id = e,
this.sid = t,
this.tmpScore = 0,
this.team = null,
this.skinIndex = 0,
this.tailIndex = 0,
this.hitTime = 0,
this.tails = {};
for (var v = 0; v < m.length; ++v)
m[v].price <= 0 && (this.tails[m[v].id] = 1);
for (this.skins = {},
v = 0; v < g.length; ++v)
g[v].price <= 0 && (this.skins[g[v].id] = 1);
this.points = 0,
this.dt = 0,
this.hidden = !1,
this.itemCounts = {},
this.isPlayer = !0,
this.pps = 0,
this.moveDir = void 0,
this.skinRot = 0,
this.lastPing = 0,
this.iconIndex = 0,
this.skinColor = 0,
this.spawn = function(e) {
this.active = !0,
this.alive = !0,
this.lockMove = !1,
this.lockDir = !1,
this.minimapCounter = 0,
this.chatCountdown = 0,
this.shameCount = 0,
this.shameTimer = 0,
this.sentTo = {},
this.gathering = 0,
this.autoGather = 0,
this.animTime = 0,
this.animSpeed = 0,
this.mouseState = 0,
this.buildIndex = -1,
this.weaponIndex = 0,
this.dmgOverTime = {},
this.noMovTimer = 0,
this.maxXP = 300,
this.XP = 0,
this.age = 1,
this.kills = 0,
this.upgrAge = 2,
this.upgradePoints = 0,
this.x = 0,
this.y = 0,
this.zIndex = 0,
this.xVel = 0,
this.yVel = 0,
this.slowMult = 1,
this.dir = 0,
this.dirPlus = 0,
this.targetDir = 0,
this.targetAngle = 0,
this.maxHealth = 100,
this.health = this.maxHealth,
this.scale = i.playerScale,
this.speed = i.playerSpeed,
this.resetMoveDir(),
this.resetResources(e),
this.items = [0, 3, 6, 10],
this.weapons = [0],
this.shootCount = 0,
this.weaponXP = [],
this.reloads = {}
}
,
this.resetMoveDir = function() {
this.moveDir = void 0
}
,
this.resetResources = function(e) {
for (var t = 0; t < i.resourceTypes.length; ++t)
this[i.resourceTypes[t]] = e ? 100 : 0
}
,
this.addItem = function(e) {
var t = p.list[e];
if (t) {
for (var i = 0; i < this.items.length; ++i)
if (p.list[this.items[i]].group == t.group)
return this.buildIndex == this.items[i] && (this.buildIndex
= e),
this.items[i] = e,
!0;
return this.items.push(e),
!0
}
return !1
}
,
this.setUserData = function(e) {
if (e) {
this.name = "unknown";
var t = e.name + ""
, s = !1
, o = (t = (t = (t = (t = t.slice(0,
i.maxNameLength)).replace(/[^\w:\(\)\/? -]+/gim, " ")).replace(/[^\x00-\x7F]/g, "
")).trim()).toLowerCase().replace(/\s/g, "").replace(/1/g, "i").replace(/0/g,
"o").replace(/5/g, "s");
for (var a of n.list)
if (-1 != o.indexOf(a)) {
s = !0;
break
}
t.length > 0 && !s && (this.name = t),
this.skinColor = 0,
i.skinColors[e.skin] && (this.skinColor = e.skin)
}
}
,
this.getData = function() {
return [this.id, this.sid, this.name, l.fixTo(this.x, 2),
l.fixTo(this.y, 2), l.fixTo(this.dir, 3), this.health, this.maxHealth, this.scale,
this.skinColor]
}
,
this.setData = function(e) {
this.id = e[0],
this.sid = e[1],
this.name = e[2],
this.x = e[3],
this.y = e[4],
this.dir = e[5],
this.health = e[6],
this.maxHealth = e[7],
this.scale = e[8],
this.skinColor = e[9]
}
;
var b = 0;
this.update = function(e) {
if (this.alive) {
if (this.shameTimer > 0 && (this.shameTimer -= e,
this.shameTimer <= 0 &&
(this.shameTimer = 0,
this.shameCount = 0)),
(b -= e) <= 0) {
var t = (this.skin && this.skin.healthRegen ?
this.skin.healthRegen : 0) + (this.tail && this.tail.healthRegen ?
this.tail.healthRegen : 0);
t && this.changeHealth(t, this),
this.dmgOverTime.dmg && (this.changeHealth(-
this.dmgOverTime.dmg, this.dmgOverTime.doer),
this.dmgOverTime.time -= 1,
this.dmgOverTime.time <= 0 &&
(this.dmgOverTime.dmg = 0)),
this.healCol && this.changeHealth(this.healCol, this),
b = 1e3
}
if (this.alive) {
if (this.slowMult < 1 && (this.slowMult += 8e-4 * e,
this.slowMult > 1 && (this.slowMult =
1)),
this.noMovTimer += e,
(this.xVel || this.yVel) && (this.noMovTimer = 0),
this.lockMove)
this.xVel = 0,
this.yVel = 0;
else {
var n = (this.buildIndex >= 0 ? .5 : 1) *
(p.weapons[this.weaponIndex].spdMult || 1) * (this.skin && this.skin.spdMult || 1)
* (this.tail && this.tail.spdMult || 1) * (this.y <= i.snowBiomeTop ? this.skin &&
this.skin.coldM ? 1 : i.snowSpeed : 1) * this.slowMult;
!this.zIndex && this.y >= i.mapScale / 2 - i.riverWidth / 2
&& this.y <= i.mapScale / 2 + i.riverWidth / 2 && (this.skin && this.skin.watrImm ?
(n *= .75,
this.xVel += .4 * i.waterCurrent * e) : (n *= .33,
this.xVel
+= i.waterCurrent * e));
var s = null != this.moveDir ? o(this.moveDir) : 0,
f = null != this.moveDir ? a(this.moveDir) : 0,
g = c(s * s + f * f);
0 != g && (s /= g,
f /= g),
s && (this.xVel += s * this.speed * n * e),
f && (this.yVel += f * this.speed * n * e)
}
var m;
this.zIndex = 0,
this.lockMove = !1,
this.healCol = 0;
for (var y = l.getDistance(0, 0, this.xVel * e, this.yVel * e),
k = Math.min(4, Math.max(1, Math.round(y / 40))), w = 1 / k, v = {}, x = 0; x < k;
++x) {
this.xVel && (this.x += this.xVel * e * w),
this.yVel && (this.y += this.yVel * e * w),
m = u.getGridArrays(this.x, this.y, this.scale);
for (var S = 0; S < m.length; ++S) {
for (var I = 0; I < m[S].length && (!m[S][I].active ||
v[m[S][I].sid] || !u.checkCollision(this, m[S][I], w) || (v[m[S][I].sid] = !0,
this.alive)); ++I)
;
if (!this.alive)
break
}
if (!this.alive)
break
}
for (x = (M = d.indexOf(this)) + 1; x < d.length; ++x)
d[x] != this && d[x].alive && u.checkCollision(this, d[x]);
if (this.xVel && (this.xVel *= r(i.playerDecel, e),
this.xVel <= .01 && this.xVel >= -.01 &&
(this.xVel = 0)),
this.yVel && (this.yVel *= r(i.playerDecel, e),
this.yVel <= .01 && this.yVel >= -.01 &&
(this.yVel = 0)),
this.x - this.scale < 0 ? this.x = this.scale : this.x +
this.scale > i.mapScale && (this.x = i.mapScale - this.scale),
this.y - this.scale < 0 ? this.y = this.scale : this.y +
this.scale > i.mapScale && (this.y = i.mapScale - this.scale),
this.buildIndex < 0)
if (this.reloads[this.weaponIndex] > 0)
this.reloads[this.weaponIndex] -= e,
this.gathering = this.mouseState;
else if (this.gathering || this.autoGather) {
var T = !0;
if (null != p.weapons[this.weaponIndex].gather)
this.gather(d);
else if (null != p.weapons[this.weaponIndex].projectile
&& this.hasRes(p.weapons[this.weaponIndex], this.skin ? this.skin.projCost : 0)) {
this.useRes(p.weapons[this.weaponIndex],
this.skin ? this.skin.projCost : 0),
this.noMovTimer = 0;
var M = p.weapons[this.weaponIndex].projectile,
C = 2 * this.scale,
P = this.skin && this.skin.aMlt ?
this.skin.aMlt : 1;
p.weapons[this.weaponIndex].rec && (this.xVel -=
p.weapons[this.weaponIndex].rec * o(this.dir),
this.yVel -=
p.weapons[this.weaponIndex].rec * a(this.dir)),
h.addProjectile(this.x + C * o(this.dir),
this.y + C * a(this.dir), this.dir, p.projectiles[M].range * P,
p.projectiles[M].speed * P, M, this, null, this.zIndex)
} else
T = !1;
this.gathering = this.mouseState,
T && (this.reloads[this.weaponIndex] =
p.weapons[this.weaponIndex].speed * (this.skin && this.skin.atkSpd || 1))
}
}
}
}
,
this.tick = function(delta) {
if (this.alive) {
if (this.skinIndex === 45) {
this.shameTimer > 0 && (this.shameTimer -= delta)
}
}
}
,
this.resetHealthAnim = function() {
this.updateHealthTime = void 0
this.lossHealth = void 0
this.oldHealth = void 0
this.healedAmount = 0
}
,
this.updateHealthAnim = function() {
if (!this.alive || !this.updateHealthTime) return
if (this.isHealing) {
this.health += amount
this.healedAmount += amount
this.hitTime = 0
if (timeSinceHit < 2) {
this.shameCount += 1
if (this.shameCount >= 8) {
this.shameTimer = 30000
this.shameCount = 0
}
} else {
this.shameCount = Math.max(0, this.shameCount - 2)
}
}
}
,
this.hasRes = function(e, t) {
for (var i = 0; i < e.req.length; ) {
if (this[e.req[i]] < Math.round(e.req[i + 1] * (t || 1)))
return !1;
i += 2
}
return !0
}
,
this.useRes = function(e, t) {
if (!i.inSandbox)
for (var n = 0; n < e.req.length; )
this.addResource(i.resourceTypes.indexOf(e.req[n]), -
Math.round(e.req[n + 1] * (t || 1))),
n += 2
}
,
this.canBuild = function(e) {
var t = i.inSandbox ? Math.max(3 * e.group.limit, 99) : e.group.limit;
return !(t && this.itemCounts[e.group.id] >= t) && (!!i.inSandbox ||
this.hasRes(e))
}
,
this.gather = function() {
this.noMovTimer = 0,
this.slowMult -= p.weapons[this.weaponIndex].hitSlow || .3,
this.slowMult < 0 && (this.slowMult = 0);
for (var e, t, n, s = i.fetchVariant(this), r = s.poison, c = s.val, h
= {}, g = u.getGridArrays(this.x, this.y, p.weapons[this.weaponIndex].range), m =
0; m < g.length; ++m)
for (var y = 0; y < g[m].length; ++y)
if ((t = g[m][y]).active && !t.dontGather && !h[t.sid] &&
t.visibleToPlayer(this) && l.getDistance(this.x, this.y, t.x, t.y) - t.scale <=
p.weapons[this.weaponIndex].range && (e = l.getDirection(t.x, t.y, this.x, this.y),
l.getAngleDist(e, this.dir) <= i.gatherAngle)) {
if (h[t.sid] = 1,
t.health) {
if (t.changeHealth(-p.weapons[this.weaponIndex].dmg * c
* (p.weapons[this.weaponIndex].sDmg || 1) * (this.skin && this.skin.bDmg ?
this.skin.bDmg : 1), this)) {
for (var k = 0; k < t.req.length; )
if (window.menu.getModelActive("reload-bars")) {
if (this.animTime >= (this.primaryReloadMax / 2)) {
this.animActive = true
} else {
this.animActive = false
}
}
}
,
this.startAnim = function(e, t) {
if (window.menu.getModelActive("reload-bars") &&
window.menu.getModelActive("reload-bars-primary")) {
this.animActive = true
this.primaryReloadMax = this.primaryReload =
p.weapons[this.weaponIndex].speed
}
x = 0
S = 0
}
,
this.updatePrimaryReload = function() {
if (!window.menu.getModelActive("reload-bars")) return
let count = 1
if (this.animActive) {
this.primaryReload -= window.delta
this.isSecondaryReloadActive = true
if (this.secondaryReload <= 0) {
this.isSecondaryReloadActive = false
this.secondaryReloadCount = 1
return
}
this.secondaryReload -= window.delta