javedpension leaked
// ==UserScript==
// @name Revelation (nachocheesefry ass gptd hack)
// @namespace http://tampermonkey.net/
// @version infinite
// @description javedpension leaked
// @author Nachocheesefry, snorlax, kwyxl, forker
// @require https://greasyfork.org/scripts/423602-msgpack/code/msgpack.js
// @match https://*.moomoo.io/*
// @icon https://i.imgur.com/Z8oaFKj.png
// @grant none
// @license WTFPL
// ==/UserScript==
// Force bot spawning toggle ON by default
/*var spawning = true;
document.onkeydown = function (evt) { // for opera gx mac
if (evt.keyCode == 27) {
evt.preventDefault();
console.log("There is no escape");
}
};*/
/* Read It Before You Use
veltick can toggle to press shift.
MUST NEEDED: turret hat, bull helmet,"SHADOW WING" ←It's easy to forget.
and diamond+ polearm
must turn off auto equip fastest weaopn.
If problems, dm me.
These are the reported bugs.
Auto-attack when placed windmills → Placing spikes with the V key somehow fixes it.
Loading screen is glitchy → Reload the page. If that doesn't work, press Esc to open the menu and toggle Veltick off. Then, reload.
Charging toward enemies significantly increases Veltick's success rate (nearly 100%).
Since I tested this in an environment with a ping of around 90-100ms, I cannot guarantee success rates in other conditions.
Beyond that ping(100ms<), the success rate drops to around 40%. And, It has never reached below that. My computer is terrible, after all lol.
While it's possible to use the auto positioning function with the U key to target openings during fight, I don't recommend it. I didn't use YouTube.
It's not a toggle; it's only active while you hold it down.)
Just Emjoy!
*/
document.title = 'Revelation';
$("#wideAdCard").remove();
// Change favicon
function changeFavicon(newIconUrl) {
// Remove existing favicon links
const existingLinks = document.querySelectorAll("link[rel*='icon']");
existingLinks.forEach(link => link.remove());
// Create new favicon link
const link = document.createElement('link');
link.rel = 'icon';
link.type = 'image/png';
link.href = newIconUrl;
// Add to document head
document.head.appendChild(link);
}
// Call the function with your icon URL
changeFavicon('https://i.imgur.com/Z8oaFKj.png');
(function() {
})();var moomooVer = $('#linksContainer2 .menuLink').html(),
hideSelectors = ['#mobileDownloadButtonContainer',
'#followText',
'#smallLinks',
'#linksContainer1',
'#twitterFollow',
'#youtubeFollow',
'#cdm-zone-02',
'#youtuberOf',
'#downloadButtonContainer',
'#promoImg',
'.menuHeader',
'.menuLink',
'.menuHeader:nth-child(5)',
'.menuHeader:nth-child(6)',
'.menuText',
'#adCard',
'#promoImgHolder',
],
css = '#rightCardHolder {display: block!important}',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
$("#mapDisplay").css({
background: `url('https://i.imgur.com/fgFsQJp.png')`
});
style.type = 'text/css';
if (style.styleSheet){
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
for ( let i = 0; i < hideSelectors.length; i++ ) {
$(hideSelectors[i]).hide();
}
head.appendChild(style);
$('#linksContainer2').html('<a href="./docs/versions.txt" target="_blank" class="menuLink">' + moomooVer + '</a>');
document.getElementById('gameName').style.fontSize = "120px";
document.getElementById('enterGame').innerHTML = 'play';
document.getElementById('loadingText').innerHTML = 'Revelation';
document.getElementById('nameInput').placeholder = "Revelation";
document.getElementById('diedText').innerHTML = 'rip';
document.getElementById("leaderboard").append ('Revelation ')
document.getElementById("gameName").innerHTML = "Revelation";
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'r';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 're';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'rev';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'reve';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revel';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revel';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revela';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revela';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revela';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revelat';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revelati';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revelati';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revelatio';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revelation';
setTimeout(() => {
document.getElementById('gameName').innerHTML = 'revelation';
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
}, 200);
$('#storeTab').css({'-webkit-border-radius': '0px',
'-moz-border-radius': '0px',
'border-radius': '0px',
'background-color': 'rgba(0, 0, 0, 0.4)'});
$('#storeHolder').css({'-webkit-border-radius': '0px',
'-moz-border-radius': '0px',
'border-radius': '0px',
'background-color': 'rgba(0, 0, 0, 0.4)'});
document.getElementById("storeHolder").style = "height: 1500px; width: 450px;"
let testeroo = 0;
let ticks = 0;
const {
sin,
cos,
min,
max,
random,
floor,
trunc,
ceil,
round,
tan,
PI,
sqrt,
abs,
pow,
log,
LN2,
atan2,
SQRT2,
acos,
sign,
hypot
} = Math;
const PI2 = PI * 2;
const gatherAng = PI / 2.6;
const JSONStringify = JSON.stringify;
const JSONParse = JSON.parse;
const timeBetweenTick = 1000 / 9;
const timeBetweenTick2 = timeBetweenTick * 2;
const {
now: getDate
} = Date;
var gFont = "https://fonts.googleapis.com/css2?family=Lilita+One&display=swap"//"https://fonts.googleapis.com/css2?family=Concert+One&display=swap"//"https://fonts.googleapis.com/css2?family=Rowdies:wght@300;400;700&display=swap"//"https://fonts.googleapis.com/css2?family=Nerko+One&display=swap"; //"https://fonts.googleapis.com/css2?family=Potta+One&display=swap"; //"https://fonts.googleapis.com/css2?family=Lilita+One&family=Titan+One&family=Wendy+One&display=swap";
//'https://fonts.googleapis.com/css2?family=Titan+One&display=swap';
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = gFont;
document.head.appendChild(link);
const outlineIntensity = 0.35;
const allColors = new Set([
"#bf8f54", "#cbb091", "#896c4b", "#fadadc", "#ececec", "#c37373", "#4c4c4c", "#ecaff7", "#738cc3", "#8bc373","#67A9DD"
]);
let autoSpacingToggled = false;
let isAutoSpacingActive = false;
let amPlacing = [];
// there is a bug with cicle reloads cuz of this
function darken(color, amount) {
const parseHex = hex => parseInt(hex, 16);
const multiplyAndRound = (value, factor) => (value * factor) | 0;
const toHex = value => value.toString(16).padStart(2, '0');
const r = multiplyAndRound(parseHex(color.substr(1, 2)), 1 - amount);
const g = multiplyAndRound(parseHex(color.substr(3, 2)), 1 - amount);
const b = multiplyAndRound(parseHex(color.substr(5, 2)), 1 - amount);
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
function lighten(color, amount) {
const parseHex = hex => parseInt(hex, 16);
const addAndRound = (value, increment) => Math.min(255, (value + increment) | 0);
const toHex = value => value.toString(16).padStart(2, '0');
const increment = 255 * amount;
const r = addAndRound(parseHex(color.substr(1, 2)), increment);
const g = addAndRound(parseHex(color.substr(3, 2)), increment);
const b = addAndRound(parseHex(color.substr(5, 2)), increment);
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
var compositeImages = {hats:{},accessories:{},weapons:{},animals:{}}
// Menu script has been remade by best coder- zylo :3
const menu = document.createElement('div');
menu.id = 'transparentMenu';
document.body.appendChild(menu);
var styleString = `
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
/* ===== CSS VARIABLES FOR THEMING ===== */
:root {
--menu-bg-primary: rgba(15, 15, 25, 0.95);
--menu-bg-secondary: rgba(25, 25, 40, 0.95);
--menu-accent: #6366f1;
--menu-accent-secondary: #8b5cf6;
--menu-text: #ffffff;
--menu-text-muted: rgba(255, 255, 255, 0.5);
--menu-border: rgba(255, 255, 255, 0.08);
--menu-card-bg: rgba(255, 255, 255, 0.02);
--menu-card-hover: rgba(255, 255, 255, 0.05);
--menu-scale: 1;
--menu-opacity: 0.95;
--menu-blur: 20px;
--menu-radius: 16px;
--sidebar-width: 180px;
}
.theme-midnight {
--menu-bg-primary: rgba(15, 15, 25, 0.95);
--menu-bg-secondary: rgba(25, 25, 40, 0.95);
--menu-accent: #6366f1;
--menu-accent-secondary: #8b5cf6;
}
.theme-ocean {
--menu-bg-primary: rgba(10, 25, 40, 0.95);
--menu-bg-secondary: rgba(15, 35, 55, 0.95);
--menu-accent: #06b6d4;
--menu-accent-secondary: #0ea5e9;
}
.theme-forest {
--menu-bg-primary: rgba(15, 25, 15, 0.95);
--menu-bg-secondary: rgba(25, 40, 25, 0.95);
--menu-accent: #10b981;
--menu-accent-secondary: #34d399;
}
.theme-sunset {
--menu-bg-primary: rgba(35, 15, 20, 0.95);
--menu-bg-secondary: rgba(50, 25, 30, 0.95);
--menu-accent: #f97316;
--menu-accent-secondary: #fb923c;
}
.theme-rose {
--menu-bg-primary: rgba(30, 15, 25, 0.95);
--menu-bg-secondary: rgba(45, 25, 40, 0.95);
--menu-accent: #ec4899;
--menu-accent-secondary: #f472b6;
}
.theme-blood {
--menu-bg-primary: rgba(25, 10, 10, 0.95);
--menu-bg-secondary: rgba(40, 15, 15, 0.95);
--menu-accent: #ef4444;
--menu-accent-secondary: #f87171;
}
.theme-golden {
--menu-bg-primary: rgba(25, 22, 10, 0.95);
--menu-bg-secondary: rgba(40, 35, 15, 0.95);
--menu-accent: #eab308;
--menu-accent-secondary: #facc15;
}
.theme-monochrome {
--menu-bg-primary: rgba(20, 20, 20, 0.95);
--menu-bg-secondary: rgba(35, 35, 35, 0.95);
--menu-accent: #a1a1aa;
--menu-accent-secondary: #d4d4d8;
}
.theme-neon {
--menu-bg-primary: rgba(5, 5, 15, 0.95);
--menu-bg-secondary: rgba(10, 10, 25, 0.95);
--menu-accent: #22d3ee;
--menu-accent-secondary: #a855f7;
}
.theme-light {
--menu-bg-primary: rgba(245, 245, 250, 0.95);
--menu-bg-secondary: rgba(235, 235, 245, 0.95);
--menu-accent: #6366f1;
--menu-accent-secondary: #8b5cf6;
--menu-text: #1f2937;
--menu-text-muted: rgba(31, 41, 55, 0.6);
--menu-border: rgba(0, 0, 0, 0.1);
--menu-card-bg: rgba(0, 0, 0, 0.03);
--menu-card-hover: rgba(0, 0, 0, 0.06);
}
#transparentMenu {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(var(--menu-scale));
background: linear-gradient(145deg, var(--menu-bg-primary) 0%, var(--menu-bg-secondary) 100%);
backdrop-filter: blur(var(--menu-blur));
-webkit-backdrop-filter: blur(var(--menu-blur));
color: var(--menu-text);
padding: 0;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 9999;
display: none;
width: 750px;
height: 500px;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
border: 1px solid var(--menu-border);
border-radius: var(--menu-radius);
box-shadow: 0 25px 60px -12px rgba(0, 0, 0, 0.7),
0 0 0 1px rgba(255, 255, 255, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
opacity: var(--menu-opacity);
overflow: hidden;
}
#transparentMenu.dragging {
cursor: grabbing;
user-select: none;
}
#transparentMenu.visible {
display: flex;
animation: menuSlideIn 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes menuSlideIn {
from {
opacity: 0;
transform: translate(-50%, -50%) scale(calc(var(--menu-scale) * 0.9));
}
to {
opacity: var(--menu-opacity);
transform: translate(-50%, -50%) scale(var(--menu-scale));
}
}
.menu-container {
display: flex;
width: 100%;
height: 100%;
}
.menu-sidebar {
width: var(--sidebar-width);
background: rgba(0, 0, 0, 0.25);
border-right: 1px solid var(--menu-border);
display: flex;
flex-direction: column;
flex-shrink: 0;
}
.sidebar-header {
padding: 20px 16px;
border-bottom: 1px solid var(--menu-border);
cursor: grab;
}
.sidebar-header:active {
cursor: grabbing;
}
.menu-title {
font-size: 16px;
font-weight: 700;
letter-spacing: -0.5px;
background: linear-gradient(135deg, var(--menu-text) 0%, var(--menu-text-muted) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin: 0 0 4px 0;
}
.menu-subtitle {
font-size: 10px;
color: var(--menu-text-muted);
letter-spacing: 0.5px;
text-transform: uppercase;
}
.sidebar-nav {
flex: 1;
overflow-y: auto;
padding: 12px 8px;
scrollbar-width: none;
}
.sidebar-nav::-webkit-scrollbar {
display: none;
}
.nav-item {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 14px;
margin-bottom: 4px;
border-radius: 10px;
cursor: pointer;
transition: all 0.2s ease;
color: var(--menu-text-muted);
font-size: 13px;
font-weight: 500;
border: 1px solid transparent;
}
.nav-item:hover {
background: var(--menu-card-hover);
color: var(--menu-text);
}
.nav-item.active {
background: linear-gradient(135deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
color: #fff;
border-color: transparent;
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);
}
.nav-item .nav-icon {
font-size: 16px;
width: 20px;
text-align: center;
}
.nav-item .nav-label {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.sidebar-footer {
padding: 12px;
border-top: 1px solid var(--menu-border);
display: flex;
gap: 6px;
}
.sidebar-btn {
flex: 1;
padding: 8px;
border-radius: 8px;
border: 1px solid var(--menu-border);
background: var(--menu-card-bg);
color: var(--menu-text-muted);
cursor: pointer;
font-size: 12px;
transition: all 0.2s ease;
text-align: center;
}
.sidebar-btn:hover {
background: var(--menu-card-hover);
color: var(--menu-text);
border-color: var(--menu-accent);
}
.menu-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.content-header {
padding: 16px 20px;
border-bottom: 1px solid var(--menu-border);
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(0, 0, 0, 0.1);
}
.content-title {
font-size: 18px;
font-weight: 600;
color: var(--menu-text);
display: flex;
align-items: center;
gap: 10px;
}
.content-title .title-icon {
font-size: 20px;
}
.content-controls {
display: flex;
gap: 8px;
}
.control-btn {
width: 32px;
height: 32px;
border-radius: 8px;
border: 1px solid var(--menu-border);
background: var(--menu-card-bg);
color: var(--menu-text-muted);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
transition: all 0.2s ease;
}
.control-btn:hover {
background: var(--menu-card-hover);
color: var(--menu-text);
border-color: var(--menu-accent);
}
.section {
display: none;
flex: 1;
overflow-y: auto;
padding: 20px;
scrollbar-width: thin;
scrollbar-color: var(--menu-accent) transparent;
}
.section::-webkit-scrollbar {
width: 6px;
}
.section::-webkit-scrollbar-track {
background: transparent;
}
.section::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
border-radius: 3px;
}
.section.active {
display: block;
animation: sectionFadeIn 0.3s ease;
}
@keyframes sectionFadeIn {
from { opacity: 0; transform: translateX(10px); }
to { opacity: 1; transform: translateX(0); }
}
.section-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
}
.section-grid.single {
grid-template-columns: 1fr;
}
.section-divider {
grid-column: 1 / -1;
font-size: 10px;
font-weight: 600;
letter-spacing: 1.5px;
text-transform: uppercase;
color: var(--menu-text-muted);
margin: 16px 0 8px 0;
padding-bottom: 8px;
border-bottom: 1px solid var(--menu-border);
}
.section-divider:first-child {
margin-top: 0;
}
.toggle-slider {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 10px;
cursor: pointer;
transition: all 0.2s ease;
}
.toggle-slider:hover {
background: var(--menu-card-hover);
border-color: rgba(255, 255, 255, 0.12);
}
.toggle-slider span:first-of-type {
font-size: 12px;
font-weight: 500;
color: var(--menu-text);
opacity: 0.85;
flex: 1;
}
.toggle-slider input {
opacity: 0;
width: 0;
height: 0;
position: absolute;
}
.slider {
position: relative;
width: 38px;
height: 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
flex-shrink: 0;
}
.slider:before {
position: absolute;
content: "";
height: 14px;
width: 14px;
left: 3px;
bottom: 3px;
background: var(--menu-text-muted);
border-radius: 50%;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
input:checked + .slider {
background: linear-gradient(135deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
}
input:checked + .slider:before {
transform: translateX(18px);
background: #fff;
box-shadow: 0 2px 10px rgba(99, 102, 241, 0.4);
}
.toggle-slider:has(input:checked) {
background: rgba(99, 102, 241, 0.08);
border-color: rgba(99, 102, 241, 0.2);
}
.dropdown-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 10px;
transition: all 0.2s ease;
}
.dropdown-wrapper:hover {
background: var(--menu-card-hover);
}
.dropdown-label {
font-size: 12px;
font-weight: 500;
color: var(--menu-text);
opacity: 0.85;
}
.dropdown {
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--menu-border);
border-radius: 6px;
color: var(--menu-text);
padding: 6px 10px;
font-size: 11px;
font-family: 'Inter', sans-serif;
cursor: pointer;
outline: none;
transition: all 0.2s ease;
min-width: 100px;
}
.dropdown:hover, .dropdown:focus {
border-color: var(--menu-accent);
background: rgba(0, 0, 0, 0.4);
}
.dropdown option {
background: #1a1a2e;
color: #fff;
padding: 8px;
}
.input-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 10px;
}
.input-wrapper label {
font-size: 12px;
font-weight: 500;
color: var(--menu-text);
opacity: 0.85;
}
.input-wrapper input[type="text"],
.input-wrapper input[type="number"] {
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--menu-border);
border-radius: 6px;
color: var(--menu-text);
padding: 6px 10px;
font-size: 11px;
font-family: 'Inter', sans-serif;
outline: none;
width: 100px;
transition: all 0.2s ease;
}
.input-wrapper input:focus {
border-color: var(--menu-accent);
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.1);
}
.throttle-slider {
grid-column: 1 / -1;
padding: 12px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 10px;
}
.throttle-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.throttle-slider span:first-of-type {
font-size: 12px;
font-weight: 500;
color: var(--menu-text);
opacity: 0.85;
}
.throttle-value {
font-size: 12px;
font-weight: 600;
color: var(--menu-accent-secondary);
background: rgba(139, 92, 246, 0.1);
padding: 3px 8px;
border-radius: 5px;
}
.throttle-tooltip {
font-size: 10px;
color: var(--menu-text-muted);
margin-bottom: 8px;
}
.throttle-slider input[type="range"] {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 5px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
outline: none;
cursor: pointer;
}
.throttle-slider input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 16px;
height: 16px;
background: linear-gradient(135deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
border-radius: 50%;
cursor: pointer;
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.4);
transition: transform 0.2s ease;
}
.throttle-slider input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.15);
}
.throttle-slider input[type="range"]::-moz-range-thumb {
width: 16px;
height: 16px;
background: linear-gradient(135deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
border-radius: 50%;
cursor: pointer;
border: none;
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.4);
}
.theme-grid {
grid-column: 1 / -1;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 8px;
margin-bottom: 8px;
}
.theme-btn {
aspect-ratio: 1.2;
border-radius: 8px;
border: 2px solid transparent;
cursor: pointer;
transition: all 0.2s ease;
position: relative;
overflow: hidden;
}
.theme-btn:hover {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.theme-btn.active {
border-color: #fff;
box-shadow: 0 0 0 2px var(--menu-accent);
}
.theme-btn::after {
content: attr(data-name);
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 2px;
font-size: 7px;
text-align: center;
background: rgba(0, 0, 0, 0.6);
color: #fff;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.theme-midnight { background: linear-gradient(135deg, #0f0f19, #19192a); }
.theme-ocean { background: linear-gradient(135deg, #0a1928, #0f2337); }
.theme-forest { background: linear-gradient(135deg, #0f190f, #192819); }
.theme-sunset { background: linear-gradient(135deg, #230f14, #32191e); }
.theme-rose { background: linear-gradient(135deg, #1e0f19, #2d1928); }
.theme-blood { background: linear-gradient(135deg, #190a0a, #280f0f); }
.theme-golden { background: linear-gradient(135deg, #19160a, #28230f); }
.theme-monochrome { background: linear-gradient(135deg, #141414, #232323); }
.theme-neon { background: linear-gradient(135deg, #05050f, #0a0a19); }
.theme-light-btn { background: linear-gradient(135deg, #f5f5fa, #ebebf5); }
.color-picker-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 10px;
}
.color-picker-wrapper label {
font-size: 12px;
font-weight: 500;
color: var(--menu-text);
opacity: 0.85;
}
.color-picker-wrapper input[type="color"] {
-webkit-appearance: none;
width: 36px;
height: 24px;
border: none;
border-radius: 5px;
cursor: pointer;
overflow: hidden;
}
.color-picker-wrapper input[type="color"]::-webkit-color-swatch-wrapper {
padding: 0;
}
.color-picker-wrapper input[type="color"]::-webkit-color-swatch {
border: 2px solid var(--menu-border);
border-radius: 5px;
}
.quick-actions {
grid-column: 1 / -1;
display: flex;
gap: 8px;
}
.quick-action-btn {
flex: 1;
padding: 10px 12px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 8px;
color: var(--menu-text);
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
}
.quick-action-btn:hover {
background: var(--menu-card-hover);
border-color: var(--menu-accent);
}
.size-presets {
grid-column: 1 / -1;
display: flex;
gap: 6px;
}
.size-preset-btn {
flex: 1;
padding: 8px;
background: var(--menu-card-bg);
border: 1px solid var(--menu-border);
border-radius: 6px;
color: var(--menu-text);
font-size: 10px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
}
.size-preset-btn:hover {
background: var(--menu-card-hover);
border-color: var(--menu-accent);
}
.size-preset-btn.active {
background: var(--menu-accent);
border-color: var(--menu-accent);
}
.chat-container {
position: fixed;
top: 15px;
left: 15px;
width: 350px;
height: 240px;
background: linear-gradient(145deg, var(--menu-bg-primary) 0%, var(--menu-bg-secondary) 100%);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
color: var(--menu-text);
font-family: 'Inter', sans-serif;
border-radius: 12px;
border: 1px solid var(--menu-border);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4);
padding: 0;
display: flex;
flex-direction: column;
overflow: hidden;
z-index: 9998;
}
.chat-header {
padding: 12px 16px;
background: rgba(0, 0, 0, 0.2);
border-bottom: 1px solid var(--menu-border);
font-size: 10px;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--menu-text-muted);
}
.chat-history {
flex: 1;
padding: 10px 14px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: rgba(99, 102, 241, 0.3) transparent;
}
.chat-history::-webkit-scrollbar {
width: 4px;
}
.chat-history::-webkit-scrollbar-track {
background: transparent;
}
.chat-history::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
border-radius: 2px;
}
.chat-message {
padding: 8px 10px;
margin-bottom: 6px;
background: var(--menu-card-bg);
border-radius: 8px;
border-left: 2px solid var(--menu-accent);
font-size: 12px;
line-height: 1.4;
animation: msgSlideIn 0.3s ease;
word-wrap: break-word;
}
.chat-message:hover {
background: var(--menu-card-hover);
}
@keyframes msgSlideIn {
from {
opacity: 0;
transform: translateX(-10px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.chat-message .time {
color: var(--menu-text-muted);
font-size: 10px;
margin-right: 6px;
}
.chat-message .name {
font-weight: 600;
}
.chat-message.pm {
border-left-color: #10b981;
background: rgba(16, 185, 129, 0.05);
}
.chat-input-wrapper {
padding: 10px 12px;
background: rgba(0, 0, 0, 0.2);
border-top: 1px solid var(--menu-border);
}
.chat-input {
width: 100%;
height: 36px;
background: rgba(0, 0, 0, 0.3);
border: 1px solid var(--menu-border);
border-radius: 8px;
outline: none;
color: var(--menu-text);
padding: 0 12px;
font-size: 12px;
font-family: 'Inter', sans-serif;
box-sizing: border-box;
transition: all 0.25s ease;
}
.chat-input::placeholder {
color: var(--menu-text-muted);
}
.chat-input:focus {
border-color: var(--menu-accent);
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.1);
background: rgba(0, 0, 0, 0.4);
}
.scroll-button {
position: fixed;
top: 215px;
left: 335px;
width: 28px;
height: 28px;
background: linear-gradient(135deg, var(--menu-accent) 0%, var(--menu-accent-secondary) 100%);
border-radius: 50%;
display: none;
justify-content: center;
align-items: center;
cursor: pointer;
z-index: 9999;
box-shadow: 0 3px 12px rgba(99, 102, 241, 0.4);
transition: all 0.25s ease;
}
.scroll-button:hover {
transform: scale(1.1);
}
.scroll-button::before {
content: "";
width: 0;
height: 0;
border-top: 6px solid white;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
.keybind-hint {
padding: 10px 16px;
font-size: 10px;
color: var(--menu-text-muted);
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
border-top: 1px solid var(--menu-border);
background: rgba(0, 0, 0, 0.1);
}
.keybind-hint kbd {
background: var(--menu-card-bg);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Inter', monospace;
font-size: 9px;
border: 1px solid var(--menu-border);
}
`;
const styleElement = document.createElement('style');
styleElement.textContent = styleString;
document.head.appendChild(styleElement);
const scrollButton = document.createElement('div');
scrollButton.className = 'scroll-button';
const chatContainer = document.createElement('div');
chatContainer.className = 'chat-container';
const chatHeader = document.createElement('div');
chatHeader.className = 'chat-header';
chatHeader.textContent = 'Chat Log';
const chatHistory = document.createElement('div');
chatHistory.className = 'chat-history';
const chatInputWrapper = document.createElement('div');
chatInputWrapper.className = 'chat-input-wrapper';
const chatInput = document.createElement('input');
chatInput.type = 'text';
chatInput.className = 'chat-input';
chatInput.placeholder = 'Type a message or press "/" ...';
chatInput.maxLength = 100;
chatInputWrapper.appendChild(chatInput);
chatContainer.appendChild(chatHeader);
chatContainer.appendChild(chatHistory);
chatContainer.appendChild(chatInputWrapper);
document.body.appendChild(scrollButton);
document.body.appendChild(chatContainer);
const maxmessages = 2000;
const addChatLog = (names, message, color, pm, timer) => {
const isScrolledToBottom =
chatHistory.scrollHeight - chatHistory.scrollTop <= chatHistory.clientHeight + 1;
const chatMessage = document.createElement('div');
chatMessage.className = 'chat-message' + (pm ? ' pm' : '');
if (!timer) {
const time = document.createElement('span');
time.className = 'time';
time.textContent = getTime();
chatMessage.appendChild(time);
}
const name = document.createElement('span');
name.className = 'name';
name.style.color = color || '#fff';
name.textContent = names;
chatMessage.appendChild(name);
const messageContent = document.createElement('span');
messageContent.textContent = message;
chatMessage.appendChild(messageContent);
chatHistory.appendChild(chatMessage);
if (chatHistory.children.length > maxmessages) {
chatHistory.removeChild(chatHistory.children[0]);
}
if (isScrolledToBottom) {
chatHistory.scrollTop = chatHistory.scrollHeight;
toggleScrollButton();
} else {
scrollButton.style.display = 'flex';
}
};
const isScrolledToBottom = () => {
return chatHistory.scrollHeight - chatHistory.scrollTop <= chatHistory.clientHeight + 1;
};
const toggleScrollButton = () => {
if (isScrolledToBottom() || chatHistory.clientHeight >= chatHistory.scrollHeight) {
scrollButton.style.display = 'none';
} else {
scrollButton.style.display = 'flex';
}
};
scrollButton.addEventListener('click', () => {
chatHistory.scrollTop = chatHistory.scrollHeight;
});
chatHistory.addEventListener('scroll', toggleScrollButton);
scrollButton.style.display = 'none';
chatInput.addEventListener('keydown', (event) => {
event.stopPropagation();
});
function createDropdown(labelText, options) {
const storedValue = getStoredValue(labelText, options[0]);
const dropdownOptions = options.map(option => `
<option value="${option}" ${option === storedValue ? 'selected' : ''}>${option}</option>
`).join('');
return `
<div class="dropdown-wrapper">
<span class="dropdown-label">${labelText}</span>
<select id="${labelText}" class="dropdown">
${dropdownOptions}
</select>
</div>
`;
}
function createToggleSlider(labelText, defaultValue) {
const storedValue = getStoredValue(labelText, defaultValue === undefined ? true : defaultValue);
return `
<label class="toggle-slider">
<span>${labelText}</span>
<input type="checkbox" ${storedValue ? 'checked' : ''} id="${labelText}">
<span class="slider round"></span>
</label>
`;
}
function createInput(labelText, inputType, maxLength = 200) {
const storedValue = getStoredValue(labelText, '');
return `
<div class="input-wrapper">
<label>${labelText}</label>
<input type="${inputType}" value="${storedValue}" id="${labelText}" maxlength="${maxLength}">
</div>
`;
}
function createThrottleSlider(labelText, min, max, defaultValue, tooltip) {
const storedValue = getStoredValue(labelText, defaultValue);
return `
<div class="throttle-slider">
${tooltip ? `<div class="throttle-tooltip">${tooltip}</div>` : ''}
<div class="throttle-header">
<span>${labelText}</span>
<span class="throttle-value" id="${labelText}-value">${storedValue}</span>
</div>
<input type="range" min="${min}" max="${max}" value="${storedValue}" id="${labelText}">
</div>
`;
}
function createSectionDivider(text) {
return `<div class="section-divider">${text}</div>`;
}
function createColorPicker(labelText, defaultValue) {
const storedValue = getStoredValue(labelText, defaultValue || '#6366f1');
return `
<div class="color-picker-wrapper">
<label>${labelText}</label>
<input type="color" value="${storedValue}" id="${labelText}">
</div>
`;
}
function updateThrottleValue(sliderId) {
const slider = gE(sliderId);
const valueSpan = gE(`${sliderId}-value`);
if (valueSpan) valueSpan.innerText = slider.value;
setStoredValue(sliderId, slider.value);
}
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
toggleMenu();
}
});
const navItems = [
{ id: 'section1', icon: '', label: 'Combat' },
{ id: 'section2', icon: '', label: 'Healing' },
{ id: 'section3', icon: '', label: 'Visuals' },
{ id: 'section4', icon: '', label: 'Keybinds' },
{ id: 'section5', icon: '', label: 'Bots' },
{ id: 'section6', icon: '', label: 'Throttles' },
{ id: 'section7', icon: '', label: 'Extra' },
{ id: 'section8', icon: '', label: 'UI Settings' }
];
menu.innerHTML = `
<div class="menu-container">
<div class="menu-sidebar">
<div class="sidebar-header" id="dragHandle">
<div class="menu-title">Revelation</div>
<div class="menu-subtitle">v2.0 • Settings • Made by zylo</div>
</div>
<div class="sidebar-nav" id="sidebarNav">
${navItems.map((item, index) => `
<div class="nav-item ${index === 0 ? 'active' : ''}" data-section="${item.id}">
<span class="nav-icon">${item.icon}</span>
<span class="nav-label">${item.label}</span>
</div>
`).join('')}
</div>
<div class="sidebar-footer">
<button class="sidebar-btn" id="resetPosBtn" title="Reset">⟲</button>
<button class="sidebar-btn" id="minimizeBtn" title="Close">✕</button>
</div>
</div>
<div class="menu-content">
<div class="content-header">
<div class="content-title" id="contentTitle">
<span class="title-icon"></span>
<span>Combat</span>
</div>
<div class="content-controls">
<button class="control-btn" id="exportBtn" title="Export">📤</button>
<button class="control-btn" id="importBtn" title="Import">📥</button>
</div>
</div>
<!-- COMBAT SECTION -->
<div id="section1" class="section active">
<div class="section-grid">
${createSectionDivider('Auto Actions')}
${createToggleSlider('auto break')}
${createToggleSlider('stop on break')}
${createToggleSlider('auto place')}
${createToggleSlider('auto replace', false)}
${createToggleSlider('auto push')}
${createSectionDivider('Combat Sync')}
${createToggleSlider('polearm aids')}
${createToggleSlider('aids spike sync', false)}
${createToggleSlider('melee sync', false)}
${createSectionDivider('Insta Combos')}
${createToggleSlider('bleed insta', false)}
${createToggleSlider('apple insta', false)}
${createToggleSlider('kbInsta')}
${createToggleSlider('VelTick', false)}
${createToggleSlider('Automatic Positioning', false)}
${createToggleSlider('SpamFrame (broken)')}
${createToggleSlider('kbInsta without turret gear', false)}
${createToggleSlider('kbAssist', false)}
${createSectionDivider('Movement & Defense')}
${createToggleSlider('stop break')}
${createToggleSlider('stop on collision', false)}
${createToggleSlider('movement on collision', false)}
${createToggleSlider('push prioritization', false)}
${createSectionDivider('Equipment')}
${createToggleSlider('strict soldier')}
${createToggleSlider('strict monkey')}
${createToggleSlider('pred wings')}
${createToggleSlider('auto equip fastest weapon', false)}
${createToggleSlider('break spike trap')}
${createToggleSlider('Auto Emp')}
${createToggleSlider('autohat')}
${createThrottleSlider("APA", 20, 180, 50, "Auto Place Accuracy")}
</div>
</div>
<div id="section2" class="section">
<div class="section-grid">
${createSectionDivider('Healing Options')}
${createToggleSlider('auto heal')}
${createToggleSlider('autoQ', false)}
</div>
</div>
<div id="section3" class="section">
<div class="section-grid">
${createSectionDivider('HUD Elements')}
${createToggleSlider('reload bars', false)}
${createToggleSlider('packet count', true)}
${createToggleSlider('all visuals')}
${createToggleSlider('ChatLog')}
${createSectionDivider('Arcs & Indicators')}
${createToggleSlider('no outline arcs')}
${createToggleSlider('no arcs')}
${createToggleSlider('reload arcs')}
${createToggleSlider('smooth reloads')}
${createSectionDivider('Building Info')}
${createToggleSlider('building hp')}
${createToggleSlider('building owner')}
${createToggleSlider('mill rotate', false)}
${createToggleSlider('regular grid')}
${createSectionDivider('Damage Display')}
${createToggleSlider('stacked damages')}
${createToggleSlider('stacked heal text')}
${createToggleSlider('show place duration', false)}
${createToggleSlider('log autoplace', false)}
${createToggleSlider('spike kb visual')}
${createToggleSlider('animated text')}
${createSectionDivider('Player Display')}
${createToggleSlider('skull', true)}
${createToggleSlider('shame count')}
${createToggleSlider('log projectiles', false)}
${createToggleSlider('vis aim')}
${createToggleSlider('hide name')}
${createToggleSlider('See through player')}
${createSectionDivider('Visual Themes')}
${createToggleSlider('shadows')}
${createToggleSlider('Shaders', false)}
${createToggleSlider('Legacy Visuals', false)}
${createToggleSlider('Light Mode', false)}
${createToggleSlider('Default Visuals', false)}
${createToggleSlider('Op Visuals', false)}
</div>
</div>
<div id="section4" class="section">
<div class="section-grid">
${createSectionDivider('Quest Toggles')}
${createToggleSlider('Toggle Quest 1')}
${createInput('Quest Progress', 'number')}
${createToggleSlider('Toggle Quest 2')}
${createInput('Quest Reward', 'text')}
${createToggleSlider('Toggle Quest 3')}
${createInput('Quest Difficulty', 'number')}
</div>
</div>
<div id="section5" class="section">
<div class="section-grid">
${createSectionDivider('Bot Movement')}
${createDropdown('Bot Summon Movement', ['Cursor', 'Copy', 'Towards', 'none'])}
${createToggleSlider('bot smart aim')}
${createToggleSlider('safe walk bots', false)}
${createToggleSlider('circle bots', false)}
${createSectionDivider('Bot Actions')}
${createToggleSlider('farm mats')}
${createToggleSlider('auto accept bots')}
${createToggleSlider('stop break bots', false)}
${createToggleSlider('bots break utility')}
${createToggleSlider('bots APB')}
${createToggleSlider('bots Qsync')}
${createSectionDivider('Bot Combat')}
${createToggleSlider('Assassin Bots', false)}
${createToggleSlider('bot auto proj sync')}
${createToggleSlider('adv bot auto proj sync')}
${createSectionDivider('Bot Communication')}
${createInput('Bots Auto Chat', 'text', 30)}
</div>
</div>
<div id="section6" class="section">
<div class="section-grid">
${createSectionDivider('Performance Tuning')}
${createThrottleSlider("Auto Place Accuracy", 20, 180, 50, "Higher = longer calculation time")}
</div>
</div>
<div id="section7" class="section">
<div class="section-grid">
${createSectionDivider('Special Modes')}
${createToggleSlider('Assassin', false)}
${createToggleSlider('send ws')}
${createToggleSlider('autobuy')}
${createToggleSlider('fix ws')}
${createSectionDivider('Network')}
${createToggleSlider('fakePing', false)}
${createThrottleSlider("pingSlider", 0, 100, 40, "Fake ping value")}
</div>
</div>
<div id="section8" class="section">
<div class="section-grid">
${createSectionDivider('Theme Selection')}
<div class="theme-grid">
<div class="theme-btn theme-midnight active" data-theme="midnight" data-name="Midnight"></div>
<div class="theme-btn theme-ocean" data-theme="ocean" data-name="Ocean"></div>
<div class="theme-btn theme-forest" data-theme="forest" data-name="Forest"></div>
<div class="theme-btn theme-sunset" data-theme="sunset" data-name="Sunset"></div>
<div class="theme-btn theme-rose" data-theme="rose" data-name="Rose"></div>
<div class="theme-btn theme-blood" data-theme="blood" data-name="Blood"></div>
<div class="theme-btn theme-golden" data-theme="golden" data-name="Golden"></div>
<div class="theme-btn theme-monochrome" data-theme="monochrome" data-name="Mono"></div>
<div class="theme-btn theme-neon" data-theme="neon" data-name="Neon"></div>
<div class="theme-btn theme-light-btn" data-theme="light" data-name="Light"></div>
</div>
${createSectionDivider('Custom Colors')}
${createColorPicker('Accent Color', '#6366f1')}
${createColorPicker('Secondary Accent', '#8b5cf6')}
${createSectionDivider('Menu Size')}
<div class="size-presets">
<div class="size-preset-btn" data-scale="0.85">S</div>
<div class="size-preset-btn active" data-scale="1">M</div>
<div class="size-preset-btn" data-scale="1.1">L</div>
<div class="size-preset-btn" data-scale="1.2">XL</div>
</div>
${createThrottleSlider("Menu Scale", 70, 130, 100, "Adjust size (70% - 130%)")}
${createSectionDivider('Opacity & Blur')}
${createThrottleSlider("Menu Opacity", 50, 100, 95, "Menu transparency")}
${createThrottleSlider("Blur Intensity", 0, 30, 20, "Background blur")}
${createSectionDivider('Border & Corners')}
${createThrottleSlider("Border Radius", 0, 24, 16, "Corner roundness")}
${createToggleSlider('Show Border', true)}
${createToggleSlider('Show Shadow', true)}
${createSectionDivider('Behavior')}
${createToggleSlider('Draggable Menu', true)}
${createToggleSlider('Remember Position', true)}
${createToggleSlider('Smooth Animations', true)}
${createSectionDivider('Quick Actions')}
<div class="quick-actions">
<div class="quick-action-btn" id="resetAllBtn">Reset All</div>
<div class="quick-action-btn" id="exportBtn2">Export</div>
<div class="quick-action-btn" id="importBtn2">Import</div>
</div>
</div>
</div>
<div class="keybind-hint">
Press <kbd>ESC</kbd> to toggle • Drag header to move
</div>
</div>
</div>
`;
function setTheme(themeName) {
const menuEl = document.getElementById('transparentMenu');
menuEl.classList.remove('theme-midnight', 'theme-ocean', 'theme-forest', 'theme-sunset', 'theme-rose', 'theme-blood', 'theme-golden', 'theme-monochrome', 'theme-neon', 'theme-light');
menuEl.classList.add(`theme-${themeName}`);
document.querySelectorAll('.theme-btn').forEach(btn => btn.classList.remove('active'));
document.querySelector(`[data-theme="${themeName}"]`)?.classList.add('active');
setStoredValue('ui-theme', themeName);
}
function setMenuScale(scale) {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.setProperty('--menu-scale', scale);
const scaleSlider = gE('Menu Scale');
if (scaleSlider) scaleSlider.value = scale * 100;
const scaleValue = gE('Menu Scale-value');
if (scaleValue) scaleValue.textContent = Math.round(scale * 100);
document.querySelectorAll('.size-preset-btn').forEach(btn => btn.classList.remove('active'));
setStoredValue('menu-scale', scale);
}
function setMenuOpacity(value) {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.setProperty('--menu-opacity', value / 100);
setStoredValue('menu-opacity', value);
}
function setMenuBlur(value) {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.setProperty('--menu-blur', `${value}px`);
setStoredValue('menu-blur', value);
}
function setMenuRadius(value) {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.setProperty('--menu-radius', `${value}px`);
setStoredValue('menu-radius', value);
}
function resetAllSettings() {
if (confirm('Reset all UI settings to default?')) {
setTheme('midnight');
setMenuScale(1);
setMenuOpacity(95);
setMenuBlur(20);
setMenuRadius(16);
const menuEl = document.getElementById('transparentMenu');
menuEl.style.top = '50%';
menuEl.style.left = '50%';
menuEl.style.transform = 'translate(-50%, -50%) scale(1)';
setStoredValue('menu-pos-x', null);
setStoredValue('menu-pos-y', null);
}
}
function exportSettings() {
const settings = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
settings[key] = localStorage.getItem(key);
}
const blob = new Blob([JSON.stringify(settings, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'revelation-settings.json';
a.click();
URL.revokeObjectURL(url);
}
function importSettings() {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.json';
input.onchange = (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.onload = (event) => {
try {
const settings = JSON.parse(event.target.result);
for (const key in settings) {
localStorage.setItem(key, settings[key]);
}
location.reload();
} catch (err) {
alert('Invalid settings file');
}
};
reader.readAsText(file);
};
input.click();
}
let isDragging = false;
let dragOffsetX = 0; // draging made by zylo
let dragOffsetY = 0;
const dragHandle = document.getElementById('dragHandle');
dragHandle?.addEventListener('mousedown', (e) => {
if (!getStoredValue('Draggable Menu', true)) return;
isDragging = true;
const menuEl = document.getElementById('transparentMenu');
const rect = menuEl.getBoundingClientRect();
dragOffsetX = e.clientX - rect.left;
dragOffsetY = e.clientY - rect.top;
menuEl.classList.add('dragging');
menuEl.style.transform = 'none';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const menuEl = document.getElementById('transparentMenu');
const newX = e.clientX - dragOffsetX;
const newY = e.clientY - dragOffsetY;
menuEl.style.left = `${newX}px`;
menuEl.style.top = `${newY}px`;
});
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
const menuEl = document.getElementById('transparentMenu');
menuEl.classList.remove('dragging');
if (getStoredValue('Remember Position', true)) {
setStoredValue('menu-pos-x', parseInt(menuEl.style.left));
setStoredValue('menu-pos-y', parseInt(menuEl.style.top));
setStoredValue('menu-centered', false);
}
}
});
document.getElementById('minimizeBtn')?.addEventListener('click', () => {
toggleMenu();
});
document.getElementById('resetPosBtn')?.addEventListener('click', () => {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.top = '50%';
menuEl.style.left = '50%';
menuEl.style.transform = 'translate(-50%, -50%) scale(var(--menu-scale))';
setStoredValue('menu-pos-x', null);
setStoredValue('menu-pos-y', null);
setStoredValue('menu-centered', true);
});
function toggleMenu() {
const menuElement = document.getElementById('transparentMenu');
menuElement.classList.toggle('visible');
menuElement.style.display = menuElement.classList.contains('visible') ? 'flex' : 'none';
}
function getStoredValue(key, defaultValue, input) {
const storedValue = localStorage.getItem(key);
if (!input) {
return storedValue !== null ? JSON.parse(storedValue) : defaultValue;
}
return storedValue !== null ? JSON.parse(storedValue).value : defaultValue;
}
function setStoredValue(key, value) {
localStorage.setItem(key, JSON.stringify(value));
}
function showTab(tabId) {
document.querySelectorAll('.nav-item').forEach(item => item.classList.remove('active'));
document.querySelector(`[data-section="${tabId}"]`)?.classList.add('active');
document.querySelectorAll('.section').forEach(section => section.classList.remove('active'));
document.getElementById(tabId)?.classList.add('active');
const navItem = navItems.find(item => item.id === tabId);
if (navItem) {
const contentTitle = document.getElementById('contentTitle');
if (contentTitle) {
contentTitle.innerHTML = `
<span class="title-icon">${navItem.icon}</span>
<span>${navItem.label}</span>
`;
}
}
}
function loadSavedUISettings() {
const menuEl = document.getElementById('transparentMenu');
const savedTheme = getStoredValue('ui-theme', 'midnight');
setTheme(savedTheme);
const savedScale = getStoredValue('menu-scale', 1);
menuEl.style.setProperty('--menu-scale', savedScale);
const savedOpacity = getStoredValue('menu-opacity', 95);
menuEl.style.setProperty('--menu-opacity', savedOpacity / 100);
const savedBlur = getStoredValue('menu-blur', 20);
menuEl.style.setProperty('--menu-blur', `${savedBlur}px`);
const savedRadius = getStoredValue('menu-radius', 16);
menuEl.style.setProperty('--menu-radius', `${savedRadius}px`);
// Load position
const isCentered = getStoredValue('menu-centered', true);
if (!isCentered && getStoredValue('Remember Position', true)) {
const savedX = getStoredValue('menu-pos-x', null);
const savedY = getStoredValue('menu-pos-y', null);
if (savedX !== null && savedY !== null) {
menuEl.style.left = `${savedX}px`;
menuEl.style.top = `${savedY}px`;
menuEl.style.transform = `scale(${savedScale})`;
}
}
}
if (gE("ChatLog")?.checked) {
chatContainer.style.display = 'flex';
} else {
chatContainer.style.display = 'none';
}
showTab('section1');
setTimeout(loadSavedUISettings, 100);
document.getElementById('transparentMenu').addEventListener('change', function (event) {
const target = event.target;
const localStorageKey = target.id;
if (localStorageKey === 'ChatLog') {
chatContainer.style.display = target.checked ? 'flex' : 'none';
}
if (localStorageKey === 'Menu Scale') {
setMenuScale(target.value / 100);
}
if (localStorageKey === 'Menu Opacity') {
setMenuOpacity(target.value);
}
if (localStorageKey === 'Blur Intensity') {
setMenuBlur(target.value);
}
if (localStorageKey === 'Border Radius') {
setMenuRadius(target.value);
}
if (localStorageKey === 'Show Border') {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.border = target.checked ? '1px solid var(--menu-border)' : 'none';
}
if (localStorageKey === 'Show Shadow') {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.boxShadow = target.checked ? '0 25px 60px -12px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.1)' : 'none';
}
if (localStorageKey === 'Smooth Animations') {
const menuEl = document.getElementById('transparentMenu');
menuEl.style.transition = target.checked ? 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)' : 'none';
}
if (localStorageKey === 'Accent Color') {
document.documentElement.style.setProperty('--menu-accent', target.value);
}
if (localStorageKey === 'Secondary Accent') {
document.documentElement.style.setProperty('--menu-accent-secondary', target.value);
}
const value = target.type == "checkbox" ? target.checked : target.value;
setStoredValue(localStorageKey, value);
if (target.type == "range") {
updateThrottleValue(localStorageKey);
}
});
function getTime() {
const date = new Date();
let hours = date.getHours();
let minutes = date.getMinutes();
let period = "AM";
if (hours === 0) {
hours = 12;
} else if (hours > 12) {
period = "PM";
hours = hours % 12;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
return hours + ":" + minutes + " " + period;
}
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', function() {
const sectionId = this.getAttribute('data-section');
showTab(sectionId);
});
});
// btn stuff
document.querySelectorAll('.theme-btn').forEach(btn => {
btn.addEventListener('click', function() {
const themeName = this.getAttribute('data-theme');
setTheme(themeName);
});
});
// presets fo size
document.querySelectorAll('.size-preset-btn').forEach(btn => {
btn.addEventListener('click', function() {
const scale = parseFloat(this.getAttribute('data-scale'));
setMenuScale(scale);
});
});
// e soem event listners
document.getElementById('resetAllBtn')?.addEventListener('click', resetAllSettings);
document.getElementById('exportBtn')?.addEventListener('click', exportSettings);
document.getElementById('importBtn')?.addEventListener('click', importSettings);
document.getElementById('exportBtn2')?.addEventListener('click', exportSettings);
document.getElementById('importBtn2')?.addEventListener('click', importSettings);
function fastHypot(a, b){
const c = Math.SQRT2-1;
a = abs(a);
b = abs(b);
if(a > b){
let temp = a;
a = b;
b = temp;
}
return (c * a) + b
}
// Set the appropriate shadow blur value based on the type
function generateCompositeImage(type,image, height,width,blurval) {
if(!width)width = height;
var c = document.createElement('canvas');
var ctx = c.getContext('2d');
c.width = height;
c.height = width;
// blurval = type==='animal'?18:type==='weapon'? :.8;
// ctx.shadowColor = `rgba(0, 0, 0, 1)`
//ctx.shadowColor = "rgba(0, 0, 0, 1)"//"rgba(255,255,255, 1)"//"white"//"pink"
//ctx.shadowBlur = type==='animal'?18:type==='weapon'?12: type == "accessory" ? 9: 20;
ctx.drawImage(image, 0, 0, height, width);
var cI = new Image();
cI.src = c.toDataURL();
return cI;
}
function generateRandomBotName() {
var prefixes = ["Bots are noobs"]; //"x-z3r0", "ReaperX","aika", "hanabira"
var suffixes = [""];
var randomPrefix = prefixes[floor(Math.random() * prefixes.length)];
var randomSuffix = suffixes[floor(Math.random() * suffixes.length)];
return randomPrefix + randomSuffix;
}
var botName = generateRandomBotName();
var managePromises = [],
keys = [],
codes = [],
ws, // ws = websocket fix global variable later
packets = 0,
minutePackets = 0,
ppT = 0,
ppsAvgs = [],
ppsAvg = 0,
packets2 = [],
msgpack5 = msgpack,
ltt = [],
tick = 0,
autoplacing = [],
placeRate = [],
restrictPlace = [],
showPlace = [],
failsafe = 0,
packetInt,
coords = {},
timeGame = Date.now(),
inGame = false,
aim = [],
aimbool = false,
hit = null,
thisTrap,
skin,
hold,
visAim = false,
dmgObjs = [],
entSearch = [],
hitList = [],
opsList = [],
list,
tail,
autobreakBuild =false,
pingarr = [],
pingavg = null,
dtavg = null,
dtarr = [],
teamID,
placeDurations = [],
bowInstaing = false,
Nsid = [],
hitPacket= 0,
incr = 0,
mapActivity = true,
autohit = false,
freeCam = false,
cameraDir,
camID,
AutoBreak,
breaking = false,
inTrap,
breaker = false,
turretOneTick,
clearRadius,
sentClan = false,
clearing = 0,
clearXY = null,
pushing=false,
pusher=false,
fS = {
sec: false,
min: false
},
enemyInTrap,
brokenObjects = [],
hatToLoop = [51,50,28,29,30,36,37,38,44,35,42,43,49,57,8,2,15,,5,4,18,31,1,10,48,6,23,13,9,32,22,12,26,21,46,14,11,58,27,52,55],
speedHats = [0],//[0,40,12,22,6,7,56],//, speedHats = [0],
speedTails = [0],//[0,11,19], // speedTails = [0],
nearObjects = [],
renderObjects = [],
thisWeapon,
ww,
lastHat = null,
lastTail = null,
amAlive = false,
time = Date.now(),
nHat = 0,
nTail = 0,
// N = [],
mills = {status : false,w:null,a:null,s:null,d:null,aim:null,x:0,y:0},
primaryReloads = [],
secondaryReloads = [],
turretReloads = [],
destroyedTraps = [],
isDisabled = false,
instaToggle = false,
instaing = false,
meleesyncing = false,
oneTickToggle = false,
oneTick = false,
updater = [],
runInto2,
calcVel2,
animals,
Qsync = false,
antiOneTick,
pingval,
enemies = [],
spikeSync = [],
decline = [],
autopusher = true,
allies = [],
Variants = [1, 1.1, 1.18, 1.18],
nEnemy,
usedAngles = [],
structures = [],
damageObjs=[],
moveDirection = null,
botBuilds = [],
botRemoveBuilds = [],
botAddedBuilds = [],
bH=[51,50,28,29,30,36,37,38,44,35,42,43,49],
bT=[],
projs=[],
buyer=[[11],40,6,7,53,[21],12,56,15,22,31,26,11,20,[18],[19],[13]],
sandbox = false,
syncing = false,
syncToggle = false,
pushPosition = 'not',//{x:null,y:null},
serverconnected = false,
pTE,
sTE,
tTE,
teamDisplay = [],
displayer = false,
grinder = false,
sos3,
dPAP,
apS,
urls,
teamMessage = {msg:"",time:0,id:null},
E,
times = [],
fps,
moveAuto,
syncTeam,
Tach,
botAC = null,
Pathfinder,
// wandering = true,
botMove = 'Wander',
sDist = 400,
bMin = 290,
bMax = 222,
Tn,
// gn = void 0, //movedirection thing fix later
cRadius = 1000,
cSid = "all",
camX = 0, camY = 0,
cType = "all",
apd = 110,
targetID = {ID: null, player: null},
specificTarget = false, // specific target set for q sync XD
qSyncChat = "L Nigger Faggot",
syncChat = "Samurai: Fastest",
botDist = 200,
placeIndicator = [],
muteList = [],
allWeapons = [],
botIDS = [],
nightMode = true,
fakePlayers = [],
placeTickInAdvance = 0,
botMsg = null,
logMsgs = false,
// spyBot = {players:[],bot:null,builds:[]},
// spyIndex = {do:null,val:0,play:false},
botAvoid = [],
placeDelay = 111,
stopnbreak = [],
boostOT = false,
tempOrigin = false,
forceHat = null,
originPoint = {x:null,y:null},
formationArr = [],
tempVisual = [],
fixingWs = [],
didEquip = 0,
breakObjs = [],
znCache = new Map(),
VnCache = new Map(),
stackedText = [],
stackedHealVal = 0,
socketer,
moostafaAI,
moofieAI,
treasureAI,
specID = undefined,
specPlayer = {players:[],player:null,builds:[], isDoing: false, isMe: null},
spectator = {players:[],player:null,builds:[], rPlayer: null, rBuilds: [], isDoing: false, isMe: null},
spyBot = {players:[],bot:null,builds:[]},//,realBuilds:[]},
spyIndex = {do:null,val:0,play:false};
let nearSpikes = [], nearTraps = [], nearEnemies = [];
let prioLoc = [], replaceLoc = [];
const isDupe = (obj, array) => array.some(item => item.sid === obj.sid);
// caching = faster
const placeAccuracy = document.getElementById("Auto Place Accuracy");
const aPlacer = document.getElementById('auto place');
const logPlacer = document.getElementById("log autoplace");
const millRotate = document.getElementById("mill rotate");
const sendWS = document.getElementById('send ws');
const stackedDmgs = document.getElementById("stacked damages");
const stackedHeal = document.getElementById("stacked heal text");
const autoRep = document.getElementById("auto replace");
const regGrid = document.getElementById('regular grid');
const reloadArcs = document.getElementById("reload arcs");
const shameCount = document.getElementById('shame count');
const allVisuals = document.getElementById("all visuals");
const reloadBars = document.getElementById('reload bars');
const pcKT = document.getElementById("packet count");
const buildHP = document.getElementById("building hp");
const buildOwner = document.getElementById("building owner");
const smoothReloads = document.getElementById('smooth reloads');
const shaderToggle = document.getElementById("Shaders");
const shadowToggle = document.getElementById('shadows');
const autoQ = document.getElementById("autoQ");
const appleInsta = document.getElementById('apple insta');
const bleedInsta = document.getElementById('bleed insta');
const aBreak = document.getElementById("auto break");
const stopBreak = document.getElementById('stop break');
const botChat = document.getElementById('Bots Auto Chat');
const fastWep = document.getElementById("auto equip fastest weapon");
const noArcs = document.getElementById("no arcs");
const noOutline = document.getElementById("no outline arcs");
const seeThrough = document.getElementById("See through player");
const skullIcon = document.getElementById("skull");
const autoAccept = document.getElementById("auto accept bots");
const breakSpike = document.getElementById("break spike trap");
const autoHeal = document.getElementById("auto heal");
const strictSoldier = document.getElementById("strict soldier");
const aHat = document.getElementById("autohat");
const strictMonkey = document.getElementById("strict monkey");
const wingPred = document.getElementById("pred wings");
const pushPrioritization = document.getElementById("push prioritization");
const autoBuy = document.getElementById("autobuy");
const stopOnColl = document.getElementById("stop on collision");
const moveOnColl = document.getElementById("movement on collision");
const placeDuration = document.getElementById("show place duration");
const kbVisual = document.getElementById("spike kb visual");
const meleeSync = document.getElementById("melee sync");
const aPush = document.getElementById("auto push");
const visA = document.getElementById("vis aim");
const stealAnim = document.getElementById("stealing animal");
const botBreakUtil = document.getElementById("bots break utility");
const hideName = document.getElementById("hide name");
const kbInstaToggle = document.getElementById("kbInsta");
const aEmp = document.getElementById("Auto Emp");
const assassin = document.getElementById("Assassin");
const sSync = document.getElementById("spike sync");
const logProj = document.getElementById("log projectiles");
const cBots = document.getElementById("circle bots");
const botSummon = document.getElementById("Bot Summon Movement");
const bSync = document.getElementById("bots Qsync");
const qSync = document.getElementById("Qsync");
const smartAim = document.getElementById("bot smart aim");
const poleAids = document.getElementById("polearm aids");
const aProjSync = document.getElementById("bot auto proj sync");
const advSync = document.getElementById("adv bot auto proj sync");
const aBots = document.getElementById("Assassin Bots");
const APB = document.getElementById("bots APB");
const sWalk = document.getElementById("safe walk bots");
const sBreak = document.getElementById("stop break bots");
const kbAssist = document.getElementById("kbAssist");
const legacy = document.getElementById("Legacy Visuals");
const regVis = document.getElementById("Default Visuals");
const lightmode = document.getElementById("Light Mode");
const spikeTicker = document.getElementById("aids spike sync");
(function() {
const t = document.createElement("link").relList;
if (t && t.supports && t.supports("modulepreload"))
return;
for (const n of document.querySelectorAll('link[rel="modulepreload"]'))
s(n);
new MutationObserver(n=>{
for (const r of n)
if (r.type === "childList")
for (const o of r.addedNodes)
o.tagName === "LINK" && o.rel === "modulepreload" && s(o)
}
).observe(document, {
childList: !0,
subtree: !0
});
function i(n) {
const r = {};
return n.integrity && (r.integrity = n.integrity),
n.referrerpolicy && (r.referrerPolicy = n.referrerpolicy),
n.crossorigin === "use-credentials" ? r.credentials = "include" : n.crossorigin === "anonymous" ? r.credentials = "omit" : r.credentials = "same-origin",
r
}
function s(n) {
if (n.ep)
return;
n.ep = !0;
const r = i(n);
fetch(n.href, r)
}
}
)();
var Ke = 4294967295;
function Ko(e, t, i) {
var s = i / 4294967296
, n = i;
e.setUint32(t, s),
e.setUint32(t + 4, n)
}
function Br(e, t, i) {
var s = floor(i / 4294967296)
, n = i;
e.setUint32(t, s),
e.setUint32(t + 4, n)
}
function zr(e, t) {
var i = e.getInt32(t)
, s = e.getUint32(t + 4);
return i * 4294967296 + s
}
function Jo(e, t) {
var i = e.getUint32(t)
, s = e.getUint32(t + 4);
return i * 4294967296 + s
}
var Gi, Yi, $i, Pi = (typeof process > "u" || ((Gi = process == null ? void 0 : process.env) === null || Gi === void 0 ? void 0 : Gi.TEXT_ENCODING) !== "never") && typeof TextEncoder < "u" && typeof TextDecoder < "u";
function Cs(e) {
for (var t = e.length, i = 0, s = 0; s < t; ) {
var n = e.charCodeAt(s++);
if (n & 4294967168)
if (!(n & 4294965248))
i += 2;
else {
if (n >= 55296 && n <= 56319 && s < t) {
var r = e.charCodeAt(s);
(r & 64512) === 56320 && (++s,
n = ((n & 1023) << 10) + (r & 1023) + 65536)
}
n & 4294901760 ? i += 4 : i += 3
}
else {
i++;
continue
}
}
return i
}
function Qo(e, t, i) {
for (var s = e.length, n = i, r = 0; r < s; ) {
var o = e.charCodeAt(r++);
if (o & 4294967168)
if (!(o & 4294965248))
t[n++] = o >> 6 & 31 | 192;
else {
if (o >= 55296 && o <= 56319 && r < s) {
var l = e.charCodeAt(r);
(l & 64512) === 56320 && (++r,
o = ((o & 1023) << 10) + (l & 1023) + 65536)
}
o & 4294901760 ? (t[n++] = o >> 18 & 7 | 240,
t[n++] = o >> 12 & 63 | 128,
t[n++] = o >> 6 & 63 | 128) : (t[n++] = o >> 12 & 15 | 224,
t[n++] = o >> 6 & 63 | 128)
}
else {
t[n++] = o;
continue
}
t[n++] = o & 63 | 128
}
}
var Ut = Pi ? new TextEncoder : void 0
, Zo = Pi ? typeof process < "u" && ((Yi = process == null ? void 0 : process.env) === null || Yi === void 0 ? void 0 : Yi.TEXT_ENCODING) !== "force" ? 200 : 0 : Ke;
function jo(e, t, i) {
t.set(Ut.encode(e), i)
}
function ea(e, t, i) {
Ut.encodeInto(e, t.subarray(i))
}
var ta = Ut != null && Ut.encodeInto ? ea : jo
, ia = 4096;
function Hr(e, t, i) {
for (var s = t, n = s + i, r = [], o = ""; s < n; ) {
var l = e[s++];
if (!(l & 128))
r.push(l);
else if ((l & 224) === 192) {
var c = e[s++] & 63;
r.push((l & 31) << 6 | c)
} else if ((l & 240) === 224) {
var c = e[s++] & 63
, a = e[s++] & 63;
r.push((l & 31) << 12 | c << 6 | a)
} else if ((l & 248) === 240) {
var c = e[s++] & 63
, a = e[s++] & 63
, u = e[s++] & 63
, p = (l & 7) << 18 | c << 12 | a << 6 | u;
p > 65535 && (p -= 65536,
r.push(p >>> 10 & 1023 | 55296),
p = 56320 | p & 1023),
r.push(p)
} else
r.push(l);
r.length >= ia && (o += String.fromCharCode.apply(String, r),
r.length = 0)
}
return r.length > 0 && (o += String.fromCharCode.apply(String, r)),
o
}
var na = Pi ? new TextDecoder : null
, sa = Pi ? typeof process < "u" && (($i = process == null ? void 0 : process.env) === null || $i === void 0 ? void 0 : $i.TEXT_DECODER) !== "force" ? 200 : 0 : Ke;
function ra(e, t, i) {
var s = e.subarray(t, t + i);
return na.decode(s)
}
var si = function() {
function e(t, i) {
this.type = t,
this.data = i
}
return e
}()
, oa = globalThis && globalThis.__extends || function() {
var e = function(t, i) {
return e = Object.setPrototypeOf || {
__proto__: []
}instanceof Array && function(s, n) {
s.__proto__ = n
}
|| function(s, n) {
for (var r in n)
Object.prototype.hasOwnProperty.call(n, r) && (s[r] = n[r])
}
,
e(t, i)
};
return function(t, i) {
if (typeof i != "function" && i !== null)
throw new TypeError("Class extends value " + String(i) + " is not a constructor or null");
e(t, i);
function s() {
this.constructor = t
}
t.prototype = i === null ? Object.create(i) : (s.prototype = i.prototype,
new s)
}
}()
, Pe = function(e) {
oa(t, e);
function t(i) {
var s = e.call(this, i) || this
, n = Object.create(t.prototype);
return Object.setPrototypeOf(s, n),
Object.defineProperty(s, "name", {
configurable: !0,
enumerable: !1,
value: t.name
}),
s
}
return t
}(Error)
, aa = -1
, la = 4294967296 - 1
, ca = 17179869184 - 1;
function ha(e) {
var t = e.sec
, i = e.nsec;
if (t >= 0 && i >= 0 && t <= ca)
if (i === 0 && t <= la) {
var s = new Uint8Array(4)
, n = new DataView(s.buffer);
return n.setUint32(0, t),
s
} else {
var r = t / 4294967296
, o = t & 4294967295
, s = new Uint8Array(8)
, n = new DataView(s.buffer);
return n.setUint32(0, i << 2 | r & 3),
n.setUint32(4, o),
s
}
else {
var s = new Uint8Array(12)
, n = new DataView(s.buffer);
return n.setUint32(0, i),
Br(n, 4, t),
s
}
}
function fa(e) {
var t = e.getTime()
, i = floor(t / 1e3)
, s = (t - i * 1e3) * 1e6
, n = floor(s / 1e9);
return {
sec: i + n,
nsec: s - n * 1e9
}
}
function ua(e) {
if (e instanceof Date) {
var t = fa(e);
return ha(t)
} else
return null
}
function da(e) {
var t = new DataView(e.buffer,e.byteOffset,e.byteLength);
switch (e.byteLength) {
case 4:
{
var i = t.getUint32(0)
, s = 0;
return {
sec: i,
nsec: s
}
}
case 8:
{
var n = t.getUint32(0)
, r = t.getUint32(4)
, i = (n & 3) * 4294967296 + r
, s = n >>> 2;
return {
sec: i,
nsec: s
}
}
case 12:
{
var i = zr(t, 4)
, s = t.getUint32(0);
return {
sec: i,
nsec: s
}
}
default:
throw new Pe("Unrecognized data size for timestamp (expected 4, 8, or 12): ".concat(e.length))
}
}
function pa(e) {
var t = da(e);
return new Date(t.sec * 1e3 + t.nsec / 1e6)
}
var ma = {
type: aa,
encode: ua,
decode: pa
}
, Fr = function() {
function e() {
this.builtInEncoders = [],
this.builtInDecoders = [],
this.encoders = [],
this.decoders = [],
this.register(ma)
}
return e.prototype.register = function(t) {
var i = t.type
, s = t.encode
, n = t.decode;
if (i >= 0)
this.encoders[i] = s,
this.decoders[i] = n;
else {
var r = 1 + i;
this.builtInEncoders[r] = s,
this.builtInDecoders[r] = n
}
}
,
e.prototype.tryToEncode = function(t, i) {
for (var s = 0; s < this.builtInEncoders.length; s++) {
var n = this.builtInEncoders[s];
if (n != null) {
var r = n(t, i);
if (r != null) {
var o = -1 - s;
return new si(o,r)
}
}
}
for (var s = 0; s < this.encoders.length; s++) {
var n = this.encoders[s];
if (n != null) {
var r = n(t, i);
if (r != null) {
var o = s;
return new si(o,r)
}
}
}
return t instanceof si ? t : null
}
,
e.prototype.decode = function(t, i, s) {
var n = i < 0 ? this.builtInDecoders[-1 - i] : this.decoders[i];
return n ? n(t, i, s) : new si(i,t)
}
,
e.defaultCodec = new e,
e
}();
function gi(e) {
return e instanceof Uint8Array ? e : ArrayBuffer.isView(e) ? new Uint8Array(e.buffer,e.byteOffset,e.byteLength) : e instanceof ArrayBuffer ? new Uint8Array(e) : Uint8Array.from(e)
}
function ga(e) {
if (e instanceof ArrayBuffer)
return new DataView(e);
var t = gi(e);
return new DataView(t.buffer,t.byteOffset,t.byteLength)
}
var ya = 100
, wa = 2048
, ka = function() {
function e(t, i, s, n, r, o, l, c) {
t === void 0 && (t = Fr.defaultCodec),
i === void 0 && (i = void 0),
s === void 0 && (s = ya),
n === void 0 && (n = wa),
r === void 0 && (r = !1),
o === void 0 && (o = !1),
l === void 0 && (l = !1),
c === void 0 && (c = !1),
this.extensionCodec = t,
this.context = i,
this.maxDepth = s,
this.initialBufferSize = n,
this.sortKeys = r,
this.forceFloat32 = o,
this.ignoreUndefined = l,
this.forceIntegerToFloat = c,
this.pos = 0,
this.view = new DataView(new ArrayBuffer(this.initialBufferSize)),
this.bytes = new Uint8Array(this.view.buffer)
}
return e.prototype.reinitializeState = function() {
this.pos = 0
}
,
e.prototype.encodeSharedRef = function(t) {
return this.reinitializeState(),
this.doEncode(t, 1),
this.bytes.subarray(0, this.pos)
}
,
e.prototype.encode = function(t) {
return this.reinitializeState(),
this.doEncode(t, 1),
this.bytes.slice(0, this.pos)
}
,
e.prototype.doEncode = function(t, i) {
if (i > this.maxDepth)
throw new Error("Too deep objects in depth ".concat(i));
t == null ? this.encodeNil() : typeof t == "boolean" ? this.encodeBoolean(t) : typeof t == "number" ? this.encodeNumber(t) : typeof t == "string" ? this.encodeString(t) : this.encodeObject(t, i)
}
,
e.prototype.ensureBufferSizeToWrite = function(t) {
var i = this.pos + t;
this.view.byteLength < i && this.resizeBuffer(i * 2)
}
,
e.prototype.resizeBuffer = function(t) {
var i = new ArrayBuffer(t)
, s = new Uint8Array(i)
, n = new DataView(i);
s.set(this.bytes),
this.view = n,
this.bytes = s
}
,
e.prototype.encodeNil = function() {
this.writeU8(192)
}
,
e.prototype.encodeBoolean = function(t) {
t === !1 ? this.writeU8(194) : this.writeU8(195)
}
,
e.prototype.encodeNumber = function(t) {
Number.isSafeInteger(t) && !this.forceIntegerToFloat ? t >= 0 ? t < 128 ? this.writeU8(t) : t < 256 ? (this.writeU8(204),
this.writeU8(t)) : t < 65536 ? (this.writeU8(205),
this.writeU16(t)) : t < 4294967296 ? (this.writeU8(206),
this.writeU32(t)) : (this.writeU8(207),
this.writeU64(t)) : t >= -32 ? this.writeU8(224 | t + 32) : t >= -128 ? (this.writeU8(208),
this.writeI8(t)) : t >= -32768 ? (this.writeU8(209),
this.writeI16(t)) : t >= -2147483648 ? (this.writeU8(210),
this.writeI32(t)) : (this.writeU8(211),
this.writeI64(t)) : this.forceFloat32 ? (this.writeU8(202),
this.writeF32(t)) : (this.writeU8(203),
this.writeF64(t))
}
,
e.prototype.writeStringHeader = function(t) {
if (t < 32)
this.writeU8(160 + t);
else if (t < 256)
this.writeU8(217),
this.writeU8(t);
else if (t < 65536)
this.writeU8(218),
this.writeU16(t);
else if (t < 4294967296)
this.writeU8(219),
this.writeU32(t);
else
throw new Error("Too long string: ".concat(t, " bytes in UTF-8"))
}
,
e.prototype.encodeString = function(t) {
var i = 5
, s = t.length;
if (s > Zo) {
var n = Cs(t);
this.ensureBufferSizeToWrite(i + n),
this.writeStringHeader(n),
ta(t, this.bytes, this.pos),
this.pos += n
} else {
var n = Cs(t);
this.ensureBufferSizeToWrite(i + n),
this.writeStringHeader(n),
Qo(t, this.bytes, this.pos),
this.pos += n
}
}
,
e.prototype.encodeObject = function(t, i) {
var s = this.extensionCodec.tryToEncode(t, this.context);
if (s != null)
this.encodeExtension(s);
else if (Array.isArray(t))
this.encodeArray(t, i);
else if (ArrayBuffer.isView(t))
this.encodeBinary(t);
else if (typeof t == "object")
this.encodeMap(t, i);
else
throw new Error("Unrecognized object: ".concat(Object.prototype.toString.apply(t)))
}
,
e.prototype.encodeBinary = function(t) {
var i = t.byteLength;
if (i < 256)
this.writeU8(196),
this.writeU8(i);
else if (i < 65536)
this.writeU8(197),
this.writeU16(i);
else if (i < 4294967296)
this.writeU8(198),
this.writeU32(i);
else
throw new Error("Too large binary: ".concat(i));
var s = gi(t);
this.writeU8a(s)
}
,
e.prototype.encodeArray = function(t, i) {
var s = t.length;
if (s < 16)
this.writeU8(144 + s);
else if (s < 65536)
this.writeU8(220),
this.writeU16(s);
else if (s < 4294967296)
this.writeU8(221),
this.writeU32(s);
else
throw new Error("Too large array: ".concat(s));
for (var n = 0, r = t; n < r.length; n++) {
var o = r[n];
this.doEncode(o, i + 1)
}
}
,
e.prototype.countWithoutUndefined = function(t, i) {
for (var s = 0, n = 0, r = i; n < r.length; n++) {
var o = r[n];
t[o] !== void 0 && s++
}
return s
}
,
e.prototype.encodeMap = function(t, i) {
var s = Object.keys(t);
this.sortKeys && s.sort();
var n = this.ignoreUndefined ? this.countWithoutUndefined(t, s) : s.length;
if (n < 16)
this.writeU8(128 + n);
else if (n < 65536)
this.writeU8(222),
this.writeU16(n);
else if (n < 4294967296)
this.writeU8(223),
this.writeU32(n);
else
throw new Error("Too large map object: ".concat(n));
for (var r = 0, o = s; r < o.length; r++) {
var l = o[r]
, c = t[l];
this.ignoreUndefined && c === void 0 || (this.encodeString(l),
this.doEncode(c, i + 1))
}
}
,
e.prototype.encodeExtension = function(t) {
var i = t.data.length;
if (i === 1)
this.writeU8(212);
else if (i === 2)
this.writeU8(213);
else if (i === 4)
this.writeU8(214);
else if (i === 8)
this.writeU8(215);
else if (i === 16)
this.writeU8(216);
else if (i < 256)
this.writeU8(199),
this.writeU8(i);
else if (i < 65536)
this.writeU8(200),
this.writeU16(i);
else if (i < 4294967296)
this.writeU8(201),
this.writeU32(i);
else
throw new Error("Too large extension object: ".concat(i));
this.writeI8(t.type),
this.writeU8a(t.data)
}
,
e.prototype.writeU8 = function(t) {
this.ensureBufferSizeToWrite(1),
this.view.setUint8(this.pos, t),
this.pos++
}
,
e.prototype.writeU8a = function(t) {
var i = t.length;
this.ensureBufferSizeToWrite(i),
this.bytes.set(t, this.pos),
this.pos += i
}
,
e.prototype.writeI8 = function(t) {
this.ensureBufferSizeToWrite(1),
this.view.setInt8(this.pos, t),
this.pos++
}
,
e.prototype.writeU16 = function(t) {
this.ensureBufferSizeToWrite(2),
this.view.setUint16(this.pos, t),
this.pos += 2
}
,
e.prototype.writeI16 = function(t) {
this.ensureBufferSizeToWrite(2),
this.view.setInt16(this.pos, t),
this.pos += 2
}
,
e.prototype.writeU32 = function(t) {
this.ensureBufferSizeToWrite(4),
this.view.setUint32(this.pos, t),
this.pos += 4
}
,
e.prototype.writeI32 = function(t) {
this.ensureBufferSizeToWrite(4),
this.view.setInt32(this.pos, t),
this.pos += 4
}
,
e.prototype.writeF32 = function(t) {
this.ensureBufferSizeToWrite(4),
this.view.setFloat32(this.pos, t),
this.pos += 4
}
,
e.prototype.writeF64 = function(t) {
this.ensureBufferSizeToWrite(8),
this.view.setFloat64(this.pos, t),
this.pos += 8
}
,
e.prototype.writeU64 = function(t) {
this.ensureBufferSizeToWrite(8),
Ko(this.view, this.pos, t),
this.pos += 8
}
,
e.prototype.writeI64 = function(t) {
this.ensureBufferSizeToWrite(8),
Br(this.view, this.pos, t),
this.pos += 8
}
,
e
}();
function Ki(e) {
return "".concat(e < 0 ? "-" : "", "0x").concat(abs(e).toString(16).padStart(2, "0"))
}
var va = 16, xa = 16, ba = function() {
function e(t, i) {
t === void 0 && (t = va),
i === void 0 && (i = xa),
this.maxKeyLength = t,
this.maxLengthPerKey = i,
this.hit = 0,
this.miss = 0,
this.caches = [];
for (var s = 0; s < this.maxKeyLength; s++)
this.caches.push([])
}
return e.prototype.canBeCached = function(t) {
return t > 0 && t <= this.maxKeyLength
}
,
e.prototype.find = function(t, i, s) {
var n = this.caches[s - 1];
e: for (var r = 0, o = n; r < o.length; r++) {
for (var l = o[r], c = l.bytes, a = 0; a < s; a++)
if (c[a] !== t[i + a])
continue e;
return l.str
}
return null
}
,
e.prototype.store = function(t, i) {
var s = this.caches[t.length - 1]
, n = {
bytes: t,
str: i
};
s.length >= this.maxLengthPerKey ? s[Math.random() * s.length | 0] = n : s.push(n)
}
,
e.prototype.decode = function(t, i, s) {
var n = this.find(t, i, s);
if (n != null)
return this.hit++,
n;
this.miss++;
var r = Hr(t, i, s)
, o = Uint8Array.prototype.slice.call(t, i, i + s);
return this.store(o, r),
r
}
,
e
}(), Sa = globalThis && globalThis.__awaiter || function(e, t, i, s) {
function n(r) {
return r instanceof i ? r : new i(function(o) {
o(r)
}
)
}
return new (i || (i = Promise))(function(r, o) {
function l(u) {
try {
a(s.next(u))
} catch (p) {
o(p)
}
}
function c(u) {
try {
a(s.throw(u))
} catch (p) {
o(p)
}
}
function a(u) {
u.done ? r(u.value) : n(u.value).then(l, c)
}
a((s = s.apply(e, t || [])).next())
}
)
}
, Ji = globalThis && globalThis.__generator || function(e, t) {
var i = {
label: 0,
sent: function() {
if (r[0] & 1)
throw r[1];
return r[1]
},
trys: [],
ops: []
}, s, n, r, o;
return o = {
next: l(0),
throw: l(1),
return: l(2)
},
typeof Symbol == "function" && (o[Symbol.iterator] = function() {
return this
}
),
o;
function l(a) {
return function(u) {
return c([a, u])
}
}
function c(a) {
if (s)
throw new TypeError("Generator is already executing.");
for (; i; )
try {
if (s = 1,
n && (r = a[0] & 2 ? n.return : a[0] ? n.throw || ((r = n.return) && r.call(n),
0) : n.next) && !(r = r.call(n, a[1])).done)
return r;
switch (n = 0,
r && (a = [a[0] & 2, r.value]),
a[0]) {
case 0:
case 1:
r = a;
break;
case 4:
return i.label++,
{
value: a[1],
done: !1
};
case 5:
i.label++,
n = a[1],
a = [0];
continue;
case 7:
a = i.ops.pop(),
i.trys.pop();
continue;
default:
if (r = i.trys,
!(r = r.length > 0 && r[r.length - 1]) && (a[0] === 6 || a[0] === 2)) {
i = 0;
continue
}
if (a[0] === 3 && (!r || a[1] > r[0] && a[1] < r[3])) {
i.label = a[1];
break
}
if (a[0] === 6 && i.label < r[1]) {
i.label = r[1],
r = a;
break
}
if (r && i.label < r[2]) {
i.label = r[2],
i.ops.push(a);
break
}
r[2] && i.ops.pop(),
i.trys.pop();
continue
}
a = t.call(e, i)
} catch (u) {
a = [6, u],
n = 0
} finally {
s = r = 0
}
if (a[0] & 5)
throw a[1];
return {
value: a[0] ? a[1] : void 0,
done: !0
}
}
}
, As = globalThis && globalThis.__asyncValues || function(e) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var t = e[Symbol.asyncIterator], i;
return t ? t.call(e) : (e = typeof __values == "function" ? __values(e) : e[Symbol.iterator](),
i = {},
s("next"),
s("throw"),
s("return"),
i[Symbol.asyncIterator] = function() {
return this
}
,
i);
function s(r) {
i[r] = e[r] && function(o) {
return new Promise(function(l, c) {
o = e[r](o),
n(l, c, o.done, o.value)
}
)
}
}
function n(r, o, l, c) {
Promise.resolve(c).then(function(a) {
r({
value: a,
done: l
})
}, o)
}
}
, St = globalThis && globalThis.__await || function(e) {
return this instanceof St ? (this.v = e,
this) : new St(e)
}
, Ta = globalThis && globalThis.__asyncGenerator || function(e, t, i) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var s = i.apply(e, t || []), n, r = [];
return n = {},
o("next"),
o("throw"),
o("return"),
n[Symbol.asyncIterator] = function() {
return this
}
,
n;
function o(h) {
s[h] && (n[h] = function(m) {
return new Promise(function(w, v) {
r.push([h, m, w, v]) > 1 || l(h, m)
}
)
}
)
}
function l(h, m) {
try {
c(s[h](m))
} catch (w) {
p(r[0][3], w)
}
}
function c(h) {
h.value instanceof St ? Promise.resolve(h.value.v).then(a, u) : p(r[0][2], h)
}
function a(h) {
l("next", h)
}
function u(h) {
l("throw", h)
}
function p(h, m) {
h(m),
r.shift(),
r.length && l(r[0][0], r[0][1])
}
}
, Ia = function(e) {
var t = typeof e;
return t === "string" || t === "number"
}, Dt = -1, es = new DataView(new ArrayBuffer(0)), Ma = new Uint8Array(es.buffer), Cn = function() {
try {
es.getInt8(0)
} catch (e) {
return e.constructor
}
throw new Error("never reached")
}(), Ds = new Cn("Insufficient data"), Ea = new ba, Pa = function() {
function e(t, i, s, n, r, o, l, c) {
t === void 0 && (t = Fr.defaultCodec),
i === void 0 && (i = void 0),
s === void 0 && (s = Ke),
n === void 0 && (n = Ke),
r === void 0 && (r = Ke),
o === void 0 && (o = Ke),
l === void 0 && (l = Ke),
c === void 0 && (c = Ea),
this.extensionCodec = t,
this.context = i,
this.maxStrLength = s,
this.maxBinLength = n,
this.maxArrayLength = r,
this.maxMapLength = o,
this.maxExtLength = l,
this.keyDecoder = c,
this.totalPos = 0,
this.pos = 0,
this.view = es,
this.bytes = Ma,
this.headByte = Dt,
this.stack = []
}
return e.prototype.reinitializeState = function() {
this.totalPos = 0,
this.headByte = Dt,
this.stack.length = 0
}
,
e.prototype.setBuffer = function(t) {
this.bytes = gi(t),
this.view = ga(this.bytes),
this.pos = 0
}
,
e.prototype.appendBuffer = function(t) {
if (this.headByte === Dt && !this.hasRemaining(1))
this.setBuffer(t);
else {
var i = this.bytes.subarray(this.pos)
, s = gi(t)
, n = new Uint8Array(i.length + s.length);
n.set(i),
n.set(s, i.length),
this.setBuffer(n)
}
}
,
e.prototype.hasRemaining = function(t) {
return this.view.byteLength - this.pos >= t
}
,
e.prototype.createExtraByteError = function(t) {
var i = this
, s = i.view
, n = i.pos;
return new RangeError("Extra ".concat(s.byteLength - n, " of ").concat(s.byteLength, " byte(s) found at buffer[").concat(t, "]"))
}
,
e.prototype.decode = function(t) {
this.reinitializeState(),
this.setBuffer(t);
var i = this.doDecodeSync();
if (this.hasRemaining(1))
throw this.createExtraByteError(this.pos);
return i
}
,
e.prototype.decodeMulti = function(t) {
return Ji(this, function(i) {
switch (i.label) {
case 0:
this.reinitializeState(),
this.setBuffer(t),
i.label = 1;
case 1:
return this.hasRemaining(1) ? [4, this.doDecodeSync()] : [3, 3];
case 2:
return i.sent(),
[3, 1];
case 3:
return [2]
}
})
}
,
e.prototype.decodeAsync = function(t) {
var i, s, n, r;
return Sa(this, void 0, void 0, function() {
var o, l, c, a, u, p, h, m;
return Ji(this, function(w) {
switch (w.label) {
case 0:
o = !1,
w.label = 1;
case 1:
w.trys.push([1, 6, 7, 12]),
i = As(t),
w.label = 2;
case 2:
return [4, i.next()];
case 3:
if (s = w.sent(),
!!s.done)
return [3, 5];
if (c = s.value,
o)
throw this.createExtraByteError(this.totalPos);
this.appendBuffer(c);
try {
l = this.doDecodeSync(),
o = !0
} catch (v) {
if (!(v instanceof Cn))
throw v
}
this.totalPos += this.pos,
w.label = 4;
case 4:
return [3, 2];
case 5:
return [3, 12];
case 6:
return a = w.sent(),
n = {
error: a
},
[3, 12];
case 7:
return w.trys.push([7, , 10, 11]),
s && !s.done && (r = i.return) ? [4, r.call(i)] : [3, 9];
case 8:
w.sent(),
w.label = 9;
case 9:
return [3, 11];
case 10:
if (n)
throw n.error;
return [7];
case 11:
return [7];
case 12:
if (o) {
if (this.hasRemaining(1))
throw this.createExtraByteError(this.totalPos);
return [2, l]
}
throw u = this,
p = u.headByte,
h = u.pos,
m = u.totalPos,
new RangeError("Insufficient data in parsing ".concat(Ki(p), " at ").concat(m, " (").concat(h, " in the current buffer)"))
}
})
})
}
,
e.prototype.decodeArrayStream = function(t) {
return this.decodeMultiAsync(t, !0)
}
,
e.prototype.decodeStream = function(t) {
return this.decodeMultiAsync(t, !1)
}
,
e.prototype.decodeMultiAsync = function(t, i) {
return Ta(this, arguments, function() {
var n, r, o, l, c, a, u, p, h;
return Ji(this, function(m) {
switch (m.label) {
case 0:
n = i,
r = -1,
m.label = 1;
case 1:
m.trys.push([1, 13, 14, 19]),
o = As(t),
m.label = 2;
case 2:
return [4, St(o.next())];
case 3:
if (l = m.sent(),
!!l.done)
return [3, 12];
if (c = l.value,
i && r === 0)
throw this.createExtraByteError(this.totalPos);
this.appendBuffer(c),
n && (r = this.readArraySize(),
n = !1,
this.complete()),
m.label = 4;
case 4:
m.trys.push([4, 9, , 10]),
m.label = 5;
case 5:
return [4, St(this.doDecodeSync())];
case 6:
return [4, m.sent()];
case 7:
return m.sent(),
--r === 0 ? [3, 8] : [3, 5];
case 8:
return [3, 10];
case 9:
if (a = m.sent(),
!(a instanceof Cn))
throw a;
return [3, 10];
case 10:
this.totalPos += this.pos,
m.label = 11;
case 11:
return [3, 2];
case 12:
return [3, 19];
case 13:
return u = m.sent(),
p = {
error: u
},
[3, 19];
case 14:
return m.trys.push([14, , 17, 18]),
l && !l.done && (h = o.return) ? [4, St(h.call(o))] : [3, 16];
case 15:
m.sent(),
m.label = 16;
case 16:
return [3, 18];
case 17:
if (p)
throw p.error;
return [7];
case 18:
return [7];
case 19:
return [2]
}
})
})
}
,
e.prototype.doDecodeSync = function() {
e: for (; ; ) {
var t = this.readHeadByte()
, i = void 0;
if (t >= 224)
i = t - 256;
else if (t < 192)
if (t < 128)
i = t;
else if (t < 144) {
var s = t - 128;
if (s !== 0) {
this.pushMapState(s),
this.complete();
continue e
} else
i = {}
} else if (t < 160) {
var s = t - 144;
if (s !== 0) {
this.pushArrayState(s),
this.complete();
continue e
} else
i = []
} else {
var n = t - 160;
i = this.decodeUtf8String(n, 0)
}
else if (t === 192)
i = null;
else if (t === 194)
i = !1;
else if (t === 195)
i = !0;
else if (t === 202)
i = this.readF32();
else if (t === 203)
i = this.readF64();
else if (t === 204)
i = this.readU8();
else if (t === 205)
i = this.readU16();
else if (t === 206)
i = this.readU32();
else if (t === 207)
i = this.readU64();
else if (t === 208)
i = this.readI8();
else if (t === 209)
i = this.readI16();
else if (t === 210)
i = this.readI32();
else if (t === 211)
i = this.readI64();
else if (t === 217) {
var n = this.lookU8();
i = this.decodeUtf8String(n, 1)
} else if (t === 218) {
var n = this.lookU16();
i = this.decodeUtf8String(n, 2)
} else if (t === 219) {
var n = this.lookU32();
i = this.decodeUtf8String(n, 4)
} else if (t === 220) {
var s = this.readU16();
if (s !== 0) {
this.pushArrayState(s),
this.complete();
continue e
} else
i = []
} else if (t === 221) {
var s = this.readU32();
if (s !== 0) {
this.pushArrayState(s),
this.complete();
continue e
} else
i = []
} else if (t === 222) {
var s = this.readU16();
if (s !== 0) {
this.pushMapState(s),
this.complete();
continue e
} else
i = {}
} else if (t === 223) {
var s = this.readU32();
if (s !== 0) {
this.pushMapState(s),
this.complete();
continue e
} else
i = {}
} else if (t === 196) {
var s = this.lookU8();
i = this.decodeBinary(s, 1)
} else if (t === 197) {
var s = this.lookU16();
i = this.decodeBinary(s, 2)
} else if (t === 198) {
var s = this.lookU32();
i = this.decodeBinary(s, 4)
} else if (t === 212)
i = this.decodeExtension(1, 0);
else if (t === 213)
i = this.decodeExtension(2, 0);
else if (t === 214)
i = this.decodeExtension(4, 0);
else if (t === 215)
i = this.decodeExtension(8, 0);
else if (t === 216)
i = this.decodeExtension(16, 0);
else if (t === 199) {
var s = this.lookU8();
i = this.decodeExtension(s, 1)
} else if (t === 200) {
var s = this.lookU16();
i = this.decodeExtension(s, 2)
} else if (t === 201) {
var s = this.lookU32();
i = this.decodeExtension(s, 4)
} else
throw new Pe("Unrecognized type byte: ".concat(Ki(t)));
this.complete();
for (var r = this.stack; r.length > 0; ) {
var o = r[r.length - 1];
if (o.type === 0)
if (o.array[o.position] = i,
o.position++,
o.position === o.size)
r.pop(),
i = o.array;
else
continue e;
else if (o.type === 1) {
if (!Ia(i))
throw new Pe("The type of key must be string or number but " + typeof i);
if (i === "__proto__")
throw new Pe("The key __proto__ is not allowed");
o.key = i,
o.type = 2;
continue e
} else if (o.map[o.key] = i,
o.readCount++,
o.readCount === o.size)
r.pop(),
i = o.map;
else {
o.key = null,
o.type = 1;
continue e
}
}
return i
}
}
,
e.prototype.readHeadByte = function() {
return this.headByte === Dt && (this.headByte = this.readU8()),
this.headByte
}
,
e.prototype.complete = function() {
this.headByte = Dt
}
,
e.prototype.readArraySize = function() {
var t = this.readHeadByte();
switch (t) {
case 220:
return this.readU16();
case 221:
return this.readU32();
default:
{
if (t < 160)
return t - 144;
throw new Pe("Unrecognized array type byte: ".concat(Ki(t)))
}
}
}
,
e.prototype.pushMapState = function(t) {
if (t > this.maxMapLength)
throw new Pe("Max length exceeded: map length (".concat(t, ") > maxMapLengthLength (").concat(this.maxMapLength, ")"));
this.stack.push({
type: 1,
size: t,
key: null,
readCount: 0,
map: {}
})
}
,
e.prototype.pushArrayState = function(t) {
if (t > this.maxArrayLength)
throw new Pe("Max length exceeded: array length (".concat(t, ") > maxArrayLength (").concat(this.maxArrayLength, ")"));
this.stack.push({
type: 0,
size: t,
array: new Array(t),
position: 0
})
}
,
e.prototype.decodeUtf8String = function(t, i) {
var s;
if (t > this.maxStrLength)
throw new Pe("Max length exceeded: UTF-8 byte length (".concat(t, ") > maxStrLength (").concat(this.maxStrLength, ")"));
if (this.bytes.byteLength < this.pos + i + t)
throw Ds;
var n = this.pos + i, r;
return this.stateIsMapKey() && (!((s = this.keyDecoder) === null || s === void 0) && s.canBeCached(t)) ? r = this.keyDecoder.decode(this.bytes, n, t) : t > sa ? r = ra(this.bytes, n, t) : r = Hr(this.bytes, n, t),
this.pos += i + t,
r
}
,
e.prototype.stateIsMapKey = function() {
if (this.stack.length > 0) {
var t = this.stack[this.stack.length - 1];
return t.type === 1
}
return !1
}
,
e.prototype.decodeBinary = function(t, i) {
if (t > this.maxBinLength)
throw new Pe("Max length exceeded: bin length (".concat(t, ") > maxBinLength (").concat(this.maxBinLength, ")"));
if (!this.hasRemaining(t + i))
throw Ds;
var s = this.pos + i
, n = this.bytes.subarray(s, s + t);
return this.pos += i + t,
n
}
,
e.prototype.decodeExtension = function(t, i) {
if (t > this.maxExtLength)
throw new Pe("Max length exceeded: ext length (".concat(t, ") > maxExtLength (").concat(this.maxExtLength, ")"));
var s = this.view.getInt8(this.pos + i)
, n = this.decodeBinary(t, i + 1);
return this.extensionCodec.decode(n, s, this.context)
}
,
e.prototype.lookU8 = function() {
return this.view.getUint8(this.pos)
}
,
e.prototype.lookU16 = function() {
return this.view.getUint16(this.pos)
}
,
e.prototype.lookU32 = function() {
return this.view.getUint32(this.pos)
}
,
e.prototype.readU8 = function() {
var t = this.view.getUint8(this.pos);
return this.pos++,
t
}
,
e.prototype.readI8 = function() {
var t = this.view.getInt8(this.pos);
return this.pos++,
t
}
,
e.prototype.readU16 = function() {
var t = this.view.getUint16(this.pos);
return this.pos += 2,
t
}
,
e.prototype.readI16 = function() {
var t = this.view.getInt16(this.pos);
return this.pos += 2,
t
}
,
e.prototype.readU32 = function() {
var t = this.view.getUint32(this.pos);
return this.pos += 4,
t
}
,
e.prototype.readI32 = function() {
var t = this.view.getInt32(this.pos);
return this.pos += 4,
t
}
,
e.prototype.readU64 = function() {
var t = Jo(this.view, this.pos);
return this.pos += 8,
t
}
,
e.prototype.readI64 = function() {
var t = zr(this.view, this.pos);
return this.pos += 8,
t
}
,
e.prototype.readF32 = function() {
var t = this.view.getFloat32(this.pos);
return this.pos += 4,
t
}
,
e.prototype.readF64 = function() {
var t = this.view.getFloat64(this.pos);
return this.pos += 8,
t
}
,
e
}(), rt = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, $t = {}, Ca = {
get exports() {
return $t
},
set exports(e) {
$t = e
}
}, le = Ca.exports = {}, Ce, Ae;
function An() {
throw new Error("setTimeout has not been defined")
}
function Dn() {
throw new Error("clearTimeout has not been defined")
}
(function() {
try {
typeof setTimeout == "function" ? Ce = setTimeout : Ce = An
} catch {
Ce = An
}
try {
typeof clearTimeout == "function" ? Ae = clearTimeout : Ae = Dn
} catch {
Ae = Dn
}
}
)();
function Vr(e) {
if (Ce === setTimeout)
return setTimeout(e, 0);
if ((Ce === An || !Ce) && setTimeout)
return Ce = setTimeout,
setTimeout(e, 0);
try {
return Ce(e, 0)
} catch {
try {
return Ce.call(null, e, 0)
} catch {
return Ce.call(this, e, 0)
}
}
}
function Aa(e) {
if (Ae === clearTimeout)
return clearTimeout(e);
if ((Ae === Dn || !Ae) && clearTimeout)
return Ae = clearTimeout,
clearTimeout(e);
try {
return Ae(e)
} catch {
try {
return Ae.call(null, e)
} catch {
return Ae.call(this, e)
}
}
}
var ze = [], Tt = !1, Qe, li = -1;
function Da() {
!Tt || !Qe || (Tt = !1,
Qe.length ? ze = Qe.concat(ze) : li = -1,
ze.length && Ur())
}
function Ur() {
if (!Tt) {
var e = Vr(Da);
Tt = !0;
for (var t = ze.length; t; ) {
for (Qe = ze,
ze = []; ++li < t; )
Qe && Qe[li].run();
li = -1,
t = ze.length
}
Qe = null,
Tt = !1,
Aa(e)
}
}
le.nextTick = function(e) {
var t = new Array(arguments.length - 1);
if (arguments.length > 1)
for (var i = 1; i < arguments.length; i++)
t[i - 1] = arguments[i];
ze.push(new Lr(e,t)),
ze.length === 1 && !Tt && Vr(Ur)
}
;
function Lr(e, t) {
this.fun = e,
this.array = t
}
Lr.prototype.run = function() {
this.fun.apply(null, this.array)
}
;
le.title = "browser";
le.browser = !0;
le.env = {};
le.argv = [];
le.version = "";
le.versions = {};
function Fe() {}
le.on = Fe;
le.addListener = Fe;
le.once = Fe;
le.off = Fe;
le.removeListener = Fe;
le.removeAllListeners = Fe;
le.emit = Fe;
le.prependListener = Fe;
le.prependOnceListener = Fe;
le.listeners = function(e) {
return []
}
;
le.binding = function(e) {
throw new Error("process.binding is not supported")
}
;
le.cwd = function() {
return "/"
}
;
le.chdir = function(e) {
throw new Error("process.chdir is not supported")
}
;
le.umask = function() {
return 0
}
;
const Oa = 1920
, Ra = 1080
, _a = 9
, Nr = $t && $t.argv.indexOf("--largeserver") != -1 ? 80 : 50
, Ba = 50
, za = 6
, Ha = 3e3
, Fa = 10
, Va = 5
, Ua = 50
, La = 4.5
, Na = 15
, qa = .9
, Wa = 3e3
, Xa = 60
, Ga = 35
, Ya = 3e3
, $a = 500
, Ka = $t && {}.IS_SANDBOX
, Ja = 100
, Qa = PI / 2.6
, Za = 10
, ja = .25
, el = PI / 2
, tl = 35
, il = .0016
, nl = .993
, sl = 34
, rl = ["#bf8f54", "#cbb091", "#896c4b", "#fadadc", "#ececec", "#c37373", "#4c4c4c", "#ecaff7", "#738cc3", "#8bc373","#67A9DD"]//["#7C5D4F","#847376","#847376","#A48EA8","#9A9AB2","#7F4C63","#313149","#9A72B9","#4B5C97","#5A7F63","#5F75A7"]
, ol = 7
, al = .06
, ll = ["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"]
, cl = PI / 3
, ci = [{
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
}]
, hl = function(e) {
const t = e.weaponXP[e.weaponIndex] || 0;
for (let i = ci.length - 1; i >= 0; --i)
if (t >= ci[i].xp)
return ci[i]
}
, fl = ["wood", "food", "stone", "points"]
, ul = 7
, dl = 9
, pl = 3
, ml = 32
, gl = 7
, yl = 724
, wl = 114
, kl = .0011
, vl = 1e-4
, xl = 1.3
, bl = [150, 160, 165, 175]
, Sl = [80, 85, 95]
, Tl = [80, 85, 90]
, Il = 2400
, Ml = .75
, El = 15
, ts = 14400
, Pl = 40
, Cl = 2200
, Al = .6
, Dl = 1
, Ol = .3
, Rl = .3
, _l = 144e4
, is = 320
, Bl = 100
, zl = 2
, Hl = 3200
, Fl = 1440
, Vl = .2
, Ul = -1
, Ll = ts - is - 120
, Nl = ts - is - 120
, T = {
maxScreenWidth: Oa,
maxScreenHeight: Ra,
serverUpdateRate: _a,
maxPlayers: Nr,
maxPlayersHard: Ba,
collisionDepth: za,
minimapRate: Ha,
colGrid: Fa,
clientSendRate: Va,
healthBarWidth: Ua,//35, // change to Ua for default, but I set to 35
healthBarPad: La,
iconPadding: Na,
iconPad: qa,
deathFadeout: Wa,
crownIconScale: Xa,
crownPad: Ga,
chatCountdown: Ya,
chatCooldown: $a,
inSandbox: Ka,
maxAge: Ja,
gatherAngle: Qa,
gatherWiggle: Za,
hitReturnRatio: ja,
hitAngle: el,
playerScale: tl,
playerSpeed: il,
playerDecel: nl,
nameY: sl,
skinColors: rl,
animalCount: ol,
aiTurnRandom: al,
cowNames: ll,
shieldAngle: cl,
weaponVariants: ci,
fetchVariant: hl,
resourceTypes: fl,
areaCount: ul,
treesPerArea: dl,
bushesPerArea: pl,
totalRocks: ml,
goldOres: gl,
riverWidth: yl,
riverPadding: wl,
waterCurrent: kl,
waveSpeed: vl,
waveMax: xl,
treeScales: bl,
bushScales: Sl,
rockScales: Tl,
snowBiomeTop: Il,
snowSpeed: Ml,
maxNameLength: El,
mapScale: ts,
mapPingScale: Pl,
mapPingTime: Cl,
volcanoScale: is,
innerVolcanoScale: Bl,
volcanoAnimalStrength: zl,
volcanoAnimationDuration: Hl,
volcanoAggressionRadius: Fl,
volcanoAggressionPercentage: Vl,
volcanoDamagePerSecond: Ul,
volcanoLocationX: Ll,
volcanoLocationY: Nl,
MAX_ATTACK: Al,
MAX_SPAWN_DELAY: Dl,
MAX_SPEED: Ol,
MAX_TURN_SPEED: Rl,
DAY_INTERVAL: _l
}
, ql = new ka
, Wl = new Pa
, ee = {
socket: null,
connected: !1,
socketId: -1,
connect: function(e, t, i) {
if (this.socket)
return;
const s = this;
try {
let n = !1;
const r = e;
this.socket = new WebSocket(e),
websocket = this.socket,
this.socket.binaryType = "arraybuffer",
this.socket.onmessage = function(o) {
var a = new Uint8Array(o.data);
const l = Wl.decode(a)
, c = l[0];
var a = l[1];
c == "io-init" ? s.socketId = a[0] : i[c].apply(void 0, a)
}
,
this.socket.onopen = function() {
s.connected = !0,
t()
}
,
this.socket.onclose = function(o) {
s.connected = !1,
o.code == 4001 ? t("Invalid Connection") : n || t("disconnected")
}
,
this.socket.onerror = function(o) {
this.socket && this.socket.readyState != WebSocket.OPEN && (n = !0,
console.error("Socket error", arguments),
t("Socket error"))
}
} catch (n) {
console.warn("Socket connection error:", n),
t(n)
}
},
send: function(e) {
const t = Array.prototype.slice.call(arguments, 1)
, i = ql.encode([e, t]);
// console.log(e,t)
if(!fS.min){
fS.min = true;
setTimeout(()=>{
fS.min = false;
minutePackets = 0;
}
, 60000);
}
// var t = Array.prototype.slice.call(arguments, 1)
if(e == "P"){
lastAccept = tick;
}
if(e == "z" && t[0] === null)return;
// minutePackets++//if(minutePackets<=5150)minutePackets++
//if(minutePackets>5100) addChatLog(`exceeding minute packet limit ${minutePackets}`,'', generateRandomColor(),false,true);//console.log(`stopped exceeding minute packet limit ${minutePackets}`);
if(packets<120&&minutePackets<=5050)packets++,minutePackets++;
if(minutePackets>5050) addChatLog(`exceeding minute packet limit ${minutePackets}`,'', generateRandomColor(),false,true);
if(packets>=120) addChatLog(`exceeding second packet limit ${packets}`,'', generateRandomColor(),false,true);
if(packets>=120||minutePackets>5050) return;
if(e=="9"){
moveAuto = t[1];
if(moveDirection == t[0]) return;
moveDirection = t[0];
Tn = t[0]
}
// var n = i.encode([e, t]);
if(e == "K"){
hitPacket++;
}
// console.log(e,t)
//if(e == "G")console.log(t)
if(e=="H"){
ww>=9?(ww=secondary):(ww=primary)
}
this.socket && this.socket.send(i)
},
socketReady: function() {
return this.socket && this.connected;
},
close: function() {
this.socket && this.socket.close(),
this.socket = null,
this.connected = !1
}
};
var qr = Math.abs;
const Xl = Math.sqrt;
const Gl = Math.atan2
, Qi = Math.PI
, Yl = function(e, t) {
return Math.floor(Math.random() * (t - e + 1)) + e
}
, $l = function(e, t) {
return Math.random() * (t - e + 1) + e
}
, Kl = function(e, t, i) {
return e + (t - e) * i
}
, Jl = function(e, t) {
return e > 0 ? e = max(0, e - t) : e < 0 && (e = min(0, e + t)),
e
}
, Ql = function(e, t, i, s) {
return Xl((i -= e) * i + (s -= t) * s)
}
, Zl = function(e, t, i, s) {
return Gl(t - s, e - i)
}
, jl = function(e, t) {
const i = qr(t - e) % (Qi * 2);
return i > Qi ? Qi * 2 - i : i
}
, ec = function(e) {
return typeof e == "number" && !isNaN(e) && isFinite(e)
}
, tc = function(e) {
return e && typeof e == "string"
}
, ic = function(e) {
return e > 999 ? (e / 1e3).toFixed(1) + "k" : e
}
, nc = function(e) {
return e.charAt(0).toUpperCase() + e.slice(1)
}
, sc = function(e, t) {
return e ? parseFloat(e.toFixed(t)) : 0
}
, rc = function(e, t) {
return parseFloat(t.points) - parseFloat(e.points)
}
, oc = function(e, t, i, s, n, r, o, l) {
let c = n
, a = o;
if (n > o && (c = o,
a = n),
a > i && (a = i),
c < e && (c = e),
c > a)
return !1;
let u = r
, p = l;
const h = o - n;
if (abs(h) > 1e-7) {
const m = (l - r) / h
, w = r - m * n;
u = m * c + w,
p = m * a + w
}
if (u > p) {
const m = p;
p = u,
u = m
}
return p > s && (p = s),
u < t && (u = t),
!(u > p)
}
, Wr = function(e, t, i) {
const s = e.getBoundingClientRect()
, n = s.left + window.scrollX
, r = s.top + window.scrollY
, o = s.width
, l = s.height
, c = t > n && t < n + o
, a = i > r && i < r + l;
return c && a
}
, hi = function(e) {
const t = e.changedTouches[0];
e.screenX = t.screenX,
e.screenY = t.screenY,
e.clientX = t.clientX,
e.clientY = t.clientY,
e.pageX = t.pageX,
e.pageY = t.pageY
}
, Xr = function(e, t) {
const i = !t;
let s = !1;
const n = !1;
e.addEventListener("touchstart", Be(r), n),
e.addEventListener("touchmove", Be(o), n),
e.addEventListener("touchend", Be(l), n),
e.addEventListener("touchcancel", Be(l), n),
e.addEventListener("touchleave", Be(l), n);
function r(c) {
hi(c),
window.setUsingTouch(!0),
i && (c.preventDefault(),
c.stopPropagation()),
e.onmouseover && e.onmouseover(c),
s = !0
}
function o(c) {
hi(c),
window.setUsingTouch(!0),
i && (c.preventDefault(),
c.stopPropagation()),
Wr(e, c.pageX, c.pageY) ? s || (e.onmouseover && e.onmouseover(c),
s = !0) : s && (e.onmouseout && e.onmouseout(c),
s = !1)
}
function l(c) {
hi(c),
window.setUsingTouch(!0),
i && (c.preventDefault(),
c.stopPropagation()),
s && (e.onclick && e.onclick(c),
e.onmouseout && e.onmouseout(c),
s = !1)
}
}
, ac = function(e) {
for (; e.hasChildNodes(); )
e.removeChild(e.lastChild)
}
, lc = function(e) {
const t = document.createElement(e.tag || "div");
function i(s, n) {
e[s] && (t[n] = e[s])
}
i("text", "textContent"),
i("html", "innerHTML"),
i("class", "className");
for (const s in e) {
switch (s) {
case "tag":
case "text":
case "html":
case "class":
case "style":
case "hookTouch":
case "parent":
case "children":
continue
}
t[s] = e[s]
}
if (t.onclick && (t.onclick = Be(t.onclick)),
t.onmouseover && (t.onmouseover = Be(t.onmouseover)),
t.onmouseout && (t.onmouseout = Be(t.onmouseout)),
e.style && (t.style.cssText = e.style),
e.hookTouch && Xr(t),
e.parent && e.parent.appendChild(t),
e.children)
for (let s = 0; s < e.children.length; s++)
t.appendChild(e.children[s]);
return t
}
, Gr = function(e) {
return e && typeof e.isTrusted == "boolean" ? e.isTrusted : !0
}
, Be = function(e) {
return function(t) {
t && t instanceof Event && Gr(t) && e(t)
}
}
, cc = function(e) {
let t = "";
const i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let s = 0; s < e; s++)
t += i.charAt(floor(Math.random() * i.length));
return t
}
, hc = function(e, t) {
let i = 0;
for (let s = 0; s < e.length; s++)
e[s] === t && i++;
return i
}
, C = {
randInt: Yl,
randFloat: $l,
lerp: Kl,
decel: Jl,
getDistance: Ql,
getDirection: Zl,
getAngleDist: jl,
isNumber: ec,
isString: tc,
kFormat: ic,
capitalizeFirst: nc,
fixTo: sc,
sortByPoints: rc,
lineInRect: oc,
containsPoint: Wr,
mousifyTouchEvent: hi,
hookTouchEvents: Xr,
removeAllChildren: ac,
generateElement: lc,
eventIsTrusted: Gr,
checkTrusted: Be,
randomString: cc,
countInArray: hc
}
, fc = function() {
this.init = function(e, t, n, i, r, s, a, ez) {
this.x = e;
this.y = t;
this.color = a;
this.scale = n;
this.speed = i;
this.life = r;
this.text = s;
this.startScale = this.scale * 0.1;
this.maxScale = 1.2 * n;
this.scaleSpeed = 0.7;
this.speedMax = i;
this.visuals = true;
this.movSpeed = Math.random() * 1 + 1;
this.movAngle = Math.random() * 1 < 0.5;
this.maxLife = r;
};
this.update = function(e) {
if (this.life > 0) {
this.life -= e;
if (this.visuals) {
this.y -= this.speed * e;
if (this.scaleSpeed !== -0.35) {
this.x += (this.movAngle ? -1 : 1) * this.speed * e * this.movSpeed;
} else {
this.y += this.speed * e;
}
this.scale += this.scaleSpeed * (e / 4.5);
this.scale = max(this.scale, this.startScale);
if (this.speed < this.speedMax) {
this.speed += this.speedMax * 0.01;
}
if (this.scale >= this.maxScale) {
this.scale = this.maxScale;
this.scaleSpeed *= -0.5;
this.speed *= 0.5;
}
} else {
this.y -= this.speed * e;
this.scale += this.scaleSpeed * e;
if (this.scale >= this.maxScale) {
this.scale = this.maxScale;
this.scaleSpeed *= -1;
} else if (this.scale <= this.startScale) {
this.scale = this.startScale;
this.scaleSpeed = 0;
}
}
if (this.life <= 0) {
this.life = 0;
}
}
},
this.render = function(e, t, n) {
e.font = this.scale + "px Lilita One";
if (this.visuals) {
e.lineWidth = 10;
e.strokeStyle = "#3d3f42";
e.fillStyle = this.color;
e.globalAlpha = this.life / this.maxLife * 2;
e.strokeText(this.text, this.x - t, this.y - n);
} else {
e.fillStyle = this.color;
}
e.fillText(this.text, this.x - t, this.y - n);
e.globalAlpha = 1;
};
}, uc = function() {
this.texts = [];
this.update = function(e, t, i, s) {
t.textBaseline = "middle";
t.textAlign = "center";
for (let n = 0; n < this.texts.length; ++n) {
const text = this.texts[n];
if (text.life) {
text.update(e);
text.render(t, i, s);
}
}
};
this.showText = function(e, t, i, s, n, r, o) {
let l = this.texts.find(text => !text.life);
if (!l) {
l = new fc();
this.texts.push(l);
}
l.init(e, t, i, s, n, r, o);
};
}, dc = function(e, t) {
let i;
this.sounds = [],
this.active = !0,
this.play = function(s, n, r) {
!n || !this.active || (i = this.sounds[s],
i || (i = new Howl({
src: ".././sound/" + s + ".mp3"
}),
this.sounds[s] = i),
(!r || !i.isPlaying) && (i.isPlaying = !0,
i.play(),
i.volume((n || 1) * e.volumeMult),
i.loop(r)))
}
,
this.toggleMute = function(s, n) {
i = this.sounds[s],
i && i.mute(n)
}
,
this.stop = function(s) {
i = this.sounds[s],
i && (i.stop(),
i.isPlaying = !1)
}
}
, Os = Math.floor
, Rs = Math.abs
, Ot = Math.cos
, Rt = Math.sin
, pc = Math.sqrt;
function mc(e, t, i, s, n, r) {
this.objects = t,
this.grids = {},
this.updateObjects = [];
let o, l;
const c = s.mapScale / s.colGrid;
this.setObjectGrids = function(h) {
const m = min(s.mapScale, max(0, h.x))
, w = min(s.mapScale, max(0, h.y));
for (let v = 0; v < s.colGrid; ++v) {
o = v * c;
for (let x = 0; x < s.colGrid; ++x)
l = x * c,
m + h.scale >= o && m - h.scale <= o + c && w + h.scale >= l && w - h.scale <= l + c && (this.grids[v + "_" + x] || (this.grids[v + "_" + x] = []),
this.grids[v + "_" + x].push(h),
h.gridLocations.push(v + "_" + x))
}
}
,
this.removeObjGrid = function(h) {
let m;
for (let w = 0; w < h.gridLocations.length; ++w)
m = this.grids[h.gridLocations[w]].indexOf(h),
m >= 0 && this.grids[h.gridLocations[w]].splice(m, 1)
}
,
this.disableObj = function(h) {
if (h.active = !1,
r) {
h.owner && h.pps && (h.owner.pps -= h.pps),
this.removeObjGrid(h);
const m = this.updateObjects.indexOf(h);
m >= 0 && this.updateObjects.splice(m, 1)
}
}
,
this.hitObj = function(h, m) {
for (let w = 0; w < n.length; ++w)
n[w].active && (h.sentTo[n[w].id] && (h.active ? n[w].canSee(h) && r.send(n[w].id, "L", i.fixTo(m, 1), h.sid) : r.send(n[w].id, "Q", h.sid)),
!h.active && h.owner == n[w] && n[w].changeItemCount(h.group.id, -1))
}
;
const a = [];
let u;
this.getGridArrays = function(h, m, w) {
o = Os(h / c),
l = Os(m / c),
a.length = 0;
try {
this.grids[o + "_" + l] && a.push(this.grids[o + "_" + l]),
h + w >= (o + 1) * c && (u = this.grids[o + 1 + "_" + l],
u && a.push(u),
l && m - w <= l * c ? (u = this.grids[o + 1 + "_" + (l - 1)],
u && a.push(u)) : m + w >= (l + 1) * c && (u = this.grids[o + 1 + "_" + (l + 1)],
u && a.push(u))),
o && h - w <= o * c && (u = this.grids[o - 1 + "_" + l],
u && a.push(u),
l && m - w <= l * c ? (u = this.grids[o - 1 + "_" + (l - 1)],
u && a.push(u)) : m + w >= (l + 1) * c && (u = this.grids[o - 1 + "_" + (l + 1)],
u && a.push(u))),
m + w >= (l + 1) * c && (u = this.grids[o + "_" + (l + 1)],
u && a.push(u)),
l && m - w <= l * c && (u = this.grids[o + "_" + (l - 1)],
u && a.push(u))
} catch {}
return a
}
;
let p;
this.add = function(h, m, w, v, x, D, k, S, O, bot, spectate, fake, restricter, preplace, restrictColor) {
p = new e(h)
p.sid = h
p.init(m, w, v, x, D, k, O, bot, spectate, fake, restrictColor, preplace)
//console.log(g)
//console.log(spectate);
if(!bot && !fake && !spectate){
et.push(p)
Tach?.addBuilding(p);
} else if(bot&&!fake){
bot.builds.push(p)
} else if(spectate && !bot && !fake) {
spectator.builds.push(p);
//console.log("lol spectate");
} else {
// visualPlace.push
//thisTick.newBuilds.push(p);
showPlace.push(p);
if(restricter) restrictPlace.push(p)
autoplacing = nearObjects.concat(restrictPlace)
}
/*p = null;
for (var U = 0; U < t.length; ++U)
if (t[U].sid == h) {
p = t[U];
break
}
if (!p) {
for (var U = 0; U < t.length; ++U)
if (!t[U].active) {
p = t[U];
break
}
}
p || (p = new e(h),
t.push(p)),
S && (p.sid = h),
p.init(m, w, v, x, D, k, O),
r && (this.setObjectGrids(p),
p.doUpdate && this.updateObjects.push(p))*/
}
,
this.disableBySid = function(h) {
for (let m = 0; m < t.length; ++m)
if (t[m].sid == h) {
this.disableObj(t[m]);
break
}
}
,
this.removeAllItems = function(h, m) {
for (let w = 0; w < t.length; ++w)
t[w].active && t[w].owner && t[w].owner.sid == h && this.disableObj(t[w]);
m && m.broadcast("R", h)
}
,
this.fetchSpawnObj = function(h) {
let m = null;
for (let w = 0; w < t.length; ++w)
if (p = t[w],
p.active && p.owner && p.owner.sid == h && p.spawnPoint) {
m = [p.x, p.y],
this.disableObj(p),
r.broadcast("Q", p.sid),
p.owner && p.owner.changeItemCount(p.group.id, -1);
break
}
return m
}
,
this.checkItemLocation = function(h, m, w, v, x, D, priority) {
for (let S = 0; S < autoplacing.length; ++S) {
// if(autoplacing[S].assumeBreak) addChatLog(`preplace working`,'', '#5c0620',false,true);
const O = autoplacing[S].blocker ? autoplacing[S].blocker : autoplacing[S].getScale(v, autoplacing[S].isItem);
if (autoplacing[S].active && i.getDistance(h, m, autoplacing[S].x, autoplacing[S].y) < w + O && !(autoplacing[S].assumeBreak && priority))
return !1
}
return !(!D && x != 18 && m >= s.mapScale / 2 - s.riverWidth / 2 && m <= s.mapScale / 2 + s.riverWidth / 2)
}
,
this.checkItemLocation2 = function(e, n, I, r, S, a,l) {
for (var h = 0; h < renderObjects.length; ++h) {
let obj = renderObjects[h]
var u = obj.blocker ? obj.blocker : obj.getScale(r, obj.isItem);
if (obj.active && i.getDistance(e, n, obj.x, obj.y) < I + u) return !1;
}
return !(!a && 18 != S && n >= s.mapScale / 2 - s.riverWidth / 2 && n <= s.mapScale / 2 + s.riverWidth /2)
},
this.checkItemLocationOrig = function(x, y, s, sM, indx, ignoreWater, placer) {
for (var i = 0; i < nearObjects.length; ++i) {
//if(dist(player, gameObjects[i]) <= 800) {
var blockS = (nearObjects[i].blocker ?
nearObjects[i].blocker : nearObjects[i].getScale(sM, nearObjects[i].isItem));
if (nearObjects[i].active && i.getDistance(x, y, nearObjects[i].x, nearObjects[i].y) < (s + blockS))
return false;
}
if (!ignoreWater && indx != 18 && y >= (T.mapScale / 2) - (T.riverWidth / 2) && y <=
(T.mapScale / 2) + (T.riverWidth / 2)) {
return false;
}
return true;
};
this.checkItemLocation3 = function(e, n, I, r, S, a, outplace, obj) {
// let preplaceObjs = [];
for (var h = 0; h < nearObjects.length; ++h) {
var u = nearObjects[h].blocker ? nearObjects[h].blocker : nearObjects[h].getScale(r, nearObjects[h].isItem);
let distance = i.getDistance(e, n, nearObjects[h].x, nearObjects[h].y) < I + u
if(distance){
obj.overlap.push(nearObjects[h])
obj.preplacer.push(nearObjects[h].assumeBreak)
obj.sids.push(nearObjects[h].sid)
}
// if (nearObjects[h].active && distance && !(nearObjects[h].assumeBreak&&outplace)) return !1
}
if(obj.preplacer.includes(false)) return !1;
return !(!a && 18 != S && n >= s.mapScale / 2 - s.riverWidth / 2 && n <= s.mapScale / 2 + s.riverWidth /2)
},
this.checkItemLocation4 = function(e, n, I, r, S, a,build) {
for (var h = 0; h < nearObjects.length; ++h) {
var u = nearObjects[h].blocker ? nearObjects[h].blocker : nearObjects[h].getScale(r, nearObjects[h].isItem);
if (nearObjects[h].active && i.getDistance(e, n, nearObjects[h].x, nearObjects[h].y) < I + u&&build.sid!=nearObjects[h].sid) return !1
}
return !(!a && 18 != S && n >= s.mapScale / 2 - s.riverWidth / 2 && n <= s.mapScale / 2 + s.riverWidth /2)
},
this.checkItemLocationBot = function(e, n, I, r, S, a, build) {
for (var h = 0; h < build.length; ++h) {
var u = build[h].blocker ? build[h].blocker : build[h].getScale(r, build[h].isItem);
if (i.getDistance(e, n, build[h].x, build[h].y) < I + u) return !1
}
return !(!a && 18 != S && n >= s.mapScale / 2 - s.riverWidth / 2 && n <= s.mapScale / 2 + s.riverWidth /2)
},
this.addProjectile = function(h, m, w, v, x) {
const D = items.projectiles[x];
let k;
for (let S = 0; S < projectiles.length; ++S)
if (!projectiles[S].active) {
k = projectiles[S];
break
}
k || (k = new Projectile(n,i),
projectiles.push(k)),
k.init(x, h, m, w, D.speed, v, D.scale)
}
,
this.checkCollision = function(h, m, w) {
w = w || 1;
const v = h.x - m.x
, x = h.y - m.y;
let D = h.scale + m.scale;
if (Rs(v) <= D || Rs(x) <= D) {
D = h.scale + (m.getScale ? m.getScale() : m.scale);
let k = pc(v * v + x * x) - D;
if (k <= 0) {
if (m.ignoreCollision)
m.trap && !h.noTrap && m.owner != h && !(m.owner && m.owner.team && m.owner.team == h.team) ? (h.lockMove = !0,
m.hideFromEnemy = !1) : m.boostSpeed ? (h.xVel += w * m.boostSpeed * (m.weightM || 1) * Ot(m.dir),
h.yVel += w * m.boostSpeed * (m.weightM || 1) * Rt(m.dir)) : m.healCol ? h.healCol = m.healCol : m.teleport && (h.x = i.randInt(0, s.mapScale),
h.y = i.randInt(0, s.mapScale));
else {
const S = i.getDirection(h.x, h.y, m.x, m.y);
if (i.getDistance(h.x, h.y, m.x, m.y),
m.isPlayer ? (k = k * -1 / 2,
h.x += k * Ot(S),
h.y += k * Rt(S),
m.x -= k * Ot(S),
m.y -= k * Rt(S)) : (h.x = m.x + D * Ot(S),// D is scales combined
h.y = m.y + D * Rt(S),
h.xVel *= .75,
h.yVel *= .75),
m.dmg && m.owner != h && !(m.owner && m.owner.team && m.owner.team == h.team)) {
h.changeHealth(-m.dmg, m.owner, m);
const O = 1.5 * (m.weightM || 1);
h.xVel += O * Ot(S),
h.yVel += O * Rt(S),
m.pDmg && !(h.skin && h.skin.poisonRes) && (h.dmgOverTime.dmg = m.pDmg,
h.dmgOverTime.time = 5,
h.dmgOverTime.doer = m.owner),
h.colDmg && m.health && (m.changeHealth(-h.colDmg) && this.disableObj(m),
this.hitObj(m, i.getDirection(h.x, h.y, m.x, m.y)))
}
}
return m.zIndex > h.zIndex && (h.zIndex = m.zIndex),
!0
}
}
return !1
},
this.checkCollision2 = function(e, t, n) {
n = n || 1;
var l = e.x2 - t.x,
h = e.y2 - t.y,
u = 35 + (t.realScale ?t.realScale:t.scale);
if (Rs(l) <= u || Rs(h) <= u) {
u = 35 + (t.getScale ? t.getScale() : t.scale);
var f = pc(l * l + h * h) - u;
if (f <= 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 += n * t.boostSpeed * (t
.weightM || 1) * r(t.dir), e.yVel += n * t.boostSpeed * (t
.weightM || 1) * s(t.dir)) : t.healCol ? e.healCol = t.healCol : t
.teleport && (e.x = o.randInt(0, c.mapScale), e.y = o.randInt(0, c.mapScale)) :
(e.lockMove = !0, t.hideFromEnemy = !1);
else {
var d = o.getDirection(e.x, e.y, t.x, t.y);
if (o.getDistance(e.x, e.y, t.x, t.y), t.isPlayer ? (f = -1 * f / 2, e.x += f *
r(d), e.y += f * s(d), t.x -= f * r(d), t.y -= f * s(d)) : (e
.x = t.x + u * r(d), e.y = t.y + u * s(d), 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 * r(d), e.yVel += p * s(d), !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, o.getDirection(e.x, e.y, t.x, t.y)))
}
}*/
return t.zIndex > t.zIndex && (t.zIndex = t.zIndex),!0
}
}
return !1
}
}
function gc(e, t, i, s, n, r, o, l, c) {
this.addProjectile = function(a, u, p, h, m, w, v, x, D) {
const k = r.projectiles[w];
let S;
for (let O = 0; O < t.length; ++O)
if (!t[O].active) {
S = t[O];
break
}
return S || (S = new e(i,s,n,r,o,l,c),
S.sid = t.length,
t.push(S)),
S.init(w, a, u, p, m, k.dmg, h, k.scale, v),
S.ignoreObj = x,
S.layer = D || k.layer,
S.src = k.src,
S
}
}
function yc(e, t, i, s, n, r, o, l, c) {
this.aiTypes = [{
id: 0,
src: "cow_1",
killScore: 150,
health: 500,
weightM: .8,
speed: 95e-5,
turnSpeed: .001,
scale: 72,
drop: ["food", 50]
}, {
id: 1,
src: "pig_1",
killScore: 200,
health: 800,
weightM: .6,
speed: 85e-5,
turnSpeed: .001,
scale: 72,
drop: ["food", 80]
}, {
id: 2,
name: "Bull",
src: "bull_2",
hostile: !0,
dmg: 20,
killScore: 1e3,
health: 1800,
weightM: .5,
speed: 94e-5,
turnSpeed: 74e-5,
scale: 78,
viewRange: 800,
chargePlayer: !0,
drop: ["food", 100]
}, {
id: 3,
name: "Bully",
src: "bull_1",
hostile: !0,
dmg: 20,
killScore: 2e3,
health: 2800,
weightM: .45,
speed: .001,
turnSpeed: 8e-4,
scale: 90,
viewRange: 900,
chargePlayer: !0,
drop: ["food", 400]
}, {
id: 4,
name: "Wolf",
src: "wolf_1",
hostile: !0,
dmg: 8,
killScore: 500,
health: 300,
weightM: .45,
speed: .001,
turnSpeed: .002,
scale: 84,
viewRange: 800,
chargePlayer: !0,
drop: ["food", 200]
}, {
id: 5,
name: "Quack",
src: "chicken_1",
dmg: 8,
killScore: 2e3,
noTrap: !0,
health: 300,
weightM: .2,
speed: .0018,
turnSpeed: .006,
scale: 70,
drop: ["food", 100]
}, {
id: 6,
name: "MOOSTAFA",
nameScale: 50,
src: "enemy",
hostile: !0,
dontRun: !0,
fixedSpawn: !0,
spawnDelay: 6e4,
noTrap: !0,
colDmg: 100,
dmg: 40,
killScore: 8e3,
health: 18e3,
weightM: .4,
speed: 7e-4,
turnSpeed: .01,
scale: 80,
spriteMlt: 1.8,
leapForce: .9,
viewRange: 1e3,
hitRange: 210,
hitDelay: 1e3,
chargePlayer: !0,
drop: ["food", 100]
}, {
id: 7,
name: "Treasure",
hostile: !0,
nameScale: 35,
src: "crate_1",
fixedSpawn: !0,
spawnDelay: 12e4,
colDmg: 200,
killScore: 5e3,
health: 2e4,
weightM: .1,
speed: 0,
turnSpeed: 0,
scale: 70,
spriteMlt: 1
}, {
id: 8,
name: "MOOFIE",
src: "wolf_2",
hostile: !0,
fixedSpawn: !0,
dontRun: !0,
hitScare: 4,
spawnDelay: 3e4,
noTrap: !0,
nameScale: 35,
dmg: 10,
colDmg: 100,
killScore: 3e3,
health: 7e3,
weightM: .45,
speed: .0015,
turnSpeed: .002,
scale: 90,
viewRange: 800,
chargePlayer: !0,
drop: ["food", 1e3]
}, {
id: 9,
name: "💀MOOFIE",
src: "wolf_2",
hostile: !0,
fixedSpawn: !0,
dontRun: !0,
hitScare: 50,
spawnDelay: 6e4,
noTrap: !0,
nameScale: 35,
dmg: 12,
colDmg: 100,
killScore: 3e3,
health: 9e3,
weightM: .45,
speed: .0015,
turnSpeed: .0025,
scale: 94,
viewRange: 1440,
chargePlayer: !0,
drop: ["food", 3e3],
minSpawnRange: .85,
maxSpawnRange: .9
}, {
id: 10,
name: "💀Wolf",
src: "wolf_1",
hostile: !0,
fixedSpawn: !0,
dontRun: !0,
hitScare: 50,
spawnDelay: 3e4,
dmg: 10,
killScore: 700,
health: 500,
weightM: .45,
speed: .00115,
turnSpeed: .0025,
scale: 88,
viewRange: 1440,
chargePlayer: !0,
drop: ["food", 400],
minSpawnRange: .85,
maxSpawnRange: .9
}, {
id: 11,
name: "💀Bully",
src: "bull_1",
hostile: !0,
fixedSpawn: !0,
dontRun: !0,
hitScare: 50,
dmg: 20,
killScore: 5e3,
health: 5e3,
spawnDelay: 1e5,
weightM: .45,
speed: .00115,
turnSpeed: .0025,
scale: 94,
viewRange: 1440,
chargePlayer: !0,
drop: ["food", 800],
minSpawnRange: .85,
maxSpawnRange: .9
}],
this.spawn = function(a, u, p, h) {
if (!this.aiTypes[h])
return console.error("missing ai type", h),
this.spawn(a, u, p, 0);
let m;
for (let w = 0; w < e.length; ++w)
if (!e[w].active) {
m = e[w];
break
}
return m || (m = new t(e.length,n,i,s,o,r,l,c),
e.push(m)),
m.init(a, u, p, h, this.aiTypes[h]),
m
}
}
const ot = Math.PI * 2
, Zi = 0;
function wc(e, t, i, s, n, r, o, l) {
this.sid = e,
this.isAI = !0,
this.nameIndex = n.randInt(0, r.cowNames.length - 1),
this.init = function(p, h, m, w, v) {
this.x = p,
this.y = h,
this.startX = v.fixedSpawn ? p : null,
this.startY = v.fixedSpawn ? h : null,
this.xVel = 0,
this.yVel = 0,
this.zIndex = 0,
this.dir = m,
this.dirPlus = 0,
this.index = w,
this.src = v.src,
v.name && (this.name = v.name),
(this.name || "").startsWith("💀") && (this.isVolcanoAi = !0),
this.weightM = v.weightM,
this.speed = v.speed,
this.killScore = v.killScore,
this.turnSpeed = v.turnSpeed,
this.scale = v.scale,
this.maxHealth = v.health,
this.health2 = 0,
this.leapForce = v.leapForce,
this.health = this.maxHealth,
this.chargePlayer = v.chargePlayer,
this.viewRange = v.viewRange,
this.drop = v.drop,
this.dmg = v.dmg,
this.hostile = v.hostile,
this.dontRun = v.dontRun,
this.hitRange = v.hitRange,
this.hitDelay = v.hitDelay,
this.hitScare = v.hitScare,
this.spriteMlt = v.spriteMlt,
this.nameScale = v.nameScale,
this.colDmg = v.colDmg,
this.noTrap = v.noTrap,
this.spawnDelay = v.spawnDelay,
this.minSpawnRange = v.minSpawnRange,
this.maxSpawnRange = v.maxSpawnRange,
this.hitWait = 0,
this.waitCount = 1e3,
this.moveCount = 0,
this.targetDir = 0,
this.active = !0,
this.alive = !0,
this.runFrom = null,
this.chargeTarget = null,
this.dmgOverTime = {}
}
,
this.getVolcanoAggression = function() {
const p = n.getDistance(this.x, this.y, r.volcanoLocationX, r.volcanoLocationY)
, h = p > r.volcanoAggressionRadius ? 0 : r.volcanoAggressionRadius - p;
return 1 + r.volcanoAggressionPercentage * (1 - h / r.volcanoAggressionRadius)
}
;
let c = 0;
this.update = function(p) {
if (this.active) {
if (this.spawnCounter) {
if (this.spawnCounter -= p * (1 + 0) * this.getVolcanoAggression(),
this.spawnCounter <= 0)
if (this.spawnCounter = 0,
this.minSpawnRange || this.maxSpawnRange) {
const W = r.mapScale * this.minSpawnRange
, F = r.mapScale * this.maxSpawnRange;
this.x = n.randInt(W, F),
this.y = n.randInt(W, F)
} else
this.x = this.startX || n.randInt(0, r.mapScale),
this.y = this.startY || n.randInt(0, r.mapScale);
return
}
c -= p,
c <= 0 && (this.dmgOverTime.dmg && (this.changeHealth(-this.dmgOverTime.dmg, this.dmgOverTime.doer),
this.dmgOverTime.time -= 1,
this.dmgOverTime.time <= 0 && (this.dmgOverTime.dmg = 0)),
c = 1e3);
let k = !1
, S = 1;
if (!this.zIndex && !this.lockMove && this.y >= r.mapScale / 2 - r.riverWidth / 2 && this.y <= r.mapScale / 2 + r.riverWidth / 2 && (S = .33,
this.xVel += r.waterCurrent * p),
this.lockMove)
this.xVel = 0,
this.yVel = 0;
else if (this.waitCount > 0) {
if (this.waitCount -= p,
this.waitCount <= 0)
if (this.chargePlayer) {
let W, F, _;
for (var h = 0; h < i.length; ++h)
i[h].alive && !(i[h].skin && i[h].skin.bullRepel) && (_ = n.getDistance(this.x, this.y, i[h].x, i[h].y),
_ <= this.viewRange && (!W || _ < F) && (F = _,
W = i[h]));
W ? (this.chargeTarget = W,
this.moveCount = n.randInt(8e3, 12e3)) : (this.moveCount = n.randInt(1e3, 2e3),
this.targetDir = n.randFloat(-PI, PI))
} else
this.moveCount = n.randInt(4e3, 1e4),
this.targetDir = n.randFloat(-PI, PI)
} else if (this.moveCount > 0) {
var m = this.speed * S * (1 + r.MAX_SPEED * Zi) * this.getVolcanoAggression();
if (this.runFrom && this.runFrom.active && !(this.runFrom.isPlayer && !this.runFrom.alive) ? (this.targetDir = n.getDirection(this.x, this.y, this.runFrom.x, this.runFrom.y),
m *= 1.42) : this.chargeTarget && this.chargeTarget.alive && (this.targetDir = n.getDirection(this.chargeTarget.x, this.chargeTarget.y, this.x, this.y),
m *= 1.75,
k = !0),
this.hitWait && (m *= .3),
this.dir != this.targetDir) {
this.dir %= ot;
const W = (this.dir - this.targetDir + ot) % ot
, F = min(abs(W - ot), W, this.turnSpeed * p)
, _ = W - PI >= 0 ? 1 : -1;
this.dir += _ * F + ot
}
this.dir %= ot,
this.xVel += m * p * cos(this.dir),
this.yVel += m * p * sin(this.dir),
this.moveCount -= p,
this.moveCount <= 0 && (this.runFrom = null,
this.chargeTarget = null,
this.waitCount = this.hostile ? 1500 : n.randInt(1500, 6e3))
}
this.zIndex = 0,
this.lockMove = !1;
var w;
const O = n.getDistance(0, 0, this.xVel * p, this.yVel * p)
, U = min(4, max(1, round(O / 40)))
, L = 1 / U;
for (var h = 0; h < U; ++h) {
this.xVel && (this.x += this.xVel * p * L),
this.yVel && (this.y += this.yVel * p * L),
w = t.getGridArrays(this.x, this.y, this.scale);
for (var v = 0; v < w.length; ++v)
for (let F = 0; F < w[v].length; ++F)
w[v][F].active && t.checkCollision(this, w[v][F], L)
}
let q = !1;
if (this.hitWait > 0 && (this.hitWait -= p,
this.hitWait <= 0)) {
q = !0,
this.hitWait = 0,
this.leapForce && !n.randInt(0, 2) && (this.xVel += this.leapForce * cos(this.dir),
this.yVel += this.leapForce * sin(this.dir));
var w = t.getGridArrays(this.x, this.y, this.hitRange), x, D;
for (let F = 0; F < w.length; ++F)
for (var v = 0; v < w[F].length; ++v)
x = w[F][v],
x.health && (D = n.getDistance(this.x, this.y, x.x, x.y),
D < x.scale + this.hitRange && (x.changeHealth(-this.dmg * 5) && t.disableObj(x),
t.hitObj(x, n.getDirection(this.x, this.y, x.x, x.y))));
for (var v = 0; v < i.length; ++v)
i[v].canSee(this) && l.send(i[v].id, "J", this.sid)
}
if (k || q) {
var x, D;
let _;
for (var h = 0; h < i.length; ++h)
x = i[h],
x && x.alive && (D = n.getDistance(this.x, this.y, x.x, x.y),
this.hitRange ? !this.hitWait && D <= this.hitRange + x.scale && (q ? (_ = n.getDirection(x.x, x.y, this.x, this.y),
x.changeHealth(-this.dmg * (1 + r.MAX_ATTACK * Zi) * this.getVolcanoAggression()),
x.xVel += .6 * cos(_),
x.yVel += .6 * sin(_),
this.runFrom = null,
this.chargeTarget = null,
this.waitCount = 3e3,
this.hitWait = n.randInt(0, 2) ? 0 : 600) : this.hitWait = this.hitDelay) : D <= this.scale + x.scale && (_ = n.getDirection(x.x, x.y, this.x, this.y),
x.changeHealth(-this.dmg * (1 + r.MAX_ATTACK * Zi) * this.getVolcanoAggression()),
x.xVel += .55 * cos(_),
x.yVel += .55 * sin(_)))
}
this.xVel && (this.xVel *= pow(r.playerDecel, p)),
this.yVel && (this.yVel *= pow(r.playerDecel, p));
const P = this.scale;
this.x - P < 0 ? (this.x = P,
this.xVel = 0) : this.x + P > r.mapScale && (this.x = r.mapScale - P,
this.xVel = 0),
this.y - P < 0 ? (this.y = P,
this.yVel = 0) : this.y + P > r.mapScale && (this.y = r.mapScale - P,
this.yVel = 0),
this.isVolcanoAi && (this.chargeTarget && (n.getDistance(this.chargeTarget.x, this.chargeTarget.y, r.volcanoLocationX, r.volcanoLocationY) || 0) > r.volcanoAggressionRadius && (this.chargeTarget = null),
this.xVel && (this.x < r.volcanoLocationX - r.volcanoAggressionRadius ? (this.x = r.volcanoLocationX - r.volcanoAggressionRadius,
this.xVel = 0) : this.x > r.volcanoLocationX + r.volcanoAggressionRadius && (this.x = r.volcanoLocationX + r.volcanoAggressionRadius,
this.xVel = 0)),
this.yVel && (this.y < r.volcanoLocationY - r.volcanoAggressionRadius ? (this.y = r.volcanoLocationY - r.volcanoAggressionRadius,
this.yVel = 0) : this.y > r.volcanoLocationY + r.volcanoAggressionRadius && (this.y = r.volcanoLocationY + r.volcanoAggressionRadius,
this.yVel = 0)))
}
}
,
this.canSee = function(p) {
if (!p || p.skin && p.skin.invisTimer && p.noMovTimer >= p.skin.invisTimer)
return !1;
const h = abs(p.x - this.x) - p.scale
, m = abs(p.y - this.y) - p.scale;
return h <= r.maxScreenWidth / 2 * 1.3 && m <= r.maxScreenHeight / 2 * 1.3
}
;
let a = 0
, u = 0;
this.animate = function(p) {
this.animTime > 0 && (this.animTime -= p,
this.animTime <= 0 ? (this.animTime = 0,
this.dirPlus = 0,
a = 0,
u = 0) : u == 0 ? (a += p / (this.animSpeed * r.hitReturnRatio),
this.dirPlus = n.lerp(0, this.targetAngle, min(1, a)),
a >= 1 && (a = 1,
u = 1)) : (a -= p / (this.animSpeed * (1 - r.hitReturnRatio)),
this.dirPlus = n.lerp(0, this.targetAngle, max(0, a))))
}
,
this.startAnim = function() {
this.animTime = this.animSpeed = 600,
this.targetAngle = PI * .8,
a = 0,
u = 0
}
,
this.changeHealth = function(p, h, m) {
if (this.active && (this.health += p,
m && (this.hitScare && !n.randInt(0, this.hitScare) ? (this.runFrom = m,
this.waitCount = 0,
this.moveCount = 2e3) : this.hostile && this.chargePlayer && m.isPlayer ? (this.chargeTarget = m,
this.waitCount = 0,
this.moveCount = 8e3) : this.dontRun || (this.runFrom = m,
this.waitCount = 0,
this.moveCount = 2e3)),
p < 0 && this.hitRange && n.randInt(0, 1) && (this.hitWait = 500),
h && h.canSee(this) && p < 0 && l.send(h.id, "8", round(this.x), round(this.y), round(-p), 1),
this.health <= 0)) {
if (this.spawnDelay)
this.spawnCounter = this.spawnDelay,
this.x = -1e6,
this.y = -1e6;
else if (this.minSpawnRange || this.maxSpawnRange) {
const w = r.mapScale * this.minSpawnRange
, v = r.mapScale * this.maxSpawnRange;
this.x = n.randInt(w, v),
this.y = n.randInt(w, v)
} else
this.x = this.startX || n.randInt(0, r.mapScale),
this.y = this.startY || n.randInt(0, r.mapScale);
if (this.health = this.maxHealth,
this.runFrom = null,
h && (o(h, this.killScore),
this.drop))
for (let w = 0; w < this.drop.length; )
h.addResource(r.resourceTypes.indexOf(this.drop[w]), this.drop[w + 1]),
w += 2
}
}
}
function kc(e) {
this.sid = e,
this.init = function(t, i, s, n, r, o, l, bot, spectate, fake, restricter, preplace) {
o = o || {},
this.sentTo = {},
this.gridLocations = [],
this.active = !0,
this.doUpdate = o.doUpdate,
this.x = t,
this.y = i,
this.dir = s,
this.xWiggle = 0,
this.yWiggle = 0,
this.scale = n,
this.type = r,
this.id = o.id,
this.owner = l,
this.name = o.name ? o.name : this.type === 0 ? "Tree" : this.type === 1 && this.y>=12000 ? "Cactus" : this.type === 1 ? "Bush" : this.type === 2 ? "Stone" : this.type === 3 ? "Gold Stone" : null,
this.isItem = this.id != null,
this.group = o.group,
this.health = this.maxHealth = o.health;
this.health2 = 0,
this.buildingID = o.buildingID,
this.setType = o.setType,
this.layer = 2,
this.group != null ? this.layer = this.group.layer : this.type == 0 ? this.layer = 3 : this.type == 2 ? this.layer = 0 : this.type == 4 && (this.layer = -1),
this.colDiv = o.colDiv || 1,
this.blocker = o.blocker,
this.ignoreCollision = o.ignoreCollision,
this.dontGather = o.dontGather,
this.hideFromEnemy = o.hideFromEnemy,
this.friction = o.friction,
this.projDmg = o.projDmg,
this.dmg = o.dmg,
this.pDmg = o.pDmg,
this.pps = o.pps,
this.zIndex = o.zIndex || 0,
this.turnSpeed = o.turnSpeed,
this.req = o.req,
this.trap = o.trap,
this.healCol = o.healCol,
this.teleport = o.teleport,
this.boostSpeed = o.boostSpeed,
this.projectile = o.projectile,
this.opacity = o.name == "pit trap" ? 1 : 1,
this.opacity2 = 1,
this.fadingOut = false,
this.dmgpot = 0,
this.assumeBreak = false,
this.ignoreWiggleDirs = [],
this.wiggleDirs = [],
this.shootRange = o.shootRange,
this.shootRate = o.shootRate,
this.shootCount = this.shootRate,
this.spawnPoint = o.spawnPoint,
this.tick = tick,
this.preplace = preplace,
this.fake = fake,
this.bot = bot,
this.elevation = typeof this.type === "number" && this.owner === null || this.name == "turret" || this?.group?.name === "mill" ? 2 : 1,
this.restricter = restricter,
this.realScale = this.type <= 1 && this.type !== null ? this.scale * .6 : this.scale
this.pathScale =
this.type===1&&this.y<=12000 ?this.scale*.6+15
: this.type===0 ? this.scale*.7+10
: this.dmg && !clan(this?.owner?.sid)||this.teleport || this.boostSpeed ? this.scale+47
: this.type===1&&this.y>=12000 ? this.scale*.55+47
: this.name == 'pit trap' && !clan(this?.owner?.sid) ? this.scale+38
: this.ignoreCollision ? 0
: this.scale+10
}
,
this.changeHealth = function(t, i) {
return this.health += t,
this.health <= 0
}
,
this.getScale = function(t, i) {
return t = t || 1,
this.scale * (this.isItem || this.type == 2 || this.type == 3 || this.type == 4 ? 1 : .6 * t) * (i ? 1 : this.colDiv)
}
,
this.visibleToPlayer = function(t) {
return !this.hideFromEnemy || this.owner && (this.owner == t || this.owner.team && t.team == this.owner.team)
}
,
this.update = function(t) {
this.active && (this.xWiggle && (this.xWiggle *= pow(.99, t)),
this.yWiggle && (this.yWiggle *= pow(.99, t)),
(millRotate.checked && this?.group?.name == "mill" || this?.group?.name != "mill") && this.turnSpeed && (this.dir += this.turnSpeed * t))
}
}
const j = [{
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,
sandboxLimit: 299,
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,
sandboxLimit: 299,
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,
sandboxLimit: 299,
layer: -1
}]
, vc = [{
indx: 0,
layer: 0,
src: "arrow_1",
dmg: 25,
speed: 1.6,
scale: 103,
range: 1e3
}, {
indx: 1,
layer: 1,
dmg: 25,
speed: 1.5,
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
}]
, xc = [{
id: 0,
type: 0,
name: "tool hammer",
uF:[],
desc: "tool for gathering all resources",
age: 1,
src: "hammer_1",
length: 140,
width: 140,
xOff: -3,
yOff: 18,
dmg: 25,
spdMult: 1,
range: 65,
gather: 1,
speed: 300
}, {
id: 1,
type: 0,
age: 2,
uF: [0],
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,
uF:[1,0,15,12,13,null],
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,
uF: [0,4],
name: "short dd",
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,
uF: [3,0,15,12,13,null,9],
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,
uF:[0],
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,
uF:[0],
name: "bat",
desc: "fast long range melee weapon",
src: "bat_1",
iPad: 1.3,
length: 110,
width: 180,
xOff: -8,
yOff: 53,
dmg: 20,
spdMult: 1,
knock: .7,
range: 110,
gather: 1,
speed: 300
}, {
id: 7,
type: 0,
age: 2,
uF: [0],
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,
uF: [0],
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,
uF: [null],
name: "hunting bow",
desc: "bow used for ranged combat and hunting",
src: "bow_1",
req: ["wood", 4,'ez',0],
length: 120,
width: 120,
xOff: -6,
dmg: 25,
yOff: 0,
projSpd: 1.6,
projectile: 0,
spdMult: .75,
speed: 600
}, {
id: 10,
type: 1,
age: 6,
uF: [null],
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,
uF: [null],
name: "wooden shield",
desc: "blocks projectiles and reduces melee damage",
src: "shield_1",
length: 120,
dmg:0,
width: 120,
shield: .2,
xOff: 6,
yOff: 0,
spdMult: .7,
speed: 1
}, {
id: 12,
type: 1,
age: 8,
pre: 9,
uF:[9,null,4],
name: "crossbow",
desc: "deals more damage and has greater range",
src: "crossbow_1",
req: ["wood", 5,'ez',0],
aboveHand: !0,
armS: .75,
length: 120,
width: 120,
xOff: -4,
yOff: 0,
dmg:35,
projSpd: 2.5,
projectile: 2,
spdMult: .7,
speed: 700
}, {
id: 13,
type: 1,
age: 9,
uF:[12,9,null,4,2],
pre: 12,
name: "repeater crossbow",
desc: "high firerate crossbow with reduced damage",
src: "crossbow_2",
req: ["wood", 10,'ez',0],
aboveHand: !0,
armS: .75,
length: 120,
width: 120,
xOff: -4,
dmg: 30,
yOff: 0,
projSpd: 2,
projectile: 3,
spdMult: .7,
speed: 230
}, {
id: 14,
type: 1,
age: 6,
uF: [null],
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,
uF: [12,9,null,4,2],
pre: 12,
name: "musket",
desc: "slow firerate but high damage and range",
src: "musket_1",
req: ["stone", 10,'ez',0],
aboveHand: !0,
dmg:50,
rec: .35,
armS: .6,
hndS: .3,
hndD: 1.6,
length: 205,
width: 205,
xOff: 25,
yOff: 0,
projectile: 5,
projSpd: 3.6,
hideProjectile: !0,
spdMult: .6,
speed: 1500
}]
, dt = [{
group: j[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: j[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: j[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) : !1
},
scale: 27,
holdOffset: 15
}, {
age:1,
group: j[1],
name: "wood wall",
desc: "provides protection for your village",
req: ["wood", 10,'ez',0],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAA4JJREFUeF7tmr1v00AYxh9baWmLxEcpbakYECyIBRALQojZcYfWlZBgQEKCjQkQ/wUwMdIBCQnE4jDkXDoihFgqYEEsSAwISCnlQ9C0SWQjJzE40fnzfHFKX29R7uz3/fl5nzvfnQK6mgQU4tAiQCDaSiAQBKLTFEgRpAhSBHegpNLol9KYnp47WK/buxcXS0t5zmlyVYSuGxsABtsAKoyZk3nByAWErhtOWMKMmT2Pq+cPjILgAeo1jJ6BCAIwMtQSx9o6P5ReAZEOQteNOwCu8EpBO12Dqrb+sW1g4ZlnF11jvIJ75bJ5UaZ/SAOh60YJwAwveP1MLTQn9pQPxHGcJ5ZV0mQAkQJC1+d+Ac72NBD+ekQADADfGDNHs4aRKYgwI4xSQVBiQepw2zvO+pBlWe4QLHxlAkIGgO7MwoBkYahCIDTNOKuqeMR7HSeONDAxZgu/Kf8NKisqlt4U+N8KinOhXC7dT/vAVCA0beaqqqq3eQ89dayOXTtC50sd3faObmv+/rIaX+Hffyp4/mqAm7Pj2Dcs6/HNpEBSgQgqhaQ+cGB/p5++//A7UfxB5ZKmVDIBIQqgO3tRILmASAJhsKBianI41lv/+LmKWiO+x/jV0bcghocKmBhreUHSq7Kygep6I7Jb34Po9oHIjAIaRJVL34LICkBc/yAQbVIEgkB0Fg0pghRBiuAOsFQaVBpUGlQaLoGgqTZ5BHkEecTm8ggv2qy+QjftZ7j/tY0MFzC+J93CzPLXDaxV/4OFGT+QwQEVUxMxl+oqVdTqm2ipzk00ybql2z6qXKLKoNskulezc1mz9AclCkQUgBdLL0FcA3CLZ98nj9YxulPuBs/qDwUvXvM3eABcZ8zkbj6FrZem2tfwbqhpxjlVxQPeA44fbmDfePwaj7Oo+2lZxcu3/C0/28b5hQXzYZz78NoIgfBuuOU3gbvJygAiexfcyyETRXCAuJuYIzwJxjXUEABrjJncQyhpy8LtJwVEc0jVDQagmAZGCASLMVMXSTiorzQQ//xj9i6gXOIFEPcwGeDMM1a6LAOA1NLgqiDgkOmWOV6YxFD9bdNMikQUI700kqhDZGYoAkGqWcYJrFg0aoqC5hTRcVC3LJN/wDLOzQTb5KIIf8zF4uwh97dlld4J5iLUPXcQQtFn2JlAtGESCALRWVekCFIEKYI71lBpUGl0CuMPpubCUvT4yHcAAAAASUVORK5CYII=",
projDmg: !0,
uF: [],
health: 380,
scale: 50,
indx: .5,
holdOffset: 20,
placeOffset: -5
}, {
age: 3,
group: j[1],
name: "stone wall",
desc: "provides improved protection for your village",
req: ["stone", 25,'ez',0],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAA2RJREFUeF7tmj9v00AYxp9YIopIOkArlXapBGozZa/6CZzr0LoSEgxISLAxAeJbABMjDEhIIBaHIee2HyDqwtSpiRi6pIrUiiEJCqlkI4dYONH5vy9O6Zstynvn9/35eZ9z7pwDfUYEcsThLwECMVYCgSAQk6ZAiiBFkCKECyW1xry0xvb23t3LS/PW4WHte5bPNJkqgjHtN4D8GECHc/1OVjAyAcGYZvkVzLk+87xmfsEgCA6gWcOYGQgvAIVCYVT7YDAQimRWQKSDYEx7B+CZqMrNzU0oijL6yTRNHB0diZe2HD7W6/pjmf4hDQRjWg3Ajij5ra0t35oajYbwd8uyDgyjpsoAIgUEY3s9wCrGgeCM8YIB4Cfn+u20YaQKws8Ig1TgVZgPEFjWoGAYhr0EJ/6kAkIGgOnK/ICkYaiJQKiqdl9R8FV0O8rlMhYXFxPfKfcEFxcXODk58TBU61G9XvsU94KxQKjqznNFUd6KLlqpVLCwsBA6n+Xl5VFsp9MJPabb7eL4+NjDUM1XhvHtdejJxoGxQHi1QlQfWF9fn8i31WpFyt+rXeK0SiogkgKYrj4pkExARIGQz+extrYW6q6fnp5iOByGirWD3OqYWxDFYhGrq6uhi3IHtttt9Pv9wLFzD2LaBwIr8ggIape5BZEWgLD+QSDGpAgEgZhsGlIEKYIUIVxgqTWoNag1qDVsAl6P2uQR5BHkEVfLI5xs0/oXemX/hrtvW6lUwsrKSqytiLOzM/R6vcCxc2uWosz/6606u+Ao+5Z2fFC7BLXBNOTp3exM9izdSSUFkhSAk8ssQbwA8EYk/6wPeAC85FwXHj75GU2scw1nQlXVHigKPosusLGxgaWlpUCTixJwfn6OZrMpHGKaeLi/r3+JMp87NhEIZ6Jrfwg8TV8GENmn4E4NqShCAMQ+kbkpkmlYQ/UB8ItzXfgSSty2sMdJAWFPzJjGAVTjwPCBYHCusyQFe42VBuKff+y+B3JPRAmEfZkMsD5wXnsqA4DU1hAlfO1fL4xiqO7YOA9FSRQjvTWiqCPJk2ESCFLNMkxi1ao2zOVww461LFwahu68oB5meKoxmSjCXUG1unvP/m4YtR+pVhZxssxBRMxXWjiBGKMlEARisstIEaQIUoRw5aHWoNaYFMYfhr/EUpJ56XkAAAAASUVORK5CYII=",
health: 900,
uF: [],
scale: 50,
holdOffset: 20,
indx: .5,
placeOffset: -5
}, {
age: 7,
group: j[1],
name: "castle wall",
// pre: 1,
desc: "provides powerful protection for your village",
req: ["stone", 35,'ez',0],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAA6pJREFUeF7tmkFrU0EQxzdRIpik0Ai1pSdFQcGLF8/pNe3BQr+P9fsI9dDm2py9eBEUFD2V1oIpNEnBoE1Z0wfvTfbNzuzOvg24PTabzczv/f+zs/u2ptLfPwK1xGFOIIG4VUICkUAUi0JSRFJEUoRxoUzWWBZr9Hqv9+v1u4PDw3eDmD1NVEX0eruzfPL9/kG0eCr/Ya0ApWpvsKdfq6nB0dHBVpUKqQQEJfmypOv1O1tV2CYoCAqAtY1NNR5dqqvxCBVAaCBBQEDvmzJ88fLVwr8no0v149sXqyNC1BIxEJTk9dNfW9+0JqoHnJ+dqPPTE3SsZC3xBrGzs9e9vv57jEXMAQDn+f71cyW28QaBKcEkf5IcSgZhUHzt4gVie3v3eDZT3Xzc0smXgfv08cPCRz4wvEBANVQFISMAYSwFCFcIq52OajTuqZ9np06uycOIAsJHDVnypszHk5GajMZkKFKqcLZGHsT9Vls9fvrcGnyj0VCrnQfWcXoAVSFRQcAlE7MFJ/kyQjYoRRizt/3++30S7dwgJ0VwbPFwfYMbk3E8BkNCFWwQUA2YLaQgZGTKYCx2oXxVsEHEUIMNhP7cVxVeIGyts7QiLoa/1HQ6NVoHqoK7lLJAwE4SK5LSEPiq4NmDBYJqi2a7pVrNtkiRhJNMp7/VxXBonNvHHs4gHj15pprtFWNAodTAVQXHHmQQVDXoYJcFhI6FCoMEIuaSaZIcZg/XpZQEAp49YqsFto+QLBplPQU8s6CedZJA6ASSNXKPMQ8jxtJpK5bw8JdaH/S8ZEVwVBHSHtg2vcLls/iWKoYqqJsv7gk3SxFQFVjRlNh+w+KKQai0xebYI0Q/QVUDp3/IYDsoomgPTBXSjZX0kplXHBsERxWS9sB2nj5F0lkRcxD0oilhEQwCPIugNlCw/jgpgqMK+INUu9iSz+aFnSSnd/C2hg8I/V1sm47tI0wtuoQt2A0VDITaaWJ7DK0QbvL5+aK/4PFVhcQGTEoNoorIEnN99ccFAyFwO0mxYplNVHYtgPr2iwPA9AY8+75rkfRaPvPBUy6K+ECh3JxxXTJFVg34JE13JeAY2/F/fjwFgB7vqwQxRZikTblPVXb4i8lfygammJ0bKoq3qbZptVesF8eU4r2noMQXxBrYD1OAlH8/LICg1sCgUGpJ6KdfuTVs8vyvL6VDOHPb/Om6XO6wgeZ8HrRYcgKJPTaBuH0CCUQCUTRjUkRSRFKEcYFK1kjWKArjBu9WC2HgRkavAAAAAElFTkSuQmCC",
health: 1500,
uF: [],
scale: 52,
holdOffset: 20,
indx: .5,
placeOffset: -5
}, {
age: 1,
group: j[2],
name: "spikes",
desc: "damages enemies when they touch them",
req: ["wood", 20, "stone", 5],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAABBdJREFUeF7tms1uEzEQx70JLZWQQgFxQCKiHLhFcATlgNpr+iFa8QC8Sds34QFQi/qRaysOERxBuXFAKEgcEFAiIRVKssibWvXOju3xrrMf4JX2knjt8W//Mx6PN2D+iggEnsOEgAdxrgQPwoOIBwWvCK+IkihibW1jC1ux9vZ20N+nvboV5hqdzpMtxoLN+ATD7W73pQfB2H8JYj3E5N7t7hai0kIG7XRwCAJMETByB4HHBqiN/F2kABBxNbTb7YhCr9eL0chbFbmCgC7RarVYo9GIAAwGg+iWrzxh5AZieXn9KAzZopgoB8BByBdURZ6rSC4gVlaeLo7HoyN50sIlYHQoykVyAQFdgqthOBySk8U8XGTqIKBLkGcvNfwnQJhyBiqYacOYmiJo+QJj169OEsxvP8ymBAE7PjzcXaLCs2lnHp3YGxYQsUfv3Rkxfuuuryc19ubdJW0bDiUI6tsHBy+OiSbq+8vSCfWt8zEe3v/DbsyPrYajABEd1mr1pSxQrBVhM3lhZOfxbysAsHH31azV82nUogWxurrxbDQaLyTrBnS7skIQI9nCkC3kagmC8cL+/s5zleVGRZiifrPZZPzmF0yGXEFQwRBJGc9J+v2+9u2YVh0jCN47hIFlhdwQOUnSxYS5y3V26+Ycavj34Rk7GeKuBGOG/BJEZ2n3LEQQybIahEFVw93bV0h+9eHTT7QddBGTHdT9CgkEtwjLEGUjZBAqNVAhCAIYjPcf64zf4lLZwP+3yTvIIDAXEdKEboHFhvnGLLvWmCGpQTT6/OWUnf5K5hyyKoQNaV1CjGUFAoPBt9IwUGEgbNWgUwV0D8wGU3CEbyQFCKwMH+82bxBwUmmSK2sQE1WoYfC9w6MHZwkXcKmI129nlHsTm7ggG5kKBOYiotOiQdi6ROoYIVNUJVtFuUZaCNEKYxXGQWPVjrMIEGnighPXEJ1g8QIDocsmVS9DlWUm9x3Zz0EyKeICRvysQlVzsA2YWEKFbc2zuISTGKGLF6oNFxUGNcV2ASFzjBAgsFih23TpskxVNsnHwtSQNTY4VYRN0MwSnLGaRCVARPlGxuqUAKcqzFQGhAsYuupUqUFgJ1muirfJvrMvnc6CJcwleI0Abs2FxClAYM1BPCsOjuNFoJKD4MZjNQIYLKkHPOraaAVA8EmrlGGzeujLcRUBISac/PbBjAL7hoI/VVrXgPVMXR3RPP1kC/nLGggibf0BjuJkrwFBcH+GnwHhAC5kTf18AJblSg3C9NZ1az/PUsNwtCl/ZqTrr4Ig7IMa5YS9EiBcGWlSiYsdqJMYAUt2rtJezCUwlZQMhL30TbHE9L+AUhoQJoOr8L8T16jCRE02ehDnhDwIDyLuLF4RXhFeEegC4l3Du4Z3DdQ1/gLN32VhHtKeXAAAAABJRU5ErkJggg==",
health: 400,
uF: [],
dmg: 20,
scale: 49,
id: 6,
spritePadding: -23,
holdOffset: 8,
indx: .5,
placeOffset: -5
}, {
age: 5,
group: j[2],
name: "greater spikes",
uF: [],
desc: "damages enemies when they touch them",
req: ["wood", 30, "stone", 10],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAABB9JREFUeF7tm89rE0EUx2cT20aEpCoFBYN48Bb0qPQg7TX9gS3+Af4ntv+Jf4C00h+5VjwEPVZy8yASQaGoTUBMrUnkbTJxdjK/Z5xJzSzkkt2dmfeZ75v39s1uguKREkgihwGBCGKohAgigsguClERURETooi1tc2nrIi1v7/zPEQkC+Ya1erjLYSSZ1mj+9u12sutqQIBxlarG33S6FptN9jEBOuYhoCBhIIRBMTq6pOlXq97xHaBMO4RBARPDSFV4R0EDaFcLqf2N5vNjEB8u0hwEIuLiymAer0+PSBWVjaO+n20hC2uVCqoWCyOAISE4U0R9AIJAAAEeTQaDdRut0d/5XL55YODF6985BXeQLDWhlarlRqOVVEqlYKtFV5AyKKEbMZ9LJxKIEDW/X53lA6Tfi4zIsT5JEEjdzo83F1WGYMSCFY6rNK4yjXXSoMs+1tLeSgqzY6uUVWTVu+2EofR3b3dTX+i4+tpDr19d0nLYNbFOoutNxAqAGhj3hzPWClFVQ3QrxYIlovghAgbQecCIP2H98+tZpcFRNavDgRDENk6AqTIOE2m8wAXEDBBGgbZL4Rg6BsfOi6B79FWhEgVtBqqj35ZKYG+ufZ6NvOXy/TcCQiYHZwc4ZHK1HBjoYAuz+Uzhn1vn6PTNh/e+495BD98QL+QhJFqgHO6bmHkGngQsgjCU0NhLo9uLhSEShEBoVVBN2TiFpYgWDXHwbAe3PuNrs/3xoydL86iq8UZJXf5fNJBnbPxMEurItuYeVHHyDVkquCp4c6tK0oQ8EUfPv1gXs9ThYlLWC2Wf0GwVcECoaMG3P7Psy76ctIZg8EGYa4GK9cQqYIFQlcNIlWwQNiowRGIrCp40cIlCDqnMF0gSalZrRHQEF1wCQECITu3cKSI7CYNNDp1rsHetmODYCVQshDCyycmbrHkJVVTFT55aoBZ5j1yq2SVWCU8NYhrFeZrhdFiKd6yG5jCU4VKPsHLKqFdWYptGkaNQNAuAWV5eOgid6tkhRgWEF4ChVVCh02ofruqfDsBwXsc/q8fw2m3IHerQBGkKmSP4rKoQZ5nqQFvENH9muQV2oqg3UJWMnMBY+JKdbIahGiGTYCIH7nletJZOJUVoRIp5EPj1yrIe20B4Lb+CQgbNciUAucvzAYPbOljgy7Sll+S5LdVdtSVXUNF9rxrbNWkI3HTcXoBkWaa1KuEuPIN5/CrAa6SIxMY3kDEF0WI6RHlIPRuFWztq27pmyiAvsebInDHPBgh359yUqHSnY34eqHARWiYPqJEcNcYRBD+LpmLirSuSoO4Bm+tMEmLTQzm3eN9sSQHEj9TGNLIuoh5vdGFMoIqAgxYX99Mv9jZ29sJ8uUOhhgchIvZdNFGBDGkGEFEEFmHioqIioiKYAaZP321OmHR4N2KAAAAAElFTkSuQmCC",
health: 500,
dmg: 35,
scale: 52,
id: 7,
spritePadding: -23,
indx: .5,
holdOffset: 8,
placeOffset: -5
}, {
age: 9,
group: j[2],
// pre:1,
uF: [],
name: "poison spikes",
desc: "poisons enemies when they touch them",
req: ["wood", 35, "stone", 15],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAABEJJREFUeF7tm01rE0EYx2ezpkkUklopKLWIoLeiR8WDtNf0BVv8AH4T22/iB5BW+pJrxYPoUelNQUSLQrE2AU1iTVZmN7Pdmc77TmcSOwu9dF9m5jf/53n+O7MJgD9iAoHnkBDwIAZK8CA8CDwpeEV4RQyJIhYXV57QKtbW1vozF5XMWWjU649WAQie4oOO1hqNF6vnCgQcbL2+HGUH3WhsOJsYZw2TEBAQVzCcgFhYeDzb7/d26SHgJjycgGCpwaUqrIMgIUxMF+PxH345xgRiO0Scg7j14GIM4OPr3+cHxPz88m4UgVk04qmZEqhUwxSASxjWFEEmyEq1AKZmypgK9vc6oN3qp/8rFMK57e3nL234CmsgaLmh3ezFA4dQ4FGphc5yhRUQoiohmnEbiVMKBJR1FPVSO5yNc9EgXJwPApCG087OxpxMH6RA0OywzMNlrpmoJS77sCndFZnHptfIqkmp9bwSh727faMX//GOH0cF8Pb9BaUB0y5WSbbWQMgAIAfz5l0xl1Jk1QDbVQJBCxFkiNAgSC8ApX//Lu4aVaeaBkTUrgoETRD4OgK0yMgmkz7ABAQEjYSRbbfd6oH9vW4u/6GsCJ4qSDXUH/5RnXzu9Y1XY9h5k/bcCAg4O8gcoZ6K1HB1sgwqpRN7De/72ToGRy02vA+fQwD/0jami6BSK2BqgOdUw0IrNFAnRBWEpYZyKQTXJnFrTcqAB4RUBXmvSqXI3quliCQ8aGuOyaPv3fkLroyfvDOgBserY+ByNXntFh3fDjqg0z1dZklV4M/RX9TRBkHLFalaGLnh5vVLovFj5z99/UW9nqUKnZBADeQEQVcFLSxU1IA61+72wPeDzikYdBD6asiVI3i5ggZCVQ3o+TRV0EDkUYMhEISvYBgokyBIT6GbII0kS/QQcsGFVTbPEgQA+cLCkCLwTZo4iVKSpUkQQxcarBJKA0EzUKISwvITQ5csWaaKZaZUVTES5ZNnqFiv3DKuEqmEpQb+WoV+rtDyEfwtu2QoLFXI+AmWq4TPFVls3TKqBYIMCbg/0W72sRVo0UIMDQjLQCGVkGUTrn6bWvk2AoL1Ovxfv4aTYZHdrYL7l9k9TNGruKhqZM/T1IA2iMh2dXyFsiLIsBAtmZmAMXRLdaI1CN4M6wDhv3KL9aSSOKUVIVMpxF1jr1Vk780LAD3rTEDkUYNIKfD8yGzwwC19NKBR2vILgnBNZkddOjRkZM+6Jq+aVCSu208rIGKnSXxKiFa+4Tn0aYApc6QDwxoI/6FIZnp4HoTcrYJb+7Jb+joKIO+xpgjUMAuGy++njKxQqc6G/7yQEyIkTBtVwnloJBWEvUtmYkVaVaVOQoOVK3Rssc6AWfdYT5bZjvifKQxo4CGiv95oQhlOFQEHsLS0Ev9iZ3Nz3ckvdxBE5yBMzKaJZ3gQA4oehAeBB5RXhFeEVwS1yPwDNX06YQXmnr8AAAAASUVORK5CYII=",
health: 600,
dmg: 30,
pDmg: 5,
id: 8,
scale: 52,
spritePadding: -23,
holdOffset: 8,
indx: .5,
placeOffset: -5
}, {
age: 9,
group: j[2],
// pre:2,
name: "spinning spikes",
desc: "damages enemies when they touch them",
req: ["wood", 30, "stone", 20],
health: 500,
uF: [],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAABB9JREFUeF7tm89rE0EUx2cT20aEpCoFBYN48Bb0qPQg7TX9gS3+Af4ntv+Jf4C00h+5VjwEPVZy8yASQaGoTUBMrUnkbTJxdjK/Z5xJzSzkkt2dmfeZ75v39s1uguKREkgihwGBCGKohAgigsguClERURETooi1tc2nrIi1v7/zPEQkC+Ya1erjLYSSZ1mj+9u12sutqQIBxlarG33S6FptN9jEBOuYhoCBhIIRBMTq6pOlXq97xHaBMO4RBARPDSFV4R0EDaFcLqf2N5vNjEB8u0hwEIuLiymAer0+PSBWVjaO+n20hC2uVCqoWCyOAISE4U0R9AIJAAAEeTQaDdRut0d/5XL55YODF6985BXeQLDWhlarlRqOVVEqlYKtFV5AyKKEbMZ9LJxKIEDW/X53lA6Tfi4zIsT5JEEjdzo83F1WGYMSCFY6rNK4yjXXSoMs+1tLeSgqzY6uUVWTVu+2EofR3b3dTX+i4+tpDr19d0nLYNbFOoutNxAqAGhj3hzPWClFVQ3QrxYIlovghAgbQecCIP2H98+tZpcFRNavDgRDENk6AqTIOE2m8wAXEDBBGgbZL4Rg6BsfOi6B79FWhEgVtBqqj35ZKYG+ufZ6NvOXy/TcCQiYHZwc4ZHK1HBjoYAuz+Uzhn1vn6PTNh/e+495BD98QL+QhJFqgHO6bmHkGngQsgjCU0NhLo9uLhSEShEBoVVBN2TiFpYgWDXHwbAe3PuNrs/3xoydL86iq8UZJXf5fNJBnbPxMEurItuYeVHHyDVkquCp4c6tK0oQ8EUfPv1gXs9ThYlLWC2Wf0GwVcECoaMG3P7Psy76ctIZg8EGYa4GK9cQqYIFQlcNIlWwQNiowRGIrCp40cIlCDqnMF0gSalZrRHQEF1wCQECITu3cKSI7CYNNDp1rsHetmODYCVQshDCyycmbrHkJVVTFT55aoBZ5j1yq2SVWCU8NYhrFeZrhdFiKd6yG5jCU4VKPsHLKqFdWYptGkaNQNAuAWV5eOgid6tkhRgWEF4ChVVCh02ofruqfDsBwXsc/q8fw2m3IHerQBGkKmSP4rKoQZ5nqQFvENH9muQV2oqg3UJWMnMBY+JKdbIahGiGTYCIH7nletJZOJUVoRIp5EPj1yrIe20B4Lb+CQgbNciUAucvzAYPbOljgy7Sll+S5LdVdtSVXUNF9rxrbNWkI3HTcXoBkWaa1KuEuPIN5/CrAa6SIxMY3kDEF0WI6RHlIPRuFWztq27pmyiAvsebInDHPBgh359yUqHSnY34eqHARWiYPqJEcNcYRBD+LpmLirSuSoO4Bm+tMEmLTQzm3eN9sSQHEj9TGNLIuoh5vdGFMoIqAgxYX99Mv9jZ29sJ8uUOhhgchIvZdNFGBDGkGEFEEFmHioqIioiKYAaZP321OmHR4N2KAAAAAElFTkSuQmCC",
dmg: 45,
turnSpeed: .0015,
scale: 52,
id: 9,
spritePadding: -23,
holdOffset: 8,
indx: .5,
placeOffset: -5
}, {
group: j[3],
name: "windmill",
desc: "generates gold over time",
req: ["wood", 50, "stone", 10],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAudJREFUeF7tm79v00AUx5+TwFaxgVQGJsaO7YgSicktUYuYUP+D/hFN/oj+B4gJkSgkniolYmzHjEwMIMGG2CCJq3Ps5OzcD5/vXRw5z1Imn+/H577v3r13Fw/oiQh4xGFJgEDESiAQBCK9KJAiSBElKaLdftsp4qEGg8+FvjNta2um4fsXoWnnWPkg6G2lj1tphA2IQMQy4EE8OVDz//N3LZ5KK4KBuHzTEFrKhy8zIBAAQCBifRAIApFeKkgRVVeEaP9g4jUSvbh2o043VLJNVBEQDEitVm8Nh58mRXaoum+cgPD98w6Ady1rvCiIZX1hNwj66PEHOojT04txGEJTNQN2IAA8DyajUa+lm2WT96ggREp4+WIO7Bd8fbzqlwkI/9U/+Pa9Hv3SD64y0ECcnb1rLhbzMd9ZNojVYmcBQlQHdmSKBiK7MPIQok4LQNxN5/Dz1zLAOnzmwclRfWOLraoHEwYKiCyExBx4dfAgTGw3C0JkJhiu1QmIbOezirABIarLOQiWXpvNQqkbNBlQ2WUbDa+rSvspFeEShEg1NsrRgd5JEDIIMu+gG2Se92ggdOk1WWf4bBMro4Mgg2HbPioIWXpNNSM3H/+vXueFIIJx9f5RnolPleFD+lJBsH3C/XSBAuL4qBbtM0yenQHRv53Bj9/rjLSNIp4/9eD8tTjhK4NDIGIyOwOCTIPTaiUXS5OFKilbOfdZBILsG92iWTRAU/URzX1iglBtrFxAYO3tLAhssLr6rEDoKk/e65IyNsFUnpDeeRheFMTeJmYim8/ciNnLVF0eE7HJYssiUswDH5RU3RrE5sHO3qXzExh0wMOtrHTkx8EQHfgkr01OunjPheEmZZ4QdY0QNULXAjJUstcL6VYdAJiYhktz4OfKuWmI9hgEIqZCIAhEOhYhRXCKUEW2e3MXO294H+Ux6P8aS1yVA0F/ZTKxgxLLbm1DVeIYczVNIGJMBIJApC2GFEGKSCviAbuwhmEKe216AAAAAElFTkSuQmCC",
health: 400,
stop: true,
pps: 1,
uF: [],
turnSpeed: .0016,
spritePadding: 25,
iconLineMult: 12,
indx: 2,
scale: 45,
holdOffset: 20,
placeOffset: 5
}, {
age: 5,
pre: 1,
group: j[3],
name: "faster windmill",
uF: [],
stop: true,
desc: "generates more gold over time",
req: ["wood", 60, "stone", 20],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAudJREFUeF7tm79v00AUx5+TwFaxgVQGJsaO7YgSicktUYuYUP+D/hFN/oj+B4gJkSgkniolYmzHjEwMIMGG2CCJq3Ps5OzcD5/vXRw5z1Imn+/H577v3r13Fw/oiQh4xGFJgEDESiAQBCK9KJAiSBElKaLdftsp4qEGg8+FvjNta2um4fsXoWnnWPkg6G2lj1tphA2IQMQy4EE8OVDz//N3LZ5KK4KBuHzTEFrKhy8zIBAAQCBifRAIApFeKkgRVVeEaP9g4jUSvbh2o043VLJNVBEQDEitVm8Nh58mRXaoum+cgPD98w6Ady1rvCiIZX1hNwj66PEHOojT04txGEJTNQN2IAA8DyajUa+lm2WT96ggREp4+WIO7Bd8fbzqlwkI/9U/+Pa9Hv3SD64y0ECcnb1rLhbzMd9ZNojVYmcBQlQHdmSKBiK7MPIQok4LQNxN5/Dz1zLAOnzmwclRfWOLraoHEwYKiCyExBx4dfAgTGw3C0JkJhiu1QmIbOezirABIarLOQiWXpvNQqkbNBlQ2WUbDa+rSvspFeEShEg1NsrRgd5JEDIIMu+gG2Se92ggdOk1WWf4bBMro4Mgg2HbPioIWXpNNSM3H/+vXueFIIJx9f5RnolPleFD+lJBsH3C/XSBAuL4qBbtM0yenQHRv53Bj9/rjLSNIp4/9eD8tTjhK4NDIGIyOwOCTIPTaiUXS5OFKilbOfdZBILsG92iWTRAU/URzX1iglBtrFxAYO3tLAhssLr6rEDoKk/e65IyNsFUnpDeeRheFMTeJmYim8/ciNnLVF0eE7HJYssiUswDH5RU3RrE5sHO3qXzExh0wMOtrHTkx8EQHfgkr01OunjPheEmZZ4QdY0QNULXAjJUstcL6VYdAJiYhktz4OfKuWmI9hgEIqZCIAhEOhYhRXCKUEW2e3MXO294H+Ux6P8aS1yVA0F/ZTKxgxLLbm1DVeIYczVNIGJMBIJApC2GFEGKSCviAbuwhmEKe216AAAAAElFTkSuQmCC",
health: 500,
pps: 1.5,
turnSpeed: .0025,
spritePadding: 25,
iconLineMult: 12,
index: 2,
scale: 47,
holdOffset: 20,
placeOffset: 5
}, {
age: 8,
group: j[3],
name: "power mill",
uF: [],
stop: true,
// pre: 1,
desc: "generates more gold over time",
req: ["wood", 100, "stone", 50],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAudJREFUeF7tm79v00AUx5+TwFaxgVQGJsaO7YgSicktUYuYUP+D/hFN/oj+B4gJkSgkniolYmzHjEwMIMGG2CCJq3Ps5OzcD5/vXRw5z1Imn+/H577v3r13Fw/oiQh4xGFJgEDESiAQBCK9KJAiSBElKaLdftsp4qEGg8+FvjNta2um4fsXoWnnWPkg6G2lj1tphA2IQMQy4EE8OVDz//N3LZ5KK4KBuHzTEFrKhy8zIBAAQCBifRAIApFeKkgRVVeEaP9g4jUSvbh2o043VLJNVBEQDEitVm8Nh58mRXaoum+cgPD98w6Ady1rvCiIZX1hNwj66PEHOojT04txGEJTNQN2IAA8DyajUa+lm2WT96ggREp4+WIO7Bd8fbzqlwkI/9U/+Pa9Hv3SD64y0ECcnb1rLhbzMd9ZNojVYmcBQlQHdmSKBiK7MPIQok4LQNxN5/Dz1zLAOnzmwclRfWOLraoHEwYKiCyExBx4dfAgTGw3C0JkJhiu1QmIbOezirABIarLOQiWXpvNQqkbNBlQ2WUbDa+rSvspFeEShEg1NsrRgd5JEDIIMu+gG2Se92ggdOk1WWf4bBMro4Mgg2HbPioIWXpNNSM3H/+vXueFIIJx9f5RnolPleFD+lJBsH3C/XSBAuL4qBbtM0yenQHRv53Bj9/rjLSNIp4/9eD8tTjhK4NDIGIyOwOCTIPTaiUXS5OFKilbOfdZBILsG92iWTRAU/URzX1iglBtrFxAYO3tLAhssLr6rEDoKk/e65IyNsFUnpDeeRheFMTeJmYim8/ciNnLVF0eE7HJYssiUswDH5RU3RrE5sHO3qXzExh0wMOtrHTkx8EQHfgkr01OunjPheEmZZ4QdY0QNULXAjJUstcL6VYdAJiYhktz4OfKuWmI9hgEIqZCIAhEOhYhRXCKUEW2e3MXO294H+Ux6P8aS1yVA0F/ZTKxgxLLbm1DVeIYczVNIGJMBIJApC2GFEGKSCviAbuwhmEKe216AAAAAElFTkSuQmCC",
health: 800,
pps: 2,
turnSpeed: .005,
spritePadding: 25,
iconLineMult: 12,
indx: 2,
scale: 47,
holdOffset: 20,
placeOffset: 5
}, {
age: 5,
group: j[4],
type: 2,
uF: [],
name: "mine",
desc: "allows you to mine stone",
req: ["wood", 20, "stone", 100],
iconLineMult: 12,
url:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAABypJREFUeF7tml1MU2cYx/98FwoojK8WRapeiMigbBoj02r8QA5zybLIYozbjVmW7XK7dRfb4tV2uZtlu8FEM8yyZMpBJToZSjRurWYi3iDIoOXDSAIUyvfyf9dD2nIOAXpK2+S8N1zQc/o+v/6fj/d5nwQYSxBIMDj8T8AA4VeCAcIAERwUDEUYijAUoZooDdcwXCO2XCMRQIq/npkBsBCtAi9arkEAZsD0VnW1/UJ2drbt7t2284DvEQBvNIBEA4QJMFkBHJCkukuBCpDllo+BxfvA9ACAaQCLG6WQjQSRBCATSKuRJKl5JQNlWX4XmL4PYBzA/EbA2AgQKYD5DWCuSpKkltUa5fV6+9va2j4Bkl2AdyTSQCIJgnHABKRX2u2VFy0Wy2E1CNPT01hcXITJZFJlNDjo+cPpdH4GzPQBmIqUu0QKRCqQXgjM75Wk+l+1VJCXl4eioiLx78HBQbx69UpTMLLc/D6Q9BcwNQyAGUbXpTeIpWxQVVX5jdVqfUdtt1TA9u3bkZ+fj6Qkhg5gfn4ew8PD6OnpQUKC+ra8Xm9fW9ufHwG+vwFM6pld9AKRCGTlALMVdnvl1xaL9aAagIWFBezevRvZ2dkCQKjBBEQgY2NjePbsGRITyXX58gM5B6R0AuOjegAJFwSfTwNMFput9IuysrLP1TY+MzODbdu2CQWYzWbNX1x5lkAmJycxNDSEgYGBJdWEvrurq+uHnp7e7wDfYLjpNhwQzAa5wFylJEk3tRx206ZN2LJlCzIzM8UvrCX70OcVdXi9XnR1dYFq0lAHs8t5IPkx4H0NYHY9wWO9INKA1Pckqb5J60spfwLgXzWJ09DZ2VlMTU0JOMwaKSkpqqDm5uZAIH19fRgfZ2mhvmS5+UNg5ncAvrXCWA+IBCAzT5KOM3ovW9z0rl27kJOTg+Tk5CDDaDx/WQJgHOjt7cXZs2fFO65cuYLS0lKhnNTU1GXw+CzfPTo6KhRCaGpLllsLgQnWHWuqStcJIsMiSbUsg4NWbm4uiouLRRwIVIECgDUDMwMD4smTJ1UNaWxshNVqRUFBwRKQQHciSKqDseP1a3pC8JLlm8XApCdqIMrLy5GVlbUEQDGem+aGVzJeS8YrQSEQuklnZ2fQ41EHYbfbkZ6eLjal+PTIyAgqKipErAhnuVwuoSQWYFSbUnswvvB/gStmQFAJBFBTUxOO7ZrPdnR0CCB0l5gHweh+7NixiIBobW0VNUnMg6D1PDccPKhaXIYNp729fel8EtOKoKVMcfv27QvbaLUXPHz4EMxOXDEPYmJiQpTT4QbJUBD9/f0i/rDWiAsQrBeY52tra3VVxY0bNwTctLS0+ADB9Pn06VOcPn1aVxBXr17Fnj17RMUaF4pg8dTd3Y36+npdQVy/fh07d+6MjzqClrPqc7vdOHLkiK4g7ty5I0p4pXyP+WDJoopl9f79+3UF8eDBA5ExlLNHzIOg9TwH8OCkZ+ZwOp0iY8QVCP5aDJrV1dW6qIIQGCSV80xcBEtukgGTpfaJEyd0AcHSeuvWrUFtu7hwDaUDxSZsuGn01q1bIkiGdrDiAgRlQBgsrlgR1tXVrUsZLS0tonOl1vWOSRC8p+DxWG3DTKcsu1lbNDQ0rApIU1MTduzYsdT0DXxIaezyQujFixdB74t6P4K70WrVKerw+Xyio3TmzJkVYVy+fFlUkGzohna9Y6xVl5kvSceH1KxhY7asrEyzeUs5M4ieOnVKFca1a9dEUMzIyFjW+FWat8+fP18qs0NfIsutBcAE7w4j3rzld5v87fxftH5a9i9LSkqC+piKMmiQx+PB0aNHgx6/ffu26DWEBkV+nq7FWMPut9aS5eYGfzufsxVrWuvpYitfoFzwVDkcjp/MZrNqY1K54FF6jYrU6efsW1AdPLKzPti8efOy5i8BrHTBw83IslwLJD+JxgWPAkO58iuy2Uq/1LryY03B9FdYWBgkefo7/8fFIKucIQiJ3W/2Hl6+fCna+mrLf+X3PeBj+z6sCZtwFBG4N+USuNzhOHTJbDaXqG1cr0tgj8fd7nI9+QpI+SdWLoFD7eX1dQaHxByOQ41aQPiL22w2cRYJHAugApgOte5H3W73vcePn1zwjwXoOnSmlyJCgXBQpACYf1uS6n/TilprHBT5AEh6BEwxW8X8oEigzYScDqS/WV1debGoyKLanGBtQQUo7bdQaB6P567L5foUmP7Xf7kbkVnMSCki0B5lmMzucDh+1MouaqqRZbnOf90f18NkobZxRigLSDuwivHCev944USkp+kC09+aCo8wP6ykWw6c1khSXWPg+2S55RyADsDnXs+MQzh72wjXUNufMnS29/Bhx89jY2PdTqfr20hkg9XCiRYIZX8EwmqJ5wKO/EQkEK4GRrRBrGaPG/IZA4QfswHCABHscYYiDEUYilDNQoZrGK5huIaqa/wH4HLecO4SZnEAAAAASUVORK5CYII=",
scale: 65,
indx: .5,
holdOffset: 20,
placeOffset: 0
}, {
age: 5,
group: j[11],
type: 0,
uF: [],
name: "sapling",
desc: "allows you to farm wood",
req: ["wood", 150],
url:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAACIdJREFUeF7tm/tTlNcZx7/v7rIXFlBQQFgQUINCYomYiumEoiZaONDOrDNtxhr1lzbJ9Mf+If2lM51O219i0smkTtyZBs6SpiYSTb3ULAlaryRCXITlKruwN/bSOXt7L7wL++4F0ul7ZhyX9ZzzPs/nPM9znud5kYM6YgQ4lUOcgAoiYQkqCBWEOCioFqFahGoRshel6hqqa3y/XIMDDN0AwkDgEwDRzUrwNtk1THWEdD9hylM6uBPwxT5vxthEECYLId1OodKUDtYBvon/JxB6QqwBOYUptRkABDcaxmZYhL6xsfn3ra3Pvymn7NTU1CWH4xrZaBgbDYID9K8T0vv+WidO6cApIPjBRgbPjQTBAUUvEdJ3UwihqnUGkUgUs/erRGwo7T8ErNzaKBgbCMLYQEjPmNQSjp7VxL767HxklZFQam8C/KvWFCJ+5AKC5QDNgKYCgBaIGuMCRpOf2d7sjwnQaAnpOS9VoPMUB4NJG/s66Avj8/dXpxGU2s8CEUbJB4D9HQU4P8CF4/uxzywPicwDgYfZWlAuILSEWEPZns4haxhl5eyC4Id7IYCbtjiYbAalNl0civKRC4iMAp+cSK3HvKhtLJOV9umYG3c/LVasCaUDbwDBvypemFiQCwgARW2E9H2l5OGWtjnsa68Cx8k/OhqN4r5jGhNfb1OyLSgdaAOCI4oWCSbnCALlhFjnhQ9vObIMnZ43b62OA9OZAxf7vnSrIfZzcoRD8SCp1cWDJhvRKOB5FkAoGEY0UX6EVvj4wb6/d9ks0plSG4tVC5sFYlWGeOycFhptZnzZ6T8YmcX8lBcvn9iZ1kqkyjF40luGUpsewMpmgeAIsYruvR/9IorikqJ15WGn/uDrGbzS0xCbe9U+jr1t2zOC4V1awb/+JoZNqY2ZVNbVa2ZHt6ZahrcIIX9MTtl/wo/qupJ1QUyOe7D/cLVo3u3rLtQ0lK671uVcwu1/JG7rWOVqfwvw/2ndhWtMyAOIohcJ6RtOPmPr7kkc/HF9Kg4w85947MbinA+RxHmt+EM48XqzrFgff/AQeiO7BQENx2HLNiMsTWUiS3F87sT86I7Uekr7DwIrjk0GUbqdkNdmUsGP8+L4uVJoNHHGkXAUVXXiwKZU4GnncirusHT8k3c80Eb5K5bSf1YCnlml+wrn58EisCpgCjNGFgtuXPoOfWf2ZSXnR+fv4/BrLJDGl8tloPko3fMCwmLZ9WFbW1tfUtP2viAqqvgT+270Gdo7a7MC4bjyFDv3bE2tnXd54RhgF0R8OJ1PHCMjt17OtWzPFQSrN94mhPxBqOXBnwZRXsmDWHYH0bCXV0YJkfEHz2Au4xVfmPHiy4/4n9lelNK3gQALlpt1axj2EEIeCRWrfn4GLxzaIQpuOYF4uAhzKX8ds+B75+YUXP+pFPGklD4HBEaVQM5TjOAbr6lAqZvH8TcqU4Ey6dO1u9a/EtdS4Om3HugTVWosALOA+d4MtCGWTPKD0sF6wCfqg2YKJlvXKCLEuqqvKE2mWKC8P+xCZ29TpvLIzrvS/xj72qtFqblcUhV3k+wyzGxAaAHDm9K4IC2rGYSxB/P44dG6nCAkF//7Myca91aIYLB65MZFcdmeiBd/UVqOZwHC2EVIz2VpXNjfUSNSWJpC50rji8FxNP+gUgSC7Xn7xqRMvLAfAfxDSp6pEMTquKCrHEdnT5OoehQKwO79b+7NobO3UYlcqblXBsawq2VbqpMl3YQVYFfsjxGaidcsyaE0XigBUUyIdVlOG82WKXScqI4VW3JtBmYdzKeH+r/B2d+2ZwTk/O8c6OrdheJSffo9PUFcp25EvfJXM6U2doezFt+6QwkIPaDvJaT3YrpdI5wPHT/ToazCKFtFTj3x4IVD4kIr3V53brqwo371bcNuDPe8H9f63SiKpG/eUDpwEggOZJpoKQHBZOYAcxUQOikNlkKF0lmIbzmE+j3yLTopkCejbpjM8eKLjZhVrWMBbB6l9DeA7iKwPK0kwVIKQijvFkB/nJDeC+lOldP7cex0Scq02WlWWcQF2PDVSYTDEbzUZRFtMz2xnMpHGITLF+YQXtqS1sQpHfg5EGRv1BfX9QOZCbmAyMhC2HuLZBuOKeRyxt3j1tAELA1lKDLEr7+VYBgTY+4YENfEErQavnUn15Hig2J2FiBlkSuIdS2k42Q41qdMDqYUp+FE2adwE2Y1rGIQtvs8iwHc+FCaL+RmAYUEkbAQ42lCet5NPmjPKx40NpdnY62pNWMPFzB6lQ+clNrPAH7Wus+6yCo0CACG3YQQvvgxLuDVU+l7kaFEF1sn6GILhWRF1qcXnIgu8QkbpfbdgP/bnOhKFufTNZJblxBi9Qifc+SMBroi3ufZvzEA086l1MuclqPeWK9TOo/FjqH3xAdPqY2Zx9L3HYTmwIHDl2pqao4kBU32J1iw9HtDeHR7BtN3xWV0cm7N/jk0tVTAZI4nZwuzPnz5d74Mn5ycvDw8fP3VxHvQvLEohEUw9+gmhNiTUtYfXEDDc+V4dGcWrjvbMxLe8uI8mvZVgMUHp4OPMZTSHiAwmNEmCiYVCERxDSE/eapAjrRTl32LMJv4/IHSj2sB72Q+9hbuUSAQMBJizSjHj7fidXpCuq9lohylNhMA9qsAeR2FArHqDZhQ6rifj5wGvC5B30ADmGoPHGh7VxhfpNrm+kYrHb1CgQBg/BUhPX+WABgaHv7qHOBn7bR0v8egBUw1XV2dX5jN5p3C9ZTafw34WdMl76OAIPQthPTeZRJTOvBLIEgBuBUkQUy2EsBoJaTnncQ+rUDwXt4pFPi/MpkAQxcQYL6vBIBUTwakDDB0AIGrALz/ayAKIW/B9iygaxRM5oJsrIJIYFVBqCDEHqZahGoRqkXI3jqqa6iuobqG6hprpaT/Bagy/2FMRPJUAAAAAElFTkSuQmCC",
iconLineMult: 12,
colDiv: .5,
scale: 110,
indx: .5,
holdOffset: 50,
placeOffset: -15
}, {
age: 4,
group: j[5],
name: "pit trap",
uF: [],
desc: "pit that traps enemies if they walk over it",
req: ["wood", 30, "stone", 30],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAA4hJREFUeF7tms1r1EAYxp8EldL6WT+qV70UFapUQUR7zqaHNgVBD4KgN08q/hfqyaMeBEHxkvWwk9pjFRF00YKKF8+yftSvttRmSWR3szUbJp+T2Wztu7dlZybz/vK8z8y+Mwro0ySgEIcWAQLhKYFAEIhOUyBFkCJIEdyFklKjV1JjfHxqv207O2ZmytUi9zSFKkLXjT8ANnkAaoyZe4uCUQgIXTfcqIAZM7s+r64/MA5CG1C3YXQNRBiA/r6WOJaW+VPpFhDpIHTduA3gMi8VtFMrUNXWL44DTD9r20VgjVdwr1IxL8j0D2kgdN0oA5jgTV4fW4mMic3ygbiu+8SyypoMIFJA6PrUAuAOZIGw6hEhMAB8Z8wczBtGriCijDBOBWGBhamj0d51l/ssy2oswcKfXEDIABCMLApIHoYqBELTjDOqike81zF6sI6hXY7wm/IPUPuqovp+A/+/guKer1TK97M+MBMITZu4oqrqLd5DTx6xsX1r5H6po9vch1ZgI8P1xDH8+KXg+ZuN3Pau61y3rMc3Eg/mNcwEIiwV0vpAUO6i/VeNNsPONBcQeQXQDkR0vCyeIQwizaQXlhTMvuJLOijlsWM2NvcnTzG/unoWxJd5FS/f8k0uLpePH65j92C86fY8iKhlLw6C//c45fUsiLwABGGFASEQHikCQSA6k4YUQYogRXBXXUoNSg1KDUqNBgHaWXo6IBAEotMS1pwiVstm4ecTaf6Fh3oD7zk9W5ipfVNRfZetMDN6qI6hnf9BYcb/2n8vKnhaTVaqOz1qY8vAGirVRS1pYdqPK9rEVaOC4wbHKyQ10pTT4gIQBVBEOf8qgJu8N35ixMbgtuSSznLAM/9TwYu50BS7xpjJPXyKcudM5fz2gJpmnFVVPOA94OhwHfv2xJtcmqXj02cVr72TsWA/x8G56WnzYZrx/G2FQLQHWveHwEH6MoDIPgVvx5CLIjhAFgH082Sa1BAjACwxZnIvoWRNi0Y/KSCaS6puMAClLDAiIFiMmbpIwGF9pYH45x+TdwDlIm8CSS+TAe5dxsqXZACQmhpcFYRcMl031wvTGKq/bZbdoYhipKdGGnWI7AxFIEg1yyQTK5WMFUVBc4vourAty+RfsEwymGCbQhThn3OpNHmg8d2yyh8FYxHqXjgIodnn2JlAeDAJBIHozCtSBCmCFMFdayg1KDU6hfEXXvzCUuiEamMAAAAASUVORK5CYII=",
trap: !0,
ignoreCollision: !0,
hideFromEnemy: !0,
health: 500,
colDiv: .2,
scale: 50,
indx: 0,
holdOffset: 20,
placeOffset: -5
}, {
age: 4,
group: j[6],
name: "boost pad",
uF: [],
desc: "provides boost when stepped on",
req: ["stone", 20, "wood", 5],
url:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAZ5JREFUeF7tmktOAkEQhhvQI3AGiSzcsTLxDCYeqA9k4hlIWLFzIeIZOIL4CNhDMmMDXVPz6NKPJel59DffX12TnoHjtycwgMMPAUAEEwABiHJRwAiMwIjoQkk0iAbR0EfDez+01Il67z9T71dUI3Yglsvnj9ST9zluNrsZAcI5B4igYacgribTPu3/de239cvhP0BghHMYESwABCDK9RIjMAIjov0L0fgL0RiPv9xmI3r3O9rNmjbi4f59P7HHp0t1u24WRAGhIKCFYRLELhJ3t9uSBfPFhSomJkFUbWjCCnMgYjb8SxDHbNDCMGXEKRsKEKvXoVutR+JVxAyIFAgaK8yAOBeJqgLS5RQQllpsqQ11IpK9EZLaUI2HpHBmD6KuDVIrsgahhSCBkS0ITSTqRCRbENeTZveLzzVZ2YIQt4bKAwBhqY9QPuykwzECI9jXYF/jVLGgRlAjMqkRSWtaT4M6/YaqpzkmXRYQAVPrIJIeRyaDWvvyNpP5tXIbzezHt3Jr3Z4UEIE3IABRjh5GYARGRJcjokE0iEY0Gt/OdwVhhTbZ6QAAAABJRU5ErkJggg==",
ignoreCollision: !0,
boostSpeed: 1.5,
health: 150,
colDiv: .7,
scale: 45,
indx: 0,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: j[7],
doUpdate: !0,
uF: [],
name: "turret",
desc: "defensive structure that shoots at enemies",
req: ["wood", 200, "stone", 150],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAABBlJREFUeF7tmj1vE0EQhufsJBUyiBRUCRUSEhYUFKBIoKTMJUUs8X+S/BokBHKK+FImQiiCggIUlIIKuaIIAosqxD40ttfeG8/e3u7NWRHsSZYL3349+847++EIwjMkEAUOIwIBxFgJAUQAkTWFoIigiKAINlFWFhqbmzvtKKq/lE7PSfLmlXSdlabPEYhoR7LTaZoeHB0dtCTrVHVVrIgAAoIixlqjINbW1rwUfXp6Oin3T4TGfwsijlvnAHBfTacEiCiCd51O+5mXtCyFKjHLOG6ltF0JEKrOJGmL91u8Qg4CDkASRBTBSafT3pBUhhiION7ZA4h2TZ2TBDFtI91PkoM9CSAiIDgIS4sAl3+mXZQAQesc1S4DQwhE1hPu3e1D73cE3y9qExISIO4sD6BxI4Wv3+oZEUh4RmkQW1ut4zSFdb1n8fNL+PhlgQXR7XYBP6an0WjA6uoq4Dc++joCQTx+cAXJ26WZ4mVhlAJBjRGVgB98KAiJOFYgsC5UhaQyvEFsb79YHwz6x2qAt2+m8PTR1BSqBoHtvv+0CD9+6UPw9wtvEFQNGA76YwOxsrIC+NGfXq8HZ2dnRvHoipisKUiY+IaIFwiqhicPr2D51iAzgNnZGv1c1DR1b1AVcyBoiNRq9Y3Dw9cnrqHoBcKmBuwENTROAbbOojpQJdSIaTnalo8qnEFQNWCnaFjQjmEGaDabtnGzv3NZxtaejyqcQdB0yYUFBVE0HEykaJhQELMZxN00nUHYwuLiZw0+fF6YjKksBFWRDkNP01KmKQ6CmmQVIIqEo6tPlAJB1w7UJNEX1ArRyyC0QtQraHjQCZgrCJtEpdTAhYfNJwKIMbUAIoDIbsLmqgibWfqsJk2mSvch18osi6QxKcPU1xG2CRhmL8cD3lLpkwNBV3lVgCiymp0DiOwhrS2Fuuw4fZfYdDXrc8rtrAifTVcZryiyA6V7m7lsuobhQC5wqHFx23CfHWiRnSfXlmtYYB3OisBCVBVceHAddAkT7mCG8wYaFj5q8AZRVBXcAavyAW4fknfCXRS2jxpKgsiaJpfSsAE6Yz6bLy70sB660fJVQykQnCpMs2YKkyJQTBCuzXG+GgR36WvqvFIIDiJ7DJ9FkgeUg+qTLukkeJklrSTvoqfIrLu8I60E1bYQiNmbcJNnuAyavstfEbifT3J9EAEx8gv+bwFcynOFYc4+MhBKmyU3IO5SWL3nAiUv9Q59wnFTZYMvpgi9IdO/ZvR3MHTo7Rim2jwTVeWlIVSiCNVZbk9imxX773KhUEnWyBuABJAyCyU73NEblYQG1zgCSdP+Lv1Tibmj6X6ttnDic6FbdPD6e3MD4dO5eZYJIMa0A4gAIht4QRFBEUERbDIKoRFCI4RGCI28lWrwiDGdv3AZkWGMex2dAAAAAElFTkSuQmCC",
health: 800,
stop: true,
projectile: 1,
shootRange: 700,
shootRate: 2200,
scale: 43,
index: 2,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: j[8],
name: "platform",
uF: [],
desc: "platform to shoot over walls and cross over water",
req: ["wood", 20],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAVtJREFUeF7tmkEOwVAURV9jQJiIHZiYGhoa64gFSOzAWsQGxAbMiKHYhYlVSEyU/PqhX59qI5o2jmH9tq/Hve/d1PeET0jAg8OdACCsEgABCLcpoAgUgSLUQYk1sAbWwBpJKTpzj/D90bUMsXy9XmV6tkyLDQBAWBkAQgEx6NdUl2z3ZwmC51fv1m12Z+f8NOtaTU963ap63+j1crWGKbzTrsSKmi9PDojppKEWPlucnONp1hkQ42E9dr3D8SKAEBFAWG0AAhBum0ARKAJFMD6NBsgR1gmAAIRINIqjCBSBIh5BAWtYFIAAhBufUQSKQBEf320SqAhUBCoC1WujYHwyPhmfjE9DgP8+rQ4AAQi2BYQaYH+Ekg9K3yy1efd3W4fUoV+Qg7nuoSrIM6tlAMJi+TmIIqvgm9oy77z95mZFPhcQ9tcBBCBco6IIFIEi1OGFNbAG1sAaScn2BpFWBnB82lh8AAAAAElFTkSuQmCC",
ignoreCollision: !0,
zIndex: 1,
health: 300,
scale: 43,
indx: 0,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: j[9],
name: "healing pad",
uF: [],
desc: "standing on it will slowly heal you",
req: ["wood", 30, "food", 10],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAVJJREFUeF7tmkEKwjAQRVM9gOAlFFy460k8UA7kSbrrQtBLCB5AEXUQgqGdjjZp8LmUpkle3p8ETeX4PAlUcHgRAISYAAhAhEUBIzACI6IbJdEgGkTj+2h472clnUS99zfteAfViAeIpmmv2pfnfK6ut3NAOOcAIRomBbFab3La/9H36Xh4fwcIjHAOI8QCQJQKYnc5dxbZ/WJpKsLFGQEIWWdAACKMPEZgBEZEt0Gi8U/R6Ftt00kp0ih26JrUgQoQSu0x4lcE5D1EAxChUhiBEYUZoamJfVssP8x0aK8BPKkDlWbAGKE8dBENotG/I2giR43gf43QE4wo1QhN3i3PFGeEZZKaNoAgGoUXS43mlmeyRcMy2FRtkt6hSjUpSz+AEGqjg7CsTq42o928zTWhFP0OuoudYkC5+gCEkAcEIMIQYgRGYER0YyIaRINoRKNxB85lEmEa+oa0AAAAAElFTkSuQmCC",
ignoreCollision: !0,
healCol: 15,
health: 400,
colDiv: .7,
scale: 45,
indx: 0,
holdOffset: 20,
placeOffset: -5
}, {
age: 9,
group: j[10],
name: "spawn pad",
uF: [],
desc: "you will spawn here when you die but it will dissapear",
req: ["wood", 100, "stone", 100],
health: 400,
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAiNJREFUeF7tmrtOwzAUhk9hQAqCpYEFtYKplRjYupR3YOZFmDPzIsy8A126MSC1E6gVC6QLiEgMIBRwqtQ9ceziJLb0d0wcX7585/jStAi/XwItcPgjABDCBIAAiNWkACNgBIxgJ0qEBkIDofH/0IiiaMunlWgURd+6/TXKESmI8fj+S7fyJssNBmfbAEFEACE0rBVEr3/apP1rbU8nD8trAAEjiGCEsAAgfAMRxy+0iF+1Emyne0xBsKtVNivkhRHz2SMlSWI0sCAIqNM90X7GeRD5DmqPKldQd5p2FkQRgP3ekPb6Q5ZJfHdDn4s5e68MiDcgVADkkXNAvATB2XB0cWUUGc+312vlVTCcM4JLjKYQMgIyDFUCdQpEknzQfPa0fJM77Q6F55dGJsiF3ycjepuOlpfb4QGF4aHbew05JDY1QR6lbAYXIk4Zke+MDRsyILIVXoGwZQOXLwBCUAEIgCDKJ0wYASM8NsJkb1G24pL3Hl6FRjo4W1Oodwsq+RTKhhWyDUWnV06tLFMLsOnKBTq24QoYJnsPeW+RVuvlwUza8aKjOhUQDkDG1lsQ3DF72TTJ3S8DwLXj7H+fOM7PvWL59EplR9EplOoZ56bPTfS38QxACIoAARCrAQUjmjbCRoKrqo5a1xFVDcJGvQAhKFYOwsbbqquOyr68rWsATbRj9C12Ex2sq02AEKQBAiBWgw5GwAgYwU5ECA2EBkKDDY0fJZh+YTa6MyMAAAAASUVORK5CYII=",
ignoreCollision: !0,
spawnPoint: !0,
scale: 45,
indx: 0,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: j[12],
name: "blocker",
uF: [],
desc: "blocks building in radius",
req: ["wood", 30, "stone", 25],
ignoreCollision: !0,
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAA05JREFUeF7tms9L3EAUxyeuXWqsFdrVg6BUKFjopWdPevCyelDw/1H/H8EedC89uKeevQgtCBYFD+1WUGsqq2tk4k47yc7vecmu5i2IsHnZ5H3y/b6ZN5mA4CchECCHRwIIoqsEBIEg0kUBFYGKQEUIB0q0BloDrYHWUM2iC60RKyvrC3Hc2YhjsqC8qYA0g6Cytbu73SyqBSgERL2+uklIsOGSVBCQ5t7ezqLLuTbn5AbCJ3l5AvFWo/F50yZB09hcQNTra7HuBt7WJkgYjiZ/UXSdhNP/v1u/dKeSRmMH/L7Bf1AFYe7DR22SfMD3b4fSeGgYYCBkVrBNXpa5GAqcVUBA5A2BwckTBhCIdE0Iw5BMz8xa2cA0+PTkmERRlAqHsIk3iGxNgLKCDkxWHb4wvEBkIaiUMN65I7PtNjkYCXU5Jsc//Y3IcbVKLirDwnhoZTiDENUFmRoohKU/l0lCR9WXWhgUwvv2TRL/5dVrKYzemuFePD1ApOuCDML89RWZurvtearb42+ET3r94rzn+7PhF+Tr6JgwHsoiICBsIciUwSshm7UpDNda4QRieXltn2+cRCB4O8iKAm8TFQR2vswmaVW42cMJhG6kMIHAkqMw6IfVBF0lFcGAsIc1CNpK39939tkNi9Rg8nR1CZuoSDYdHxqqLNq28NYgTGzBhj/Tp2wKRTXi8Kpwad2tQehswSclGgFMkxbFyUYaGutrDy8QtJWu1SaVuUHYxGTu0Wr9TLXwtqOHF4jpmXfJeoLu4wPDBAK9Pl3LOD358e9WBhKEa80whcCy5+1RKAibBstFFTYgnoQiXCDw8wyTRq2vILBYctVRZY9nPXzihKqrApxic3bQzS5L0XRRHtnVqUFqw136DJqT9cySCYNXRWkXZh5VgUt1iShw8VZRNEu5nC+qFfQ7m/5D17WqjvuuP2R/27lY8j9k86LHJ3l6LvSLHXY/QCDEO2Kg1THwL4FlxRPSKnlC8JpHyCRe+o0iqpohgsa2DtFjbPvQs9o69H80cd9JJy+obm+xTAo0SLHUXSjbuuvi08fzS56/TiEg2AVLv+HUTgH9iS5UEf1J0eyqCKLLCUEgiLRlUBGoCFSEcBhBa6A10BpoDdUc8wG9ozFhleVISQAAAABJRU5ErkJggg==",
blocker: 300,
health: 400,
colDiv: .7,
indx: 0,
scale: 45,
holdOffset: 20,
placeOffset: -5
}, {
age: 7,
group: j[13],
name: "teleporter",
uF: [],
desc: "teleports you to a random point on the map",
req: ["wood", 60, "stone", 60],
url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABCCAYAAADjVADoAAAAAXNSR0IArs4c6QAAAzVJREFUeF7tmkFP2zAUxx16YMom7bBsN9B2otO+Age4Fg5F2vcBvs8keoBe6YGvMFFOTHDbssOkLdoOJZPbesRuHPs9v7gTeZUQqmon9i///3vPjhPBnzmBhDksCDCIpRIYBIPQgwIrghXBiqhNlGwNtgZbg63RVEVHjRGHhx/3ynJ2XJZir3FQiZgkSe/0/PzTJNYSIAqIwWB4IkRyjJlUkojJxcXZPqYvpE9rIEImb59AeToej04gE/Rt2wqIweCodA3gVfZapOnz+V9R/Jo3l/+/599cXcV4fEY+bvILNkHY6X9wTrLa4Gb62dqeGgYZCJsVoJO3zbweCp1VSEC0DUHBaRMGEQg9JqRpKra234Fs4Nv4/u5WFEWhNaewSTAIMyZQWcEFxlRHKIwgECaENpVggqFWBhpEXVyIpQZ7zMAHzwAQelyAQtj9uSuyWaY96JvNqbh+NnW5Qu9jpFisRUhAQCDUATBnDgVSjRdRQRwcHF1WF06+IIY/hqCnPXo58mqvB06cPVCKwGQKKARFwAcGRQYBg5BL6YeH2aUaqI8asBCwMDY2evvQJTwYBNQW73/3xc6fvpfEbY3yXi6uXlw1XqOqCszSHQwCaotQNfiqItQeQSDkUjrL3lifFIUa1MVdqsjzr9oSHpo9gkBsbb+d7yfYPlRq8FGF3Mu4v/vybyidBSEJhNQTQYpwZQxWxFKgnQHhCpY+5bRvXnWV3WsNlnISsezhqjCjp09oQUWhCpcazEAZpaDiErtiZmh1KbtiA6fLEqYa5HdoDSH7gNOn7GTuTrnihGIIheEDgcIWaBALGI87VL4gZD+fsttVTq9s5FR2qTBqIAPhkz3MwdcBgQKgskUgiNU33BBl+NYPTe1WX/jgdqeCQJj2kN87uZ2vnhQmg7ShBmxsUGNBZQ1zIjFf9FC/2CEGUX8ihjpm/PcvgetqC0WaCkabEIKDZZ3XO39QpAoFcnRokW0Wx4ee1NGhx2yCP0lnzyr4OsGVqUiyhusm5tLd1V7/vb3JV+8TBYS6YecPnMIUsJ7WURWxnin63ZVBLDkxCAahW4YVwYpgRdSmEbYGW4OtwdZoqjH/Av5ExVLxSFbJAAAAAElFTkSuQmCC",
ignoreCollision: !0,
teleport: !0,
health: 200,
colDiv: .7,
indx: 0,
scale: 45,
holdOffset: 20,
placeOffset: -5
}];
for (let e = 0; e < dt.length; ++e)
dt[e].id = e,
dt[e].pre && (dt[e].pre = e - dt[e].pre);
const R = {
groups: j,
projectiles: vc,
weapons: xc,
list: dt
}
, bc = []//["ahole", "anus", "ash0le", "ash0les", "asholes", "ass", "Ass Monkey", "Assface", "assh0le", "assh0lez", "asshole", "assholes", "assholz", "asswipe", "azzhole", "bassterds", "bastard", "bastards", "bastardz", "basterds", "basterdz", "Biatch", "bitch", "bitches", "Blow Job", "boffing", "butthole", "buttwipe", "c0ck", "c0cks", "c0k", "Carpet Muncher", "cawk", "cawks", "Clit", "cnts", "cntz", "cock", "cockhead", "cock-head", "cocks", "CockSucker", "cock-sucker", "crap", "cum", "cunt", "cunts", "cuntz", "dick", "dild0", "dild0s", "dildo", "dildos", "dilld0", "dilld0s", "dominatricks", "dominatrics", "dominatrix", "dyke", "enema", "f u c k", "f u c k e r", "fag", "fag1t", "faget", "fagg1t", "faggit", "faggot", "fagg0t", "fagit", "fags", "fagz", "faig", "faigs", "fart", "flipping the bird", "fuck", "fucker", "fuckin", "fucking", "fucks", "Fudge Packer", "fuk", "Fukah", "Fuken", "fuker", "Fukin", "Fukk", "Fukkah", "Fukken", "Fukker", "Fukkin", "g00k", "God-damned", "h00r", "h0ar", "h0re", "hells", "hoar", "hoor", "hoore", "jackoff", "jap", "japs", "jerk-off", "jisim", "jiss", "jizm", "jizz", "knob", "knobs", "knobz", "kunt", "kunts", "kuntz", "Lezzian", "Lipshits", "Lipshitz", "masochist", "masokist", "massterbait", "masstrbait", "masstrbate", "masterbaiter", "masterbate", "masterbates", "Motha Fucker", "Motha Fuker", "Motha Fukkah", "Motha Fukker", "Mother Fucker", "Mother Fukah", "Mother Fuker", "Mother Fukkah", "Mother Fukker", "mother-fucker", "Mutha Fucker", "Mutha Fukah", "Mutha Fuker", "Mutha Fukkah", "Mutha Fukker", "n1gr", "nastt", "nigger;", "nigur;", "niiger;", "niigr;", "orafis", "orgasim;", "orgasm", "orgasum", "oriface", "orifice", "orifiss", "packi", "packie", "packy", "paki", "pakie", "paky", "pecker", "peeenus", "peeenusss", "peenus", "peinus", "pen1s", "penas", "penis", "penis-breath", "penus", "penuus", "Phuc", "Phuck", "Phuk", "Phuker", "Phukker", "polac", "polack", "polak", "Poonani", "pr1c", "pr1ck", "pr1k", "pusse", "pussee", "pussy", "puuke", "puuker", "qweir", "recktum", "rectum", "retard", "sadist", "scank", "schlong", "screwing", "semen", "sex", "sexy", "Sh!t", "sh1t", "sh1ter", "sh1ts", "sh1tter", "sh1tz", "shit", "shits", "shitter", "Shitty", "Shity", "shitz", "Shyt", "Shyte", "Shytty", "Shyty", "skanck", "skank", "skankee", "skankey", "skanks", "Skanky", "slag", "slut", "sluts", "Slutty", "slutz", "son-of-a-bitch", "tit", "turd", "va1jina", "vag1na", "vagiina", "vagina", "vaj1na", "vajina", "vullva", "vulva", "w0p", "wh00r", "wh0re", "whore", "xrated", "xxx", "b!+ch", "bitch", "blowjob", "clit", "arschloch", "fuck", "shit", "ass", "asshole", "b!tch", "b17ch", "b1tch", "bastard", "bi+ch", "boiolas", "buceta", "c0ck", "cawk", "chink", "cipa", "clits", "cock", "cum", "cunt", "dildo", "dirsa", "ejakulate", "fatass", "fcuk", "fuk", "fux0r", "hoer", "hore", "jism", "kawk", "l3itch", "l3i+ch", "masturbate", "masterbat*", "masterbat3", "motherfucker", "s.o.b.", "mofo", "nazi", "nigga", "nigger", "nutsack", "phuck", "pimpis", "pusse", "pussy", "scrotum", "sh!t", "shemale", "shi+", "sh!+", "slut", "smut", "teets", "tits", "boobs", "b00bs", "teez", "testical", "testicle", "titt", "w00se", "jackoff", "wank", "whoar", "whore", "*damn", "*dyke", "*fuck*", "*shit*", "@$$", "amcik", "andskota", "arse*", "assrammer", "ayir", "bi7ch", "bitch*", "bollock*", "breasts", "butt-pirate", "cabron", "cazzo", "chraa", "chuj", "Cock*", "cunt*", "d4mn", "daygo", "dego", "dick*", "dike*", "dupa", "dziwka", "ejackulate", "Ekrem*", "Ekto", "enculer", "faen", "fag*", "fanculo", "fanny", "feces", "feg", "Felcher", "ficken", "fitt*", "Flikker", "foreskin", "Fotze", "Fu(*", "fuk*", "futkretzn", "gook", "guiena", "h0r", "h4x0r", "hell", "helvete", "hoer*", "honkey", "Huevon", "hui", "injun", "jizz", "kanker*", "kike", "klootzak", "kraut", "knulle", "kuk", "kuksuger", "Kurac", "kurwa", "kusi*", "kyrpa*", "lesbo", "mamhoon", "masturbat*", "merd*", "mibun", "monkleigh", "mouliewop", "muie", "mulkku", "muschi", "nazis", "nepesaurio", "nigger*", "orospu", "paska*", "perse", "picka", "pierdol*", "pillu*", "pimmel", "piss*", "pizda", "poontsee", "poop", "porn", "p0rn", "pr0n", "preteen", "pula", "pule", "puta", "puto", "qahbeh", "queef*", "rautenberg", "schaffer", "scheiss*", "schlampe", "schmuck", "screw", "sh!t*", "sharmuta", "sharmute", "shipal", "shiz", "skribz", "skurwysyn", "sphencter", "spic", "spierdalaj", "splooge", "suka", "b00b*", "testicle*", "titt*", "twat", "vittu", "wank*", "wetback*", "wichser", "wop*", "yed", "zabourah"]
, Sc = {
words: bc
};
var Tc = {
/* "4r5e": 1,
"5h1t": 1,
"5hit": 1,
a55: 1,
anal: 1,
anus: 1,
ar5e: 1,
arrse: 1,
arse: 1,
ass: 1,
"ass-fucker": 1,
asses: 1,
assfucker: 1,
assfukka: 1,
asshole: 1,
assholes: 1,
asswhole: 1,
a_s_s: 1,
"b!tch": 1,
b00bs: 1,
b17ch: 1,
b1tch: 1,
ballbag: 1,
balls: 1,
ballsack: 1,
bastard: 1,
beastial: 1,
beastiality: 1,
bellend: 1,
bestial: 1,
bestiality: 1,
"bi+ch": 1,
biatch: 1,
bitch: 1,
bitcher: 1,
bitchers: 1,
bitches: 1,
bitchin: 1,
bitching: 1,
bloody: 1,
"blow job": 1,
blowjob: 1,
blowjobs: 1,
boiolas: 1,
bollock: 1,
bollok: 1,
boner: 1,
boob: 1,
boobs: 1,
booobs: 1,
boooobs: 1,
booooobs: 1,
booooooobs: 1,
breasts: 1,
buceta: 1,
bugger: 1,
bum: 1,
"bunny fucker": 1,
butt: 1,
butthole: 1,
buttmuch: 1,
buttplug: 1,
c0ck: 1,
c0cksucker: 1,
"carpet muncher": 1,
cawk: 1,
chink: 1,
cipa: 1,
cl1t: 1,
clit: 1,
clitoris: 1,
clits: 1,
cnut: 1,
cock: 1,
"cock-sucker": 1,
cockface: 1,
cockhead: 1,
cockmunch: 1,
cockmuncher: 1,
cocks: 1,
cocksuck: 1,
cocksucked: 1,
cocksucker: 1,
cocksucking: 1,
cocksucks: 1,
cocksuka: 1,
cocksukka: 1,
cok: 1,
cokmuncher: 1,
coksucka: 1,
coon: 1,
cox: 1,
crap: 1,
cum: 1,
cummer: 1,
cumming: 1,
cums: 1,
cumshot: 1,
cunilingus: 1,
cunillingus: 1,
cunnilingus: 1,
cunt: 1,
cuntlick: 1,
cuntlicker: 1,
cuntlicking: 1,
cunts: 1,
cyalis: 1,
cyberfuc: 1,
cyberfuck: 1,
cyberfucked: 1,
cyberfucker: 1,
cyberfuckers: 1,
cyberfucking: 1,
d1ck: 1,
damn: 1,
dick: 1,
dickhead: 1,
dildo: 1,
dildos: 1,
dink: 1,
dinks: 1,
dirsa: 1,
dlck: 1,
"dog-fucker": 1,
doggin: 1,
dogging: 1,
donkeyribber: 1,
doosh: 1,
duche: 1,
dyke: 1,
ejaculate: 1,
ejaculated: 1,
ejaculates: 1,
ejaculating: 1,
ejaculatings: 1,
ejaculation: 1,
ejakulate: 1,
"f u c k": 1,
"f u c k e r": 1,
f4nny: 1,
fag: 1,
fagging: 1,
faggitt: 1,
faggot: 1,
faggs: 1,
fagot: 1,
fagots: 1,
fags: 1,
fanny: 1,
fannyflaps: 1,
fannyfucker: 1,
fanyy: 1,
fatass: 1,
fcuk: 1,
fcuker: 1,
fcuking: 1,
feck: 1,
fecker: 1,
felching: 1,
fellate: 1,
fellatio: 1,
fingerfuck: 1,
fingerfucked: 1,
fingerfucker: 1,
fingerfuckers: 1,
fingerfucking: 1,
fingerfucks: 1,
fistfuck: 1,
fistfucked: 1,
fistfucker: 1,
fistfuckers: 1,
fistfucking: 1,
fistfuckings: 1,
fistfucks: 1,
flange: 1,
fook: 1,
fooker: 1,
fuck: 1,
fucka: 1,
fucked: 1,
fucker: 1,
fuckers: 1,
fuckhead: 1,
fuckheads: 1,
fuckin: 1,
fucking: 1,
fuckings: 1,
fuckingshitmotherfucker: 1,
fuckme: 1,
fucks: 1,
fuckwhit: 1,
fuckwit: 1,
"fudge packer": 1,
fudgepacker: 1,
fuk: 1,
fuker: 1,
fukker: 1,
fukkin: 1,
fuks: 1,
fukwhit: 1,
fukwit: 1,
fux: 1,
fux0r: 1,
f_u_c_k: 1,
gangbang: 1,
gangbanged: 1,
gangbangs: 1,
gaylord: 1,
gaysex: 1,
goatse: 1,
God: 1,
"god-dam": 1,
"god-damned": 1,
goddamn: 1,
goddamned: 1,
hardcoresex: 1,
hell: 1,
heshe: 1,
hoar: 1,
hoare: 1,
hoer: 1,
homo: 1,
hore: 1,
horniest: 1,
horny: 1,
hotsex: 1,
"jack-off": 1,
jackoff: 1,
jap: 1,
"jerk-off": 1,
jism: 1,
jiz: 1,
jizm: 1,
jizz: 1,
kawk: 1,
knob: 1,
knobead: 1,
knobed: 1,
knobend: 1,
knobhead: 1,
knobjocky: 1,
knobjokey: 1,
kock: 1,
kondum: 1,
kondums: 1,
kum: 1,
kummer: 1,
kumming: 1,
kums: 1,
kunilingus: 1,
"l3i+ch": 1,
l3itch: 1,
labia: 1,
lust: 1,
lusting: 1,
m0f0: 1,
m0fo: 1,
m45terbate: 1,
ma5terb8: 1,
ma5terbate: 1,
masochist: 1,
"master-bate": 1,
masterb8: 1,
"masterbat*": 1,
masterbat3: 1,
masterbate: 1,
masterbation: 1,
masterbations: 1,
masturbate: 1,
"mo-fo": 1,
mof0: 1,
mofo: 1,
mothafuck: 1,
mothafucka: 1,
mothafuckas: 1,
mothafuckaz: 1,
mothafucked: 1,
mothafucker: 1,
mothafuckers: 1,
mothafuckin: 1,
mothafucking: 1,
mothafuckings: 1,
mothafucks: 1,
"mother fucker": 1,
motherfuck: 1,
motherfucked: 1,
motherfucker: 1,
motherfuckers: 1,
motherfuckin: 1,
motherfucking: 1,
motherfuckings: 1,
motherfuckka: 1,
motherfucks: 1,
muff: 1,
mutha: 1,
muthafecker: 1,
muthafuckker: 1,
muther: 1,
mutherfucker: 1,
n1gga: 1,
n1gger: 1,
nazi: 1,
nigg3r: 1,
nigg4h: 1,
nigga: 1,
niggah: 1,
niggas: 1,
niggaz: 1,
nigger: 0,
niggers: 1,
nob: 1,
"nob jokey": 1,
nobhead: 1,
nobjocky: 1,
nobjokey: 1,
numbnuts: 1,
nutsack: 1,
orgasim: 1,
orgasims: 1,
orgasm: 1,
orgasms: 1,
p0rn: 1,
pawn: 1,
pecker: 1,
penis: 1,
penisfucker: 1,
phonesex: 1,
phuck: 1,
phuk: 1,
phuked: 1,
phuking: 1,
phukked: 1,
phukking: 1,
phuks: 1,
phuq: 1,
pigfucker: 1,
pimpis: 1,
piss: 1,
pissed: 1,
pisser: 1,
pissers: 1,
pisses: 1,
pissflaps: 1,
pissin: 1,
pissing: 1,
pissoff: 1,
poop: 1,
porn: 1,
porno: 1,
pornography: 1,
pornos: 1,
prick: 1,
pricks: 1,
pron: 1,
pube: 1,
pusse: 1,
pussi: 1,
pussies: 1,
pussy: 1,
pussys: 1,
rectum: 1,
retard: 1,
rimjaw: 1,
rimming: 1,
"s hit": 1,
"s.o.b.": 1,
sadist: 1,
schlong: 1,
screwing: 1,
scroat: 1,
scrote: 1,
scrotum: 1,
semen: 1,
sex: 1,
"sh!+": 1,
"sh!t": 1,
sh1t: 1,
shag: 1,
shagger: 1,
shaggin: 1,
shagging: 1,
shemale: 1,
"shi+": 1,
shit: 1,
shitdick: 1,
shite: 1,
shited: 1,
shitey: 1,
shitfuck: 1,
shitfull: 1,
shithead: 1,
shiting: 1,
shitings: 1,
shits: 1,
shitted: 1,
shitter: 1,
shitters: 1,
shitting: 1,
shittings: 1,
shitty: 1,
skank: 1,
slut: 1,
sluts: 1,
smegma: 1,
smut: 1,
snatch: 1,
"son-of-a-bitch": 1,
spac: 1,
spunk: 1,
s_h_i_t: 1,
t1tt1e5: 1,
t1tties: 1,
teets: 1,
teez: 1,
testical: 1,
testicle: 1,
tit: 1,
titfuck: 1,
tits: 1,
titt: 1,
tittie5: 1,
tittiefucker: 1,
titties: 1,
tittyfuck: 1,
tittywank: 1,
titwank: 1,
tosser: 1,
turd: 1,
tw4t: 1,
twat: 1,
twathead: 1,
twatty: 1,
twunt: 1,
twunter: 1,
v14gra: 1,
v1gra: 1,
vagina: 1,
viagra: 1,
vulva: 1,
w00se: 1,
wang: 1,
wank: 1,
wanker: 1,
wanky: 1,
whoar: 1,
whore: 1,
willies: 1,
willy: 1,
xrated: 1,
xxx: 1*/
}
, Ic = []//["4r5e", "5h1t", "5hit", "a55", "anal", "anus", "ar5e", "arrse", "arse", "ass", "ass-fucker", "asses", "assfucker", "assfukka", "asshole", "assholes", "asswhole", "a_s_s", "b!tch", "b00bs", "b17ch", "b1tch", "ballbag", "balls", "ballsack", "bastard", "beastial", "beastiality", "bellend", "bestial", "bestiality", "bi+ch", "biatch", "bitch", "bitcher", "bitchers", "bitches", "bitchin", "bitching", "bloody", "blow job", "blowjob", "blowjobs", "boiolas", "bollock", "bollok", "boner", "boob", "boobs", "booobs", "boooobs", "booooobs", "booooooobs", "breasts", "buceta", "bugger", "bum", "bunny fucker", "butt", "butthole", "buttmuch", "buttplug", "c0ck", "c0cksucker", "carpet muncher", "cawk", "chink", "cipa", "cl1t", "clit", "clitoris", "clits", "cnut", "cock", "cock-sucker", "cockface", "cockhead", "cockmunch", "cockmuncher", "cocks", "cocksuck", "cocksucked", "cocksucker", "cocksucking", "cocksucks", "cocksuka", "cocksukka", "cok", "cokmuncher", "coksucka", "coon", "cox", "crap", "cum", "cummer", "cumming", "cums", "cumshot", "cunilingus", "cunillingus", "cunnilingus", "cunt", "cuntlick", "cuntlicker", "cuntlicking", "cunts", "cyalis", "cyberfuc", "cyberfuck", "cyberfucked", "cyberfucker", "cyberfuckers", "cyberfucking", "d1ck", "damn", "dick", "dickhead", "dildo", "dildos", "dink", "dinks", "dirsa", "dlck", "dog-fucker", "doggin", "dogging", "donkeyribber", "doosh", "duche", "dyke", "ejaculate", "ejaculated", "ejaculates", "ejaculating", "ejaculatings", "ejaculation", "ejakulate", "f u c k", "f u c k e r", "f4nny", "fag", "fagging", "faggitt", "faggot", "faggs", "fagot", "fagots", "fags", "fanny", "fannyflaps", "fannyfucker", "fanyy", "fatass", "fcuk", "fcuker", "fcuking", "feck", "fecker", "felching", "fellate", "fellatio", "fingerfuck", "fingerfucked", "fingerfucker", "fingerfuckers", "fingerfucking", "fingerfucks", "fistfuck", "fistfucked", "fistfucker", "fistfuckers", "fistfucking", "fistfuckings", "fistfucks", "flange", "fook", "fooker", "fuck", "fucka", "fucked", "fucker", "fuckers", "fuckhead", "fuckheads", "fuckin", "fucking", "fuckings", "fuckingshitmotherfucker", "fuckme", "fucks", "fuckwhit", "fuckwit", "fudge packer", "fudgepacker", "fuk", "fuker", "fukker", "fukkin", "fuks", "fukwhit", "fukwit", "fux", "fux0r", "f_u_c_k", "gangbang", "gangbanged", "gangbangs", "gaylord", "gaysex", "goatse", "God", "god-dam", "god-damned", "goddamn", "goddamned", "hardcoresex", "hell", "heshe", "hoar", "hoare", "hoer", "homo", "hore", "horniest", "horny", "hotsex", "jack-off", "jackoff", "jap", "jerk-off", "jism", "jiz", "jizm", "jizz", "kawk", "knob", "knobead", "knobed", "knobend", "knobhead", "knobjocky", "knobjokey", "kock", "kondum", "kondums", "kum", "kummer", "kumming", "kums", "kunilingus", "l3i+ch", "l3itch", "labia", "lust", "lusting", "m0f0", "m0fo", "m45terbate", "ma5terb8", "ma5terbate", "masochist", "master-bate", "masterb8", "masterbat*", "masterbat3", "masterbate", "masterbation", "masterbations", "masturbate", "mo-fo", "mof0", "mofo", "mothafuck", "mothafucka", "mothafuckas", "mothafuckaz", "mothafucked", "mothafucker", "mothafuckers", "mothafuckin", "mothafucking", "mothafuckings", "mothafucks", "mother fucker", "motherfuck", "motherfucked", "motherfucker", "motherfuckers", "motherfuckin", "motherfucking", "motherfuckings", "motherfuckka", "motherfucks", "muff", "mutha", "muthafecker", "muthafuckker", "muther", "mutherfucker", "n1gga", "n1gger", "nazi", "nigg3r", "nigg4h", "nigga", "niggah", "niggas", "niggaz", "nigger", "niggers", "nob", "nob jokey", "nobhead", "nobjocky", "nobjokey", "numbnuts", "nutsack", "orgasim", "orgasims", "orgasm", "orgasms", "p0rn", "pawn", "pecker", "penis", "penisfucker", "phonesex", "phuck", "phuk", "phuked", "phuking", "phukked", "phukking", "phuks", "phuq", "pigfucker", "pimpis", "piss", "pissed", "pisser", "pissers", "pisses", "pissflaps", "pissin", "pissing", "pissoff", "poop", "porn", "porno", "pornography", "pornos", "prick", "pricks", "pron", "pube", "pusse", "pussi", "pussies", "pussy", "pussys", "rectum", "retard", "rimjaw", "rimming", "s hit", "s.o.b.", "sadist", "schlong", "screwing", "scroat", "scrote", "scrotum", "semen", "sex", "sh!+", "sh!t", "sh1t", "shag", "shagger", "shaggin", "shagging", "shemale", "shi+", "shit", "shitdick", "shite", "shited", "shitey", "shitfuck", "shitfull", "shithead", "shiting", "shitings", "shits", "shitted", "shitter", "shitters", "shitting", "shittings", "shitty", "skank", "slut", "sluts", "smegma", "smut", "snatch", "son-of-a-bitch", "spac", "spunk", "s_h_i_t", "t1tt1e5", "t1tties", "teets", "teez", "testical", "testicle", "tit", "titfuck", "tits", "titt", "tittie5", "tittiefucker", "titties", "tittyfuck", "tittywank", "titwank", "tosser", "turd", "tw4t", "twat", "twathead", "twatty", "twunt", "twunter", "v14gra", "v1gra", "vagina", "viagra", "vulva", "w00se", "wang", "wank", "wanker", "wanky", "whoar", "whore", "willies", "willy", "xrated", "xxx"]
, Mc = null// /\b(4r5e|5h1t|5hit|a55|anal|anus|ar5e|arrse|arse|ass|ass-fucker|asses|assfucker|assfukka|asshole|assholes|asswhole|a_s_s|b!tch|b00bs|b17ch|b1tch|ballbag|balls|ballsack|bastard|beastial|beastiality|bellend|bestial|bestiality|bi\+ch|biatch|bitch|bitcher|bitchers|bitches|bitchin|bitching|bloody|blow job|blowjob|blowjobs|boiolas|bollock|bollok|boner|boob|boobs|booobs|boooobs|booooobs|booooooobs|breasts|buceta|bugger|bum|bunny fucker|butt|butthole|buttmuch|buttplug|c0ck|c0cksucker|carpet muncher|cawk|chink|cipa|cl1t|clit|clitoris|clits|cnut|cock|cock-sucker|cockface|cockhead|cockmunch|cockmuncher|cocks|cocksuck|cocksucked|cocksucker|cocksucking|cocksucks|cocksuka|cocksukka|cok|cokmuncher|coksucka|coon|cox|crap|cum|cummer|cumming|cums|cumshot|cunilingus|cunillingus|cunnilingus|cunt|cuntlick|cuntlicker|cuntlicking|cunts|cyalis|cyberfuc|cyberfuck|cyberfucked|cyberfucker|cyberfuckers|cyberfucking|d1ck|damn|dick|dickhead|dildo|dildos|dink|dinks|dirsa|dlck|dog-fucker|doggin|dogging|donkeyribber|doosh|duche|dyke|ejaculate|ejaculated|ejaculates|ejaculating|ejaculatings|ejaculation|ejakulate|f u c k|f u c k e r|f4nny|fag|fagging|faggitt|faggot|faggs|fagot|fagots|fags|fanny|fannyflaps|fannyfucker|fanyy|fatass|fcuk|fcuker|fcuking|feck|fecker|felching|fellate|fellatio|fingerfuck|fingerfucked|fingerfucker|fingerfuckers|fingerfucking|fingerfucks|fistfuck|fistfucked|fistfucker|fistfuckers|fistfucking|fistfuckings|fistfucks|flange|fook|fooker|fuck|fucka|fucked|fucker|fuckers|fuckhead|fuckheads|fuckin|fucking|fuckings|fuckingshitmotherfucker|fuckme|fucks|fuckwhit|fuckwit|fudge packer|fudgepacker|fuk|fuker|fukker|fukkin|fuks|fukwhit|fukwit|fux|fux0r|f_u_c_k|gangbang|gangbanged|gangbangs|gaylord|gaysex|goatse|God|god-dam|god-damned|goddamn|goddamned|hardcoresex|hell|heshe|hoar|hoare|hoer|homo|hore|horniest|horny|hotsex|jack-off|jackoff|jap|jerk-off|jism|jiz|jizm|jizz|kawk|knob|knobead|knobed|knobend|knobhead|knobjocky|knobjokey|kock|kondum|kondums|kum|kummer|kumming|kums|kunilingus|l3i\+ch|l3itch|labia|lust|lusting|m0f0|m0fo|m45terbate|ma5terb8|ma5terbate|masochist|master-bate|masterb8|masterbat*|masterbat3|masterbate|masterbation|masterbations|masturbate|mo-fo|mof0|mofo|mothafuck|mothafucka|mothafuckas|mothafuckaz|mothafucked|mothafucker|mothafuckers|mothafuckin|mothafucking|mothafuckings|mothafucks|mother fucker|motherfuck|motherfucked|motherfucker|motherfuckers|motherfuckin|motherfucking|motherfuckings|motherfuckka|motherfucks|muff|mutha|muthafecker|muthafuckker|muther|mutherfucker|n1gga|n1gger|nazi|nigg3r|nigg4h|nigga|niggah|niggas|niggaz|nigger|niggers|nob|nob jokey|nobhead|nobjocky|nobjokey|numbnuts|nutsack|orgasim|orgasims|orgasm|orgasms|p0rn|pawn|pecker|penis|penisfucker|phonesex|phuck|phuk|phuked|phuking|phukked|phukking|phuks|phuq|pigfucker|pimpis|piss|pissed|pisser|pissers|pisses|pissflaps|pissin|pissing|pissoff|poop|porn|porno|pornography|pornos|prick|pricks|pron|pube|pusse|pussi|pussies|pussy|pussys|rectum|retard|rimjaw|rimming|s hit|s.o.b.|sadist|schlong|screwing|scroat|scrote|scrotum|semen|sex|sh!\+|sh!t|sh1t|shag|shagger|shaggin|shagging|shemale|shi\+|shit|shitdick|shite|shited|shitey|shitfuck|shitfull|shithead|shiting|shitings|shits|shitted|shitter|shitters|shitting|shittings|shitty|skank|slut|sluts|smegma|smut|snatch|son-of-a-bitch|spac|spunk|s_h_i_t|t1tt1e5|t1tties|teets|teez|testical|testicle|tit|titfuck|tits|titt|tittie5|tittiefucker|titties|tittyfuck|tittywank|titwank|tosser|turd|tw4t|twat|twathead|twatty|twunt|twunter|v14gra|v1gra|vagina|viagra|vulva|w00se|wang|wank|wanker|wanky|whoar|whore|willies|willy|xrated|xxx)\b/gi
, Ec = {
object: Tc,
array: Ic,
regex: Mc
};
const Pc = Sc.words
//console.log(Pc)
const Cc = Ec.array;
class Ac {
constructor(t={}) {
Object.assign(this, {
list: t.emptyList && [] || Array.prototype.concat.apply(Pc, [Cc, t.list || []]),
exclude: t.exclude || [],
splitRegex: t.splitRegex || /\b/,
placeHolder: t.placeHolder || "*",
regex: t.regex || /[^a-zA-Z0-9|\$|\@]|\^/g,
replaceRegex: t.replaceRegex || /\w/g
})
}
isProfane(t) {
return this.list.filter(i=>{
const s = new RegExp(`\\b ${i.replace(/(\W)/g, "\\$1")}\\b`,"gi");
return !this.exclude.includes(i.toLowerCase()) && s.test(t)
}
).length > 0 || !1
return false
}
replaceWord(t) {
return t.replace(this.regex, "").replace(this.replaceRegex, this.placeHolder)
}
clean(t) {
return t.split(this.splitRegex).map(i=>this.isProfane(i) ? this.replaceWord(i) : i).join(this.splitRegex.exec(t)[0])
}
addWords() {
let t = Array.from(arguments);
this.list.push(...t),
t.map(i=>i.toLowerCase()).forEach(i=>{
this.exclude.includes(i) && this.exclude.splice(this.exclude.indexOf(i), 1)
}
)
}
removeWords() {
this.exclude.push(...Array.from(arguments).map(t=>t.toLowerCase()))
}
}
var Dc = Ac;
const Yr = new Dc
, Oc = []//["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"];
Yr.addWords(...Oc);
const _s = Math.abs
, at = Math.cos
, lt = Math.sin
, Bs = Math.pow
, Rc = Math.sqrt;
function _c(e, t, i, s, n, r, o, l, c, a, u, p, h, m) {
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 w = 0; w < u.length; ++w)
u[w].price <= 0 && (this.tails[u[w].id] = 1);
this.skins = {};
for (var w = 0; w < a.length; ++w)
a[w].price <= 0 && (this.skins[a[w].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.deaths = 0,
this.skinColor = 0,
this.spawn = function(k) {
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.deathCount = 0,
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.health2 = 0,
this.samRP = 1,
this.samRS = 1,
this.pr = 1,
this.sr = 1,
this.hasSoldier = false,
this.hasTank = false,
this.health = this.maxHealth,
this.scale = i.playerScale,
this.speed = i.playerSpeed,
this.resetMoveDir(),
this.resetResources(k),
this.items = [0, 3, 6, 10],
this.weapons = [0],
this.shootCount = 0,
this.weaponXP = [],
this.reloads = {},
this.timeSpentNearVolcano = 0
}
,
this.resetMoveDir = function() {
this.moveDir = void 0
}
,
this.resetResources = function(k) {
for (let S = 0; S < i.resourceTypes.length; ++S)
this[i.resourceTypes[S]] = k ? 100 : 100
}
,
this.addItem = function(k) {
const S = c.list[k];
if (S) {
for (let O = 0; O < this.items.length; ++O)
if (c.list[this.items[O]].group == S.group)
return this.buildIndex == this.items[O] && (this.buildIndex = k),
this.items[O] = k,
!0;
return this.items.push(k),
!0
}
return !1
}
,
this.setUserData = function(k) {
if (k) {
this.name = "unknown";
let S = k.name + "";
S = S.slice(0, i.maxNameLength),
S = S.replace(/[^\w:\(\)\/? -]+/gmi, " "),
S = S.replace(/[^\x00-\x7F]/g, " "),
S = S.trim();
let O = !1;
const U = S.toLowerCase().replace(/\s/g, "").replace(/1/g, "i").replace(/0/g, "o").replace(/5/g, "s");
for (const L of Yr.list)
if (U.indexOf(L) != -1) {
O = !0;
break
}
S.length > 0 && !O && (this.name = S),
this.skinColor = 0,
i.skinColors[k.skin] && (this.skinColor = k.skin)
}
}
,
this.getData = function() {
return [this.id, this.sid, this.name, s.fixTo(this.x, 2), s.fixTo(this.y, 2), s.fixTo(this.dir, 3), this.health, this.maxHealth, this.scale, this.skinColor]
}
,
this.setData = function(k,t,ez, spec) {
if(k[2]!=t.name&&t.name!=undefined&&!botIDS.includes(k[1])){addChatLog(`${t.name}[${t.sid}] has changed name to ${k[2]}`,'', '#e38b49')}
this.id = k[0],
this.sid = k[1],
this.name = k[2],
this.x = k[3],
this.y = k[4],
this.dir = k[5],
this.bot = ez? true : false,
this.health = k[6],
this.maxHealth = k[7],
this.scale = k[8],
this.skinColor = k[9],
this.pr = 1,
this.sr = 1,
this.tr = 1,
this.hitProjs = 0,
this.primary = undefined,
this.secondary = undefined,
this.shameCount = 0,
this.primaryVar = 3,
this.secondaryVar = 3,
this.lastx = 0,
this.tick = tick,
this.lasty = 0;
}
;
let v = 0;
this.update = function(k) {
if (!this.alive)
return;
if ((s.getDistance(this.x, this.y, i.volcanoLocationX, i.volcanoLocationY) || 0) < i.volcanoAggressionRadius && (this.timeSpentNearVolcano += k,
this.timeSpentNearVolcano >= 1e3 && (this.changeHealth(i.volcanoDamagePerSecond, null),
p.send(this.id, "8", round(this.x), round(this.y), i.volcanoDamagePerSecond, -1),
this.timeSpentNearVolcano %= 1e3)),
this.shameTimer > 0 && (this.shameTimer -= k,
this.shameTimer <= 0 && (this.shameTimer = 0,
this.shameCount = 0)),
v -= k,
v <= 0) {
const _ = (this.skin && this.skin.healthRegen ? this.skin.healthRegen : 0) + (this.tail && this.tail.healthRegen ? this.tail.healthRegen : 0);
_ && this.changeHealth(_, 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),
v = 1e3
}
if (!this.alive)
return;
if (this.slowMult < 1 && (this.slowMult += 8e-4 * k,
this.slowMult > 1 && (this.slowMult = 1)),
this.noMovTimer += k,
(this.xVel || this.yVel) && (this.noMovTimer = 0),
this.lockMove)
this.xVel = 0,
this.yVel = 0;
else {
let _ = (this.buildIndex >= 0 ? .5 : 1) * (c.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 ? (_ *= .75,
this.xVel += i.waterCurrent * .4 * k) : (_ *= .33,
this.xVel += i.waterCurrent * k));
let $ = this.moveDir != null ? at(this.moveDir) : 0
, V = this.moveDir != null ? lt(this.moveDir) : 0;
const z = Rc($ * $ + V * V);
z != 0 && ($ /= z,
V /= z),
$ && (this.xVel += $ * this.speed * _ * k),
V && (this.yVel += V * this.speed * _ * k)
}
this.zIndex = 0,
this.lockMove = !1,
this.healCol = 0;
let O;
const U = s.getDistance(0, 0, this.xVel * k, this.yVel * k)
, L = min(4, max(1, round(U / 40)))
, q = 1 / L;
let P = {};
for (var W = 0; W < L; ++W) {
this.xVel && (this.x += this.xVel * k * q),
this.yVel && (this.y += this.yVel * k * q),
O = r.getGridArrays(this.x, this.y, this.scale);
for (let _ = 0; _ < O.length; ++_) {
for (let $ = 0; $ < O[_].length && !(O[_][$].active && !P[O[_][$].sid] && r.checkCollision(this, O[_][$], q) && (P[O[_][$].sid] = !0,
!this.alive)); ++$)
;
if (!this.alive)
break
}
if (!this.alive)
break
}
for (var F = o.indexOf(this), W = F + 1; W < o.length; ++W)
o[W] != this && o[W].alive && r.checkCollision(this, o[W]);
if (this.xVel && (this.xVel *= Bs(i.playerDecel, k),
this.xVel <= .01 && this.xVel >= -.01 && (this.xVel = 0)),
this.yVel && (this.yVel *= Bs(i.playerDecel, k),
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] -= k,
this.gathering = this.mouseState;
else if (this.gathering || this.autoGather) {
let _ = !0;
if (c.weapons[this.weaponIndex].gather != null)
this.gather(o);
else if (c.weapons[this.weaponIndex].projectile != null && this.hasRes(c.weapons[this.weaponIndex], this.skin ? this.skin.projCost : 0)) {
this.useRes(c.weapons[this.weaponIndex], this.skin ? this.skin.projCost : 0),
this.noMovTimer = 0;
var F = c.weapons[this.weaponIndex].projectile;
const V = this.scale * 2
, z = this.skin && this.skin.aMlt ? this.skin.aMlt : 1;
c.weapons[this.weaponIndex].rec && (this.xVel -= c.weapons[this.weaponIndex].rec * at(this.dir),
this.yVel -= c.weapons[this.weaponIndex].rec * lt(this.dir)),
n.addProjectile(this.x + V * at(this.dir), this.y + V * lt(this.dir), this.dir, c.projectiles[F].range * z, c.projectiles[F].speed * z, F, this, null, this.zIndex)
} else
_ = !1;
this.gathering = this.mouseState,
_ && (this.reloads[this.weaponIndex] = c.weapons[this.weaponIndex].speed * (this.skin && this.skin.atkSpd || 1))
}
}
}
,
this.addWeaponXP = function(k) {
this.weaponXP[this.weaponIndex] || (this.weaponXP[this.weaponIndex] = 0),
this.weaponXP[this.weaponIndex] += k
}
,
this.earnXP = function(k) {
this.age < i.maxAge && (this.XP += k,
this.XP >= this.maxXP ? (this.age < i.maxAge ? (this.age++,
this.XP = 0,
this.maxXP *= 1.2) : this.XP = this.maxXP,
this.upgradePoints++,
p.send(this.id, "U", this.upgradePoints, this.upgrAge),
p.send(this.id, "T", this.XP, s.fixTo(this.maxXP, 1), this.age)) : p.send(this.id, "T", this.XP))
}
,
this.changeHealth = function(k, S) {
if (k > 0 && this.health >= this.maxHealth)
return !1;
k < 0 && this.skin && (k *= this.skin.dmgMult || 1),
k < 0 && this.tail && (k *= this.tail.dmgMult || 1),
k < 0 && (this.hitTime = Date.now()),
this.health += k,
this.health > this.maxHealth && (k -= this.health - this.maxHealth,
this.health = this.maxHealth),
this.health <= 0 && this.kill(S);
for (let O = 0; O < o.length; ++O)
this.sentTo[o[O].id] && p.send(o[O].id, "O", this.sid, this.health);
return S && S.canSee(this) && !(S == this && k < 0) && p.send(S.id, "8", round(this.x), round(this.y), round(-k), 1),
!0
}
,
this.kill = function(k) {
k && k.alive && (k.kills++,
k.skin && k.skin.goldSteal ? h(k, round(this.points / 2)) : h(k, round(this.age * 100 * (k.skin && k.skin.kScrM ? k.skin.kScrM : 1))),
p.send(k.id, "N", "kills", k.kills, 1)),
this.alive = !1,
p.send(this.id, "P"),
m()
}
,
this.addResource = function(k, S, O) {
!O && S > 0 && this.addWeaponXP(S),
k == 3 ? h(this, S, !0) : (this[i.resourceTypes[k]] += S,
p.send(this.id, "N", i.resourceTypes[k], this[i.resourceTypes[k]], 1))
}
,
this.changeItemCount = function(k, S) {
this.itemCounts[k] = this.itemCounts[k] || 0,
this.itemCounts[k] += S,
p.send(this.id, "S", k, this.itemCounts[k])
}
,
this.buildItem = function(k) {
const S = this.scale + k.scale + (k.placeOffset || 0)
, O = this.x + S * at(this.dir)
, U = this.y + S * lt(this.dir);
if (this.canBuild(k) && !(k.consume && this.skin && this.skin.noEat) && (k.consume || r.checkItemLocation(O, U, k.scale, .6, k.id, !1, this))) {
let L = !1;
if (k.consume) {
if (this.hitTime) {
const q = Date.now() - this.hitTime;
this.hitTime = 0,
q <= 120 ? (this.shameCount++,
this.shameCount >= 8 && (this.shameTimer = 3e4,
this.shameCount = 0)) : (this.shameCount -= 2,
this.shameCount <= 0 && (this.shameCount = 0))
}
this.shameTimer <= 0 && (L = k.consume(this))
} else
L = !0,
k.group.limit && this.changeItemCount(k.group.id, 1),
k.pps && (this.pps += k.pps),
r.add(r.objects.length, O, U, this.dir, k.scale, k.type, k, !1, this);
L && (this.useRes(k),
this.buildIndex = -1)
}
}
,
this.hasRes = function(k, S) {
for (let O = 0; O < k.req.length; ) {
if (this[k.req[O]] < round(k.req[O + 1] * (S || 1)))
return !1;
O += 2
}
return !0
}
,
this.useRes = function(k, S) {
if (!i.inSandbox)
for (let O = 0; O < k.req.length; )
this.addResource(i.resourceTypes.indexOf(k.req[O]), -round(k.req[O + 1] * (S || 1))),
O += 2
}
,
this.canBuild = function(k) {
const S = sandbox ? k.group.sandboxLimit || max(k.group.limit * 3, 99) : k.group.limit;
return S && this.itemCounts[k.group.id] >= S ? !1 : sandbox ? !0 : this.hasRes(k)
}
,
this.gather = function() {
this.noMovTimer = 0,
this.slowMult -= c.weapons[this.weaponIndex].hitSlow || .3,
this.slowMult < 0 && (this.slowMult = 0);
const k = i.fetchVariant(this)
, S = k.poison
, O = k.val
, U = {};
let L, q, P, W;
const F = r.getGridArrays(this.x, this.y, c.weapons[this.weaponIndex].range);
for (let $ = 0; $ < F.length; ++$)
for (var _ = 0; _ < F[$].length; ++_)
if (P = F[$][_],
P.active && !P.dontGather && !U[P.sid] && P.visibleToPlayer(this) && (L = s.getDistance(this.x, this.y, P.x, P.y) - P.scale,
L <= c.weapons[this.weaponIndex].range && (q = s.getDirection(P.x, P.y, this.x, this.y),
s.getAngleDist(q, this.dir) <= i.gatherAngle))) {
if (U[P.sid] = 1,
P.health) {
if (P.changeHealth(-c.weapons[this.weaponIndex].dmg * O * (c.weapons[this.weaponIndex].sDmg || 1) * (this.skin && this.skin.bDmg ? this.skin.bDmg : 1), this)) {
for (let V = 0; V < P.req.length; )
this.addResource(i.resourceTypes.indexOf(P.req[V]), P.req[V + 1]),
V += 2;
r.disableObj(P)
}
} else {
if (P.name === "volcano")
this.hitVolcano(c.weapons[this.weaponIndex].gather);
else {
this.earnXP(4 * c.weapons[this.weaponIndex].gather);
const V = c.weapons[this.weaponIndex].gather + (P.type == 3 ? 4 : 0);
this.addResource(P.type, V)
}
this.skin && this.skin.extraGold && this.addResource(3, 1)
}
W = !0,
r.hitObj(P, q)
}
for (var _ = 0; _ < o.length + l.length; ++_)
if (P = o[_] || l[_ - o.length],
P != this && P.alive && !(P.team && P.team == this.team) && (L = s.getDistance(this.x, this.y, P.x, P.y) - P.scale * 1.8,
L <= c.weapons[this.weaponIndex].range && (q = s.getDirection(P.x, P.y, this.x, this.y),
s.getAngleDist(q, this.dir) <= i.gatherAngle))) {
let V = c.weapons[this.weaponIndex].steal;
V && P.addResource && (V = min(P.points || 0, V),
this.addResource(3, V),
P.addResource(3, -V));
let z = O;
P.weaponIndex != null && c.weapons[P.weaponIndex].shield && s.getAngleDist(q + PI, P.dir) <= i.shieldAngle && (z = c.weapons[P.weaponIndex].shield);
const X = c.weapons[this.weaponIndex].dmg
, G = X * (this.skin && this.skin.dmgMultO ? this.skin.dmgMultO : 1) * (this.tail && this.tail.dmgMultO ? this.tail.dmgMultO : 1)
, te = .3 * (P.weightM || 1) + (c.weapons[this.weaponIndex].knock || 0);
P.xVel += te * at(q),
P.yVel += te * lt(q),
this.skin && this.skin.healD && this.changeHealth(G * z * this.skin.healD, this),
this.tail && this.tail.healD && this.changeHealth(G * z * this.tail.healD, this),
P.skin && P.skin.dmg && this.changeHealth(-X * P.skin.dmg, P),
P.tail && P.tail.dmg && this.changeHealth(-X * P.tail.dmg, P),
P.dmgOverTime && this.skin && this.skin.poisonDmg && !(P.skin && P.skin.poisonRes) && (P.dmgOverTime.dmg = this.skin.poisonDmg,
P.dmgOverTime.time = this.skin.poisonTime || 1,
P.dmgOverTime.doer = this),
P.dmgOverTime && S && !(P.skin && P.skin.poisonRes) && (P.dmgOverTime.dmg = 5,
P.dmgOverTime.time = 5,
P.dmgOverTime.doer = this),
P.skin && P.skin.dmgK && (this.xVel -= P.skin.dmgK * at(q),
this.yVel -= P.skin.dmgK * lt(q)),
P.changeHealth(-G * z, this, this)
}
this.sendAnimation(W ? 1 : 0)
}
,
this.hitVolcano = function(k) {
const S = 5 + round(k / 3.5);
this.addResource(2, S),
this.addResource(3, S)
}
,
this.sendAnimation = function(k) {
for (let S = 0; S < o.length; ++S)
this.sentTo[o[S].id] && this.canSee(o[S]) && p.send(o[S].id, "K", this.sid, k ? 1 : 0, this.weaponIndex)
}
;
let x = 0
, D = 0;
this.animate = function(k) {
this.animTime > 0 && (this.animTime -= k,
this.animTime <= 0 ? (this.animTime = 0,
this.dirPlus = 0,
x = 0,
D = 0) : D == 0 ? (x += k / (this.animSpeed * i.hitReturnRatio),
this.dirPlus = s.lerp(0, this.targetAngle, min(1, x)),
x >= 1 && (x = 1,
D = 1)) : (x -= k / (this.animSpeed * (1 - i.hitReturnRatio)),
this.dirPlus = s.lerp(0, this.targetAngle, max(0, x))))
}
,
this.startAnim = function(k, S) {
this.animTime = this.animSpeed = c.weapons[S].speed,
this.targetAngle = k ? -i.hitAngle : -PI,
x = 0,
D = 0
}
,
this.canSee = function(k) {
if (!k || k.skin && k.skin.invisTimer && k.noMovTimer >= k.skin.invisTimer)
return !1;
const S = _s(k.x - this.x) - k.scale
, O = _s(k.y - this.y) - k.scale;
return S <= i.maxScreenWidth / 2 * 1.3 && O <= i.maxScreenHeight / 2 * 1.3
}
}
const Bc = [{
id: 45,
name: "Shame!",
dontSell: !0,
price: 0,
scale: 120,
desc: "hacks are for losers"
}, {
id: 51,
name: "Moo Cap",
price: 0,
scale: 120,
desc: "coolest mooer around"
}, {
id: 50,
name: "Apple Cap",
price: 0,
scale: 120,
desc: "apple farms remembers"
}, {
id: 28,
name: "Moo Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 29,
name: "Pig Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 30,
name: "Fluff Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 36,
name: "Pandou Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 37,
name: "Bear Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 38,
name: "Monkey Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 44,
name: "Polar Head",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 35,
name: "Fez Hat",
price: 0,
scale: 120,
desc: "no effect"
}, {
id: 42,
name: "Enigma Hat",
price: 0,
scale: 120,
desc: "join the enigma army"
}, {
id: 43,
name: "Blitz Hat",
price: 0,
scale: 120,
desc: "hey everybody i'm blitz"
}, {
id: 49,
name: "Bob XIII Hat",
price: 0,
scale: 120,
desc: "like and subscribe"
}, {
id: 57,
name: "Pumpkin",
price: 50,
scale: 120,
desc: "Spooooky"
}, {
id: 8,
name: "Bummle Hat",
price: 100,
scale: 120,
desc: "no effect"
}, {
id: 2,
name: "Straw Hat",
price: 500,
scale: 120,
desc: "no effect"
}, {
id: 15,
name: "Winter Cap",
price: 600,
scale: 120,
desc: "allows you to move at normal speed in snow",
coldM: 1
}, {
id: 5,
name: "Cowboy Hat",
price: 1e3,
scale: 120,
desc: "no effect"
}, {
id: 4,
name: "Ranger Hat",
price: 2e3,
scale: 120,
desc: "no effect"
}, {
id: 18,
name: "Explorer Hat",
price: 2e3,
scale: 120,
desc: "no effect"
}, {
id: 31,
name: "Flipper Hat",
price: 2500,
scale: 120,
desc: "have more control while in water",
watrImm: !0
}, {
id: 1,
name: "Marksman Cap",
price: 3e3,
scale: 120,
desc: "increases arrow speed and range",
aMlt: 1.3
}, {
id: 10,
name: "Bush Gear",
price: 3e3,
scale: 160,
desc: "allows you to disguise yourself as a bush"
}, {
id: 48,
name: "Halo",
price: 3e3,
scale: 120,
desc: "no effect"
}, {
id: 6,
name: "Soldier Helmet",
price: 4e3,
scale: 120,
desc: "reduces damage taken but slows movement",
spdMult: .94,
dmgMult: .75
}, {
id: 23,
name: "Anti Venom Gear",
price: 4e3,
scale: 120,
desc: "makes you immune to poison",
poisonRes: 1
}, {
id: 13,
name: "Medic Gear",
price: 5e3,
scale: 110,
desc: "slowly regenerates health over time",
healthRegen: 3
}, {
id: 9,
name: "Miners Helmet",
price: 5e3,
scale: 120,
desc: "earn 1 extra gold per resource",
extraGold: 1
}, {
id: 32,
name: "Musketeer Hat",
price: 5e3,
scale: 120,
desc: "reduces cost of projectiles",
projCost: .5
}, {
id: 7,
name: "Bull Helmet",
price: 6e3,
scale: 120,
desc: "increases damage done but drains health",
healthRegen: -5,
dmgMultO: 1.5,
spdMult: .96
}, {
id: 22,
name: "Emp Helmet",
price: 6e3,
scale: 120,
desc: "turrets won't attack but you move slower",
antiTurret: 1,
spdMult: .7
}, {
id: 12,
name: "Booster Hat",
price: 6e3,
scale: 120,
desc: "increases your movement speed",
spdMult: 1.16
}, {
id: 26,
name: "Barbarian Armor",
price: 8e3,
scale: 120,
desc: "knocks back enemies that attack you",
dmgK: .6
}, {
id: 21,
name: "Plague Mask",
price: 1e4,
scale: 120,
desc: "melee attacks deal poison damage",
poisonDmg: 5,
poisonTime: 6
}, {
id: 46,
name: "Bull Mask",
price: 1e4,
scale: 120,
desc: "bulls won't target you unless you attack them",
bullRepel: 1
}, {
id: 14,
name: "Windmill Hat",
topSprite: !0,
price: 1e4,
scale: 120,
desc: "generates points while worn",
pps: 1.5
}, {
id: 11,
name: "Spike Gear",
topSprite: !0,
price: 1e4,
scale: 120,
desc: "deal damage to players that damage you",
dmg: .45
}, {
id: 53,
name: "Turret Gear",
topSprite: !0,
price: 1e4,
scale: 120,
desc: "you become a walking turret",
turret: {
proj: 1,
range: 700,
rate: 2500
},
spdMult: .7
}, {
id: 20,
name: "Samurai Armor",
price: 12e3,
scale: 120,
desc: "increased attack speed and fire rate",
atkSpd: .78
}, {
id: 58,
name: "Dark Knight",
price: 12e3,
scale: 120,
desc: "restores health when you deal damage",
healD: .4
}, {
id: 27,
name: "Scavenger Gear",
price: 15e3,
scale: 120,
desc: "earn double points for each kill",
kScrM: 2
}, {
id: 40,
name: "Tank Gear",
price: 15e3,
scale: 120,
desc: "increased damage to buildings but slower movement",
spdMult: .3,
bDmg: 3.3
}, {
id: 52,
name: "Thief Gear",
price: 15e3,
scale: 120,
desc: "steal half of a players gold when you kill them",
goldSteal: .5
}, {
id: 55,
name: "Bloodthirster",
price: 2e4,
scale: 120,
desc: "Restore Health when dealing damage. And increased damage",
healD: .25,
dmgMultO: 1.2
}, {
id: 56,
name: "Assassin Gear",
price: 2e4,
scale: 120,
desc: "Go invisible when not moving. Can't eat. Increased speed",
noEat: !0,
spdMult: 1.1,
invisTimer: 1e3
}]
, zc = [{
id: 12,
name: "Snowball",
price: 1e3,
scale: 105,
xOff: 18,
desc: "no effect"
}, {
id: 9,
name: "Tree Cape",
price: 1e3,
scale: 90,
desc: "no effect"
}, {
id: 10,
name: "Stone Cape",
price: 1e3,
scale: 90,
desc: "no effect"
}, {
id: 3,
name: "Cookie Cape",
price: 1500,
scale: 90,
desc: "no effect"
}, {
id: 8,
name: "Cow Cape",
price: 2e3,
scale: 90,
desc: "no effect"
}, {
id: 11,
name: "Monkey Tail",
price: 2e3,
scale: 97,
xOff: 25,
desc: "Super speed but reduced damage",
spdMult: 1.35,
dmgMultO: .2
}, {
id: 17,
name: "Apple Basket",
price: 3e3,
scale: 80,
xOff: 12,
desc: "slowly regenerates health over time",
healthRegen: 1
}, {
id: 6,
name: "Winter Cape",
price: 3e3,
scale: 90,
desc: "no effect"
}, {
id: 4,
name: "Skull Cape",
price: 4e3,
scale: 90,
desc: "no effect"
}, {
id: 5,
name: "Dash Cape",
price: 5e3,
scale: 90,
desc: "no effect"
}, {
id: 2,
name: "Dragon Cape",
price: 6e3,
scale: 90,
desc: "no effect"
}, {
id: 1,
name: "Super Cape",
price: 8e3,
scale: 90,
desc: "no effect"
}, {
id: 7,
name: "Troll Cape",
price: 8e3,
scale: 90,
desc: "no effect"
}, {
id: 14,
name: "Thorns",
price: 1e4,
scale: 115,
xOff: 20,
desc: "no effect"
}, {
id: 15,
name: "Blockades",
price: 1e4,
scale: 95,
xOff: 15,
desc: "no effect"
}, {
id: 20,
name: "Devils Tail",
price: 1e4,
scale: 95,
xOff: 20,
desc: "no effect"
}, {
id: 16,
name: "Sawblade",
price: 12e3,
scale: 90,
spin: !0,
xOff: 0,
desc: "deal damage to players that damage you",
dmg: .15
}, {
id: 13,
name: "Angel Wings",
price: 15e3,
scale: 138,
xOff: 22,
desc: "slowly regenerates health over time",
healthRegen: 3
}, {
id: 19,
name: "Shadow Wings",
price: 15e3,
scale: 138,
xOff: 22,
desc: "increased movement speed",
spdMult: 1.1
}, {
id: 18,
name: "Blood Wings",
price: 2e4,
scale: 178,
xOff: 26,
desc: "restores health when you deal damage",
healD: .2
}, {
id: 21,
name: "Corrupt X Wings",
price: 2e4,
scale: 178,
xOff: 26,
desc: "deal damage to players that damage you",
dmg: .25
}]
, $r = {
hats: Bc,
accessories: zc
};
function Hc(e, t, i, s, n, r, o) {
this.init = function(a, u, p, h, m, w, v, x, D) {
this.active = !0,
this.indx = a,
this.x = u,
this.y = p,
this.dir = h,
this.skipMov = !0,
this.speed = m,
this.dmg = w,
this.scale = x,
this.range = v,
this.owner = D,
o && (this.sentTo = {})
}
;
const l = [];
let c;
this.update = function(a) {
if (this.active) {
let p = this.speed * a, h;
if (this.skipMov ? this.skipMov = !1 : (this.x += p * cos(this.dir),
this.y += p * sin(this.dir),
this.range -= p,
this.range <= 0 && (this.x += this.range * cos(this.dir),
this.y += this.range * sin(this.dir),
p = 1,
this.range = 0,
this.active = !1)),
o) {
for (var u = 0; u < e.length; ++u)
!this.sentTo[e[u].id] && e[u].canSee(this) && (this.sentTo[e[u].id] = 1,
o.send(e[u].id, "X", r.fixTo(this.x, 1), r.fixTo(this.y, 1), r.fixTo(this.dir, 2), r.fixTo(this.range, 1), this.speed, this.indx, this.layer, this.sid));
l.length = 0;
for (var u = 0; u < e.length + t.length; ++u)
c = e[u] || t[u - e.length],
c.alive && c != this.owner && !(this.owner.team && c.team == this.owner.team) && r.lineInRect(c.x - c.scale, c.y - c.scale, c.x + c.scale, c.y + c.scale, this.x, this.y, this.x + p * cos(this.dir), this.y + p * sin(this.dir)) && l.push(c);
const m = i.getGridArrays(this.x, this.y, this.scale);
for (let w = 0; w < m.length; ++w)
for (let v = 0; v < m[w].length; ++v)
c = m[w][v],
h = c.getScale(),
c.active && this.ignoreObj != c.sid && this.layer <= c.layer && l.indexOf(c) < 0 && !c.ignoreCollision && r.lineInRect(c.x - h, c.y - h, c.x + h, c.y + h, this.x, this.y, this.x + p * cos(this.dir), this.y + p * sin(this.dir)) && l.push(c);
if (l.length > 0) {
let w = null
, v = null
, x = null;
for (var u = 0; u < l.length; ++u)
x = r.getDistance(this.x, this.y, l[u].x, l[u].y),
(v == null || x < v) && (v = x,
w = l[u]);
if (w.isPlayer || w.isAI) {
const D = .3 * (w.weightM || 1);
w.xVel += D * cos(this.dir),
w.yVel += D * sin(this.dir),
(w.weaponIndex == null || !(s.weapons[w.weaponIndex].shield && r.getAngleDist(this.dir + PI, w.dir) <= n.shieldAngle)) && w.changeHealth(-this.dmg, this.owner, this.owner)
} else {
w.projDmg && w.health && w.changeHealth(-this.dmg) && i.disableObj(w);
for (var u = 0; u < e.length; ++u)
e[u].active && (w.sentTo[e[u].id] && (w.active ? e[u].canSee(w) && o.send(e[u].id, "L", r.fixTo(this.dir, 2), w.sid) : o.send(e[u].id, "Q", w.sid)),
!w.active && w.owner == e[u] && e[u].changeItemCount(w.group.id, -1))
}
this.active = !1;
for (var u = 0; u < e.length; ++u)
this.sentTo[e[u].id] && o.send(e[u].id, "Y", this.sid, r.fixTo(v, 1))
}
}
}
}
}
var On = {}
, Fc = {
get exports() {
return On
},
set exports(e) {
On = e
}
}
, Rn = {}
, Vc = {
get exports() {
return Rn
},
set exports(e) {
Rn = e
}
};
(function() {
var e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
, t = {
rotl: function(i, s) {
return i << s | i >>> 32 - s
},
rotr: function(i, s) {
return i << 32 - s | i >>> s
},
endian: function(i) {
if (i.constructor == Number)
return t.rotl(i, 8) & 16711935 | t.rotl(i, 24) & 4278255360;
for (var s = 0; s < i.length; s++)
i[s] = t.endian(i[s]);
return i
},
randomBytes: function(i) {
for (var s = []; i > 0; i--)
s.push(floor(Math.random() * 256));
return s
},
bytesToWords: function(i) {
for (var s = [], n = 0, r = 0; n < i.length; n++,
r += 8)
s[r >>> 5] |= i[n] << 24 - r % 32;
return s
},
wordsToBytes: function(i) {
for (var s = [], n = 0; n < i.length * 32; n += 8)
s.push(i[n >>> 5] >>> 24 - n % 32 & 255);
return s
},
bytesToHex: function(i) {
for (var s = [], n = 0; n < i.length; n++)
s.push((i[n] >>> 4).toString(16)),
s.push((i[n] & 15).toString(16));
return s.join("")
},
hexToBytes: function(i) {
for (var s = [], n = 0; n < i.length; n += 2)
s.push(parseInt(i.substr(n, 2), 16));
return s
},
bytesToBase64: function(i) {
for (var s = [], n = 0; n < i.length; n += 3)
for (var r = i[n] << 16 | i[n + 1] << 8 | i[n + 2], o = 0; o < 4; o++)
n * 8 + o * 6 <= i.length * 8 ? s.push(e.charAt(r >>> 6 * (3 - o) & 63)) : s.push("=");
return s.join("")
},
base64ToBytes: function(i) {
i = i.replace(/[^A-Z0-9+\/]/ig, "");
for (var s = [], n = 0, r = 0; n < i.length; r = ++n % 4)
r != 0 && s.push((e.indexOf(i.charAt(n - 1)) & pow(2, -2 * r + 8) - 1) << r * 2 | e.indexOf(i.charAt(n)) >>> 6 - r * 2);
return s
}
};
Vc.exports = t
}
)();
var _n = {
utf8: {
stringToBytes: function(e) {
return _n.bin.stringToBytes(unescape(encodeURIComponent(e)))
},
bytesToString: function(e) {
return decodeURIComponent(escape(_n.bin.bytesToString(e)))
}
},
bin: {
stringToBytes: function(e) {
for (var t = [], i = 0; i < e.length; i++)
t.push(e.charCodeAt(i) & 255);
return t
},
bytesToString: function(e) {
for (var t = [], i = 0; i < e.length; i++)
t.push(String.fromCharCode(e[i]));
return t.join("")
}
}
}
, zs = _n;
/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
var Uc = function(e) {
return e != null && (Kr(e) || Lc(e) || !!e._isBuffer)
};
function Kr(e) {
return !!e.constructor && typeof e.constructor.isBuffer == "function" && e.constructor.isBuffer(e)
}
function Lc(e) {
return typeof e.readFloatLE == "function" && typeof e.slice == "function" && Kr(e.slice(0, 0))
}
(function() {
var e = Rn
, t = zs.utf8
, i = Uc
, s = zs.bin
, n = function(r, o) {
r.constructor == String ? o && o.encoding === "binary" ? r = s.stringToBytes(r) : r = t.stringToBytes(r) : i(r) ? r = Array.prototype.slice.call(r, 0) : !Array.isArray(r) && r.constructor !== Uint8Array && (r = r.toString());
for (var l = e.bytesToWords(r), c = r.length * 8, a = 1732584193, u = -271733879, p = -1732584194, h = 271733878, m = 0; m < l.length; m++)
l[m] = (l[m] << 8 | l[m] >>> 24) & 16711935 | (l[m] << 24 | l[m] >>> 8) & 4278255360;
l[c >>> 5] |= 128 << c % 32,
l[(c + 64 >>> 9 << 4) + 14] = c;
for (var w = n._ff, v = n._gg, x = n._hh, D = n._ii, m = 0; m < l.length; m += 16) {
var k = a
, S = u
, O = p
, U = h;
a = w(a, u, p, h, l[m + 0], 7, -680876936),
h = w(h, a, u, p, l[m + 1], 12, -389564586),
p = w(p, h, a, u, l[m + 2], 17, 606105819),
u = w(u, p, h, a, l[m + 3], 22, -1044525330),
a = w(a, u, p, h, l[m + 4], 7, -176418897),
h = w(h, a, u, p, l[m + 5], 12, 1200080426),
p = w(p, h, a, u, l[m + 6], 17, -1473231341),
u = w(u, p, h, a, l[m + 7], 22, -45705983),
a = w(a, u, p, h, l[m + 8], 7, 1770035416),
h = w(h, a, u, p, l[m + 9], 12, -1958414417),
p = w(p, h, a, u, l[m + 10], 17, -42063),
u = w(u, p, h, a, l[m + 11], 22, -1990404162),
a = w(a, u, p, h, l[m + 12], 7, 1804603682),
h = w(h, a, u, p, l[m + 13], 12, -40341101),
p = w(p, h, a, u, l[m + 14], 17, -1502002290),
u = w(u, p, h, a, l[m + 15], 22, 1236535329),
a = v(a, u, p, h, l[m + 1], 5, -165796510),
h = v(h, a, u, p, l[m + 6], 9, -1069501632),
p = v(p, h, a, u, l[m + 11], 14, 643717713),
u = v(u, p, h, a, l[m + 0], 20, -373897302),
a = v(a, u, p, h, l[m + 5], 5, -701558691),
h = v(h, a, u, p, l[m + 10], 9, 38016083),
p = v(p, h, a, u, l[m + 15], 14, -660478335),
u = v(u, p, h, a, l[m + 4], 20, -405537848),
a = v(a, u, p, h, l[m + 9], 5, 568446438),
h = v(h, a, u, p, l[m + 14], 9, -1019803690),
p = v(p, h, a, u, l[m + 3], 14, -187363961),
u = v(u, p, h, a, l[m + 8], 20, 1163531501),
a = v(a, u, p, h, l[m + 13], 5, -1444681467),
h = v(h, a, u, p, l[m + 2], 9, -51403784),
p = v(p, h, a, u, l[m + 7], 14, 1735328473),
u = v(u, p, h, a, l[m + 12], 20, -1926607734),
a = x(a, u, p, h, l[m + 5], 4, -378558),
h = x(h, a, u, p, l[m + 8], 11, -2022574463),
p = x(p, h, a, u, l[m + 11], 16, 1839030562),
u = x(u, p, h, a, l[m + 14], 23, -35309556),
a = x(a, u, p, h, l[m + 1], 4, -1530992060),
h = x(h, a, u, p, l[m + 4], 11, 1272893353),
p = x(p, h, a, u, l[m + 7], 16, -155497632),
u = x(u, p, h, a, l[m + 10], 23, -1094730640),
a = x(a, u, p, h, l[m + 13], 4, 681279174),
h = x(h, a, u, p, l[m + 0], 11, -358537222),
p = x(p, h, a, u, l[m + 3], 16, -722521979),
u = x(u, p, h, a, l[m + 6], 23, 76029189),
a = x(a, u, p, h, l[m + 9], 4, -640364487),
h = x(h, a, u, p, l[m + 12], 11, -421815835),
p = x(p, h, a, u, l[m + 15], 16, 530742520),
u = x(u, p, h, a, l[m + 2], 23, -995338651),
a = D(a, u, p, h, l[m + 0], 6, -198630844),
h = D(h, a, u, p, l[m + 7], 10, 1126891415),
p = D(p, h, a, u, l[m + 14], 15, -1416354905),
u = D(u, p, h, a, l[m + 5], 21, -57434055),
a = D(a, u, p, h, l[m + 12], 6, 1700485571),
h = D(h, a, u, p, l[m + 3], 10, -1894986606),
p = D(p, h, a, u, l[m + 10], 15, -1051523),
u = D(u, p, h, a, l[m + 1], 21, -2054922799),
a = D(a, u, p, h, l[m + 8], 6, 1873313359),
h = D(h, a, u, p, l[m + 15], 10, -30611744),
p = D(p, h, a, u, l[m + 6], 15, -1560198380),
u = D(u, p, h, a, l[m + 13], 21, 1309151649),
a = D(a, u, p, h, l[m + 4], 6, -145523070),
h = D(h, a, u, p, l[m + 11], 10, -1120210379),
p = D(p, h, a, u, l[m + 2], 15, 718787259),
u = D(u, p, h, a, l[m + 9], 21, -343485551),
a = a + k >>> 0,
u = u + S >>> 0,
p = p + O >>> 0,
h = h + U >>> 0
}
return e.endian([a, u, p, h])
};
n._ff = function(r, o, l, c, a, u, p) {
var h = r + (o & l | ~o & c) + (a >>> 0) + p;
return (h << u | h >>> 32 - u) + o
}
,
n._gg = function(r, o, l, c, a, u, p) {
var h = r + (o & c | l & ~c) + (a >>> 0) + p;
return (h << u | h >>> 32 - u) + o
}
,
n._hh = function(r, o, l, c, a, u, p) {
var h = r + (o ^ l ^ c) + (a >>> 0) + p;
return (h << u | h >>> 32 - u) + o
}
,
n._ii = function(r, o, l, c, a, u, p) {
var h = r + (l ^ (o | ~c)) + (a >>> 0) + p;
return (h << u | h >>> 32 - u) + o
}
,
n._blocksize = 16,
n._digestsize = 16,
Fc.exports = function(r, o) {
if (r == null)
throw new Error("Illegal argument " + r);
var l = e.wordsToBytes(n(r, o));
return o && o.asBytes ? l : o && o.asString ? s.bytesToString(l) : e.bytesToHex(l)
}
}
)();
var ji, Hs;
function Ge() {
if (Hs)
return ji;
Hs = 1;
function e(t, i, s, n, r, o) {
return {
tag: t,
key: i,
attrs: s,
children: n,
text: r,
dom: o,
domSize: void 0,
state: void 0,
events: void 0,
instance: void 0
}
}
return e.normalize = function(t) {
return Array.isArray(t) ? e("[", void 0, void 0, e.normalizeChildren(t), void 0, void 0) : t == null || typeof t == "boolean" ? null : typeof t == "object" ? t : e("#", void 0, void 0, String(t), void 0, void 0)
}
,
e.normalizeChildren = function(t) {
var i = [];
if (t.length) {
for (var s = t[0] != null && t[0].key != null, n = 1; n < t.length; n++)
if ((t[n] != null && t[n].key != null) !== s)
throw new TypeError(s && (t[n] != null || typeof t[n] == "boolean") ? "In fragments, vnodes must either all have keys or none have keys. You may wish to consider using an explicit keyed empty fragment, m.fragment({key: ...}), instead of a hole." : "In fragments, vnodes must either all have keys or none have keys.");
for (var n = 0; n < t.length; n++)
i[n] = e.normalize(t[n])
}
return i
}
,
ji = e,
ji
}
var Nc = Ge()
, Jr = function() {
var e = arguments[this], t = this + 1, i;
if (e == null ? e = {} : (typeof e != "object" || e.tag != null || Array.isArray(e)) && (e = {},
t = this),
arguments.length === t + 1)
i = arguments[t],
Array.isArray(i) || (i = [i]);
else
for (i = []; t < arguments.length; )
i.push(arguments[t++]);
return Nc("", e.key, e, i)
}
, Ci = {}.hasOwnProperty
, qc = Ge()
, Wc = Jr
, pt = Ci
, Xc = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g
, Qr = {};
function Fs(e) {
for (var t in e)
if (pt.call(e, t))
return !1;
return !0
}
function Gc(e) {
for (var t, i = "div", s = [], n = {}; t = Xc.exec(e); ) {
var r = t[1]
, o = t[2];
if (r === "" && o !== "")
i = o;
else if (r === "#")
n.id = o;
else if (r === ".")
s.push(o);
else if (t[3][0] === "[") {
var l = t[6];
l && (l = l.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")),
t[4] === "class" ? s.push(l) : n[t[4]] = l === "" ? l : l || !0
}
}
return s.length > 0 && (n.className = s.join(" ")),
Qr[e] = {
tag: i,
attrs: n
}
}
function Yc(e, t) {
var i = t.attrs
, s = pt.call(i, "class")
, n = s ? i.class : i.className;
if (t.tag = e.tag,
t.attrs = {},
!Fs(e.attrs) && !Fs(i)) {
var r = {};
for (var o in i)
pt.call(i, o) && (r[o] = i[o]);
i = r
}
for (var o in e.attrs)
pt.call(e.attrs, o) && o !== "className" && !pt.call(i, o) && (i[o] = e.attrs[o]);
(n != null || e.attrs.className != null) && (i.className = n != null ? e.attrs.className != null ? String(e.attrs.className) + " " + String(n) : n : e.attrs.className != null ? e.attrs.className : null),
s && (i.class = null);
for (var o in i)
if (pt.call(i, o) && o !== "key") {
t.attrs = i;
break
}
return t
}
function $c(e) {
if (e == null || typeof e != "string" && typeof e != "function" && typeof e.view != "function")
throw Error("The selector must be either a string or a component.");
var t = Wc.apply(1, arguments);
return typeof e == "string" && (t.children = qc.normalizeChildren(t.children),
e !== "[") ? Yc(Qr[e] || Gc(e), t) : (t.tag = e,
t)
}
var Zr = $c
, Kc = Ge()
, Jc = function(e) {
return e == null && (e = ""),
Kc("<", void 0, void 0, e, void 0, void 0)
}
, Qc = Ge()
, Zc = Jr
, jc = function() {
var e = Zc.apply(0, arguments);
return e.tag = "[",
e.children = Qc.normalizeChildren(e.children),
e
}
, ns = Zr;
ns.trust = Jc;
ns.fragment = jc;
var eh = ns, yi = {}, en = {
get exports() {
return yi
},
set exports(e) {
yi = e
}
}, tn, Vs;
function jr() {
if (Vs)
return tn;
Vs = 1;
var e = function(t) {
if (!(this instanceof e))
throw new Error("Promise must be called with 'new'.");
if (typeof t != "function")
throw new TypeError("executor must be a function.");
var i = this
, s = []
, n = []
, r = a(s, !0)
, o = a(n, !1)
, l = i._instance = {
resolvers: s,
rejectors: n
}
, c = typeof setImmediate == "function" ? setImmediate : setTimeout;
function a(p, h) {
return function m(w) {
var v;
try {
if (h && w != null && (typeof w == "object" || typeof w == "function") && typeof (v = w.then) == "function") {
if (w === i)
throw new TypeError("Promise can't be resolved with itself.");
u(v.bind(w))
} else
c(function() {
!h && p.length === 0 && console.error("Possible unhandled promise rejection:", w);
for (var x = 0; x < p.length; x++)
p[x](w);
s.length = 0,
n.length = 0,
l.state = h,
l.retry = function() {
m(w)
}
})
} catch (x) {
o(x)
}
}
}
function u(p) {
var h = 0;
function m(v) {
return function(x) {
h++ > 0 || v(x)
}
}
var w = m(o);
try {
p(m(r), w)
} catch (v) {
w(v)
}
}
u(t)
};
return e.prototype.then = function(t, i) {
var s = this
, n = s._instance;
function r(a, u, p, h) {
u.push(function(m) {
if (typeof a != "function")
p(m);
else
try {
o(a(m))
} catch (w) {
l && l(w)
}
}),
typeof n.retry == "function" && h === n.state && n.retry()
}
var o, l, c = new e(function(a, u) {
o = a,
l = u
}
);
return r(t, n.resolvers, o, !0),
r(i, n.rejectors, l, !1),
c
}
,
e.prototype.catch = function(t) {
return this.then(null, t)
}
,
e.prototype.finally = function(t) {
return this.then(function(i) {
return e.resolve(t()).then(function() {
return i
})
}, function(i) {
return e.resolve(t()).then(function() {
return e.reject(i)
}) // javedpension leaked
})
}
,
e.resolve = function(t) {
return t instanceof e ? t : new e(function(i) {
i(t)
}
)
}
,
e.reject = function(t) {
return new e(function(i, s) {
s(t)
}
)
}
,
e.all = function(t) {
return new e(function(i, s) {
var n = t.length
, r = 0
, o = [];
if (t.length === 0)
i([]);
else
for (var l = 0; l < t.length; l++)
(function(c) {
function a(u) {
r++,
o[c] = u,
r === n && i(o)
}
t[c] != null && (typeof t[c] == "object" || typeof t[c] == "function") && typeof t[c].then == "function" ? t[c].then(a, s) : a(t[c])
}
)(l)
}
)
}
,
e.race = function(t) {
return new e(function(i, s) {
for (var n = 0; n < t.length; n++)
t[n].then(i, s)
}
)
}
,
tn = e,
tn
}
var _t = jr();
typeof window < "u" ? (typeof window.Promise > "u" ? window.Promise = _t : window.Promise.prototype.finally || (window.Promise.prototype.finally = _t.prototype.finally),
en.exports = window.Promise) : typeof rt < "u" ? (typeof rt.Promise > "u" ? rt.Promise = _t : rt.Promise.prototype.finally || (rt.Promise.prototype.finally = _t.prototype.finally),
en.exports = rt.Promise) : en.exports = _t;
var nn, Us;
function th() {
if (Us)
return nn;
Us = 1;
var e = Ge();
return nn = function(t) {
var i = t && t.document, s, n = {
svg: "http://www.w3.org/2000/svg",
math: "http://www.w3.org/1998/Math/MathML"
};
function r(d) {
return d.attrs && d.attrs.xmlns || n[d.tag]
}
function o(d, f) {
if (d.state !== f)
throw new Error("'vnode.state' must not be modified.")
}
function l(d) {
var f = d.state;
try {
return this.apply(f, arguments)
} finally {
o(d, f)
}
}
function c() {
try {
return i.activeElement
} catch {
return null
}
}
function a(d, f, g, b, I, A, H) {
for (var N = g; N < b; N++) {
var B = f[N];
B != null && u(d, B, I, H, A)
}
}
function u(d, f, g, b, I) {
var A = f.tag;
if (typeof A == "string")
switch (f.state = {},
f.attrs != null && Fi(f.attrs, f, g),
A) {
case "#":
p(d, f, I);
break;
case "<":
m(d, f, b, I);
break;
case "[":
w(d, f, g, b, I);
break;
default:
v(d, f, g, b, I)
}
else
D(d, f, g, b, I)
}
function p(d, f, g) {
f.dom = i.createTextNode(f.children),
X(d, f.dom, g)
}
var h = {
caption: "table",
thead: "table",
tbody: "table",
tfoot: "table",
tr: "tbody",
th: "tr",
td: "tr",
colgroup: "table",
col: "colgroup"
};
function m(d, f, g, b) {
var I = f.children.match(/^\s*?<(\w+)/im) || []
, A = i.createElement(h[I[1]] || "div");
g === "http://www.w3.org/2000/svg" ? (A.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg">' + f.children + "</svg>",
A = A.firstChild) : A.innerHTML = f.children,
f.dom = A.firstChild,
f.domSize = A.childNodes.length,
f.instance = [];
for (var H = i.createDocumentFragment(), N; N = A.firstChild; )
f.instance.push(N),
H.appendChild(N);
X(d, H, b)
}
function w(d, f, g, b, I) {
var A = i.createDocumentFragment();
if (f.children != null) {
var H = f.children;
a(A, H, 0, H.length, g, null, b)
}
f.dom = A.firstChild,
f.domSize = A.childNodes.length,
X(d, A, I)
}
function v(d, f, g, b, I) {
var A = f.tag
, H = f.attrs
, N = H && H.is;
b = r(f) || b;
var B = b ? N ? i.createElementNS(b, A, {
is: N
}) : i.createElementNS(b, A) : N ? i.createElement(A, {
is: N
}) : i.createElement(A);
if (f.dom = B,
H != null && Bi(f, H, b),
X(d, B, I),
!G(f) && f.children != null) {
var Y = f.children;
a(B, Y, 0, Y.length, g, null, b),
f.tag === "select" && H != null && No(f, H)
}
}
function x(d, f) {
var g;
if (typeof d.tag.view == "function") {
if (d.state = Object.create(d.tag),
g = d.state.view,
g.$$reentrantLock$$ != null)
return;
g.$$reentrantLock$$ = !0
} else {
if (d.state = void 0,
g = d.tag,
g.$$reentrantLock$$ != null)
return;
g.$$reentrantLock$$ = !0,
d.state = d.tag.prototype != null && typeof d.tag.prototype.view == "function" ? new d.tag(d) : d.tag(d)
}
if (Fi(d.state, d, f),
d.attrs != null && Fi(d.attrs, d, f),
d.instance = e.normalize(l.call(d.state.view, d)),
d.instance === d)
throw Error("A view cannot return the vnode it received as argument");
g.$$reentrantLock$$ = null
}
function D(d, f, g, b, I) {
x(f, g),
f.instance != null ? (u(d, f.instance, g, b, I),
f.dom = f.instance.dom,
f.domSize = f.dom != null ? f.instance.domSize : 0) : f.domSize = 0
}
function k(d, f, g, b, I, A) {
if (!(f === g || f == null && g == null))
if (f == null || f.length === 0) // javedpension leaked
a(d, g, 0, g.length, b, I, A);
else if (g == null || g.length === 0)
te(d, f, 0, f.length);
else {
var H = f[0] != null && f[0].key != null
, N = g[0] != null && g[0].key != null
, B = 0
, Y = 0;
if (!H)
for (; Y < f.length && f[Y] == null; )
Y++;
if (!N)
for (; B < g.length && g[B] == null; )
B++;
if (H !== N)
te(d, f, Y, f.length),
a(d, g, B, g.length, b, I, A);
else if (N) {
for (var ve = f.length - 1, fe = g.length - 1, ni, xe, oe, ge, Z, Li; ve >= Y && fe >= B && (ge = f[ve],
Z = g[fe],
ge.key === Z.key); )
ge !== Z && S(d, ge, Z, b, I, A),
Z.dom != null && (I = Z.dom),
ve--,
fe--;
for (; ve >= Y && fe >= B && (xe = f[Y],
oe = g[B],
xe.key === oe.key); )
Y++,
B++,
xe !== oe && S(d, xe, oe, b, $(f, Y, I), A);
for (; ve >= Y && fe >= B && !(B === fe || xe.key !== Z.key || ge.key !== oe.key); )
Li = $(f, Y, I),
V(d, ge, Li),
ge !== oe && S(d, ge, oe, b, Li, A),
++B <= --fe && V(d, xe, I),
xe !== Z && S(d, xe, Z, b, I, A),
Z.dom != null && (I = Z.dom),
Y++,
ve--,
ge = f[ve],
Z = g[fe],
xe = f[Y],
oe = g[B];
for (; ve >= Y && fe >= B && ge.key === Z.key; )
ge !== Z && S(d, ge, Z, b, I, A),
Z.dom != null && (I = Z.dom),
ve--,
fe--,
ge = f[ve],
Z = g[fe];
if (B > fe)
te(d, f, Y, ve + 1);
else if (Y > ve)
a(d, g, B, fe + 1, b, I, A);
else {
var $o = I, Ps = fe - B + 1, At = new Array(Ps), Ni = 0, ne = 0, qi = 2147483647, Wi = 0, ni, Xi;
for (ne = 0; ne < Ps; ne++)
At[ne] = -1;
for (ne = fe; ne >= B; ne--) {
ni == null && (ni = W(f, Y, ve + 1)),
Z = g[ne];
var st = ni[Z.key];
st != null && (qi = st < qi ? st : -1,
At[ne - B] = st,
ge = f[st],
f[st] = null,
ge !== Z && S(d, ge, Z, b, I, A),
Z.dom != null && (I = Z.dom),
Wi++)
}
if (I = $o,
Wi !== ve - Y + 1 && te(d, f, Y, ve + 1),
Wi === 0)
a(d, g, B, fe + 1, b, I, A);
else if (qi === -1)
for (Xi = _(At),
Ni = Xi.length - 1,
ne = fe; ne >= B; ne--)
oe = g[ne],
At[ne - B] === -1 ? u(d, oe, b, A, I) : Xi[Ni] === ne - B ? Ni-- : V(d, oe, I),
oe.dom != null && (I = g[ne].dom);
else
for (ne = fe; ne >= B; ne--)
oe = g[ne],
At[ne - B] === -1 && u(d, oe, b, A, I),
oe.dom != null && (I = g[ne].dom)
}
} else {
var Ui = f.length < g.length ? f.length : g.length;
for (B = B < Y ? B : Y; B < Ui; B++)
xe = f[B],
oe = g[B],
!(xe === oe || xe == null && oe == null) && (xe == null ? u(d, oe, b, A, $(f, B + 1, I)) : oe == null ? ie(d, xe) : S(d, xe, oe, b, $(f, B + 1, I), A));
f.length > Ui && te(d, f, B, f.length),
g.length > Ui && a(d, g, B, g.length, b, I, A)
}
}
}
function S(d, f, g, b, I, A) {
var H = f.tag
, N = g.tag;
if (H === N) {
if (g.state = f.state,
g.events = f.events,
Yo(g, f))
return;
if (typeof H == "string")
switch (g.attrs != null && Vi(g.attrs, g, b),
H) {
case "#":
O(f, g);
break;
case "<":
U(d, f, g, A, I);
break;
case "[":
L(d, f, g, b, I, A);
break;
default:
q(f, g, b, A)
}
else
P(d, f, g, b, I, A)
} else
ie(d, f),
u(d, g, b, A, I)
}
function O(d, f) {
d.children.toString() !== f.children.toString() && (d.dom.nodeValue = f.children),
f.dom = d.dom
}
function U(d, f, g, b, I) {
f.children !== g.children ? (K(d, f),
m(d, g, b, I)) : (g.dom = f.dom,
g.domSize = f.domSize,
g.instance = f.instance)
}
function L(d, f, g, b, I, A) {
k(d, f.children, g.children, b, I, A);
var H = 0
, N = g.children;
if (g.dom = null,
N != null) {
for (var B = 0; B < N.length; B++) {
var Y = N[B];
Y != null && Y.dom != null && (g.dom == null && (g.dom = Y.dom),
H += Y.domSize || 1)
}
H !== 1 && (g.domSize = H)
}
}
function q(d, f, g, b) {
var I = f.dom = d.dom;
b = r(f) || b,
f.tag === "textarea" && f.attrs == null && (f.attrs = {}),
qo(f, d.attrs, f.attrs, b),
G(f) || k(I, d.children, f.children, g, null, b)
}
function P(d, f, g, b, I, A) {
if (g.instance = e.normalize(l.call(g.state.view, g)),
g.instance === g)
throw Error("A view cannot return the vnode it received as argument");
Vi(g.state, g, b),
g.attrs != null && Vi(g.attrs, g, b),
g.instance != null ? (f.instance == null/*javedpension leaked*/ ? u(d, g.instance, b, A, I) : S(d, f.instance, g.instance, b, I, A),
g.dom = g.instance.dom,
g.domSize = g.instance.domSize) : f.instance != null ? (ie(d, f.instance),
g.dom = void 0,
g.domSize = 0) : (g.dom = f.dom,
g.domSize = f.domSize)
}
function W(d, f, g) {
for (var b = Object.create(null); f < g; f++) {
var I = d[f];
if (I != null) {
var A = I.key;
A != null && (b[A] = f)
}
}
return b
}
var F = [];
function _(d) {
for (var f = [0], g = 0, b = 0, I = 0, A = F.length = d.length, I = 0; I < A; I++)
F[I] = d[I];
for (var I = 0; I < A; ++I)
if (d[I] !== -1) {
var H = f[f.length - 1];
if (d[H] < d[I]) {
F[I] = H,
f.push(I);
continue
}
for (g = 0,
b = f.length - 1; g < b; ) {
var N = (g >>> 1) + (b >>> 1) + (g & b & 1);
d[f[N]] < d[I] ? g = N + 1 : b = N
}
d[I] < d[f[g]] && (g > 0 && (F[I] = f[g - 1]),
f[g] = I)
}
for (g = f.length,
b = f[g - 1]; g-- > 0; )
f[g] = b,
b = F[b];
return F.length = 0,
f
}
function $(d, f, g) {
for (; f < d.length; f++)
if (d[f] != null && d[f].dom != null)
return d[f].dom;
return g
}
function V(d, f, g) {
var b = i.createDocumentFragment();
z(d, b, f),
X(d, b, g)
}
function z(d, f, g) {
for (; g.dom != null && g.dom.parentNode === d; ) {
if (typeof g.tag != "string") {
if (g = g.instance,
g != null)
continue
} else if (g.tag === "<")
for (var b = 0; b < g.instance.length; b++)
f.appendChild(g.instance[b]);
else if (g.tag !== "[")
f.appendChild(g.dom);
else if (g.children.length === 1) {
if (g = g.children[0],
g != null)
continue
} else
for (var b = 0; b < g.children.length; b++) {
var I = g.children[b];
I != null && z(d, f, I)
}
break
}
}
function X(d, f, g) {
g != null ? d.insertBefore(f, g) : d.appendChild(f)
}
function G(d) {
if (d.attrs == null || d.attrs.contenteditable == null && d.attrs.contentEditable == null)
return !1;
var f = d.children;
if (f != null && f.length === 1 && f[0].tag === "<") {
var g = f[0].children;
d.dom.innerHTML !== g && (d.dom.innerHTML = g)
} else if (f != null && f.length !== 0)
throw new Error("Child node of a contenteditable must be trusted.");
return !0
}
function te(d, f, g, b) {
for (var I = g; I < b; I++) {
var A = f[I];
A != null && ie(d, A)
}
}
function ie(d, f) {
var g = 0, b = f.state, I, A;
if (typeof f.tag != "string" && typeof f.state.onbeforeremove == "function") {
var H = l.call(f.state.onbeforeremove, f);
H != null && typeof H.then == "function" && (g = 1,
I = H)
}
if (f.attrs && typeof f.attrs.onbeforeremove == "function") {
var H = l.call(f.attrs.onbeforeremove, f);
H != null && typeof H.then == "function" && (g |= 2,
A = H)
}
if (o(f, b),
!g)
nt(f),
ke(d, f);
else {
if (I != null) {
var N = function() {
g & 1 && (g &= 2,
g || B())
};
I.then(N, N)
}
if (A != null) {
var N = function() {
g & 2 && (g &= 1,
g || B())
};
A.then(N, N)
}
}
function B() {
o(f, b),
nt(f),
ke(d, f)
}
}
function K(d, f) {
for (var g = 0; g < f.instance.length; g++)
d.removeChild(f.instance[g])
}
function ke(d, f) {
for (; f.dom != null && f.dom.parentNode === d; ) {
if (typeof f.tag != "string") {
if (f = f.instance,
f != null)
continue
} else if (f.tag === "<")
K(d, f);
else {
if (f.tag !== "[" && (d.removeChild(f.dom),
!Array.isArray(f.children)))
break;
if (f.children.length === 1) {
if (f = f.children[0],
f != null)
continue
} else
for (var g = 0; g < f.children.length; g++) {
var b = f.children[g];
b != null && ke(d, b)
}
}
break
}
}
function nt(d) {
if (typeof d.tag != "string" && typeof d.state.onremove == "function" && l.call(d.state.onremove, d),
d.attrs && typeof d.attrs.onremove == "function" && l.call(d.attrs.onremove, d),
typeof d.tag != "string")
d.instance != null && nt(d.instance);
else {
var f = d.children;
if (Array.isArray(f))
for (var g = 0; g < f.length; g++) {
var b = f[g];
b != null && nt(b)
}
}
}
function Bi(d, f, g) {
d.tag === "input" && f.type != null && d.dom.setAttribute("type", f.type);
var b = f != null && d.tag === "input" && f.type === "file";
for (var I in f)
Ue(d, I, null, f[I], g, b)
}
function Ue(d, f, g, b, I, A) {
if (!(f === "key" || f === "is" || b == null || Ts(f) || g === b && !Wo(d, f) && typeof b != "object" || f === "type" && d.tag === "input")) {
if (f[0] === "o" && f[1] === "n")
return Es(d, f, b);
if (f.slice(0, 6) === "xlink:")
d.dom.setAttributeNS("http://www.w3.org/1999/xlink", f.slice(6), b);
else if (f === "style")
Ms(d.dom, g, b);
else if (Is(d, f, I)) {
if (f === "value") {
if ((d.tag === "input" || d.tag === "textarea") && d.dom.value === "" + b && (A || d.dom === c()) || d.tag === "select" && g !== null && d.dom.value === "" + b || d.tag === "option" && g !== null && d.dom.value === "" + b)
return;
if (A && "" + b != "") {
console.error("`value` is read-only on file inputs!");
return
}
}
d.dom[f] = b
} else
typeof b == "boolean" ? b ? d.dom.setAttribute(f, "") : d.dom.removeAttribute(f) : d.dom.setAttribute(f === "className" ? "class" : f, b)
}
}
function Ye(d, f, g, b) {
if (!(f === "key" || f === "is" || g == null || Ts(f)))
if (f[0] === "o" && f[1] === "n")
Es(d, f, void 0);
else if (f === "style")
Ms(d.dom, g, null);
else if (Is(d, f, b) && f !== "className" && f !== "title" && !(f === "value" && (d.tag === "option" || d.tag === "select" && d.dom.selectedIndex === -1 && d.dom === c())) && !(d.tag === "input" && f === "type"))
d.dom[f] = null;
else {
var I = f.indexOf(":");
I !== -1 && (f = f.slice(I + 1)),
g !== !1 && d.dom.removeAttribute(f === "className" ? "class" : f)
}
}
function No(d, f) {
if ("value"in f)
if (f.value === null)
d.dom.selectedIndex !== -1 && (d.dom.value = null);
else {
var g = "" + f.value;
(d.dom.value !== g || d.dom.selectedIndex === -1) && (d.dom.value = g)
}
"selectedIndex"in f && Ue(d, "selectedIndex", null, f.selectedIndex, void 0)
}
function qo(d, f, g, b) {
if (f && f === g && console.warn("Don't reuse attrs object, use new object for every redraw, this will throw in next major"),
g != null) {
d.tag === "input" && g.type != null && d.dom.setAttribute("type", g.type);
var I = d.tag === "input" && g.type === "file";
for (var A in g)
Ue(d, A, f && f[A], g[A], b, I)
}
var H;
if (f != null)
for (var A in f)
(H = f[A]) != null && (g == null || g[A] == null) && Ye(d, A, H, b)
}
function Wo(d, f) {
return f === "value" || f === "checked" || f === "selectedIndex" || f === "selected" && d.dom === c() || d.tag === "option" && d.dom.parentNode === i.activeElement
}
function Ts(d) {
return d === "oninit" || d === "oncreate" || d === "onupdate" || d === "onremove" || d === "onbeforeremove" || d === "onbeforeupdate"
}
function Is(d, f, g) {
return g === void 0 && (d.tag.indexOf("-") > -1 || d.attrs != null && d.attrs.is || f !== "href" && f !== "list" && f !== "form" && f !== "width" && f !== "height") && f in d.dom
}
var Xo = /[A-Z]/g;
function Go(d) {
return "-" + d.toLowerCase()
}
function zi(d) {
return d[0] === "-" && d[1] === "-" ? d : d === "cssFloat" ? "float" : d.replace(Xo, Go)
}
function Ms(d, f, g) {
if (f !== g)
if (g == null)
d.style.cssText = "";
else if (typeof g != "object")
d.style.cssText = g;
else if (f == null || typeof f != "object") {
d.style.cssText = "";
for (var b in g) {
var I = g[b];
I != null && d.style.setProperty(zi(b), String(I))
}
} else {
for (var b in g) {
var I = g[b];
I != null && (I = String(I)) !== String(f[b]) && d.style.setProperty(zi(b), I)
}
for (var b in f)
f[b] != null && g[b] == null && d.style.removeProperty(zi(b))
}
}
function Hi() {
this._ = s
}
Hi.prototype = Object.create(null),
Hi.prototype.handleEvent = function(d) {
var f = this["on" + d.type], g;
typeof f == "function" ? g = f.call(d.currentTarget, d) : typeof f.handleEvent == "function" && f.handleEvent(d),
this._ && d.redraw !== !1 && (0,
this._)(),
g === !1 && (d.preventDefault(),
d.stopPropagation())
}
;
function Es(d, f, g) {
if (d.events != null) {
if (d.events._ = s,
d.events[f] === g)
return;
g != null && (typeof g == "function" || typeof g == "object") ? (d.events[f] == null && d.dom.addEventListener(f.slice(2), d.events, !1),
d.events[f] = g) : (d.events[f] != null && d.dom.removeEventListener(f.slice(2), d.events, !1),
d.events[f] = void 0)
} else
g != null && (typeof g == "function" || typeof g == "object") && (d.events = new Hi,
d.dom.addEventListener(f.slice(2), d.events, !1),
d.events[f] = g)
}
function Fi(d, f, g) {
typeof d.oninit == "function" && l.call(d.oninit, f),
typeof d.oncreate == "function" && g.push(l.bind(d.oncreate, f))
}
function Vi(d, f, g) {
typeof d.onupdate == "function" && g.push(l.bind(d.onupdate, f))
}
function Yo(d, f) {
do {
if (d.attrs != null && typeof d.attrs.onbeforeupdate == "function") {
var g = l.call(d.attrs.onbeforeupdate, d, f);
if (g !== void 0 && !g)
break
}
if (typeof d.tag != "string" && typeof d.state.onbeforeupdate == "function") {
var g = l.call(d.state.onbeforeupdate, d, f);
if (g !== void 0 && !g)
break
}
return !1
} while (!1);
return d.dom = f.dom,
d.domSize = f.domSize,
d.instance = f.instance,
d.attrs = f.attrs,
d.children = f.children,
d.text = f.text,
!0
}
var Ct;
return function(d, f, g) {
if (!d)
throw new TypeError("DOM element being rendered to does not exist.");
if (Ct != null && d.contains(Ct))
throw new TypeError("Node is currently being rendered to and thus is locked.");
var b = s
, I = Ct
, A = []
, H = c()
, N = d.namespaceURI;
Ct = d,
s = typeof g == "function" ? g : void 0;
try {
d.vnodes == null && (d.textContent = ""),
f = e.normalizeChildren(Array.isArray(f) ? f : [f]),
k(d, d.vnodes, f, A, null, N === "http://www.w3.org/1999/xhtml" ? void 0 : N),
d.vnodes = f,
H != null && c() !== H && typeof H.focus == "function" && H.focus();
for (var B = 0; B < A.length; B++)
A[B]()
} finally {
s = b,
Ct = I
}
}
}
,
nn
}
var sn, Ls;
function eo() {
return Ls || (Ls = 1,
sn = th()(typeof window < "u" ? window : null)),
sn
}
var Ns = Ge(), ih = function(e, t, i) {
var s = []
, n = !1
, r = -1;
function o() {
for (r = 0; r < s.length; r += 2)
try {
e(s[r], Ns(s[r + 1]), l)
} catch (a) {
i.error(a)
}
r = -1
}
function l() {
n || (n = !0,
t(function() {
n = !1,
o()
}))
}
l.sync = o;
function c(a, u) {
if (u != null && u.view == null && typeof u != "function")
throw new TypeError("m.mount expects a component, not a vnode.");
var p = s.indexOf(a);
p >= 0 && (s.splice(p, 2),
p <= r && (r -= 2),
e(a, [])),
u != null && (s.push(a, u),
e(a, Ns(u), l))
}
return {
mount: c,
redraw: l
}
}, nh = eo(), ss = ih(nh, typeof requestAnimationFrame < "u" ? requestAnimationFrame : null, typeof console < "u" ? console : null), rn, qs;
function to() {
return qs || (qs = 1,
rn = function(e) {
if (Object.prototype.toString.call(e) !== "[object Object]")
return "";
var t = [];
for (var i in e)
s(i, e[i]);
return t.join("&");
function s(n, r) {
if (Array.isArray(r))
for (var o = 0; o < r.length; o++)
s(n + "[" + o + "]", r[o]);
else if (Object.prototype.toString.call(r) === "[object Object]")
for (var o in r)
s(n + "[" + o + "]", r[o]);
else
t.push(encodeURIComponent(n) + (r != null && r !== "" ? "=" + encodeURIComponent(r) : ""))
}
}
),
rn
}
var on, Ws;
function io() {
if (Ws)
return on;
Ws = 1;
var e = Ci;
return on = Object.assign || function(t, i) {
for (var s in i)
e.call(i, s) && (t[s] = i[s])
}
,
on
}
var an, Xs;
function rs() {
if (Xs)
return an;
Xs = 1;
var e = to()
, t = io();
return an = function(i, s) {
if (/:([^\/\.-]+)(\.{3})?:/.test(i))
throw new SyntaxError("Template parameter names must be separated by either a '/', '-', or '.'.");
if (s == null)
return i;
var n = i.indexOf("?")
, r = i.indexOf("#")
, o = r < 0 ? i.length : r
, l = n < 0 ? o : n
, c = i.slice(0, l)
, a = {};
t(a, s);
var u = c.replace(/:([^\/\.-]+)(\.{3})?/g, function(D, k, S) {
return delete a[k],
s[k] == null ? D : S ? s[k] : encodeURIComponent(String(s[k]))
})
, p = u.indexOf("?")
, h = u.indexOf("#")
, m = h < 0 ? u.length : h
, w = p < 0 ? m : p
, v = u.slice(0, w);
n >= 0 && (v += i.slice(n, o)),
p >= 0 && (v += (n < 0 ? "?" : "&") + u.slice(p, m));
var x = e(a);
return x && (v += (n < 0 && p < 0 ? "?" : "&") + x),
r >= 0 && (v += i.slice(r)),
h >= 0 && (v += (r < 0 ? "" : "&") + u.slice(h)),
v
}
,
an
}
var sh = rs(), Gs = Ci, rh = function(e, t, i) {
var s = 0;
function n(l) {
return new t(l)
}
n.prototype = t.prototype,
n.__proto__ = t;
function r(l) {
return function(c, a) {
typeof c != "string" ? (a = c,
c = c.url) : a == null && (a = {});
var u = new t(function(w, v) {
l(sh(c, a.params), a, function(x) {
if (typeof a.type == "function")
if (Array.isArray(x))
for (var D = 0; D < x.length; D++)
x[D] = new a.type(x[D]);
else
x = new a.type(x);
w(x)
}, v)
}
);
if (a.background === !0)
return u;
var p = 0;
function h() {
--p === 0 && typeof i == "function" && i()
}
return m(u);
function m(w) {
var v = w.then;
return w.constructor = n,
w.then = function() {
p++;
var x = v.apply(w, arguments);
return x.then(h, function(D) {
if (h(),
p === 0)
throw D
}),
m(x)
}
,
w
}
}
}
function o(l, c) {
for (var a in l.headers)
if (Gs.call(l.headers, a) && a.toLowerCase() === c)
return !0;
return !1
}
return {
request: r(function(l, c, a, u) {
var p = c.method != null ? c.method.toUpperCase() : "GET", h = c.body, m = (c.serialize == null || c.serialize === JSON.serialize) && !(h instanceof e.FormData || h instanceof e.URLSearchParams), w = c.responseType || (typeof c.extract == "function" ? "" : "json"), v = new e.XMLHttpRequest, x = !1, D = !1, k = v, S, O = v.abort;
v.abort = function() {
x = !0,
O.call(this)
}
,
v.open(p, l, c.async !== !1, typeof c.user == "string" ? c.user : void 0, typeof c.password == "string" ? c.password : void 0),
m && h != null && !o(c, "content-type") && v.setRequestHeader("Content-Type", "application/json; charset=utf-8"),
typeof c.deserialize != "function" && !o(c, "accept") && v.setRequestHeader("Accept", "application/json, text/*"),
c.withCredentials && (v.withCredentials = c.withCredentials),
c.timeout && (v.timeout = c.timeout),
v.responseType = w;
for (var U in c.headers)
Gs.call(c.headers, U) && v.setRequestHeader(U, c.headers[U]);
v.onreadystatechange = function(L) {
if (!x && L.target.readyState === 4)
try {
var q = L.target.status >= 200 && L.target.status < 300 || L.target.status === 304 || /^file:\/\//i.test(l), P = L.target.response, W;
if (w === "json") {
if (!L.target.responseType && typeof c.extract != "function")
try {
P = JSONParse(L.target.responseText)
} catch {
P = null
}
} else
(!w || w === "text") && P == null && (P = L.target.responseText);
if (typeof c.extract == "function" ? (P = c.extract(L.target, c),
q = !0) : typeof c.deserialize == "function" && (P = c.deserialize(P)),
q)
a(P);
else {
var F = function() {
try {
W = L.target.responseText
} catch {
W = P
}
var _ = new Error(W);
_.code = L.target.status,
_.response = P,
u(_)
};
v.status === 0 ? setTimeout(function() {
D || F()
}) : F()
}
} catch (_) {
u(_)
}
}
,
v.ontimeout = function(L) {
D = !0;
var q = new Error("Request timed out");
q.code = L.target.status,
u(q)
}
,
typeof c.config == "function" && (v = c.config(v, c, l) || v,
v !== k && (S = v.abort,
v.abort = function() {
x = !0,
S.call(this)
}
)),
h == null ? v.send() : typeof c.serialize == "function" ? v.send(c.serialize(h)) : h instanceof e.FormData || h instanceof e.URLSearchParams ? v.send(h) : v.send(JSONStringify(h))
}),
jsonp: r(function(l, c, a, u) {
var p = c.callbackName || "_mithril_" + round(Math.random() * 1e16) + "_" + s++
, h = e.document.createElement("script");
e[p] = function(m) {
delete e[p],
h.parentNode.removeChild(h),
a(m)
}
,
h.onerror = function() {
delete e[p],
h.parentNode.removeChild(h),
u(new Error("JSONP request failed"))
}
,
h.src = l + (l.indexOf("?") < 0 ? "?" : "&") + encodeURIComponent(c.callbackKey || "callback") + "=" + encodeURIComponent(p),
e.document.documentElement.appendChild(h)
})
}
}, oh = yi, ah = ss, lh = rh(typeof window < "u" ? window : null, oh, ah.redraw), ln, Ys;
function no() {
if (Ys)
return ln;
Ys = 1;
function e(t) {
try {
return decodeURIComponent(t)
} catch {
return t
}
}
return ln = function(t) {
if (t === "" || t == null)
return {};
t.charAt(0) === "?" && (t = t.slice(1));
for (var i = t.split("&"), s = {}, n = {}, r = 0; r < i.length; r++) {
var o = i[r].split("=")
, l = e(o[0])
, c = o.length === 2 ? e(o[1]) : "";
c === "true" ? c = !0 : c === "false" && (c = !1);
var a = l.split(/\]\[?|\[/)
, u = n;
l.indexOf("[") > -1 && a.pop();
for (var p = 0; p < a.length; p++) {
var h = a[p]
, m = a[p + 1]
, w = m == "" || !isNaN(parseInt(m, 10));
if (h === "") {
var l = a.slice(0, p).join();
s[l] == null && (s[l] = Array.isArray(u) ? u.length : 0),
h = s[l]++
} else if (h === "__proto__")
break;
if (p === a.length - 1)
u[h] = c;
else {
var v = Object.getOwnPropertyDescriptor(u, h);
v != null && (v = v.value),
v == null && (u[h] = v = w ? [] : {}),
u = v
}
}
}
return n
}
,
ln
}
var cn, $s;
function os() {
if ($s)
return cn;
$s = 1;
var e = no();
return cn = function(t) {
var i = t.indexOf("?")
, s = t.indexOf("#")
, n = s < 0 ? t.length : s
, r = i < 0 ? n : i
, o = t.slice(0, r).replace(/\/{2,}/g, "/");
return o ? (o[0] !== "/" && (o = "/" + o),
o.length > 1 && o[o.length - 1] === "/" && (o = o.slice(0, -1))) : o = "/",
{
path: o,
params: i < 0 ? {} : e(t.slice(i + 1, n))
}
}
,
cn
}
var hn, Ks;
function ch() {
if (Ks)
return hn;
Ks = 1;
var e = os();
return hn = function(t) {
var i = e(t)
, s = Object.keys(i.params)
, n = []
, r = new RegExp("^" + i.path.replace(/:([^\/.-]+)(\.{3}|\.(?!\.)|-)?|[\\^$*+.()|\[\]{}]/g, function(o, l, c) {
return l == null ? "\\" + o : (n.push({
k: l,
r: c === "..."
}),
c === "..." ? "(.*)" : c === "." ? "([^/]+)\\." : "([^/]+)" + (c || ""))
}) + "$");
return function(o) {
for (var l = 0; l < s.length; l++)
if (i.params[s[l]] !== o.params[s[l]])
return !1;
if (!n.length)
return r.test(o.path);
var c = r.exec(o.path);
if (c == null)
return !1;
for (var l = 0; l < n.length; l++)
o.params[n[l].k] = n[l].r ? c[l + 1] : decodeURIComponent(c[l + 1]);
return !0
}
}
,
hn
}
var fn, Js;
function so() {
if (Js)
return fn;
Js = 1;
var e = Ci
, t = new RegExp("^(?:key|oninit|oncreate|onbeforeupdate|onupdate|onbeforeremove|onremove)$");
return fn = function(i, s) {
var n = {};
if (s != null)
for (var r in i)
e.call(i, r) && !t.test(r) && s.indexOf(r) < 0 && (n[r] = i[r]);
else
for (var r in i)
e.call(i, r) && !t.test(r) && (n[r] = i[r]);
return n
}
,
fn
}
var un, Qs;
function hh() {
if (Qs)
return un;
Qs = 1;
var e = Ge()
, t = Zr
, i = yi
, s = rs()
, n = os()
, r = ch()
, o = io()
, l = so()
, c = {};
function a(u) {
try {
return decodeURIComponent(u)
} catch {
return u
}
}
return un = function(u, p) {
var h = u == null ? null : typeof u.setImmediate == "function" ? u.setImmediate : u.setTimeout, m = i.resolve(), w = !1, v = !1, x = 0, D, k, S = c, O, U, L, q, P = {
onbeforeupdate: function() {
return x = x ? 2 : 1,
!(!x || c === S)
},
onremove: function() {
u.removeEventListener("popstate", _, !1),
u.removeEventListener("hashchange", F, !1)
},
view: function() {
if (!(!x || c === S)) {
var z = [e(O, U.key, U)];
return S && (z = S.render(z[0])),
z
}
}
}, W = V.SKIP = {};
function F() {
w = !1;
var z = u.location.hash;
V.prefix[0] !== "#" && (z = u.location.search + z,
V.prefix[0] !== "?" && (z = u.location.pathname + z,
z[0] !== "/" && (z = "/" + z)));
var X = z.concat().replace(/(?:%[a-f89][a-f0-9])+/gim, a).slice(V.prefix.length)
, G = n(X);
o(G.params, u.history.state);
function te(K) {
console.error(K),
$(k, null, {
replace: !0
})
}
ie(0);
function ie(K) {
for (; K < D.length; K++)
if (D[K].check(G)) {
var ke = D[K].component
, nt = D[K].route
, Bi = ke
, Ue = q = function(Ye) {
if (Ue === q) {
if (Ye === W)
return ie(K + 1);
O = Ye != null && (typeof Ye.view == "function" || typeof Ye == "function") ? Ye : "div",
U = G.params,
L = X,
q = null,
S = ke.render ? ke : null,
x === 2 ? p.redraw() : (x = 2,
p.redraw.sync())
}
}
;
ke.view || typeof ke == "function" ? (ke = {},
Ue(Bi)) : ke.onmatch ? m.then(function() {
return ke.onmatch(G.params, X, nt)
}).then(Ue, X === k ? null : te) : Ue("div");
return
}
if (X === k)
throw new Error("Could not resolve default route " + k + ".");
$(k, null, {
replace: !0
})
}
}
function _() {
w || (w = !0,
h(F))
}
function $(z, X, G) {
if (z = s(z, X),
v) {
_();
var te = G ? G.state : null
, ie = G ? G.title : null;
G && G.replace ? u.history.replaceState(te, ie, V.prefix + z) : u.history.pushState(te, ie, V.prefix + z)
} else
u.location.href = V.prefix + z
}
function V(z, X, G) {
if (!z)
throw new TypeError("DOM element being rendered to does not exist.");
if (D = Object.keys(G).map(function(ie) {
if (ie[0] !== "/")
throw new SyntaxError("Routes must start with a '/'.");
if (/:([^\/\.-]+)(\.{3})?:/.test(ie))
throw new SyntaxError("Route parameter names must be separated with either '/', '.', or '-'.");
return {
route: ie,
component: G[ie],
check: r(ie)
}
}),
k = X,
X != null) {
var te = n(X);
if (!D.some(function(ie) {
return ie.check(te)
}))
throw new ReferenceError("Default route doesn't match any known routes.")
}
typeof u.history.pushState == "function" ? u.addEventListener("popstate", _, !1) : V.prefix[0] === "#" && u.addEventListener("hashchange", F, !1),
v = !0,
p.mount(z, P),
F()
}
return V.set = function(z, X, G) {
q != null && (G = G || {},
G.replace = !0),
q = null,
$(z, X, G)
}
,
V.get = function() {
return L
}
,
V.prefix = "#!",
V.Link = {
view: function(z) {
var X = t(z.attrs.selector || "a", l(z.attrs, ["options", "params", "selector", "onclick"]), z.children), G, te, ie;
return (X.attrs.disabled = Boolean(X.attrs.disabled)) ? (X.attrs.href = null,
X.attrs["aria-disabled"] = "true") : (G = z.attrs.options,
te = z.attrs.onclick,
ie = s(X.attrs.href, z.attrs.params),
X.attrs.href = V.prefix + ie,
X.attrs.onclick = function(K) {
var ke;
typeof te == "function" ? ke = te.call(K.currentTarget, K) : te == null || typeof te != "object" || typeof te.handleEvent == "function" && te.handleEvent(K),
ke !== !1 && !K.defaultPrevented && (K.button === 0 || K.which === 0 || K.which === 1) && (!K.currentTarget.target || K.currentTarget.target === "_self") && !K.ctrlKey && !K.metaKey && !K.shiftKey && !K.altKey && (K.preventDefault(),
K.redraw = !1,
V.set(ie, null, G))
}
),
X
}
},
V.param = function(z) {
return U && z != null ? U[z] : U
}
,
V
}
,
un
}
var dn, Zs;
function fh() {
if (Zs)
return dn;
Zs = 1;
var e = ss;
return dn = hh()(typeof window < "u" ? window : null, e),
dn
}
var Ai = eh
, ro = lh
, oo = ss
, pe = function() {
return Ai.apply(this, arguments)
};
pe.m = Ai;
pe.trust = Ai.trust;
pe.fragment = Ai.fragment;
pe.Fragment = "[";
pe.mount = oo.mount;
pe.route = fh();
pe.render = eo();
pe.redraw = oo.redraw;
pe.request = ro.request;
pe.jsonp = ro.jsonp;
pe.parseQueryString = no();
pe.buildQueryString = to();
pe.parsePathname = os();
pe.buildPathname = rs();
pe.vnode = Ge();
pe.PromisePolyfill = jr();
pe.censor = so();
var Ne = pe;
function we(e, t, i, s, n) {
this.debugLog = !1,
this.baseUrl = e,
this.lobbySize = i,
this.devPort = t,
this.lobbySpread = s,
this.rawIPs = !!n,
this.server = void 0,
this.gameIndex = void 0,
this.callback = void 0,
this.errorCallback = void 0
}
we.prototype.regionInfo = {
0: {
name: "Local",
latitude: 0,
longitude: 0
},
"us-east": {
name: "Miami",
latitude: 40.1393329,
longitude: -75.8521818
},
miami: {
name: "Miami",
latitude: 40.1393329,
longitude: -75.8521818
},
"us-west": {
name: "Silicon Valley",
latitude: 47.6149942,
longitude: -122.4759879
},
siliconvalley: {
name: "Silicon Valley",
latitude: 47.6149942,
longitude: -122.4759879
},
gb: {
name: "London",
latitude: 51.5283063,
longitude: -.382486
},
london: {
name: "London",
latitude: 51.5283063,
longitude: -.382486
},
"eu-west": {
name: "Frankfurt",
latitude: 50.1211273,
longitude: 8.496137
},
frankfurt: {
name: "Frankfurt",
latitude: 50.1211273,
longitude: 8.496137
},
au: {
name: "Sydney",
latitude: -33.8479715,
longitude: 150.651084
},
sydney: {
name: "Sydney",
latitude: -33.8479715,
longitude: 150.651084
},
saopaulo: {
name: "São Paulo",
latitude: 23.5558,
longitude: 46.6396
},
sg: {
name: "Singapore",
latitude: 1.3147268,
longitude: 103.7065876
},
singapore: {
name: "Singapore",
latitude: 1.3147268,
longitude: 103.7065876
}
};
we.prototype.start = function(e, t, i, s) {
if (this.callback = t,
this.errorCallback = i,
s)
return t();
const n = this.parseServerQuery(e);
n && n.length > 0 ? (this.log("Found server in query."),
this.password = n[3],
this.connect(n[0], n[1], n[2])) : this.errorCallback("Unable to find server")
}
;
we.prototype.parseServerQuery = function(e) {
const t = new URLSearchParams(location.search,!0)
, i = e || t.get("server");
if (typeof i != "string")
return [];
const [s,n] = i.split(":");
return [s, n, t.get("password")]
}
;
we.prototype.findServer = function(e, t) {
var i = this.servers[e];
for (let s = 0; s < i.length; s++) {
const n = i[s];
if (n.name === t)
return n
}
console.warn("Could not find server in region " + e + " with serverName " + t + ".")
}
;
we.prototype.seekServer = function(e, t, i) {
i == null && (i = "random"),
t == null && (t = !1);
const s = ["random"]
, n = this.lobbySize
, r = this.lobbySpread
, o = this.servers[e].flatMap(function(h) {
let m = 0;
return h.games.map(function(w) {
const v = m++;
return {
region: h.region,
index: h.index * h.games.length + v,
gameIndex: v,
gameCount: h.games.length,
playerCount: w.playerCount,
playerCapacity: 50,
isPrivate: w.isPrivate
}
})
}).filter(function(h) {
return !h.isPrivate
}).filter(function(h) {
return t ? h.playerCount == 0 && h.gameIndex >= h.gameCount / 2 : !0
}).filter(function(h) {
return i == "random" ? !0 : s[h.index % s.length].key == i
}).sort(function(h, m) {
return m.playerCount - h.playerCount
}).filter(function(h) {
return h.playerCount < n
});
if (t && o.reverse(),
o.length == 0) {
this.errorCallback("No open servers.");
return
}
const l = min(r, o.length);
var u = floor(Math.random() * l);
u = min(u, o.length - 1);
const c = o[u]
, a = c.region;
var u = floor(c.index / c.gameCount);
const p = c.index % c.gameCount;
return this.log("Found server."),
[a, u, p]
}
;
we.prototype.connect = function(e, t, i) {
if (this.connected)
return;
const s = this.findServer(e, t);
if (s == null) {
this.errorCallback("Failed to find server for region " + e + " and serverName " + t);
return
}
// if (this.log("Connecting to server", s, "with game index", i),
// s.playerCount >= 50) {
// this.errorCallback("Server is already full.");
// return
// }
window.history.replaceState(document.title, document.title, this.generateHref(e, t, this.password)),
this.server = s,
this.gameIndex = i,
this.log("Calling callback with address", this.serverAddress(s), "on port", this.serverPort(s)),
this.callback(this.serverAddress(s), this.serverPort(s), i),
Lt && clearInterval(Lt)
}
;
we.prototype.switchServer = function(e, t) {
this.switchingServers = !0,
window.location = this.generateHref(e, t, null)
}
;
we.prototype.generateHref = function(e, t, i) {
let s = window.location.href.split("?")[0];
return s += "?server=" + e + ":" + t,
i && (s += "&password=" + encodeURIComponent(i)),
s
}
;
we.prototype.serverAddress = function(e) {
return e.region == 0 ? "localhost" : e.key + "." + e.region + "." + this.baseUrl
}
;
we.prototype.serverPort = function(e) {
return e.port
}
;
let Lt;
function uh(e) {
e = e.filter(n=>n.playerCount !== 50);
const t = min(...e.map(n=>n.ping || 1 / 0))
, i = e.filter(n=>n.ping === t);
return !i.length > 0 ? null : i.reduce((n,r)=>n.playerCount > r.playerCount ? n : r)
}
we.prototype.processServers = function(e) {
return Lt && clearInterval(Lt),
new Promise(t=>{
const i = {}
, s = c=>{
const a = i[c]
, u = a[0];
let p = this.serverAddress(u);
const h = this.serverPort(u);
h && (p += `:${h}`);
const m = `https://${p}/ping`
, w = new Date().getTime();
return Promise.race([fetch(m).then(()=>{
const v = new Date().getTime() - w;
a.forEach(x=>{
x.pings = x.pings ?? [],
x.pings.push(v),
x.pings.length > 10 && x.pings.shift(),
x.ping = floor(x.pings.reduce((D,k)=>D + k, 0) / x.pings.length)
}
)
}
).catch(()=>{}
), new Promise(v=>setTimeout(()=>v(), 100))])
}
, n = async()=>{
await Promise.all(Object.keys(i).map(s)),
window.blockRedraw || Ne.redraw()
}
;
e.forEach(c=>{
i[c.region] = i[c.region] || [],
i[c.region].push(c)
}
);
for (const c in i)
i[c] = i[c].sort(function(a, u) {
return u.playerCount - a.playerCount
});
this.servers = i;
let r;
const [o,l] = this.parseServerQuery();
e.forEach(c=>{
o === c.region && l === c.name && (c.selected = !0,
r = c)
}
),
n().then(n).then(()=>{
if (r)
return;
let c = uh(e);
c || (c = e[0]),
c && (c.selected = !0,
window.history.replaceState(document.title, document.title, this.generateHref(c.region, c.name, this.password))),
window.blockRedraw || Ne.redraw()
}
).then(n).catch(c=>{}
).finally(t),
Lt = setInterval(n, 5e3)
}
)
}
;
we.prototype.ipToHex = function(e) {
return e.split(".").map(i=>("00" + parseInt(i).toString(16)).substr(-2)).join("").toLowerCase()
}
;
we.prototype.hashIP = function(e) {
return On(this.ipToHex(e))
}
;
we.prototype.log = function() {
if (this.debugLog)
return console.log.apply(void 0, arguments);
if (console.verbose)
return console.verbose.apply(void 0, arguments)
}
;
we.prototype.stripRegion = function(e) {
return e.startsWith("vultr:") ? e = e.slice(6) : e.startsWith("do:") && (e = e.slice(3)),
e
}
;
const dh = function(e, t) {
return e.concat(t)
}
, ph = function(e, t) {
return t.map(e).reduce(dh, [])
};
Array.prototype.flatMap = function(e) {
return ph(e, this)
}
;
const fi = (e,t)=>{
const i = t.x - e.x
, s = t.y - e.y;
return sqrt(i * i + s * s)
}
, mh = (e,t)=>{
const i = t.x - e.x
, s = t.y - e.y;
return yh(atan2(s, i))
}
, gh = (e,t,i)=>{
const s = {
x: 0,
y: 0
};
return i = Bn(i),
s.x = e.x - t * cos(i),
s.y = e.y - t * sin(i),
s
}
, Bn = e=>e * (PI / 180)
, yh = e=>e * (180 / PI)
, wh = e=>isNaN(e.buttons) ? e.pressure !== 0 : e.buttons !== 0
, pn = new Map
, js = e=>{
pn.has(e) && clearTimeout(pn.get(e)),
pn.set(e, setTimeout(e, 100))
}
, wi = (e,t,i)=>{
const s = t.split(/[ ,]+/g);
let n;
for (let r = 0; r < s.length; r += 1)
n = s[r],
e.addEventListener ? e.addEventListener(n, i, !1) : e.attachEvent && e.attachEvent(n, i)
}
, er = (e,t,i)=>{
const s = t.split(/[ ,]+/g);
let n;
for (let r = 0; r < s.length; r += 1)
n = s[r],
e.removeEventListener ? e.removeEventListener(n, i) : e.detachEvent && e.detachEvent(n, i)
}
, ao = e=>(e.preventDefault(),
e.type.match(/^touch/) ? e.changedTouches : e)
, tr = ()=>{
const e = window.pageXOffset !== void 0 ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft
, t = window.pageYOffset !== void 0 ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
return {
x: e,
y: t
}
}
, ir = (e,t)=>{
t.top || t.right || t.bottom || t.left ? (e.style.top = t.top,
e.style.right = t.right,
e.style.bottom = t.bottom,
e.style.left = t.left) : (e.style.left = t.x + "px",
e.style.top = t.y + "px")
}
, as = (e,t,i)=>{
const s = lo(e);
for (let n in s)
if (s.hasOwnProperty(n))
if (typeof t == "string")
s[n] = t + " " + i;
else {
let r = "";
for (let o = 0, l = t.length; o < l; o += 1)
r += t[o] + " " + i + ", ";
s[n] = r.slice(0, -2)
}
return s
}
, kh = (e,t)=>{
const i = lo(e);
for (let s in i)
i.hasOwnProperty(s) && (i[s] = t);
return i
}
, lo = e=>{
const t = {};
return t[e] = "",
["webkit", "Moz", "o"].forEach(function(s) {
t[s + e.charAt(0).toUpperCase() + e.slice(1)] = ""
}),
t
}
, mn = (e,t)=>{
for (let i in t)
t.hasOwnProperty(i) && (e[i] = t[i]);
return e
}
, vh = (e,t)=>{
const i = {};
for (let s in e)
e.hasOwnProperty(s) && t.hasOwnProperty(s) ? i[s] = t[s] : e.hasOwnProperty(s) && (i[s] = e[s]);
return i
}
, zn = (e,t)=>{
if (e.length)
for (let i = 0, s = e.length; i < s; i += 1)
t(e[i]);
else
t(e)
}
, xh = (e,t,i)=>({
x: min(max(e.x, t.x - i), t.x + i),
y: min(max(e.y, t.y - i), t.y + i)
});
var bh = "ontouchstart"in window, Sh = !!window.PointerEvent, Th = !!window.MSPointerEvent, Bt = {
touch: {
start: "touchstart",
move: "touchmove",
end: "touchend, touchcancel"
},
mouse: {
start: "mousedown",
move: "mousemove",
end: "mouseup"
},
pointer: {
start: "pointerdown",
move: "pointermove",
end: "pointerup, pointercancel"
},
MSPointer: {
start: "MSPointerDown",
move: "MSPointerMove",
end: "MSPointerUp"
}
}, vt, Kt = {};
Sh ? vt = Bt.pointer : Th ? vt = Bt.MSPointer : bh ? (vt = Bt.touch,
Kt = Bt.mouse) : vt = Bt.mouse;
function Ve() {}
Ve.prototype.on = function(e, t) {
var i = this, s = e.split(/[ ,]+/g), n;
i._handlers_ = i._handlers_ || {};
for (var r = 0; r < s.length; r += 1)
n = s[r],
i._handlers_[n] = i._handlers_[n] || [],
i._handlers_[n].push(t);
return i
}
;
Ve.prototype.off = function(e, t) {
var i = this;
return i._handlers_ = i._handlers_ || {},
e === void 0 ? i._handlers_ = {} : t === void 0 ? i._handlers_[e] = null : i._handlers_[e] && i._handlers_[e].indexOf(t) >= 0 && i._handlers_[e].splice(i._handlers_[e].indexOf(t), 1),
i
}
;
Ve.prototype.trigger = function(e, t) {
var i = this, s = e.split(/[ ,]+/g), n;
i._handlers_ = i._handlers_ || {};
for (var r = 0; r < s.length; r += 1)
n = s[r],
i._handlers_[n] && i._handlers_[n].length && i._handlers_[n].forEach(function(o) {
o.call(i, {
type: n,
target: i
}, t)
})
}
;
Ve.prototype.config = function(e) {
var t = this;
t.options = t.defaults || {},
e && (t.options = vh(t.options, e))
}
;
Ve.prototype.bindEvt = function(e, t) {
var i = this;
return i._domHandlers_ = i._domHandlers_ || {},
i._domHandlers_[t] = function() {
typeof i["on" + t] == "function" ? i["on" + t].apply(i, arguments) : console.warn('[WARNING] : Missing "on' + t + '" handler.')
}
,
wi(e, vt[t], i._domHandlers_[t]),
Kt[t] && wi(e, Kt[t], i._domHandlers_[t]),
i
}
;
Ve.prototype.unbindEvt = function(e, t) {
var i = this;
return i._domHandlers_ = i._domHandlers_ || {},
er(e, vt[t], i._domHandlers_[t]),
Kt[t] && er(e, Kt[t], i._domHandlers_[t]),
delete i._domHandlers_[t],
this
}
;
function he(e, t) {
return this.identifier = t.identifier,
this.position = t.position,
this.frontPosition = t.frontPosition,
this.collection = e,
this.defaults = {
size: 100,
threshold: .1,
color: "white",
fadeTime: 250,
dataOnly: !1,
restJoystick: !0,
restOpacity: .5,
mode: "dynamic",
zone: document.body,
lockX: !1,
lockY: !1,
shape: "circle"
},
this.config(t),
this.options.mode === "dynamic" && (this.options.restOpacity = 0),
this.id = he.id,
he.id += 1,
this.buildEl().stylize(),
this.instance = {
el: this.ui.el,
on: this.on.bind(this),
off: this.off.bind(this),
show: this.show.bind(this),
hide: this.hide.bind(this),
add: this.addToDom.bind(this),
remove: this.removeFromDom.bind(this),
destroy: this.destroy.bind(this),
setPosition: this.setPosition.bind(this),
resetDirection: this.resetDirection.bind(this),
computeDirection: this.computeDirection.bind(this),
trigger: this.trigger.bind(this),
position: this.position,
frontPosition: this.frontPosition,
ui: this.ui,
identifier: this.identifier,
id: this.id,
options: this.options
},
this.instance
}
he.prototype = new Ve;
he.constructor = he;
he.id = 0;
he.prototype.buildEl = function(e) {
return this.ui = {},
this.options.dataOnly ? this : (this.ui.el = document.createElement("div"),
this.ui.back = document.createElement("div"),
this.ui.front = document.createElement("div"),
this.ui.el.className = "nipple collection_" + this.collection.id,
this.ui.back.className = "back",
this.ui.front.className = "front",
this.ui.el.setAttribute("id", "nipple_" + this.collection.id + "_" + this.id),
this.ui.el.appendChild(this.ui.back),
this.ui.el.appendChild(this.ui.front),
this)
}
;
he.prototype.stylize = function() {
if (this.options.dataOnly)
return this;
var e = this.options.fadeTime + "ms"
, t = kh("borderRadius", "50%")
, i = as("transition", "opacity", e)
, s = {};
return s.el = {
position: "absolute",
opacity: this.options.restOpacity,
display: "block",
zIndex: 999
},
s.back = {
position: "absolute",
display: "block",
width: this.options.size + "px",
height: this.options.size + "px",
marginLeft: -this.options.size / 2 + "px",
marginTop: -this.options.size / 2 + "px",
background: this.options.color,
opacity: ".5"
},
s.front = {
width: this.options.size / 2 + "px",
height: this.options.size / 2 + "px",
position: "absolute",
display: "block",
marginLeft: -this.options.size / 4 + "px",
marginTop: -this.options.size / 4 + "px",
background: this.options.color,
opacity: ".5",
transform: "translate(0px, 0px)"
},
mn(s.el, i),
this.options.shape === "circle" && mn(s.back, t),
mn(s.front, t),
this.applyStyles(s),
this
}
;
he.prototype.applyStyles = function(e) {
for (var t in this.ui)
if (this.ui.hasOwnProperty(t))
for (var i in e[t])
this.ui[t].style[i] = e[t][i];
return this
}
;
he.prototype.addToDom = function() {
return this.options.dataOnly || document.body.contains(this.ui.el) ? this : (this.options.zone.appendChild(this.ui.el),
this)
}
;
he.prototype.removeFromDom = function() {
return this.options.dataOnly || !document.body.contains(this.ui.el) ? this : (this.options.zone.removeChild(this.ui.el),
this)
}
;
he.prototype.destroy = function() {
clearTimeout(this.removeTimeout),
clearTimeout(this.showTimeout),
clearTimeout(this.restTimeout),
this.trigger("destroyed", this.instance),
this.removeFromDom(),
this.off()
}
;
he.prototype.show = function(e) {
var t = this;
return t.options.dataOnly || (clearTimeout(t.removeTimeout),
clearTimeout(t.showTimeout),
clearTimeout(t.restTimeout),
t.addToDom(),
t.restCallback(),
setTimeout(function() {
t.ui.el.style.opacity = 1
}, 0),
t.showTimeout = setTimeout(function() {
t.trigger("shown", t.instance),
typeof e == "function" && e.call(this)
}, t.options.fadeTime)),
t
}
;
he.prototype.hide = function(e) {
var t = this;
if (t.options.dataOnly)
return t;
if (t.ui.el.style.opacity = t.options.restOpacity,
clearTimeout(t.removeTimeout),
clearTimeout(t.showTimeout),
clearTimeout(t.restTimeout),
t.removeTimeout = setTimeout(function() {
var i = t.options.mode === "dynamic" ? "none" : "block";
t.ui.el.style.display = i,
typeof e == "function" && e.call(t),
t.trigger("hidden", t.instance)
}, t.options.fadeTime),
t.options.restJoystick) {
const i = t.options.restJoystick
, s = {};
s.x = i === !0 || i.x !== !1 ? 0 : t.instance.frontPosition.x,
s.y = i === !0 || i.y !== !1 ? 0 : t.instance.frontPosition.y,
t.setPosition(e, s)
}
return t
}
;
he.prototype.setPosition = function(e, t) {
var i = this;
i.frontPosition = {
x: t.x,
y: t.y
};
var s = i.options.fadeTime + "ms"
, n = {};
n.front = as("transition", ["transform"], s);
var r = {
front: {}
};
r.front = {
transform: "translate(" + i.frontPosition.x + "px," + i.frontPosition.y + "px)"
},
i.applyStyles(n),
i.applyStyles(r),
i.restTimeout = setTimeout(function() {
typeof e == "function" && e.call(i),
i.restCallback()
}, i.options.fadeTime)
}
;
he.prototype.restCallback = function() {
var e = this
, t = {};
t.front = as("transition", "none", ""),
e.applyStyles(t),
e.trigger("rested", e.instance)
}
;
he.prototype.resetDirection = function() {
this.direction = {
x: !1,
y: !1,
angle: !1
}
}
;
he.prototype.computeDirection = function(e) {
var t = e.angle.radian, i = PI / 4, s = PI / 2, n, r, o;
if (t > i && t < i * 3 && !e.lockX ? n = "up" : t > -i && t <= i && !e.lockY ? n = "left" : t > -i * 3 && t <= -i && !e.lockX ? n = "down" : e.lockY || (n = "right"),
e.lockY || (t > -s && t < s ? r = "left" : r = "right"),
e.lockX || (t > 0 ? o = "up" : o = "down"),
e.force > this.options.threshold) {
var l = {}, c;
for (c in this.direction)
this.direction.hasOwnProperty(c) && (l[c] = this.direction[c]);
var a = {};
this.direction = {
x: r,
y: o,
angle: n
},
e.direction = this.direction;
for (c in l)
l[c] === this.direction[c] && (a[c] = !0);
if (a.x && a.y && a.angle)
return e;
(!a.x || !a.y) && this.trigger("plain", e),
a.x || this.trigger("plain:" + r, e),
a.y || this.trigger("plain:" + o, e),
a.angle || this.trigger("dir dir:" + n, e)
} else
this.resetDirection();
return e
}
;
function ae(e, t) {
var i = this;
i.nipples = [],
i.idles = [],
i.actives = [],
i.ids = [],
i.pressureIntervals = {},
i.manager = e,
i.id = ae.id,
ae.id += 1,
i.defaults = {
zone: document.body,
multitouch: !1,
maxNumberOfNipples: 10,
mode: "dynamic",
position: {
top: 0,
left: 0
},
catchDistance: 200,
size: 100,
threshold: .1,
color: "white",
fadeTime: 250,
dataOnly: !1,
restJoystick: !0,
restOpacity: .5,
lockX: !1,
lockY: !1,
shape: "circle",
dynamicPage: !1,
follow: !1
},
i.config(t),
(i.options.mode === "static" || i.options.mode === "semi") && (i.options.multitouch = !1),
i.options.multitouch || (i.options.maxNumberOfNipples = 1);
const s = getComputedStyle(i.options.zone.parentElement);
return s && s.display === "flex" && (i.parentIsFlex = !0),
i.updateBox(),
i.prepareNipples(),
i.bindings(),
i.begin(),
i.nipples
}
ae.prototype = new Ve;
ae.constructor = ae;
ae.id = 0;
ae.prototype.prepareNipples = function() {
var e = this
, t = e.nipples;
t.on = e.on.bind(e),
t.off = e.off.bind(e),
t.options = e.options,
t.destroy = e.destroy.bind(e),
t.ids = e.ids,
t.id = e.id,
t.processOnMove = e.processOnMove.bind(e),
t.processOnEnd = e.processOnEnd.bind(e),
t.get = function(i) {
if (i === void 0)
return t[0];
for (var s = 0, n = t.length; s < n; s += 1)
if (t[s].identifier === i)
return t[s];
return !1
}
}
;
ae.prototype.bindings = function() {
var e = this;
e.bindEvt(e.options.zone, "start"),
e.options.zone.style.touchAction = "none",
e.options.zone.style.msTouchAction = "none"
}
;
ae.prototype.begin = function() {
var e = this
, t = e.options;
if (t.mode === "static") {
var i = e.createNipple(t.position, e.manager.getIdentifier());
i.add(),
e.idles.push(i)
}
}
;
ae.prototype.createNipple = function(e, t) {
var i = this
, s = i.manager.scroll
, n = {}
, r = i.options
, o = {
x: i.parentIsFlex ? s.x : s.x + i.box.left,
y: i.parentIsFlex ? s.y : s.y + i.box.top
};
if (e.x && e.y)
n = {
x: e.x - o.x,
y: e.y - o.y
};
else if (e.top || e.right || e.bottom || e.left) {
var l = document.createElement("DIV");
l.style.display = "hidden",
l.style.top = e.top,
l.style.right = e.right,
l.style.bottom = e.bottom,
l.style.left = e.left,
l.style.position = "absolute",
r.zone.appendChild(l);
var c = l.getBoundingClientRect();
r.zone.removeChild(l),
n = e,
e = {
x: c.left + s.x,
y: c.top + s.y
}
}
var a = new he(i,{
color: r.color,
size: r.size,
threshold: r.threshold,
fadeTime: r.fadeTime,
dataOnly: r.dataOnly,
restJoystick: r.restJoystick,
restOpacity: r.restOpacity,
mode: r.mode,
identifier: t,
position: e,
zone: r.zone,
frontPosition: {
x: 0,
y: 0
},
shape: r.shape
});
return r.dataOnly || (ir(a.ui.el, n),
ir(a.ui.front, a.frontPosition)),
i.nipples.push(a),
i.trigger("added " + a.identifier + ":added", a),
i.manager.trigger("added " + a.identifier + ":added", a),
i.bindNipple(a),
a
}
;
ae.prototype.updateBox = function() {
var e = this;
e.box = e.options.zone.getBoundingClientRect()
}
;
ae.prototype.bindNipple = function(e) {
var t = this, i, s = function(n, r) {
i = n.type + " " + r.id + ":" + n.type,
t.trigger(i, r)
};
e.on("destroyed", t.onDestroyed.bind(t)),
e.on("shown hidden rested dir plain", s),
e.on("dir:up dir:right dir:down dir:left", s),
e.on("plain:up plain:right plain:down plain:left", s)
}
;
ae.prototype.pressureFn = function(e, t, i) {
var s = this
, n = 0;
clearInterval(s.pressureIntervals[i]),
s.pressureIntervals[i] = setInterval(function() {
var r = e.force || e.pressure || e.webkitForce || 0;
r !== n && (t.trigger("pressure", r),
s.trigger("pressure " + t.identifier + ":pressure", r),
n = r)
}
.bind(s), 100)
}
;
ae.prototype.onstart = function(e) {
var t = this
, i = t.options
, s = e;
e = ao(e),
t.updateBox();
var n = function(r) {
t.actives.length < i.maxNumberOfNipples ? t.processOnStart(r) : s.type.match(/^touch/) && (Object.keys(t.manager.ids).forEach(function(o) {
if (Object.values(s.touches).findIndex(function(c) {
return c.identifier === o
}) < 0) {
var l = [e[0]];
l.identifier = o,
t.processOnEnd(l)
}
}),
t.actives.length < i.maxNumberOfNipples && t.processOnStart(r))
};
return zn(e, n),
t.manager.bindDocument(),
!1
}
;
ae.prototype.processOnStart = function(e) {
var t = this, i = t.options, s, n = t.manager.getIdentifier(e), r = e.force || e.pressure || e.webkitForce || 0, o = {
x: e.pageX,
y: e.pageY
}, l = t.getOrCreate(n, o);
l.identifier !== n && t.manager.removeIdentifier(l.identifier),
l.identifier = n;
var c = function(u) {
u.trigger("start", u),
t.trigger("start " + u.id + ":start", u),
u.show(),
r > 0 && t.pressureFn(e, u, u.identifier),
t.processOnMove(e)
};
if ((s = t.idles.indexOf(l)) >= 0 && t.idles.splice(s, 1),
t.actives.push(l),
t.ids.push(l.identifier),
i.mode !== "semi")
c(l);
else {
var a = fi(o, l.position);
if (a <= i.catchDistance)
c(l);
else {
l.destroy(),
t.processOnStart(e);
return
}
}
return l
}
;
ae.prototype.getOrCreate = function(e, t) {
var i = this, s = i.options, n;
return /(semi|static)/.test(s.mode) ? (n = i.idles[0],
n ? (i.idles.splice(0, 1),
n) : s.mode === "semi" ? i.createNipple(t, e) : (console.warn("Coudln't find the needed nipple."),
!1)) : (n = i.createNipple(t, e),
n)
}
;
ae.prototype.processOnMove = function(e) {
var t = this
, i = t.options
, s = t.manager.getIdentifier(e)
, n = t.nipples.get(s)
, r = t.manager.scroll;
if (!wh(e)) {
this.processOnEnd(e);
return
}
if (!n) {
console.error("Found zombie joystick with ID " + s),
t.manager.removeIdentifier(s);
return
}
if (i.dynamicPage) {
var o = n.el.getBoundingClientRect();
n.position = {
x: r.x + o.left,
y: r.y + o.top
}
}
n.identifier = s;
var l = n.options.size / 2
, c = {
x: e.pageX,
y: e.pageY
};
i.lockX && (c.y = n.position.y),
i.lockY && (c.x = n.position.x);
var a = fi(c, n.position), u = mh(c, n.position), p = Bn(u), h = a / l, m = {
distance: a,
position: c
}, w, v;
if (n.options.shape === "circle" ? (w = min(a, l),
v = gh(n.position, w, u)) : (v = xh(c, n.position, l),
w = fi(v, n.position)),
i.follow) {
if (a > l) {
let S = c.x - v.x
, O = c.y - v.y;
n.position.x += S,
n.position.y += O,
n.el.style.top = n.position.y - (t.box.top + r.y) + "px",
n.el.style.left = n.position.x - (t.box.left + r.x) + "px",
a = fi(c, n.position)
}
} else
c = v,
a = w;
var x = c.x - n.position.x
, D = c.y - n.position.y;
n.frontPosition = {
x,
y: D
},
i.dataOnly || (n.ui.front.style.transform = "translate(" + x + "px," + D + "px)");
var k = {
identifier: n.identifier,
position: c,
force: h,
pressure: e.force || e.pressure || e.webkitForce || 0,
distance: a,
angle: {
radian: p,
degree: u
},
vector: {
x: x / l,
y: -D / l
},
raw: m,
instance: n,
lockX: i.lockX,
lockY: i.lockY
};
k = n.computeDirection(k),
k.angle = {
radian: Bn(180 - u),
degree: 180 - u
},
n.trigger("move", k),
t.trigger("move " + n.id + ":move", k)
}
;
ae.prototype.processOnEnd = function(e) {
var t = this
, i = t.options
, s = t.manager.getIdentifier(e)
, n = t.nipples.get(s)
, r = t.manager.removeIdentifier(n.identifier);
n && (i.dataOnly || n.hide(function() {
i.mode === "dynamic" && (n.trigger("removed", n),
t.trigger("removed " + n.id + ":removed", n),
t.manager.trigger("removed " + n.id + ":removed", n),
n.destroy())
}),
clearInterval(t.pressureIntervals[n.identifier]),
n.resetDirection(),
n.trigger("end", n),
t.trigger("end " + n.id + ":end", n),
t.ids.indexOf(n.identifier) >= 0 && t.ids.splice(t.ids.indexOf(n.identifier), 1),
t.actives.indexOf(n) >= 0 && t.actives.splice(t.actives.indexOf(n), 1),
/(semi|static)/.test(i.mode) ? t.idles.push(n) : t.nipples.indexOf(n) >= 0 && t.nipples.splice(t.nipples.indexOf(n), 1),
t.manager.unbindDocument(),
/(semi|static)/.test(i.mode) && (t.manager.ids[r.id] = r.identifier))
}
;
ae.prototype.onDestroyed = function(e, t) {
var i = this;
i.nipples.indexOf(t) >= 0 && i.nipples.splice(i.nipples.indexOf(t), 1),
i.actives.indexOf(t) >= 0 && i.actives.splice(i.actives.indexOf(t), 1),
i.idles.indexOf(t) >= 0 && i.idles.splice(i.idles.indexOf(t), 1),
i.ids.indexOf(t.identifier) >= 0 && i.ids.splice(i.ids.indexOf(t.identifier), 1),
i.manager.removeIdentifier(t.identifier),
i.manager.unbindDocument()
}
;
ae.prototype.destroy = function() {
var e = this;
e.unbindEvt(e.options.zone, "start"),
e.nipples.forEach(function(i) {
i.destroy()
});
for (var t in e.pressureIntervals)
e.pressureIntervals.hasOwnProperty(t) && clearInterval(e.pressureIntervals[t]);
e.trigger("destroyed", e.nipples),
e.manager.unbindDocument(),
e.off()
}
;
function de(e) {
var t = this;
t.ids = {},
t.index = 0,
t.collections = [],
t.scroll = tr(),
t.config(e),
t.prepareCollections();
var i = function() {
var n;
t.collections.forEach(function(r) {
r.forEach(function(o) {
n = o.el.getBoundingClientRect(),
o.position = {
x: t.scroll.x + n.left,
y: t.scroll.y + n.top
}
})
})
};
wi(window, "resize", function() {
js(i)
});
var s = function() {
t.scroll = tr()
};
return wi(window, "scroll", function() {
js(s)
}),
t.collections
}
de.prototype = new Ve;
de.constructor = de;
de.prototype.prepareCollections = function() {
var e = this;
e.collections.create = e.create.bind(e),
e.collections.on = e.on.bind(e),
e.collections.off = e.off.bind(e),
e.collections.destroy = e.destroy.bind(e),
e.collections.get = function(t) {
var i;
return e.collections.every(function(s) {
return i = s.get(t),
!i
}),
i
}
}
;
de.prototype.create = function(e) {
return this.createCollection(e)
}
;
de.prototype.createCollection = function(e) {
var t = this
, i = new ae(t,e);
return t.bindCollection(i),
t.collections.push(i),
i
}
;
de.prototype.bindCollection = function(e) {
var t = this, i, s = function(n, r) {
i = n.type + " " + r.id + ":" + n.type,
t.trigger(i, r)
};
e.on("destroyed", t.onDestroyed.bind(t)),
e.on("shown hidden rested dir plain", s),
e.on("dir:up dir:right dir:down dir:left", s),
e.on("plain:up plain:right plain:down plain:left", s)
}
;
de.prototype.bindDocument = function() {
var e = this;
e.binded || (e.bindEvt(document, "move").bindEvt(document, "end"),
e.binded = !0)
}
;
de.prototype.unbindDocument = function(e) {
var t = this;
(!Object.keys(t.ids).length || e === !0) && (t.unbindEvt(document, "move").unbindEvt(document, "end"),
t.binded = !1)
}
;
de.prototype.getIdentifier = function(e) {
var t;
return e ? (t = e.identifier === void 0 ? e.pointerId : e.identifier,
t === void 0 && (t = this.latest || 0)) : t = this.index,
this.ids[t] === void 0 && (this.ids[t] = this.index,
this.index += 1),
this.latest = t,
this.ids[t]
}
;
de.prototype.removeIdentifier = function(e) {
var t = {};
for (var i in this.ids)
if (this.ids[i] === e) {
t.id = i,
t.identifier = this.ids[i],
delete this.ids[i];
break
}
return t
}
;
de.prototype.onmove = function(e) {
var t = this;
return t.onAny("move", e),
!1
}
;
de.prototype.onend = function(e) {
var t = this;
return t.onAny("end", e),
!1
}
;
de.prototype.oncancel = function(e) {
var t = this;
return t.onAny("end", e),
!1
}
;
de.prototype.onAny = function(e, t) {
var i = this, s, n = "processOn" + e.charAt(0).toUpperCase() + e.slice(1);
t = ao(t);
var r = function(l, c, a) {
a.ids.indexOf(c) >= 0 && (a[n](l),
l._found_ = !0)
}
, o = function(l) {
s = i.getIdentifier(l),
zn(i.collections, r.bind(null, l, s)),
l._found_ || i.removeIdentifier(s)
};
return zn(t, o),
!1
}
;
de.prototype.destroy = function() {
var e = this;
e.unbindDocument(!0),
e.ids = {},
e.index = 0,
e.collections.forEach(function(t) {
t.destroy()
}),
e.off()
}
;
de.prototype.onDestroyed = function(e, t) {
var i = this;
if (i.collections.indexOf(t) < 0)
return !1;
i.collections.splice(i.collections.indexOf(t), 1)
}
;
const nr = new de
, sr = {
create: function(e) {
return nr.create(e)
},
factory: nr
};
let rr = !1;
const Ih = e=>{
if (rr)
return;
rr = !0;
const t = document.getElementById("touch-controls-left")
, i = sr.create({
zone: t
});
i.on("start", e.onStartMoving),
i.on("end", e.onStopMoving),
i.on("move", e.onRotateMoving);
const s = document.getElementById("touch-controls-right")
, n = sr.create({
zone: s
});
n.on("start", e.onStartAttacking),
n.on("end", e.onStopAttacking),
n.on("move", e.onRotateAttacking),
t.style.display = "block",
s.style.display = "block"
}
, Mh = {
enable: Ih
};
window.loadedScript = !0;
const Eh = location.hostname !== "localhost" && location.hostname !== "127.0.0.1" && !location.hostname.startsWith("192.168.")
, co = location.hostname === "sandbox-dev.moomoo.io" || location.hostname === "sandbox.moomoo.io"
, Ph = location.hostname === "dev.moomoo.io" || location.hostname === "dev2.moomoo.io"
, Hn = new uc;
let ui, di;
const ki = location.hostname === "localhost" || location.hostname === "127.0.0.1"
, Ch = !1
, ls = ki || Ch;
co ? (ui = "https://api-sandbox.moomoo.io",
di = "moomoo.io") : Ph ? (ui = "https://api-dev.moomoo.io",
di = "moomoo.io") : (ui = "https://api.moomoo.io",
di = "moomoo.io");
const Ah = !ls
, qe = new we(di,443,50,5,Ah);
qe.debugLog = !1;
const Me = {
animationTime: 0,
land: null,
lava: null,
x: T.volcanoLocationX,
y: T.volcanoLocationY
};
function Dh() {
let e = !1;
return function(t) {
(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(t) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0, 4))) && (e = !0)
}(navigator.userAgent || navigator.vendor || window.opera),
e
}
const ho = Dh();
let vi = !1
, Fn = !1;
let code;
function Oh() {
// !ps ||
// Fn ||
// ((Fn = !0),
// Eh || ls
// ? window.turnstileToken
// ? gn(window.turnstileToken)
// : window.grecaptcha.ready(() => {
// window.grecaptcha
// .execute("6LfahtgjAAAAAF8SkpjyeYMcxMdxIaQeh-VoPATP", {
// action: "homepage",
// })
// .then(function (e) {
// gn("re:" + e);
// })
// .catch(console.error);
// })
// : gn());
!ps || Fn || (Fn = !0,
Eh || ls ? code && gn("alt:" + code) : Ei ? gn("alt:" + code) : gn())
}
let Vn = !1;
function sd(e) {
var t;
((t = e == null ? void 0 : e.detail) == null ? void 0 : t.state) === "verified" && (code = e.detail.payload,
Le.classList.remove("disabled"))
console.log(code)
}
window.addEventListener("load", () => {
const e = document.getElementById("altcha");
e == null || e.addEventListener("statechange", sd)
}
);
function gn(e) {
qe.start(bi, function(t, i, s) {
let r = "wss" + "://" + t;
e && (r += "?token=" + encodeURIComponent(e)),
console.log(r),
ki && (r = "wss://localhost:3000"),
ee.connect(r, function(o) {
if (Vn) {
Vn = !1;
return
}
Vo(),
o ? disconnect(o) : (vi = !0,
bs())
}, {
// gamepackets Game packets Game Packets game packets game functions gamefunctions Game functions Game Functions
A: setInitData, // qh = setInitData !
B: disconnect, // bn = disconnect !
C: setupGame, // If = setupGame !
D: playerEncounter, // Qf = playerEncounter !
E: removePlayer, // Zf = removePlayer !
a: playerUpdate, // iu = playerUpdate !
G: updateLeaderboard, // Df = updateLeaderboard !
H: loadObject, // qf = loadObject !
I: animalUpdate, // Kf = animalUpdate !
J: animateAnimal, // $f = animateAnimal !
K: gatherAnimation, // _f = gatherAnimation !
L: objectHit, // Wf = objectHit !
M: turretShot, // Xf = turretShot !
N: updatePlayerValue, // eu = updatePlayerValue !
O: healthUpdate, //tu = healthUpdate !
P: died,
Q: removeObject,
R: removeInactivePlayerObjects,
S: resourceUpdate,
T: ageUpdate,
U: updateUpdate,
V: itemUpdate,
X: addProjectile,
Y: remProjectile,
Z: serverShutdown,
g: addAlliance,
1: deleteAlliance,
2: allianceNotification,
3: setPlayerTeam,
4: setAlliancePlayers,
5: storebuy,
6: receiveChat,
7: updateMinimap,
8: showText,
9: pingMinimap,
0: pingSocketResponse
})
}, function(t) {
console.error("Vultr error:", t),
alert(`Error:
` + t),
disconnect("disconnected")
}, ki)
}
function cs() {
return ee.connected
}
function Rh() {
const t = prompt("party key", bi);
t && (window.onbeforeunload = void 0,
window.location.href = "/?server=" + t)
}
const _h = new dc(T)
, fo = Math.PI
, Ze = fo * 2;
Math.lerpAngle = function(e, t, i) {
abs(t - e) > fo && (e > t ? t += Ze : e += Ze);
const n = t + (e - t) * i;
return n >= 0 && n <= Ze ? n : n % Ze
}
;
/*CanvasRenderingContext2D.prototype.roundRect = function(e, t, i, s, n) {
var r = e + i,
o = t + s,
a = Math.min(i, s, n),
h = .5522847498 * a,
c = e + a,
u = e + i - a,
l = t + a,
d = t + s - a,
f = e + i,
g = t + s;
return this.beginPath(), this.moveTo(c, t), this.lineTo(u, t), this.bezierCurveTo(u + h, t, f, l - h, f, l), this.lineTo(f, d), this.bezierCurveTo(f, d + h, u + h, g, u, g), this.lineTo(c, g), this.bezierCurveTo(c - h, g, e, d + h, e, d), this.lineTo(e, l), this.bezierCurveTo(e, l - h, c - h, t, c, t), this.closePath(), this
};*/
// original
CanvasRenderingContext2D.prototype.roundRect = function(e, t, i, s, n) {
return i < 2 * n && (n = i / 2),
s < 2 * n && (n = s / 2),
n < 0 && (n = 0),
this.beginPath(),
this.moveTo(e + n, t),
this.arcTo(e + i, t, e + i, t + s, n),
this.arcTo(e + i, t + s, e, t + s, n),
this.arcTo(e, t + s, e, t, n),
this.arcTo(e, t, e + i, t, n),
this.closePath(),
this
};
let hs;
typeof Storage < "u" && (hs = !0);
function Di(e, t) {
hs && localStorage.setItem(e, t)
}
function Nt(e) {
return hs ? localStorage.getItem(e) : null
}
let xi = Nt("moofoll");
function Bh() {
xi || (xi = !0,
Di("moofoll", 1))
}
let uo, $e, mt = 1, be, It, yn, or = Date.now();
//var He;
let Ee;
// game variables
var ye = []
, J = [];
let Oe = [];
var et = []
, Mt = []
, po = new gc(Hc,Mt,J,ye,ue,R,T,C)
, ar = new yc(ye,wc,J,R,null,T,C);
let mo, y, ct = 1, wn = 0, go = 0, yo = 0, Re, _e, lr, fs = 0;
var se = T.maxScreenWidth
, re = T.maxScreenHeight;
let gt, yt, Jt = !1;
document.getElementById("ad-container");
const Oi = document.getElementById("mainMenu")
, Un = document.getElementById("enterGame")
, kn = document.getElementById("promoImg");
document.getElementById("partyButton");
const vn = document.getElementById("joinPartyButton")
, Ln = document.getElementById("settingsButton")
, cr = Ln.getElementsByTagName("span")[0]
, hr = document.getElementById("allianceButton")
, fr = document.getElementById("storeButton")
, ur = document.getElementById("chatButton")
, xt = document.getElementById("gameCanvas")
, M = xt.getContext("2d");
var zh = document.getElementById("serverBrowser");
const Nn = document.getElementById("nativeResolution")
, xn = document.getElementById("showPing");
document.getElementById("playMusic");
const Qt = document.getElementById("pingDisplay")
, dr = document.getElementById("shutdownDisplay")
, Zt = document.getElementById("menuCardHolder")
, qt = document.getElementById("guideCard")
, Et = document.getElementById("loadingText")
, us = document.getElementById("gameUI")
, pr = document.getElementById("actionBar")
, Hh = document.getElementById("scoreDisplay")
, Fh = document.getElementById("foodDisplay")
, Vh = document.getElementById("woodDisplay")
, Uh = document.getElementById("stoneDisplay")
, Lh = document.getElementById("killCounter")
, mr = document.getElementById("leaderboardData")
, jt = document.getElementById("nameInput")
, Le = document.getElementById("itemInfoHolder")
, gr = document.getElementById("ageText")
, yr = document.getElementById("ageBarBody")
, ht = document.getElementById("upgradeHolder")
, ri = document.getElementById("upgradeCounter")
, Te = document.getElementById("allianceMenu")
, oi = document.getElementById("allianceHolder")
, ai = document.getElementById("allianceManager")
, me = document.getElementById("mapDisplay")
, Wt = document.getElementById("diedText")
, Nh = document.getElementById("skinColorHolder")
, ce = me.getContext("2d");
const We = document.getElementById("storeMenu")
, wr = document.getElementById("storeHolder")
, ft = document.getElementById("noticationDisplay")
, Xt = $r.hats
, Gt = $r.accessories;
var ue = new mc(kc,et,C,T);
const ei = "#525252"
, kr = "#3d3f42"
, Xe = 5.5;
T.DAY_INTERVAL / 24;
T.DAY_INTERVAL / 2;
window.addEventListener('wheel', function(e){
if(!keys.q) return;
if(e.deltaY > 0){
se *= 1.05;
//o.maxScreenWidth *= 1.05;
re *= 1.05;
//o.maxScreenHeight *= 1.05;
}else{
se /= 1.05;
//o.maxScreenWidth /= 1.05;
re /= 1.05;
//o.maxScreenHeight /= 1.05;
}
resizeScreen();
})
function setInitData(e) {
Oe = e.teams
}
let ds = !0;
var ps = !1;
(!ls || ki) && (ps = !0);
window.onblur = function() {
ds = !1
}
;
window.onfocus = function() {
ds = !0,
E && E.alive && xs()
}
;
window.captchaCallbackHook = function() {
ps = !0
}
;
window.captchaCallbackComplete && window.captchaCallbackHook();
window.addEventListener("keydown", function(e) {
e.keyCode == 32 && e.target == document.body && e.preventDefault()
});
xt.oncontextmenu = function() {
return !1
}
;
["touch-controls-left", "touch-controls-right", "touch-controls-fullscreen", "storeMenu"].forEach(e=>{
document.getElementById(e) && (document.getElementById(e).oncontextmenu = function(t) {
t.preventDefault()
}
)
}
);
function disconnect(e) {
vi = !1,
ee.close(),
ms(e)
}
function ms(e, t) {
Oi.style.display = "block",
us.style.display = "none",
Zt.style.display = "none",
Wt.style.display = "none",
Et.style.display = "block",
Et.innerHTML = e + (t ? "<a href='javascript:window.location.href=window.location.href' class='ytLink'>reload</a>" : "")
}
function Wh() {
Qt.hidden = false,
Et.style.display = "none",
Oi.style.display = "block",
Zt.style.display = "block",
uf(),
Xh(),
Af(),
Et.style.display = "none",
Zt.style.display = "block";
let e = Nt("moo_name") || "";
!e.length && FRVR.profile && (e = FRVR.profile.name(),
e && (e += floor(Math.random() * 90) + 9)),
jt.value = e || ""
}
function Xh() {
Un.onclick = C.checkTrusted(function() {
ms("Connecting..."),
cs() ? bs() : Oh()
}),
C.hookTouchEvents(Un),
kn && (kn.onclick = C.checkTrusted(function() {
// Lo("https://krunker.io/?play=SquidGame_KB")
}),
C.hookTouchEvents(kn)),
vn && (vn.onclick = C.checkTrusted(function() {
setTimeout(function() {
Rh()
}, 10)
}),
C.hookTouchEvents(vn)),
Ln.onclick = C.checkTrusted(function() {
pf()
}),
C.hookTouchEvents(Ln),
hr.onclick = C.checkTrusted(function() {
nf()
}),
C.hookTouchEvents(hr),
fr.onclick = C.checkTrusted(function() {
hf()
}),
C.hookTouchEvents(fr),
ur.onclick = C.checkTrusted(function() {
Mo()
}),
C.hookTouchEvents(ur),
me.onclick = C.checkTrusted(function(event) {
console.log(event)
const meRect = me.getBoundingClientRect();
const clickX = event.clientX - meRect.left
const clickY = event.clientY - meRect.top
let scale = 14400/meRect.width
const realGameX = clickX * scale;
const realGameY = clickY * scale;
// console.log(realGameX, realGameY);
Tach?.updateChat(`goto ${realGameX} ${realGameY}`, E?.sid);
Tach?.updateChat("path", E?.sid);
Ao()
}),
C.hookTouchEvents(me)
}
let bi;
const Gh = {
view: ()=>{
if (!qe.servers)
return;
let e = 0;
const t = Object.keys(qe.servers).map(i=>{
const s = qe.regionInfo[i].name;
let n = 0;
const r = qe.servers[i].map(o=>{
var h;
n += o.playerCount;
const l = o.selected;
let c = s + " " + o.name + " [" + Math.min(o.playerCount, 50) + "/" + 50 + "]";
const a = o.name
, u = l ? "selected" : "";
o.ping && ((h = o.pings) == null ? void 0 : h.length) >= 2 ? c += ` [${Math.floor(o.ping)}ms]` : l || (c += " [?]");
let p = {
value: i + ":" + a
};
return u && (bi = i + ":" + a,
p.selected = !0),
Ne("option", p, c)
}
);
return e += n,
[Ne("option[disabled]", `${s} - ${n} players`), r, Ne("option[disabled]")]
}
);
return Ne("select", {
value: bi,
onfocus: ()=>{
window.blockRedraw = !0
}
,
onblur: ()=>{
window.blockRedraw = !1
}
,
onchange: Kh
}, [t, Ne("option[disabled]", `All Servers - ${e} players`)])
}
};
Ne.mount(zh, Gh);
var qn, Wn;
location.hostname == "sandbox.moomoo.io" ? (qn = "Back to MooMoo",
Wn = "//moomoo.io/") : (qn = "Try the sandbox",
Wn = "//sandbox.moomoo.io/");
document.getElementById("altServer").innerHTML = "<a href='" + Wn + "'>" + qn + "<i class='material-icons' style='font-size:10px;vertical-align:middle'>arrow_forward_ios</i></a>";
const Yh = `${ui}/servers?v=1.26`
, wo = async()=>fetch(Yh).then(e=>e.json()).then(async e=>qe.processServers(e)).catch(e=>{
console.error("Failed to load server data with status code:", e)
}
)
, $h = ()=>wo().then(Wh).catch(e=>{
console.error("Failed to load.")
}
);
window.frvrSdkInitPromise.then(()=>window.FRVR.bootstrapper.complete()).then(()=>$h());
const Kh = e=>{
if (window.blockRedraw = !1,
FRVR.channelCharacteristics.allowNavigation) {
const [t,i] = e.target.value.split(":");
qe.switchServer(t, i)
} else
vi && (vi = !1,
Fn = !1,
Vn = !0,
Ei = !0,
ee.close())
}
;
document.getElementById("pre-content-container");
function Jh() {
// FRVR.ads.show("interstitial", bs)
}
window.showPreAd = Jh;
function Se(e, t, i) {
if (E && e) {
if (C.removeAllChildren(Le),
Le.classList.add("visible"),
C.generateElement({
id: "itemInfoName",
text: C.capitalizeFirst(e.name),
parent: Le
}),
C.generateElement({
id: "itemInfoDesc",
text: e.desc,
parent: Le
}),
!i)
if (t)
C.generateElement({
class: "itemInfoReq",
text: e.type ? "secondary" : "primary",
parent: Le
});
else {
for (let n = 0; n < e.req.length; n += 2)
C.generateElement({
class: "itemInfoReq",
html: e.req[n] + "<span class='itemInfoReqVal'> x" + e.req[n + 1] + "</span>",
parent: Le
});
const s = co ? e.group.sandboxLimit || Math.max(e.group.limit * 3, 99) : e.group.limit;
e.group.limit && C.generateElement({
class: "itemInfoLmt",
text: (E.itemCounts[e.group.id] || 0) + "/" + s,
parent: Le
})
}
} else
Le.classList.remove("visible")
}
let Pt = []
, wt = [];
function allianceNotification(e, t) {
Pt.push({
sid: e,
name: t
}),
addChatLog(`${t}[${e}] requested to join ${E.team}`,'', 'blue',false,true);
gs()
}
async function gs() {
if (Pt[0]) {
var e = Pt[0];
var textColor = botIDS.includes(e.sid) ? "#53a7db" : "#FFFFFF"//modBots.find((x) => x.sid === e.sid) ? "#53a7db" : "#FFFFFF";
C.removeAllChildren(ft)
ft.style.display = "block"
/*C.generateElement({
class: "notificationText",
text: e.name,
parent: ft
}),*/
if(!(botIDS.includes(e.sid)&&gE("auto accept bots")?.checked)&&true===false){
var notificationText = C.generateElement({
class: "notificationText",
parent: ft
});
notificationText.textContent = e.name + ` [${e.sid}]`;
notificationText.style.color = textColor;
C.generateElement({
class: "notifButton",
html: "<i class='material-icons' style='font-size:28px;color:#cc5151;'></i>",
parent: ft,
onclick: function() {
handleClanRequest(0)
},
hookTouch: !0
}),
C.generateElement({
class: "notifButton",
html: "<i class='material-icons' style='font-size:28px;color:#8ecc51;'></i>",
parent: ft,
onclick: function() {
handleClanRequest(1)
},
hookTouch: !0
})
}
} else
ft.style.display = "none"
}
var lastAccept = 0
async function handleBotRequest(e,ID) {
lastAccept === 0 && (lastAccept=tick)
await nextTick();
await nextTick();
if(tick-lastAccept<=5) return;
for(let i=0;i<Pt.length;i++){
if(Pt[i].sid === e){
ee.send("P", e, 1)
Pt.splice(i, 1)
break;
return;
}
}
}
function addAlliance(e) {
Oe.push(e),
Te.style.display == "block" && ti()
}
function setPlayerTeam(e, t) {
E && (E.team = e,
E.isOwner = t,
Te.style.display == "block" && ti())
if(e == undefined && t == undefined||e == null&&t==false){
clanMates= []
if(Tach?.goal?.pathing){
et.forEach((x) => {
if(x.dmg && !clan(x?.owner?.sid)){
x.pathScale = x.scale+47
}
if(x.name == "pit trap" && !clan(x?.owner?.sid)){
x.pathScale = x.scale+38
}
})
Pathfinder?.setBuildings(et);
// console.log(Date.now(),tick, "removed clan")
}
}
}
function setAlliancePlayers(e) {
wt = e,
Te.style.display == "block" && ti()
clanMates = e;
if(Tach?.goal?.pathing){
et.forEach((x) => {
if(x.dmg && !clan(x?.owner?.sid)){
x.pathScale = x.scale+50
}
if(x.name == "pit trap" && !clan(x?.owner?.sid)){
x.pathScale = x.scale+40
}
})
Pathfinder?.setBuildings(et);
}
}
function deleteAlliance(e) {
lastAccept = 0;
for (let t = Oe.length - 1; t >= 0; t--)
Oe[t].sid == e && Oe.splice(t, 1);
Te.style.display == "block" && ti()
}
function nf() {
xs(),
Te.style.display != "block" ? ti() : Xn()
}
function Xn() {
Te.style.display == "block" && (Te.style.display = "none")
}
function ti() {
if (E && E.alive) {
if (Ri(),
We.style.display = "none",
Te.style.display = "block",
C.removeAllChildren(oi),
E.team)
for (var e = 0; e < wt.length; e += 2)
(function(t) {
const i = C.generateElement({
class: "allianceItem",
style: "color:" + (wt[t] == E.sid ? "#fff" : botIDS.includes(wt[t]) ? "#53a7db" : "rgba(255,255,255,0.6)"),
text: wt[t + 1]+` [${wt[t]}]`,
parent: oi
});
E.isOwner && wt[t] != E.sid && C.generateElement({
class: "joinAlBtn",
text: "Kick",
onclick: function() {
kickPlayer(wt[t])
},
hookTouch: !0,
parent: i
})
}
)(e);
else if (Oe.length)
for (var e = 0; e < Oe.length; ++e)
(function(i) {
const s = C.generateElement({
class: "allianceItem",
style: "color:" + (Oe[i].sid == E.team ? "#fff" : "rgba(255,255,255,0.6)"),
text: Oe[i].sid,
parent: oi
});
C.generateElement({
class: "joinAlBtn",
text: "Join",
onclick: function() {
sendClanRequest(i)
},
hookTouch: !0,
parent: s
})
}
)(e);
else
C.generateElement({
class: "allianceItem",
text: "No Tribes Yet",
parent: oi
});
C.removeAllChildren(ai),
E.team ? C.generateElement({
class: "allianceButtonM",
style: "width: 360px",
text: E.isOwner ? "Delete Tribe" : "Leave Tribe",
onclick: function() {
leaveClan()// xo()
},
hookTouch: !0,
parent: ai
}) : (C.generateElement({
tag: "input",
type: "text",
id: "allianceInput",
maxLength: 7,
placeholder: "unique name",
onchange: t=>{
t.target.value = (t.target.value || "").slice(0, 7)
}
,
onkeypress: t=>{
if (t.key === "Enter")
return t.preventDefault(),
createClan(),
!1
}
,
parent: ai
}),
C.generateElement({
tag: "div",
class: "allianceButtonM",
style: "width: 140px;",
text: "Create",
onclick: function() {
createClan()
},
hookTouch: !0,
parent: ai
}))
}
}
function handleClanRequest(e) {
lastAccept === 0 && (lastAccept=tick)
// gs();
// if(tick-lastAccept<=8) return;
ee.send("P", Pt[0].sid, e),
Pt.splice(0, 1)
gs()
}
function kickPlayer(sid) {
ee.send("Q", sid)
}
function sendClanRequest(e) {
ee.send("b", Oe[e].sid)
}
function createClan(e = document.getElementById("allianceInput").value) {
lastAccept = 0;
ee.send("L", e == "" ? String.fromCharCode(0) : e)
}
function leaveClan() {
lastAccept = 0;
Pt = [],
gs(),
ee.send("N")
}
let pi, Ht, je;
const bt = [];
let Je;
function sf() {
this.init = function(e, t) {
this.scale = 0,
this.x = e,
this.y = t,
this.active = !0
}
,
this.update = function(e, t) {
this.active && (this.scale += .05 * t,
this.scale >= T.mapPingScale ? this.active = !1 : (e.globalAlpha = 1 - max(0, this.scale / T.mapPingScale),
e.beginPath(),
e.arc(this.x / T.mapScale * me.width, this.y / T.mapScale * me.width, this.scale, 0, PI2),
e.stroke()))
}
}
function pingMinimap(e, t) {
for (let i = 0; i < bt.length; ++i)
if (!bt[i].active) {
Je = bt[i];
break
}
Je || (Je = new sf,
bt.push(Je)),
Je.init(e, t)
}
function landmark() {
je || (je = {}),
je.x = E.x,
je.y = E.y
}
function updateMinimap(e) {
Ht = e
}
function lf(e) {
if (E && E.alive) {
ce.clearRect(0, 0, me.width, me.height),
ce.strokeStyle = "#fff",
ce.lineWidth = 4;
if(brokenObjects.length && mapActivity){
brokenObjects.forEach(e=>{
let imgURL = urls.find(t => t.name == e.name)?.url;
if (imgURL) {
ce.globalAlpha =1
let image = new Image();
image.src = imgURL;
ce.drawImage(image, e.x / T.mapScale * me.width - 32 / 2, e.y / T.mapScale * me.height - 32 / 2, 32, 32);
}
})
}
ce.strokeStyle = "#fff", ce.lineWidth = 1;
for (var t = 0; t < bt.length; ++t)
Je = bt[t],
Je.update(ce, e);
if (ce.globalAlpha = 1,ce.fillStyle = "#fff",Q(E.x / T.mapScale * me.width, E.y / T.mapScale * me.height, 7, ce, !0),
// ce.fillStyle = "rgba(255,255,255,0.35)",
E.team && Ht)
for (var t = 0; t < Ht.length; ){
ce.fillStyle = "rgba(255,255,255,0.35)"
Q(Ht[t] / T.mapScale * me.width, Ht[t + 1] / T.mapScale * me.height, 7, ce, !0),
t += 2;
pi && (ce.fillStyle = "#fc5553",
ce.font = "34px Lilita One",
ce.textBaseline = "middle",
ce.textAlign = "center",
ce.fillText("x", pi.x / T.mapScale * me.width, pi.y / T.mapScale * me.height)),
je && (ce.fillStyle = "#fff",
ce.font = "34px Lilita One",
ce.textBaseline = "middle",
ce.textAlign = "center",
ce.fillText("x", je.x / T.mapScale * me.width, je.y / T.mapScale * me.height))
}
Tach?.drawWaypointMap(ce, me);
modBots.forEach((e) => {
if(e.enemies.length){
e.enemies.forEach((x) => {
ce.fillStyle = 'red'
ce.globalAlpha = 1;
Q(x.x/ T.mapScale * me.width, x.y / T.mapScale * me.height, 5, ce, !0);
})
}
})
if(displayer&&teamDisplay.length){
for(let i=0;i<teamDisplay.length;i++){
ce.globalAlpha = 1;
ce.fillStyle = "#000000";
Q(teamDisplay[i].x2 / T.mapScale * me.width, teamDisplay[i].y2 / T.mapScale * me.height, 8, ce, !0);
}
}
if(spyIndex.do&&modBots.length&&modBots[spyIndex.val]?.HERE){
ce.globalAlpha = 1;
ce.fillStyle = "#000000";
Q(modBots[spyIndex.val].x2 / T.mapScale * me.width, modBots[spyIndex.val].y2 / T.mapScale * me.height, 8, ce, !0);
}
/*for(let i = 0; i < botEnemies.length; i++) {
if(botEnemies[i]== undefined ||botEnemies[i] == null||!botEnemies[i]?.length||!botEnemies[i][0]) continue;
if(botEnemies[i][0] != R.sid && !inRender(R,{x:botEnemies[i][1],y:botEnemies[i][2]})&& !clan(botEnemies[i][0]) && !botInfo.find(e => e&&e[0] && e[0] == botEnemies[i][0])) {
Je.fillStyle = "red";
Je.globalAlpha = 1;
ti(botEnemies[i][1] / o.mapScale * Xe.width, botEnemies[i][2] / o.mapScale * Xe.height, 5, Je, !0);
}
}*/
opsList.forEach((x, index, array) => {
let finder = x?.sid ? findPlayerSID(x.sid) : x?.name ? J.find(X => X.name === x.name) : false;
if (finder?.visible) {
finder.color = x.color;
finder.spotted = true;
array[index] = finder;
}
let player = checkIfVisible(x);
if (player) {
player.color = x.color;
let display = finder && finder.visible ? finder : player;
ce.fillStyle = display.color;
ce.globalAlpha = 1;
Q(display.x / T.mapScale * me.width, display.y / T.mapScale * me.height, 9, ce, true);
} else {
x.spotted = false;
}
});
}
}
let $n = 0;
function cf(e) {
$n != e && ($n = e,
ys())
}
function hf() {
We.style.display != "block" ? (We.style.display = "block",
Te.style.display = "none",
Ri(),
ys()) : Kn()
}
function Kn() {
We.style.display == "block" && (We.style.display = "none",
Se())
}
// made changes to lasthat, lastTail here
function storebuy(e, t, i) {
i ? e ? (E.tailIndex = t, lastTail = t) : E.tails[t] = 1 : e ? (E.skinIndex = t, lastHat = t) : E.skins[t] = 1;
We.style.display == "block" && ys()
if(e == 0 && t!=0){
if(i==0)bH.push(t)
if(i==1)bT.push(t);
if(buyer.length && (i==0||i==1)){
for(let ccc =0;ccc<buyer.length;ccc++){
if(i==0&&!Array.isArray(buyer[ccc]) &&buyer[ccc] == t){
buyer.splice(ccc,1)
}
if(i==1&&Array.isArray(buyer[ccc])&& buyer[ccc][0] == t){
buyer.splice(ccc,1)
}
}
if([40,12,22,6,7,56,53,15,31].includes(t)&&!speedHats.includes(t)&&i==0)speedHats.push(t);
if([11,19].includes(t)&&!speedTails.includes(t)&&i==1)speedTails.push(t);
}
}
}
function ys() {
if (E) {
C.removeAllChildren(wr);
const e = $n,
t = e ? Gt : Xt;
for (let i = 0; i < t.length; ++i)
t[i].dontSell || (function(s) {
const n = C.generateElement({
id: "storeDisplay" + s,
class: "storeItem",
onmouseout: Se(),
onmouseover: () => Se(t[s], !1, !0),
parent: wr
});
C.hookTouchEvents(n, !0);
const imgSrc = "./img/" + (e ? "accessories/access_" : "hats/hat_") + t[s].id + (t[s].topSprite ? "_p" : "") + ".png";
const imgElement = C.generateElement({ tag: "img", class: "hatPreview smallImage", src: imgSrc, parent: n });
const textElement = C.generateElement({
tag: "span",
style: "font-size: 85%; vertical-align: middle; line-height: 1.2;",
text: `[${t[s].id}] ${t[s].name}`,
parent: n
});
if ((e ? !E.tails[t[s].id] : !E.skins[t[s].id])) {
C.generateElement({
class: "joinAlBtn",
style: "margin-top: 5px; font-size: 85%; vertical-align: middle; line-height: 1.51;",
text: "Buy",
onclick: () => storeBuy(t[s].id, e),
hookTouch: !0,
parent: n
});
C.generateElement({ tag: "span", class: "itemPrice", style: "font-size: 85%; vertical-align: middle; line-height: 1.51;", text: t[s].price/1000>=1?t[s].price/1000+"k":t[s].price, parent: n });
} else {
const equipText = (e ? E.tailIndex : E.skinIndex) == t[s].id ? "Unequip" : "Equip";
C.generateElement({
class: "joinAlBtn",
style: "margin-top: 5px; font-size: 85%; vertical-align: middle; line-height: 1.51;",
text: equipText,
onclick: () => (equipText == "Unequip" ? storeEquip(0, e) : storeEquip(t[s].id, e)),
hookTouch: !0,
parent: n
});
}
})(i);
}
}
function storeEquip(e, t) {
ee.send("c", 0, e, t)
}
function storeBuy(e, t) {
ee.send("c", 1, e, t)
}
function So() {
We.style.display = "none",
Te.style.display = "none",
Ri()
}
function uf() {
const e = Nt("native_resolution");
Sn(e ? e == "true" : typeof cordova < "u"),
$e = "true"//Nt("show_ping") == "true",
Qt.hidden = false//!$e || !Jt,
Nt("moo_moosic"),
setInterval(function() {
window.cordova && (document.getElementById("downloadButtonContainer").classList.add("cordova"),
document.getElementById("mobileDownloadButtonContainer").classList.add("cordova"))
}, 1e3),
Io(),
C.removeAllChildren(pr);
for (var t = 0; t < R.weapons.length + R.list.length; ++t)
(function(i) {
C.generateElement({
id: "actionBarItem" + i,
class: "actionBarItem",
style: "display:none",
onmouseout: function() {
Se()
},
parent: pr
})
}
)(t);
for (var t = 0; t < R.list.length + R.weapons.length; ++t)
(function(s) {
const n = document.createElement("canvas");
n.width = n.height = 66;
const r = n.getContext("2d");
if (r.translate(n.width / 2, n.height / 2),
r.imageSmoothingEnabled = !1,
r.webkitImageSmoothingEnabled = !1,
r.mozImageSmoothingEnabled = !1,
R.weapons[s]) {
r.rotate(Math.PI / 4 + Math.PI);
var o = new Image;
jn[R.weapons[s].src] = o,
o.onload = function() {
this.isLoaded = !0;
const c = 1 / (this.height / this.width)
, a = R.weapons[s].iPad || 1;
r.drawImage(this, -(n.width * a * T.iconPad * c) / 2, -(n.height * a * T.iconPad) / 2, n.width * a * c * T.iconPad, n.height * a * T.iconPad),
r.fillStyle = "rgba(0, 0, 70, 0.1)",
r.globalCompositeOperation = "source-atop",
r.fillRect(-n.width / 2, -n.height / 2, n.width, n.height),
document.getElementById("actionBarItem" + s).style.backgroundImage = "url(" + n.toDataURL() + ")"
}
,
o.src = "./img/weapons/" + R.weapons[s].src + ".png";
var l = document.getElementById("actionBarItem" + s);
l.onmouseover = C.checkTrusted(function() {
Se(R.weapons[s], !0)
}),
l.onclick = C.checkTrusted(function() {
Yt(s, !0)
}),
C.hookTouchEvents(l)
} else {
var o = Ss(R.list[s - R.weapons.length], !0,true);
const a = Math.min(n.width - T.iconPadding, o.width);
r.globalAlpha = 1,
r.drawImage(o, -a / 2, -a / 2, a, a),
r.fillStyle = "rgba(0, 0, 70, 0.1)",
r.globalCompositeOperation = "source-atop",
r.fillRect(-a / 2, -a / 2, a, a),
document.getElementById("actionBarItem" + s).style.backgroundImage = "url(" + n.toDataURL() + ")";
var l = document.getElementById("actionBarItem" + s);
l.onmouseover = C.checkTrusted(function() {
Se(R.list[s - R.weapons.length])
}),
l.onclick = C.checkTrusted(function() {
Yt(s - R.weapons.length)
}),
C.hookTouchEvents(l)
}
}
)(t);
jt.onchange = i=>{
i.target.value = (i.target.value || "").slice(0, 15)
}
,
jt.onkeypress = i=>{
if (i.key === "Enter")
return i.preventDefault(),
Un.onclick(i),
!1
}
,
Nn.checked = uo,
Nn.onchange = C.checkTrusted(function(i) {
Sn(i.target.checked)
}),
xn.checked = true//$e,
xn.onchange = C.checkTrusted(function(i) {
$e = "true"// xn.checked,
Qt.hidden = true//!$e,
// Di("show_ping", $e ? "true" : "true")
})
}
function itemUpdate(e, t) {
e && (t ? E.weapons = e : E.items = e);
for (var i = 0; i < R.list.length; ++i) {
const s = R.weapons.length + i;
document.getElementById("actionBarItem" + s).style.display = E.items.indexOf(R.list[i].id) >= 0 ? "inline-block" : "none"
}
for (var i = 0; i < R.weapons.length; ++i)
document.getElementById("actionBarItem" + i).style.display = E.weapons[R.weapons[i].type] == R.weapons[i].id ? "inline-block" : "none"
}
function Sn(e) {
uo = e,
mt = e && window.devicePixelRatio || 1,
Nn.checked = e,
Di("native_resolution", e.toString()),
resizeScreen()
}
function df() {
ii ? qt.classList.add("touch") : qt.classList.remove("touch")
}
function pf() {
qt.classList.contains("showing") ? (qt.classList.remove("showing"),
cr.innerText = "Settings") : (qt.classList.add("showing"),
cr.innerText = "Close")
}
function Io() {
let e = "";
for (let t = 0; t < T.skinColors.length; ++t)
t == fs ? e += "<div class='skinColorItem activeSkin' style='background-color:" + T.skinColors[t] + "' onclick='selectSkinColor(" + t + ")'></div>" : e += "<div class='skinColorItem' style='background-color:" + T.skinColors[t] + "' onclick='selectSkinColor(" + t + ")'></div>";
Nh.innerHTML = e
}
function selectSkinColor(e) {
fs = e,
Io()
}
const Ft = document.getElementById("chatBox")
, Si = document.getElementById("chatHolder");
function Mo() {
if(document.activeElement === chatInput) return;
ii ? vr(prompt("chat message"))/*setTimeout(function() {
const e = prompt("chat message");
e && vr(e)
}, 0)*/ : Si.style.display == "block" ? (Ft.value && vr(Ft.value),
Ri()) : (We.style.display = "none",
Te.style.display = "none",
Si.style.display = "block",
Ft.focus(),
xs()),
Ft.value = ""
}
function multiCreation(player, angle, distance, amount = 1, chatVis){
if(fakePlayers.length + amount >= 1500){
addChatLog(`Error amount exceeds player render capacity rate`,'', '#5c0620',false,true);
return false
}
let playerSID = player
player = fakePlayers.find(x => x.purpose == "formation" && x.sid == player)
console.log(fakePlayers)
if(!player){
addChatLog(`Error ID: ${playerSID} not found`,'', '#5c0620',false,true);
return false;
}
for(let i = 0; i < amount; i++){
let newXY = calcPoint(player.x2, player.y2, toRad(angle)-toRad(90), distance * (i + 1))
let newPlayer = {...E}
newPlayer.sid = formationArr.length + 1
formationArr.push({origin: playerSID, distance: distance * (i + 1), angle: angle})
createFakePlayer(createPlayerInfo(newPlayer, newXY.x, newXY.y, 0, 0, 0), "formation");
}
}
function helpCommands(){
addChatLog(`Pathfinder commands ↓`,'', '#5c0620',false,true);
addChatLog(`"setPF (search radius) (resolution)" to adjust Pathfinder`,'', '#5c0620',false,true);
addChatLog(`</ * path`,'', '#5c0620',false,true);
addChatLog(`* stop`,'', '#5c0620',false,true);
addChatLog(`* goal`,'', '#5c0620',false,true);
addChatLog(`* <goal/goto> x [Number: x position]`,'', '#5c0620',false,true);
addChatLog(`* <goal/goto> y [Number: y position]`,'', '#5c0620',false,true);
addChatLog(`* <goal/goto> [x: Number] [y: Number]`,'', '#5c0620',false,true);
addChatLog(`* waypoint set [name: String]`,'', '#5c0620',false,true);
addChatLog(`* waypoint del [name: String]`,'', '#5c0620',false,true);
addChatLog(`* waypoint goto [name: String]`,'', '#5c0620',false,true);
addChatLog(`* follow player <[ID/Name: Any]/all(default)>`,'', '#5c0620',false,true);
addChatLog(`* follow animal <[ID/Name: Any]/all(default)>`,'', '#5c0620',false,true);
addChatLog(`* wander />`,'', '#5c0620',false,true);
addChatLog(`---------------------------------------------------`,'', '#5c0620',false,true);
addChatLog(`Bot commands ↓`,'', '#5c0620',false,true);
addChatLog(`dc bots "!dc (any | all | botID) if using "any" → (number of bots)"`,'', '#5c0620',false,true);
addChatLog(`"!clear (radius) (all | team | clan | enemy | enemies) (all)"`,'', '#5c0620',false,true);
addChatLog(`"!summon" to summon bots "!summon false" to wander`,'', '#5c0620',false,true);
addChatLog(`scout bot (best when bots set to wander) → "!find (sid or -(name))"`,'', '#5c0620',false,true);
addChatLog(`bots attack → "!attack (sid | don't fill for nearest enemy) " (coming soon)`,'', '#5c0620',false,true);
addChatLog(`q = proj sync with bots`,'', '#5c0620',false,true);
addChatLog(`!q instachat (chatInput) [sets q sync chat]`,'', '#5c0620',false,true);
addChatLog(`!target (id) [sets target for q sync insta] | !target [none] | resets target to nearest enemy (default)`,'', '#5c0620',false,true);
addChatLog(`spawn bots press 'y'`,'', '#5c0620',false,true);
addChatLog(`!watch (botID) to spectate bot`,'', '#5c0620',false,true);
addChatLog(`!play (botID) to play as bot`,'', '#5c0620',false,true);
addChatLog(`v = spike macro f = trap macro n = triple mills`,'', '#5c0620',false,true);
addChatLog(`zoom = hold q and use mouse wheel`,'', '#5c0620',false,true);
addChatLog(`p = reset camera zoom`,'', '#5c0620',false,true);
}
function getNumbers(val = 400){
let string = '';
for(let i = 0; i < val; i++){
string += val
}
return string
}
function command(cmd) {
if (cmd === 'debug') {
console.log('debugged');
instaing = false;
oneTick = false;
lastHat = null;
lastTail = null;
meleesyncing = false;
return true;
}
}
document.addEventListener('keydown', function(event) {
if (event.key === 'm') {
command('debug');
}
});
function vr(e,sendmsg) {
let command = function(chat) {
return e.toLowerCase().startsWith("!" + chat.toLowerCase());
};
const parts = e.split(' ');
if (command("jumpscare")) {
const sid = parseFloat(parts[1]);
if(!isNaN(sid)) {
socketer.send(JSONStringify({msg:"jumpscare",player:E,target:sid, sender: E?.sid, doing: false, time:Date.now(),server:location.href}))
// playVideo();
} else {
addChatLog(`specify a user sid to jumpscare`,'',generateRandomColor() ,false,true);
}
} else if (command("radius")) {
const value = parseFloat(parts[1]);
if (!isNaN(value)) {
RADIUS = value;
addChatLog(`move circle radius set at ${value}`,'',generateRandomColor() ,false,true);
return true
}
} else if (command("speed")) {
const value = parseFloat(parts[1]);
if (!isNaN(value)) {
xdIncrement = value;
addChatLog(`move circle speed set at ${value}`,'',generateRandomColor() ,false,true);
return true;
}
}
if(command("botCount") ||command("bc")){
addChatLog(`bot count is ${modBots.length}`,'',generateRandomColor() ,false,true);
return true;
}
if (command("kys")) {
const value = parseFloat(parts[1]);
if(parts[1] == ".all"){
modBots.forEach((x) => {x.kys = !x.kys})
return true
}else if (!isNaN(value)) {
let values = parts[1].split(',').map((str) => parseFloat(str.trim()));
modBots.forEach((x) => {values.includes(x.sid)&&(x.kys=!x.kys)})
return true;
}
}
if(command("chat")){
const value = parseFloat(parts[1]);
if(!isNaN(value)){
for(let i=0;i<value;i++){
chatHistory.removeChild(chatHistory.children[0]);
}
return;
}
}
if(command("clear")) {
chatHistory.innerHTML = ``;
}
if(command("botMsg")){
if(parts[1] == "?player") {
let val = parseFloat(parts[2])
if(isNaN(val)){
addChatLog(`${val} is NaN`,'','red' ,false,true);
return true;
}
let player = findPlayerSID(val)
if(!player){
addChatLog(`player [${val}] is NaN`,'','red' ,false,true);
return true;
} else {
botChat.value = player.chatMessage;
// botMsg = player.chatMessage
addChatLog(`botMsg copied chat ${player.name}[${player.sid}] "${parts[1]}"`,'','red' ,false,true);
return true;
}
}
botChat.value = parts[1]
// botMsg = parts[1];
addChatLog(`botMsg is ${parts[1]}`,'','red' ,false,true);
return true;
}
if(command("logmsgs")){
logMsgs = !logMsgs
addChatLog(`logging messages is ${logMsgs}`,'','red' ,false,true);
return true
}
if(command("hitlist")){
let seetrue = false
for(let i = 0; i < opsList.length; i++){
let player = opsList[i]
if(player.name||player.sid){
seetrue = true;
let msgs = player?.sid && player?.name ? `${player.name}[${player.sid}]` : player.name ? `${player.name}` :`${player.sid}`
addChatLog(`${i+1}. ${msgs}`,'', player.color,false,true);
}
}
if(seetrue)return true;
}
if (command("start")) {
startRandomSongs();
}
if(command('botdist')){
let val = parseFloat(parts[1])
if(!isNaN(val)){
botDist = val;
addChatLog(`bot distance set to ${val}`,'',generateRandomColor() ,false,true);
return true
}
}
if(command('origin')){
fakePlayers = fakePlayers.filter(x => x?.purpose != "formation")
formationArr = [];
originPoint.x = E.x2
originPoint.y = E.y2
let newPlayer = {...E}
newPlayer.sid = 1
formationArr.push(newPlayer)
createFakePlayer(createPlayerInfo(newPlayer,E.x2,E.y2,0,0,0), "formation")
return true
}
if (command('changeBot')) {
if (parts.length !== 4) {
addChatLog("Error: 3 parameters required (ID/all, property, value)", '', 'red', false, true);
return true;
}
console.log(parts)
let val = parts[1] === 'all' ? 'all' : parseFloat(parts[1]);
let val2 = isNaN(parseFloat(parts[3])) ? (parts[3] === 'true' || parts[3] === 'false' ? JSONParse(parts[3]) : parts[3]) : parseFloat(parts[3]);
if (isNaN(val) && val !== "all") {
return addChatLog("Error: 1st parameter invalid (all / ID)", '', 'red', false, true);
}
if(parts[2] === "dir" || parts[2] === "d2" || parts[2] === "d1")val2 = toRad(val2) - toRad(90);
fakePlayers.forEach(x => {
if (x.purpose === 'formation' && (val === 'all' || x.sid === val)) {
x[parts[2]] = val2;
addChatLog(`Fake ID: [${x.sid}] changed ${parts[2]} to ${val2}`, '', 'red', false, true);
}
});
return true;
}
if (command('createFrom')) {
if(!originPoint.x && !originPoint.y){
addChatLog("Error create an origin point first" , '', 'red', false, true);
}
let vals = [parseFloat(parts[1]), parseFloat(parts[2]), parseFloat(parts[3]), parseFloat(parts[4])];
for (let i = 0; i < 4; i++) {
if (isNaN(vals[i])) {
let errorMsg;
switch (i) {
case 0:
errorMsg = 'Error first parameter (creation point) is NaN';
break;
case 1:
errorMsg = 'Error second parameter (angle - degrees) is NaN';
break;
case 2:
errorMsg = 'Error third parameter (distance) is NaN';
break;
// case 3:
// errorMsg = 'Error fourth parameter (repetition amount) is NaN';
// break;
}
addChatLog(errorMsg, '', 'red', false, true);
return true;
}
}
multiCreation(vals[0], vals[1], vals[2], vals[3] || 1);
return true;
// createFakePlayer(createPlayerInfo(E, E.x2, E.y2, 0, 0, 0));
}
if(command('savePos') && originPoint.x){
}
if(command('delay')){
let val = parseFloat(parts[1])
if(!isNaN(val)){
placeDelay = val;
addChatLog(`preplace delay set to ${val}`,'',generateRandomColor() ,false,true);
return true
}
}
if(command('pdelay')){
let val = parseFloat(parts[1])
if(!isNaN(val)){
placeTickInAdvance = val * 111;
addChatLog(`preplace in advance delay set to ${val * 111}`,'',generateRandomColor() ,false,true);
return true
}
}
if(command('kick')){
let val = parseFloat(parts[1])
if(!isNaN(val) && clan(val)){
kickPlayer(val)
let nID = findPlayerSID(val)
let string = nID ? `kicked player: ${nID.name}[${nID.sid}]` : `kicked ID: [${val}]`
addChatLog(string,'',generateRandomColor() ,false,true);
return true
} else {
let string = isNaN(val) ? `Syntax Error: input value is not a number => !kick (teammate SID)` : `ID: ${val} is not in the clan`
addChatLog(string,'',generateRandomColor() ,false,true);
return true
}
}
if(command("musket")&&modBots.length){
let getNum = parseFloat(parts[1])
// let bot = modBots.find(x=> x.sid ==getNum)
if(!isNaN(getNum)){
let bot = modBots.find(x=> x.sid == getNum)
if(!bot){
addChatLog(`cannot set properties of bot undefined`,'','red' ,false,true);
return;
}
bot.getCrossBow = !bot.getCrossBow
addChatLog(`${bot.name}[${getNum}] crossbow set to ${bot.getCrossBow}`,'',generateRandomColor() ,false,true);
return true;
}
if(parts[1] === "all"){
let val = parts[2] === "true" || parts[2] === "false" ? JSONParse(parts[2]) : !isNaN(parseFloat(parts[2])) ? parseFloat(parts[2]) : null
modBots.forEach((x) => {
x.getCrossBow = val !== null ? val : !x.getCrossBow
addChatLog(`${x.name}[${getNum}] crossbow set to ${x.getCrossBow}`,'',generateRandomColor() ,false,true);
})
return true;
}
addChatLog(`error in setting bot loadout`,'','red' ,false,true);
/* if(bot){
let bIndex = modBots.findIndex(D => D.sid === bot.sid)
// if(!isNaN(getNum) && getNum<=modBots.length-1&&getNum>=modBots.length-1){
spyIndex = {do:true,val:bIndex,play:false}
addChatLog(`watching Bot ID: ${getNum}`,'',generateRandomColor() ,false,true);
return;
} else{
addChatLog(`Bot ID: ${parts[1]} not found`,'',generateRandomColor() ,false,true);
}*/
}
if(command('apd')){
let val = parseFloat(parts[1])
if(!isNaN(val)){
apd = val;
addChatLog(`autoplace distance set to ${val}`,'',generateRandomColor() ,false,true);
return true
}
}
if(command('botinfo')){
let val = parseFloat(parts[1])
let bot = modBots.find(x=> x.sid == val)
if(!bot){
addChatLog(`bot ID: ${val} not found`, 'red' ,false,true);
return true
}
if(!isNaN(val)){
console.log(bot)
//addChatLog(JSONStringify(bot),'', 'red',false,true);
return true
}
}
if(command("watch")&&modBots.length){
let getNum = parseFloat(parts[1])
let bot = modBots.find(x=> x.sid ==getNum)
if(bot){
let bIndex = modBots.findIndex(D => D.sid === bot.sid)
// if(!isNaN(getNum) && getNum<=modBots.length-1&&getNum>=modBots.length-1){
spyIndex = {do:true,val:bIndex,play:false}
addChatLog(`watching Bot ID: ${getNum}`,'',generateRandomColor() ,false,true);
return;
} else {
addChatLog(`Bot ID: ${parts[1]} not found, stopped watching`,'',generateRandomColor() ,false,true);
spyIndex.do = false;
}
}
if(e === "!play"&& spyIndex.do){
spyIndex.play = true;
addChatLog(`playing as Bot: ${spyBot?.bot?.name}[${spyBot.bot?.sid}]`,'',generateRandomColor() ,false,true);
return;
} else if(command("play")&&modBots.length){
let getNum = [parseFloat(parts[1]),parseFloat(parts[2])]
if(!isNaN(getNum[0])){
let bIndex = modBots.findIndex(D => D.sid === getNum[0])
let bot = modBots.find(D => D.sid === getNum[0])
if(!bot){
addChatLog(`Bot ID: ${parts[1]} not found`,'',generateRandomColor() ,false,true);
return
}
spyIndex = {do:true,val:bIndex,play:true}
let botInfo = bot.findPlayer(bot.sid)
addChatLog(`playing as Bot: ${botInfo.name}[${botInfo.sid}]`,'',generateRandomColor() ,false,true);
return;
} else {
addChatLog(`Bot ID: ${parts[1]} not found`,'',generateRandomColor() ,false,true);
return;
}
}
if(command("target")){
let val = parseFloat(parts[1])//.slice(1).join(' ');
targetID.ID = val;
let text = isNaN(val) ? 'target ID has been reset' : `projectile sync target set to ID: ${val}`
addChatLog(text, '', generateRandomColor(), false, true);
return true;
}
if(command("instachat")) { // bot insta chat (q sync)
let val = parts.slice(1).join(' ');
qSyncChat = val;
addChatLog(`Q sync insta chat set to ${val}`, '', generateRandomColor(), false, true);
return true;
}
if (command('botName')) {
let val = parts.slice(1).join(' ');
botName = val;
addChatLog(`bot name set to ${val}`, '', generateRandomColor(), false, true);
return true
}
if (command("skip")) {
if (currentSong !== null) {
currentSong.pause();
currentSong = null;
return true
}
}
if (command('syncChat')) {
let val = parts.slice(1).join(' ');
syncChat = val;
addChatLog(`syncChat name set to ${val}`, '',generateRandomColor(), false, true);
return true
}
if(command('sDist')){
let val = parseFloat(parts[1])
if(!isNaN(val)){
sDist = val;
addChatLog(`soldier distance set to ${val}`,'',generateRandomColor() ,false,true);
return true
}
}
if(parts[1] === ".clan"){
}
if (command("accept")) {
let val = parseFloat(parts[1])
ee.send("P", val, 1)
for(let i = 0; i < Pt.length; i++){
let p = Pt[i]
if(p.sid === val){
addChatLog(`accepted request ${p.name}[${p.sid}]`,'', '#32CD32');
Pt.slice(i,1)
}
}
return true
}
if (command("decline")) {
let val = parseFloat(parts[1])
ee.send("P", val, 0)
for(let i = 0; i < Pt.length; i++){
let p = Pt[i]
if(p.sid === val){
addChatLog(`declined request ${p.name}[${p.sid}]`,'', '#FF7F7F');
Pt.slice(i,1)
}
}
return true
}
if (command("kick")) {
let val = parseFloat(parts[1])
kickPlayer(val)
for(let i = 0; i < clanMates.length; i++){
let p = clanMates[i]
if(p.sid === val){
addChatLog(`kicked request ${p.name}[${p.sid}]`,'', '#FF7F7F');
// addChatLog(`Encountered ${e[2]}[${e[1]}] ${getOrdinalNumber(i.seenCount)} time`,'', '#15c283')
Pt.slice(i,1)
}
}
return true
}
if(command("autodecline")){
let val = parseFloat(parts[1])
if(!isNaN(val))decline.push(val);
}
if (command("clanreq")) {
for(let i = 0; i< Pt.length; i ++){
let p = Pt[i]
if(i === 0) addChatLog(`clan requests`,'', 'blue',false,true);
addChatLog(`${i}. ${p.name}[${p.sid}]`,'', 'blue',false,true);
}
return true
}
if (command("clanreset")) {
for(let i = 0; i< Pt.length; i ++){
ee.send("P", Pt[i].sid, 0)
}
return true
}
if(command("search")) {
let val = parseFloat(parts[1]);
let ply = findPlayerSID(val);
if(ply) {
let information = [
`Deaths: ${ply.deaths}`,
ply.noAnti ? `Leaks shame at: ${ply.noAnti}` : `Could not find information about shame from heal tracking`
];//.join('\n');
addChatLog(`Information found for ${ply.name} [${ply.sid}]`, '', '#f2e9d3', false, true);
for(let index = 0; index < information.length; index++) {
addChatLog(`${information[index]}`, '', '#f2e9d3', false, true);
}
} else {
addChatLog(`Could not find player.`,'', '#f2e9d3',false,true);
}
return true;
}
if(command("lookup")) {
if(Oe.length) {
addChatLog(`Clans found: ${Oe.length}`,'', '#baab99',false,true);
for (var data = 0; data < Oe.length; ++data) {
//console.log(Oe[data]);
let seenYet = findPlayerSID(Oe[data].owner);
if(seenYet) {
addChatLog(`Clan ${Oe[data].sid} ${seenYet.name} [${Oe[data].owner}]`,'', '#f2e9d3',false,true);
} else {
addChatLog(`Clan: ${Oe[data].sid} [${Oe[data].owner}]`,'', '#f2e9d3',false, true);
}
}
} else {
addChatLog(`No clans found.`,'', '#FF7F7F',false, true);
}
return true;
}
if(command("ping")) {
if(serverconnected && amAlive) {
socketer.send(JSONStringify({msg:"pinger",player:E, sender: E?.sid, doing: false, time:Date.now(),server:location.href}))
displayer = 10000;
teamDisplay = [];
}
return true;
}
if(command("XP")) {
addChatLog(`Primary: ${E.weaponXP[E.weapons[0]]}, Secondary: ${E.weaponXP[E.weapons[1]]}`,'', '#baab99',false,true);
return true;
}
if(command("mute")){
const value = [parseFloat(parts[1]),parseFloat(parts[2]),parseFloat(parts[3])]
if(!isNaN(value[0])){
muteList.push(value[0])
let player = findPlayerSID(value[0])
let text = player ? `${player.name}[${player.sid}]` :`ID: ${value[0]}`
addChatLog(`muted ${text}`,'', 'red',false,true);
return true;
}
if(parts[1] === ".clanval" && value[1]){
let player = findPlayerSID(value[1])
if(player && typeof player.team === "string"){
J.forEach((e) => {
if(e.team === player.team){
muteList.push(e.sid)
addChatLog(`muted ${e.name}[${e.sid}] in clan ${player.team}`,'', 'red',false,true);
}
})
return true;
}
}
// if(parts[1] === ".clan")
addChatLog(`failed to mute parameter issue`,'', 'red',false,true);
}
if(command("unmute")){
const value = [parseFloat(parts[1]),parseFloat(parts[2]),parseFloat(parts[3])]
if(!isNaN(value[0]) && muteList.includes(value[0])){
muteList = muteList.filter(e => e != value[0])//.push(value[0])
let player = findPlayerSID(value[0])
let text = player ? `${player.name}[${player.sid}]` :`ID: ${value[0]}`
addChatLog(`unmuted ${text}`,'', 'green',false,true);
return true;
}
if(parts[1] === ".clanval" && value[1]){
let player = findPlayerSID(value[1])
if(player && typeof player.team === "string"){
for(let i = 0; i< muteList.length; i++){
J.forEach((e) => {
if(e.team === player.team && muteList[i] === e.sid){
muteList.splice(i,1)
addChatLog(`unmuted ${e.name}[${e.sid}] in clan ${player.team}`,'', 'green',false,true);
}
})
}
return true;
}
}
// if(parts[1] === ".clan")
addChatLog(`failed to unmute parameter issue`,'', 'green',false,true);
}
if(command("find")){
var player;
const value = [parseFloat(parts[1]),parseFloat(parts[2]),parseFloat(parts[3])]
if(parts[1] === ".del"){
let op
if(parts[2] == "all"){
opsList = []
addChatLog(`hit list cleared`,'', generateRandomColor(),false,true);
return true;
}
if(!isNaN(value[1])){
op = opsList.find(x => x.sid==value[1])
opsList = opsList.filter(x => x.sid != value[1])
let msgs = op ? `${op.name}[${op.sid}]` : `${op.name}`
addChatLog(`${msgs} has been removed from hit list`,'', op.color,false,true);
return true;
}
}
if(!isNaN(value[0])){
player = findPlayerSID(value[0])
if(player){
if(!player.color) player.color = generateRandomColor(opsList);
player.spotted = player.visible ? true : false;
opsList.push(player)
addChatLog(`${player?.name}[${player.sid}] was added to the hit list`,'', player.color,false,true);
return true
} else{
player = {}
player.sid = value[0]
if(!player.color) player.color = generateRandomColor(opsList);
player.spotted = false;
opsList.push(player)
addChatLog(`ID: ${player.sid} was added to the hit list`,'', player.color,false,true);
return true
}
}
if(isNaN(value[0]) &&typeof parts[1] === 'string'){
let divide = e.split('.')
player = J.find(e => e.name == divide[1]);
// console.log(player)
if(player){
if(!player.color) player.color = generateRandomColor(opsList);
opsList.push(player)
player.spotted = player.visible ? true : false;
addChatLog(`${player.name}[${player.sid}] was added to the hit list`,'', player.color,false,true);
return true
} else{
player = {}
player.name = divide[1]
if(!player.color) player.color = generateRandomColor(opsList);
player.spotted = false;
opsList.push(player)
addChatLog(`${player.name} was added to the hit list`,'', player.color,false,true);
return true
}
}
}
if(e.startsWith("setPF")){
if(!isNaN(parts[1])||!isNaN(parts[2])){
Pathfinder.size= parseInt(parts[1])
Pathfinder.res = parseInt(parts[2])
Pathfinder.initiateCanvas();
Tach.pathfinder.size = parseInt(parts[1])
Tach.pathfinder.res = parseInt(parts[2])
Tach.pathfinder.initiateCanvas();
if(Tach.goal.pathing){
Tach?.updateChat("stop", E?.sid);
Tach?.updateChat("path", E?.sid);
addChatLog(`Change Pathfinder | radius: ${parts[1]} resolution: ${parts[2]} `,'', generateRandomColor());
}
return true
}
}
Tach?.updateChat(e.slice(0,30), E?.sid);
if(command("commands")||command("help")){
helpCommands()
return true
}
if(command("teamID")) {
teamID = parseFloat(parts[1])
addChatLog(`sync ID set to ${teamID}`,'',generateRandomColor() ,false,true);
return true
}
if (command("bMin")) {
bMin = parseFloat(parts[1])
addChatLog(`bMin is ${bMin}`,'',generateRandomColor() ,false,true);
return true
}
if (command("bMax")) {
bMax = parseFloat(parts[1])
addChatLog(`max one tick distance: ${bMax}`,'',generateRandomColor() ,false,true);
return true
}
if (command("set")) {
cRadius = parseFloat(parts[1])
cSid = parts[2]
cType = parts[3];
if(clearing) {
setTimeout(() => {
vr(`!clear ${cRadius} ${cSid} ${cType}`);
}, 500)
}
return true
}
if(command("summon")){
botMove = "Summon"
return true;
}
if(command("wander")){
botMove = "Wander"
return true;
}
if(command("Static")){
botMove = "Static"
return true;
}
if(command("dc")){
const value = [parseFloat(parts[1]),parseFloat(parts[2])];
if(parts[1] == "any"){
if(!isNaN(value[1])){
modBots.slice(-value[1]).forEach((element) => {
element.close();
});
return true
}
}
if(parts[1] == "all"){
modBots.forEach(x => x.close())
return true
}
if(!isNaN(value[0])){
modBots.forEach(x => x.sid == value[0] &&x.close())
return true;
}
}
if (command("build")) {
const value = parseFloat(parts[1]);
if (!isNaN(value)) {
if(!spyBot?.bot) {
clearRadius = {x: E.x2, y: E.y2, scale: value};
// !clear (radius, SID, type)
let IDS = parts[2]
!IDS ? IDS = R.sid : !isNaN(parseFloat(IDS)) ? IDS = parseFloat(IDS) : IDS = IDS;
parts[3] = parts[3] + (parts[4]!==undefined&&parts[4]!==null&&typeof parts[4] !== "number" ? parts[4] : '');
let types = parts[3]
clearXY = {x:E.x2,y:E.y2,types:types,IDS:IDS,value:value,r:false}
clearing = et.filter(x => {
const g= dist(E, x);
if(x.name == "pit trap"){x.opacity =1} else x.opacity = 1;
if (g <= value &&(types!= 'all' &&(x.group?.name === 'spikes' || x.name === 'pit trap' || x?.name == 'turret' && botBreakUtil.checked || x?.name == 'teleporter' && botBreakUtil.checked) ||types == 'all'||x?.name == types ||x?.group?.name == types) &&(x.type === null || x.type === undefined)) {
if((IDS == "team" || IDS == "clan"|| IDS == "tribe") && clan(x?.owner?.sid))return true;
if((IDS == "enemy"||IDS == "enemies"||IDS == "hostile"||IDS == "nEnemy") && !clan(x?.owner?.sid)) return true;
if(typeof IDS === "number" && x?.owner?.sid === IDS){return true}
if(IDS == "all"||IDS == "every"||IDS =="everything") return true;
if(!IDS && x?.owner?.sid === R.sid) return true;
}
return false;
});
} else {
clearRadius = {x: spyBot?.bot.x, y: spyBot?.bot.y, scale: value};
// !clear (radius, SID, type)
let IDS = parts[2]
!IDS ? IDS = R.sid : !isNaN(parseFloat(IDS)) ? IDS = parseFloat(IDS) : IDS = IDS;
parts[3] = parts[3] + (parts[4]!==undefined&&parts[4]!==null&&typeof parts[4] !== "number" ? parts[4] : '');
let types = parts[3]
clearXY = {x:spyBot?.bot.x,y:spyBot?.bot.y,types:types,IDS:IDS,value:value,r:false}
clearing = spyBot.builds.filter(x => {
const g= dist(spyBot.bot, x);
if(x.name == "pit trap"){x.opacity =1} else x.opacity = 1;
if (g <= value &&(types!= 'all' &&(x.group?.name === 'spikes' || x.name === 'pit trap' || x?.name == 'turret' && botBreakUtil.checked || x?.name == 'teleporter' && botBreakUtil.checked) ||types == 'all'||x?.name == types ||x?.group?.name == types) &&(x.type === null || x.type === undefined)) {
if((IDS == "team" || IDS == "clan"|| IDS == "tribe") && clan(x?.owner?.sid))return true;
if((IDS == "enemy"||IDS == "enemies"||IDS == "hostile"||IDS == "nEnemy") && !clan(x?.owner?.sid)) return true;
if(typeof IDS === "number" && x?.owner?.sid === IDS){return true}
if(IDS == "all"||IDS == "every"||IDS =="everything") return true;
if(!IDS && x?.owner?.sid === R.sid) return true;
}
return false;
});
}
return true
}
}
if (command("rclear")) {
const value = parseFloat(parts[1]);
if (!isNaN(value)) {
clearRadius = {x: E.x2, y: E.y2, scale: value};
// !clear (radius, SID, type)
let IDS = parts[2]
!IDS ? IDS = R.sid : !isNaN(parseFloat(IDS)) ? IDS = parseFloat(IDS) : IDS = IDS;
parts[3] = parts[3] + (parts[4]!==undefined&&parts[4]!==null&&typeof parts[4] !== "number" ? parts[4] : '');
let types = parts[3]
/* parts[3] === "pads"||parts[3] === "spawnpads"||parts[3] === "spawn"||parts[3] === "pad" && (types = "spawn pad")
parts[3] === "pm" || parts[3] === "powermills"
parts[3] === "mills" || parts[3] === "mill" && (types = "mill")
parts[3] === "fw" ||parts[3] === "fasterwindmill"*/
clearXY = {x:E.x2,y:E.y2,types:types,IDS:IDS,value:value,r:true}
clearing = et.filter(x => {
const g= dist(E, x);
// if(x.name == "pit trap"){x.opacity =1} else x.opacity = 1;
if (g >= value &&(types!= 'all' &&(x.group?.name === 'spikes' || x.name === 'pit trap' || x?.name == 'turret' && botBreakUtil.checked || x?.name == 'teleporter' && botBreakUtil.checked ) ||types == 'all'||x?.name == types ||x?.group?.name == types) &&(x.type === null || x.type === undefined)) {
if((IDS == "team" || IDS == "clan"|| IDS == "tribe") && clan(x?.owner?.sid))return true;
if((IDS == "enemy"||IDS == "enemies"||IDS == "hostile"||IDS == "nEnemy") && !clan(x?.owner?.sid)) return true;
if(typeof IDS === "number" && x?.owner?.sid === IDS){return true}
if(IDS == "all"||IDS == "every"||IDS =="everything") return true;
if(!IDS && x?.owner?.sid === R.sid) return true;
}
return false;
});
return true
}
}
if(spyIndex.do && modBots.length){
modBots[spyIndex.val].emit("6", e.slice(0, 30))
return;
}
// Tach?.updateChat(e.slice(0,30), R?.sid);
if(isRegularChat) {
!sendmsg && ee.send("6", e.slice(0, 30),false)
} else if(isPrivateChat) {
socketer.send(JSONStringify({message:e.slice(0, 30),id:E.sid, time:3000}))
}
// console.log(e.slice(0,30))
}
function Ri() {
Ft.value = "",
Si.style.display = "none"
}
let isPrivateChat = false; // Variable to track private chat mode
let isRegularChat = true; // Variable to track regular chat mode
function receiveChat(e, t) {
// console.log(t)
const i = findPlayerSID(e);
// if(muteList.includes(i.sid)){ console.log(i.name, 'talked but muted')return
if(logMsgs) console.log(`${i.name}[${i.sid}] ${t}`);
if((!botIDS.includes(e)||spyBot?.bot?.sid === e) && !muteList.includes(i.sid))addChatLog(`${i.name}[${i.sid}]: `, t, E.sid==e||spyBot?.bot?.sid === e?"#0aa8fc":"#FFFFFF");
//console.log(t)
if((e==E.sid||spyBot?.bot?.sid===e)&&serverconnected && document.getElementById('send ws')?.checked){
socketer.send(JSONStringify({message:t,id:E.sid===e?E.sid:spyBot?.bot?.sid,time:3000}))
}
if(e==E.sid && t == "spectate none" && serverconnected&&amAlive) {
spectator.isDoing = false;
addChatLog(`You have stopped spectating`,'', '#2b0640',false,true);
socketer.send(JSONStringify({msg:"spectate",playerToSpec:undefined, sender: E?.sid, doing: false, time:Date.now(),server:location.href}))
} else if(e==E.sid && t.startsWith("spectate") && serverconnected&&amAlive) {
let msger = t.split("spectate");
let sid = Number(msger[1]);
if(sid != E?.sid) {
// console.log(sid);
addChatLog(`You are now spectating ${findPlayerSID(sid)?.name} [${sid}]`,'', '#2b0640',false,true);
spectator.isDoing = true;
socketer.send(JSONStringify({msg:"spectate",playerToSpec:sid, sender: E?.sid, time:Date.now(),server:location.href}))
} else {
addChatLog(`You cannot spectate yourself.`,'', '#2b0640',false,true);
}
}
if(e==E.sid && t == "ping"&&serverconnected&&amAlive) {
socketer.send(JSONStringify({msg:"pinger",player:E, sender: E?.sid, doing: false, time:Date.now(),server:location.href}))
displayer = 10000;
//setTimeout(() => {
// displayer = false;
teamDisplay = []
//},10000)
}
serverconnected && document.getElementById('send ws').checked &&(!botIDS.includes(e) || spyBot?.bot?.sid===e)&& socketer.send(JSONStringify({chat: t, id:i,chatter:false,color:E.sid==e||spyBot?.bot?.sid===e?"#0aa8fc":"#FFFFFF",server:location.href}))
i && (i.chatMessage = t,
i.chatCountdown = T.chatCountdown)
}
window.addEventListener("resize", C.checkTrusted(resizeScreen));
async function resetCam(){
if(se>T.maxScreenWidth+1){
await wait(2)
se /= 1.05
re /= 1.05
resizeScreen()
resetCam();
} else if(se<T.maxScreenWidth-1) {
await wait(2)
se *= 1.05
re *= 1.05
resizeScreen()
resetCam()
} else return;
}
let initialWidth = window.innerWidth;
let initialHeight = window.innerHeight;
let zoomLevel = 1.0;
function resizeScreen() {
gt = window.innerWidth;
yt = window.innerHeight;
zoomLevel *= Math.min(se / initialWidth, re / initialHeight);
// Update initial size for the next resize event
initialWidth = se;
initialHeight = re;
const e = Math.max(gt / se, yt / re) * mt;
xt.width = gt * mt;
xt.height = yt * mt;
xt.style.width = gt + "px";
xt.style.height = yt + "px";
M.setTransform(e, 0, 0, e, (gt * mt - se * e) / 2, (yt * mt - re * e) / 2)
//console.log(M)
}
var cursor = {x:null, y:null,x2:null,y2:null}
function mouseXY(event, c) {
c = xt.getBoundingClientRect();
if(event){
cursor.x = event.clientX;
cursor.y = event.clientY;
}
const offsetX = (cursor.x - gt / 2) * zoomLevel * .91975;
const offsetY = (cursor.y - yt / 2) * zoomLevel * .91975;
const realGameX = E?.x2 + offsetX;
const realGameY = E?.y2 + offsetY;
cursor.x2 = realGameX;
cursor.y2 = realGameY;
return { x: realGameX, y: realGameY };
}
resizeScreen();
let ii;
tt(!1);
function tt(e) {
ii = e,
df()
}
window.setUsingTouch = tt;
let yf = document.getElementById("leaderboardButton")
, Eo = document.getElementById("leaderboard");
yf.addEventListener("touchstart", ()=>{
Eo.classList.add("is-showing")
}
);
const ks = ()=>{
Eo.classList.remove("is-showing")
}
;
document.body.addEventListener("touchend", ks);
document.body.addEventListener("touchleave", ks);
document.body.addEventListener("touchcancel", ks);
if (!ho) {
let t = function(n) {
mouseXY(n)
n.preventDefault(),
n.stopPropagation(),
tt(!1),
go = n.clientX,
yo = n.clientY
}
, i = function(n) {
if(n.button == 0) {
if(keys.lc===undefined)keys.lc=0;
keys.lc = 1;
}
if(n.button ==1) {
if(keys.mc===undefined)keys.mc=0;
keys.mc = 1;
}
if(n.button == 2){
if(keys.rc===undefined)keys.rc=0;
keys.rc = 1;
}
tt(!1),
Ee != 1 && (Ee = 1,
it())
}
, s = function(n) {
if(n.button == 0){
if(keys.lc===undefined)keys.lc=0;
keys.lc = 0;
}
if(n.button == 1) {
if(keys.mc===undefined)keys.mc=0;
keys.mc = 0;
}
if(n.button == 2){
if(keys.rc===undefined)keys.rc=0;
keys.rc = 0;
}
tt(!1),
Ee != 0 && (Ee = 0,
it())
};
var gameInput = t
, mouseDown = i
, mouseUp = s;
const e = document.getElementById("touch-controls-fullscreen");
e.style.display = "block",
e.addEventListener("mousemove", t, !1),
e.addEventListener("mousedown", i, !1),
e.addEventListener("mouseup", s, !1)
}
let Qn = !1, Po;
function wf() {
// console.log(He)
let e = 0, t = 0, i;
if (ii) {
if (!Qn)
return;
i = Po
}
for (var s in Ii) {
var n = Ii[s];
e += !!He[s] * n[0],
t += !!He[s] * n[1]
}
if ((e != 0 || t != 0) && (i = atan2(t, e)),
i !== void 0)
return C.fixTo(i, 2)
}
let Ti;
function vs(RRR) {
//var visAim = visA.checked; // Toggle visAim based on the checkbox state
if(visAim && !RRR) return E.dir;
return E ? (!E.lockDir && !ii && (Ti = atan2(yo - yt / 2, go - gt / 2)),
C.fixTo(Ti || 0, 2)) : 0;
}
function vs2() {
return E ? (!E.lockDir && !ii && (Ti = atan2(yo - yt / 2, go - gt / 2)),
C.fixTo(Ti || 0, 2)) : 0
}
var He = {}
, Ii = {
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 xs() {
He = {}
// ee.send("e")
}
function Co() {
return Te.style.display != "block" && Si.style.display != "block"
}
var tPressed = false;
var spawning = false;
function keybinds(e) {
// G = repel all bots away from mouse
if (e.key === 'g' || e.keyCode === 71) {
if (typeof modBots !== 'undefined' && modBots.length) {
for (let i = 0; i < modBots.length; i++) {
const bot = modBots[i];
const dx = bot.x - cursor.x2;
const dy = bot.y - cursor.y2;
const angle = Math.atan2(dy, dx);
const repelDist = 400;
const targetX = bot.x + Math.cos(angle) * repelDist;
const targetY = bot.y + Math.sin(angle) * repelDist;
sendBotMove(bot.sid, targetX, targetY);
}
// Optional: on-screen feedback
if (typeof Hn !== 'undefined' && Hn.showText) Hn.showText(E.x2, E.y2, 30, 0.2, 400, "Repel G", "#fff");
}
return;
}
// veltick key, key is shift
if(!elem()||!amAlive)return;
if (e.key == "t") {
let velCheck = document.getElementById("VelTick");
if (velCheck) {
velCheck.checked = !velCheck.checked;
setStoredValue("VelTick", velCheck.checked);
let statusText = "Velocity: " + (velCheck.checked);
if (typeof Hn !== "undefined" && E) {
Hn.showText(E.x2, E.y2, 35, 0.2, 500, statusText, "#fff");
}
}
}
if (e.key.toLowerCase() === "u" && document.activeElement.tagName !== 'INPUT' && document.activeElement.tagName !== 'TEXTAREA') {
if (e.repeat) {
isAutoSpacingActive = true;
return;
}
isAutoSpacingActive = true;
let statusText = "Auto Spacing: Active";
if (typeof Hn !== "undefined" && E) {
Hn.showText(E.x2, E.y2, 35, 0.2, 500, statusText, "#fff");
}
}
const t = e.which || e.keyCode || 0;
78 == t && (mills.status = !mills.status);
e.key == 'e' && (autohit = !autohit);
if(keys[e.key]===undefined)keys[e.key]=0;
keys[e.key]<=2&&keys[e.key]++;
t == 27 ? So() : E && E.alive && Co() && (He[t] || (He[t] = 1,
//t == 69 ? sendHit() :
t == 75 ? Tach?.setWaypoint("quick", E) ://landmark() : // landmark X on minimap
t == 88 ? lockDirection() : // lock direction
E.weapons[t - 49] != null ?Yt(E.weapons[t - 49], !0) :
E.items[t - 49 - E.weapons.length] != null ? Yt(E.items[t - 49 - E.weapons.length]) :
//t == 81 ?Yt(E.items[0]) :
t == 82 ? Ao()/* :
Ii[t] ? Mi()*/ : //null
t == 32 && (Ee = 1,it())))
// e.key === 'Escape' && toggleMenu();
codes[e.keyCode] = 1
let lastBotMove;
if (e.keyCode == 79) {
if (botMove == 'Wander') {
botMove = "Summon";
} else {
botMove = "Wander";
}
Hn.showText(E.x2, E.y2, 30, .2, 400, botMove, "#fff");
} else if (e.keyCode == 189) {
if (botMove == "Static") {
botMove = "Summon";
} else {
lastBotMove = botMove;
botMove = "Static";
}
Hn.showText(E.x2, E.y2, 30, .2, 400, botMove, "#fff");
}
if(modBots.length){
if (e.keyCode === 37) {
// Left arrow key pressed
spyIndex.do = true;
spyIndex.val = (spyIndex.val - 1 + modBots.length) % modBots.length;
//spyBot = modBots[spyIndex]
spyIndex.play = false;
} else if (e.keyCode === 39) {
// Right arrow key pressed
spyIndex.do = true;
spyIndex.val = (spyIndex.val + 1) % modBots.length;
// spyBot = modBots[spyIndex]
spyIndex.play = false;
}
}
if(e.code == "ShiftRight"){
spyIndex.do = false;
spyIndex.play = false;
}
if(e.keyCode == 66&&modBots.length){
if(!clearing){
vr(`!clear ${cRadius} ${cSid} ${cType}`);
} else{
clearXY = null;
clearing = null;
et.forEach(e=>{
if(e.name == "pit trap"){
e.opacity = 1
} else{
e.opacity = 1;
}
})
}
}
codes[e.keyCode] = 1
if(keys[e.key]===undefined)keys[e.key]=0;
keys[e.key]<=2&&keys[e.key]++;
// codes[32] == 1 && (stealingAnimal = !stealingAnimal)
// keys.q === 1 && serverconnected && gE('Qsync')?.checked&&gE('send ws')?.checked&& nEnemy && socketer.send(JSONStringify({msg: 'pz', enemy: nEnemy, team: E, server:location.href}));
// keys.q === 1 && serverconnected && gE('chatSync')?.checked&&gE('send ws')?.checked&& nEnemy && ee.send('6', `${syncChat}`);
if(keys.q){
Qsync = true;
setTimeout(() => {
Qsync = false;
}, timeBetweenTick);
}
//if(keys.g) { // looking for exploits for msgpack vulnerability
//let maliciousObject = { "constructor": { "prototype": { "evil": true } } };
//let maliciousPayload = { "__proto__": { "attack": () => { console.log("Attack!"); } } };
//for(let i = 0; i < 30; i++) {
// ee.send("z", maliciousObject, true);
//ee.send("d", maliciousObject, maliciousObject);
//ee.send("0", maliciousPayload);
//}
// look at "deep object"
//let malformedBuffer = new ArrayBuffer(1);
//let view = new DataView(malformedBuffer);
//view.setUint8(0, 0xFF);
//for(let i = 0; i < 50; i++) {
//place(E.items[2], malformedBuffer);
// ee.send('D', malformedBuffer);
//}
/*let maxDepth = 100;
let deepObject = {};
let current = deepObject;
for (let i = 0; i < maxDepth - 1; i++) {
current.child = {};
current = current.child;
}
ee.send("0", deepObject);*/
/*let obj = {};
obj.self = obj;
for(let i = 0; i < 20; i++) {
ee.send("0""a", obj);
}*/
//}
if(e.code == "ShiftRight"|| e.code == "ShiftLeft"){
if(keys[e.code]===undefined) keys[e.key]=0;
keys[e.code] = 1
}
e.key == 'l' && (autopusher = !autopusher,Hn.showText(E.x2, E.y2, 30, .2, 400, autopusher,"#fff"));
// m.showText(R.x2, R.y2, 50, .18, 500, autopusher,"#fff")
e.key == "U" && !serverconnected && (connectToWS(),console.log('trying to connect'))
e.key == 'k' && (clearing = !clearing) && Hn.showText(E.x2, E.y2, 30, .2, 400, "stop clear","#fff")//(se = T.maxScreenWidth, re = T.maxScreenHeight,resizeScreen());
e.key == 'p' && resetCam()//(se = T.maxScreenWidth, re = T.maxScreenHeight,resizeScreen());
e.key == 'r' && (instaToggle = (instaToggle=="normal"?instaToggle=false:instaToggle = "normal"))
e.key == 'R' && (instaToggle = (instaToggle == "reverse"?instaToggle=false:instaToggle = "reverse"))
e.key == 'p' && (oneTickToggle = !oneTickToggle, Hn.showText(E.x2, E.y2, 30, .2, 400, oneTickToggle,"#fff"))
e.code == 'NumpadSubtract' && (E.customColor = Array.from(allColors)[floor(Math.random() * allColors.size)]); //(oneTickToggle = !oneTickToggle, Hn.showText(E.x2, E.y2, 30, .2, 400, oneTickToggle,"#fff")); //(grinder = !grinder); //(oneTickToggle = !oneTickToggle)
e.key == 'i' && Tach.goal.pathing? Tach?.updateChat("stop", E?.sid) : e.key == "t" ? Tach?.updateChat("path", E?.sid) : null;
e.key == '0' && (spawning = false)
if(e.keyCode == 32) {
if(keys.mc===undefined)keys.mc=0;
keys.mc = 1;
}
// 'Y' toggles infinite bot spawning on/off
if (e.key.toLowerCase() === 'y') {
// Flip spawning flag
spawning = !spawning;
Hn.showText(E.x2, E.y2, 30, 0.2, 400, spawning, "#fff"); // visual cue
console.log(`Bot spawning ${spawning ? 'enabled' : 'disabled'}`);
if (spawning) {
// Start infinite spawn loop
(async function spawnLoop() {
while (spawning) {
try {
const tk = code; // use existing token logic
await connectBot(tk, modBots.length);
// Throttle spawn rate to avoid freezing
await new Promise(resolve => setTimeout(resolve, 200));
// Optional throttle:
// await new Promise(r => setTimeout(r, 50));
} catch (err) {
console.error('Error spawning bot:', err);
spawning = false;
}
}
console.log('Bot spawning loop ended');
})();
}
}
// e.key == 'z' && (instaToggle = (instaToggle == "onetick"?instaToggle=false:instaToggle = "onetick"))
// e.key == 'Z' && (instaToggle = (instaToggle == "nobull"?instaToggle=false:instaToggle = "nobull"))
// e.key == 'z' && (instaTogg = !oneTickToggle);
// keys.v===1&&place(spikeType,ln2())
// keys.f===1&&boostType&& place(boostType,ln2())
// keys.h===1&&utilityType&&place(utilityType,ln2())
// keys.j===1 &&mineType!=null&&place(mineType)
keys['1']==1 && (ww=primary)
keys['2']==1 && secondary!=null&& (ww=secondary)
}
window.addEventListener("keydown", C.checkTrusted(keybinds));
function keybindsdown(e) {
if (E && E.alive) {
const t = e.which || e.keyCode || 0;
if (t == 13) {
if (Te.style.display === "block")
return;
Mo()
} else{
Co() && He[t] && (He[t] = 0,
/*Ii[t] ? Mi() :*/ t == 32 && (Ee = 0,
it()))
}
if(keys[e.key]===undefined)keys[e.key]=0;
keys[e.key] = 0
keys[e.key] = 0
codes[e.keyCode] = 0
}
if(e.code == "ShiftRight"|| e.code == "ShiftLeft"){
if(keys[e.code]===undefined)keys[e.key]=0;
keys[e.code] = 0;
}
if (e.key === 'Enter') {
if (document.activeElement === chatInput) {
const message = chatInput.value.trim();
if (message !== '') {
// addChatLog(`${E.name}[${E.sid}]: `, chatInput.value, "#0aa8fc");
vr(chatInput.value,true)
document.getElementById('send ws').checked && socketer.send(JSONStringify({ chat: message, id: E, chatter: true, color:"#0aa8fc",server:location.href,pm:true}));
// addChatLog('User: ' + message, 'blue');
// socketer.send(JSONStringify({ chat: message, id: R, chatter: true, color:"#0aa8fc",server:location.href,pm:true}));
// chatInput.value = '';
// chatInput.blur();
}
chatInput.value = '';
setTimeout(() => {
chatInput.blur();
}, 0);
// Handle sending the message here
}
}
if (e.key === '/'&&"chatbox" !== document.activeElement.id.toLowerCase()) {
chatInput.focus();
}
if(e.keyCode == 32) {
if(keys.mc===undefined)keys.mc=0;
keys.mc = 0;
}
}
window.addEventListener("keyup", C.checkTrusted(keybindsdown));
function it() {
return;
//E && E.alive && ee.send("d", Ee, E.buildIndex >= 0 ? vs() : null)
}
//let Tn;
var botMD = null;
function collisionDetection(x1, y1, s1, x2, y2, s2) {
return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2) - (s1 + s2) < 1;
}
const PID12 = PI / 12;
function mutateDirection(dir) {
let velocity = speedMultTest(E) * defaultSpeed;w
if (dir === undefined) return undefined;
if (checkAreasForCollision(dir, velocity) === null) {
for (let i = 0; i < PI; i += PID12) {
if (checkAreasForCollision(dir + i, velocity) !== null) return dir + i;
if (checkAreasForCollision(dir - i, velocity) !== null) return dir - i;
}
return PI + null;
}
return dir;
}
function checkAreasForCollision(dir, velocity) {
let x = E.x2 + cos(dir) * velocity;
let y = E.y2 + sin(dir) * velocity;
let tmpScale = 45;
if (collisionDetection(x, y, 35, inTrap.x, inTrap.y, 45)) {
let angle = atan2(x - inTrap.x, y - inTrap.y), dist = sqrt((x - inTrap.x) ** 2 + (y - inTrap.y) ** 2) + 35;
let x2 = x + cos(angle) * dist;
let y2 = y + sin(angle) * dist;
if (collisionDetection(x2, y2, 35, inTrap.x, inTrap.y, tmpScale)) {
return null;
}
}
return dir;
}
let oneticking = false;
function Mi(collides = false) {
var e = wf();
let p2 = {...E}
let velL = autohat(1, e)
p2.buildIndex = -1;
p2.weaponIndex = hold != null ? hold : E.weaponIndex;
p2.skinIndex = (E.skins[velL.skinIndex] ? velL.skinIndex : E.skinIndex);
p2.tailIndex = (E.tails[velL.tailIndex] ? velL.tailIndex : E.tailIndex);
collides = !isNaN(e) ? runInto(E,e,calcVel(p2,e, p2, 1)) : false;
let isBOT = !(modBots.length&&spyIndex.do&&spyIndex.play) ? false : true
let MD = isBOT ? Tn : botMD
if(collides&&!keys.ShiftLeft&&!(moveAuto=="pathfinder"&&Tach.goal.pathing)) e = undefined;
if(e == moveDirection&& !isBOT) return;
if((null == Tn || null == e || Math.abs(e - Tn) > .3) &&!(moveAuto=="pathfinder"&&Tach.goal.pathing&& !isBOT)&&!pushing){
if((pushPrioritization && moveAuto!="autopush"&& typeof pushCoords=== "object") || oneTickToggle) return;
if(!isBOT){
//if(inTrap) {
// let circular = mutateDirection(e);
// ee.send("9", circular);
//} else {
ee.send("9",e)
//}
Tn = e
} else {
modBots[spyIndex.val].emit('9',e)
botMD = e;
}//, gn = e//console.log(e)
}
// (Tn == null || e == null || Math.abs(e - Tn) > .3) && (ee.send("9", e),
// Tn = e)
}
function lockDirection() {
E.lockDir = E.lockDir ? 0 : 1
// ee.send("K", 0)
}
function Ao() {
ee.send("S", 1)
}
function sendHit() {
ee.send("K", 1)
}
function Yt(e, t) {
ee.send("z", e, t)
}
window.io = ee;
function bs() {
Qt.hidden = !$e,
window.onbeforeunload = function(e) {
return "Are you sure?"
}
,
window.FRVR && window.FRVR.tracker.levelStart("game_start"),
Di("moo_name", jt.value),
!Jt && cs() && (Jt = !0,
_h.stop("menu"),
ms("Loading..."),
ee.send("M", {
name: jt.value,
moofoll: 1,
skin: fs === 10 ? "constructor" : fs
})),
Sf()
}
function Sf() {
var e = document.getElementById("ot-sdk-btn-floating");
e && (e.style.display = "none")
}
function Tf() {
var e = document.getElementById("ot-sdk-btn-floating");
e && (e.style.display = "block")
}
let Ei = !0
, In = !1;
function setupGame(e) {
amAlive = true;
inGame = true;
mills = {status : false,w:null,a:null,s:null,d:null,aim:null,x:0,y:0};
Et.style.display = "none",
Zt.style.display = "block",
Oi.style.display = "none",
He = {},
mo = e,
Ee = 0,
Jt = !0,
Ei && (Ei = !1,
et.length = 0)
ho && Mh.enable({
onStartMoving: ()=>{
Kn(),
Xn(),
tt(!0),
Qn = !0
}
,
onStopMoving: ()=>{
Qn = !1,
Mi()
}
,
onRotateMoving: (t,i)=>{
i.force < .25 || (Po = -i.angle.radian,
Mi(),
In || (Ti = -i.angle.radian))
}
,
/* onStartAttacking: ()=>{
Kn(),
Xn(),
tt(!0),
In = !0,
E.buildIndex < 0 && (Ee = 1,
it())
}
,
onStopAttacking: ()=>{
E.buildIndex >= 0 && (Ee = 1,
it()),
Ee = 0,
it(),
In = !1
}
,
onRotateAttacking: (t,i)=>{
i.force < .25 || (Ti = -i.angle.radian)
}*/
})
}
function showText(e, t, i, s) {
if(i<0||!stackedDmgs.checked){
s === -1 ? Hn.showText(e, t, 50, .18, 500, i, "#ee5551") : stackedHeal.checked ? stackedText.push({ x: e, y: t, value: i}) : Hn.showText(e, t, 50, .18, 500, abs(i), i >= 0 ? "#fff" : "#8ecc51")
}
}
let mi = 99999;
async function died() {
Jt = !1,
Tf();
amAlive = false;
hitPacket=0;
instaing = false;
meleesyncing = false;
mills = {status : false,w:null,a:null,s:null,d:null,aim:null,x:0,y:0};
Tach?.setWaypoint("death", E)
us.style.display = "none",
So(),
pi = {
x: E.x,
y: E.y
},
Et.style.display = "none",
Wt.style.display = "block",
Wt.style.fontSize = "0px",
mi = 0,
setTimeout(function() {
Zt.style.display = "block",
Oi.style.display = "block",
Wt.style.display = "none"
}, T.deathFadeout),
wo()
await nextTick()
setTimeout(() => {
addChatLog(JSONStringify(E.dmgpots),'', 'black',false,true);
addChatLog(JSONStringify(E.healths),'', '#ff17dd',false,true);
addChatLog(`Ping: ${window.pingTime}`,'', 'black',false,true);
addChatLog(`Shame Leak attempted: ${E.shameLeak}`,'', 'black',false,true);
}, 10);
}
function removeInactivePlayerObjects(e) {
if(targetID.ID == e){
addChatLog(`target ID reset to undefined`,'', 'green',false,true);
targetID.ID = null
}
et=et.filter(t => t?.owner?.sid!=e)
opsList = opsList.filter(x => x?.sid != e)
modBots.length && (modBots = modBots.filter(x => x.HERE))
Pt = Pt.filter(x=> x.sid != e)//.splice(i, 1)
// addChatLog(`${W[t].name}[${W[t].sid}] has left`,' ',"red")
//E && //ue.removeAllItems(e)
}
function gradeReplace(spike, trap, newEnemies, time){
//let newEnemies = enemies.filter(e => dist2(E,e)<=275);
let bestSpike;
let bestTrap;
let spikeNtrap = nearObjects.filter(x => (x.name == "pit trap" || x.group?.name == "spikes" || x.type === 1 && x.y >= 12000) && x.distance <= 450);
let overlapDists = {};
let spikeOffset = R.list[spikeType].scale - 50
for(let m = 0; m < newEnemies.length; m++) {
let x = newEnemies[m];
for(let i = 0; i < trap.length; i++){
let angleAbuse = true;
for(let t = 0; t < x.placePot.possible.length; t++){
let obj = x.placePot.possible[t]
overlapDists[trap[i].angle+x.name+x.sid+obj.angle] = dist2(trap[i],obj)
if(overlapDists[trap[i].angle+x.name+x.sid+obj.angle] <= trap[i].scale + obj.scale){
trap[i].placePriority = true;
angleAbuse = false;
break;
// trap[i].intercepts.push(obj);
}
}
let plyrDist = dist2(trap[i],x)
if(plyrDist <= 200) trap[i].points += 1;
if(plyrDist<=20.4){
trap[i].points += 1
// trap[i].origin.push({amount:1,from:`stops ${x.name}[${x.sid}] from placing`,player:x})
}
if(plyrDist <= 50){
trap[i].collide.push(x.sid)
trap[i].points += inTrap ? 4 : 2;
// trap[i].origin.push({amount:1,from:`collide with ${x.name}[${x.sid}]`,player:x})
}
let obj = spikeNtrap.filter(t => (t?.group?.name === "spikes" && (clan(t.owner.sid) || !x.team && t?.owner?.sid != x.sid)|| t.y >= 12000 && t.type === 1) && fastHypot(t.x-trap[i].x,t.y-trap[i].y) <= 50 + (t.type == 1 ? t.scale * 0.55 : t.scale) + 24 && !trap[i].sids.includes(t.sid))
if(obj.length){
trap[i].points+= (1 + obj.length)
trap[i].canPush = true;
// trap[i].origin.push({amount:1 + obj.length,from:'trap autopush potential',player:x})
}
/* if(!angleAbuse){ // too performance inefficient to use may revisit later
let points = trap[i].intercepts.length * .25
trap[i].points += points
trap[i].origin.push({amount:points,from:'blocks angle',player:x})
}*/
if(plyrDist<=x.placePot.placeRange){
if(angleAbuse){
trap[i].points += 1
// trap[i].origin.push({amount:2,from:'angle abuse',player:x})
} else {
trap[i].points += .5
// trap[i].origin.push({amount:.5,from:'blocks angle',player:x})
}
}
if(!bestTrap ||bestTrap.points<=trap[i].points) bestTrap = trap[i];
}
for(let i = 0; i < spike.length; i++){
spike[i].bounce = false;
spike[i].collision = false;
if(isInPath(spike[i])) continue;
let plyrDist = dist2(spike[i],x)
let angleAbuse = true
for(let t = 0; t < x.placePot.possible.length; t++){
let obj = x.placePot.possible[t]
if(overlapDists[spike[i].angle+x.name+x.sid+obj.angle] + spikeOffset <= spike[i].scale + obj.scale){
spike[i].placePriority = true;
angleAbuse = false;
break;
// spike[i].intercepts.push(obj)
// break;
}
}
let trapDist = x.inTrap ? dist2(spike[i],x.inTrap) : Infinity
let angDist = dAng(atan2(spike[i].y - E.y2, spike[i].x - E.x2), dAng(atan2(x.y2 - E.y2, x.x2 - E.x2)));
//let buildIsPerpendicularToEnemy = 1.6 - dAng(1.57, angleDistToEnemy);
//let buildBlocksPlayerEscape = angleDistToEnemy > 2;
//logAndStack(`trapDist: ${trapDist}, angleDistToEnemy: ${angleDistToEnemy}, buildIsPerpendicularToEnemy: ${buildIsPerpendicularToEnemy}, buildBlocksPlayerEscape: ${buildBlocksPlayerEscape}, preventsBounceBack: ${preventsBounceBack}`);
if(plyrDist <= 35 + spike[i].scale){
if(spike[i].collide.length >=1)spike[i].origin.push({amount:1,from:`collides with ${x.name}[${x.sid}]`,player:x})
spike[i].collide.push(x.sid)
spike[i].collision = true;
//if(!x.inTrap){ uncomment this maybe lets find out
let bouncer = knockInto(spike[i],spikeNtrap,x)
if(bouncer.building){
spike[i].into = bouncer
if(bouncer.building.name == "pit trap" && !(spike[i].preplace && x.inTrap && spike[i].sids.includes(x.inTrap.sid))){
spike[i].points += 2.5;
//spike[i].origin.push({amount:1.5,from:'spike knocks into trap',player:x})
} else if(bouncer.bounce){
spike[i].bounce = true;
spike[i].points += 5;
//spike[i].origin.push({amount:2,from:'knocks between spike infinitely test',player:x})
} else if(bouncer.building.name !== "pit trap"){
spike[i].points += 3;
//spike[i].origin.push({amount:2,from:'knocks into spike',player:x})
} else {
spike[i].into = false
}
}
//}
if(x.inTrap && !spike[i].sids.includes(x.inTrap.sid)){
spike[i].points+=2
spike[i].spikeTrap = true;
spike[i].canPush = true;
//spike[i].origin.push({amount:2,from:'spike collides with player while in trap',player:x})
}
}
if(x.inTrap && !spike[i].sids.includes(x.inTrap.sid) && trapDist <= 50 + spike[i].scale + 21){
spike[i].canPush = true;
spike[i].points+=1
// spike[i].origin.push({amount:1,from:'possible autopush spike',player:x})
}
if(x.inTrap && plyrDist <= 250 && (dAng(spike[i].angle,x.inTrap.angToMe) >= 1.5 || moveDirection === null || moveDirection === undefined)){
spike[i].points+=2
// spike[i].origin.push({amount:1,from:'spike surrounds trapped player',player:x})
}
//if(pushing) console.log(dAng(pushVector.dir, atan2(x.y2 - E.y2, x.x2 - E.x2)));
if(x.inTrap && pushing && dAng(pushVector.dir, atan2(x.y2 - E.y2, x.x2 - E.x2)) > 4.7) {
logAndStack("prevents bounce back");
spike[i].points += 2;
}
if(angleAbuse&&plyrDist<=x.placePot.placeRange){
spike[i].points+=1
// spike[i].origin.push({amount:1,from:'angle abuse',player:x})
}
if(!bestSpike ||bestSpike.points<=spike[i].points) bestSpike = spike[i];
}
overlapDists = {};
}
return {spikes:spike,traps:trap,bestSpike:bestSpike,bestTrap:bestTrap}
}
let prioSync = false;
function removeObject(e,t,d) {
/*serverconnected && socketer.send(JSONStringify({
msg: "removeBuild",
sender: E?.sid, // add + 1 for testing purposes
sendX: E?.x2,
sendY: E?.y2,
removeSid: e,
time: Date.now(),
server: location.href
}));*/
et = et.filter(x => {
if(x.sid !== e) return true;
if(!inRender(E,x)){
x.TICK = tick;
brokenObjects.push(x)
}
if(x.sid == e && inTrap.sid === x.sid) {
Hg(6, E.tailIndex);
}
if(x.sid == e && nEnemy && nEnemy?.globalTrap?.sid === x.sid && dist(E, x) <= 126){
//console.log(x);
destroyedTraps.push({
build: x,
destroyedAt: tick,
});
//spikeSync.push(x);
if(autobreakBuild) {
place(E.items[2], getDir(E, x));
place(E.items[2], getDir(E, nEnemy));
}
/*if(spikeSync.length && spikeTicker.checked && (primary == 3 || primary == 4 || primary == 5) && polePlacer(R.list[spikeType], getDir(E, x), x)) {
prioSync = true;
} else prioSync = false;*/
}
if (x.sid === e && !prioSync && nEnemy &&dist(E,nEnemy) <= 235&& dist(E,x) <= 190&& autoRep.checked && R.list[E.items[4]]?.name == "pit trap") {
// TO DO: check if it doesn't collide with our preplace locations, and also create replaceLocations, so auto place doesn't collide with auto place, whilst still both being able to run at the same time
// im restricting preplace location, so auto replace doesn't mess up with it
const possibleSpikes = findAvailableAnglesR(spikeType, 0, 0, PI / placeAccuracy.value);
const possibleTraps = findAvailableAnglesR(boostType, 0, 0, PI / placeAccuracy.value);
const placer = gradeReplace(possibleSpikes, possibleTraps, nearEnemies);
const { bestTrap, bestSpike } = placer;
placer.spikes.sort((a, b) => b.points - a.points);
placer.traps.sort((a, b) => b.points - a.points);
if(placer.spikes.length && placer.traps.length) {
function fullplace(placedItems, allItems = placer.spikes.concat(placer.traps)) {
allItems = allItems.filter(item => item.points > 0);
if (packets >= 85 || (!bestSpike && !bestTrap && !keys.c)) return;
allItems.sort((a, b) => {
if (b.points === a.points && a.name !== b.name) {
return a.name === 'pit trap' ? -1 : 1;
}
return b.points - a.points;
});
// remove intersections, once it reaches 4 stop.
//dist(trap,spike) <= trap.scale+spike.scale
for (let item of allItems) {
const intersectsWithPlaced = placedItems.some(placed => dist2(placed, item) <= placed.scale + item.scale);
const intersectsWithPrioLoc = prioLoc.some(prio => dist2(prio, item) <= prio.scale + item.scale);
if (!intersectsWithPlaced && !intersectsWithPrioLoc) {
placedItems.push(item);
}
if (placedItems.length === 4) break;
}
// actually do the placing
for (let item of placedItems) {
if (!item.did) {
placers(item.id, item.angle)
replaceLoc.push(item);
usedAngles.push({ ...item, tick: tick });
}
}
}
// add place priority back, but not preplace (nvm, don't add either)
let placing = [];
// !prioLoc.some(item => dist2(item, bestSpike) <= item.scale + bestSpike.scale) maybe comment this out
// !prioLoc.some(item => dist2(item, bestTrap) <= item.scale + bestTrap.scale) maybe comment this out
// check if preplace doesn't block where we are replacing lol
//logAndStack(`Auto place activty check ${amPlacing}`);
if (bestSpike && bestSpike.points > 0 && !prioLoc.some(item => dist2(item, bestSpike) <= item.scale + bestSpike.scale) && (!bestTrap.canPush || bestSpike.into) && (pushing && bestTrap.points > 0 || bestSpike.bounce)) {
if (bestSpike.into) {
createSpikeKB(bestSpike.into.newPos);
}
if(bestSpike.collision) {
logAndStack(`spike sync tester`);
}
if(bestSpike.placePriority) {
placers(inTrap ? 15 : spikeType, bestSpike.angle)
usedAngles.push({ ...bestSpike, tick: tick });
} else {
placers(inTrap ? 15 : spikeType/*.id*/, bestSpike.angle)
usedAngles.push({ ...bestSpike, tick: tick });
}
bestSpike.did = true;
placing.push(bestSpike);
replaceLoc.push(bestSpike);
}
if(bestTrap && bestTrap.points > 0 && !prioLoc.some(item => dist2(item, bestTrap) <= item.scale + bestTrap.scale) && !(bestSpike &&bestSpike.points>0 && (!pushing && bestSpike.bounce) && dist(bestTrap, bestSpike) <= bestTrap.scale + bestSpike.scale)|| bestTrap?.canPush || pushing){
if(bestTrap.placePriority) {
placers(boostType, bestTrap.angle);
usedAngles.push({ ...bestTrap, tick: tick });
} else {
placers(boostType, bestTrap.angle);
usedAngles.push({ ...bestTrap, tick: tick });
}
bestTrap.did = true;
placing.push(bestTrap);
replaceLoc.push(bestTrap);
}
fullplace(placing);
/*d = getDir(E,x)
if(pushing){
Hq(boostType,d,true)
}
for (let i = -1; i <= 1; i++) {
Hq(boostType, d+i,true);
}*/
}
}
return false;
});
//ue.disableBySid(e)
}
function resourceCount() {
Hh.innerText = E.points,
Fh.innerText = E.food,
Vh.innerText = E.wood,
Uh.innerText = E.stone;
if (E.kills > Lh.innerText) {
ee.send("6", "Revelation on top!");//killchat
}
Lh.innerText = E.kills;
}
const Vt = {}
, Mn = ["crown", "skull"];
function Af() {
for (let e = 0; e < Mn.length; ++e) {
const t = new Image;
t.onload = function() {
this.isLoaded = !0
}
,
t.src = "./img/icons/" + Mn[e] + ".png",
Vt[Mn[e]] = t
}
}
const ut = [];
function updateUpdate(e, t) {
displayItemCount()
if (E.upgradePoints = e,
E.upgrAge = t,
e > 0) {
ut.length = 0,
C.removeAllChildren(ht);
for (var i = 0; i < R.weapons.length; ++i)
if (R.weapons[i].age == t && (R.weapons[i].pre == null || E.weapons.indexOf(R.weapons[i].pre) >= 0)) {
var s = C.generateElement({
id: "upgradeItem" + i,
class: "actionBarItem",
onmouseout: function() {
Se()
},
parent: ht
});
s.style.backgroundImage = document.getElementById("actionBarItem" + i).style.backgroundImage,
ut.push(i)
}
for (var i = 0; i < R.list.length; ++i)
if (R.list[i].age == t && (R.list[i].pre == null || E.items.indexOf(R.list[i].pre) >= 0)) {
const r = R.weapons.length + i;
var s = C.generateElement({
id: "upgradeItem" + r,
class: "actionBarItem",
onmouseout: function() {
Se()
},
parent: ht
});
s.style.backgroundImage = document.getElementById("actionBarItem" + r).style.backgroundImage,
ut.push(r)
}
for (var i = 0; i < ut.length; i++)
(function(r) {
const o = document.getElementById("upgradeItem" + r);
o.onmouseover = function() {
R.weapons[r] ? Se(R.weapons[r], !0) : Se(R.list[r - R.weapons.length])
}
,
o.onclick = C.checkTrusted(function() {
ee.send("H", r)
}),
C.hookTouchEvents(o)
}
)(ut[i]);
ut.length ? (ht.style.display = "block",
ri.style.display = "block",
ri.innerHTML = "SELECT ITEMS (" + e + ")") : (ht.style.display = "none",
ri.style.display = "none",
Se())
} else
ht.style.display = "none",
ri.style.display = "none",
Se()
}
function ageUpdate(e, t, i) {
e != null && (E.XP = e),
t != null && (E.maxXP = t),
i != null && (E.age = i),
i == T.maxAge ? (gr.innerHTML = "MAX AGE",
yr.style.width = "100%") : (gr.innerHTML = "AGE " + E.age,
yr.style.width = E.XP / E.maxXP * 100 + "%")
}
function updateLeaderboard(e) {
C.removeAllChildren(mr);
let t = 1;
for (let i = 0; i < e.length; i += 3) {
(function (s) {
C.generateElement({
class: "leaderHolder",
style: "font-size: 14px; display: flex; justify-content: space-between; align-items: center;",
parent: mr,
children: [C.generateElement({
class: "",
style: "color:" + (e[s] == mo ? "#fff; font-size: 14px;" : "rgba(255,255,255,0.6); font-size: 14px;"),
text: `${e[s+1]} [${e[s]}]`
}), C.generateElement({
class: "leaderScore",
style: "font-size: 14px;",
text: C.kFormat(e[s + 2]) || "0"
})]
});
})(i);
t++;
}
}
let xr = null;
function Of() {
{
// console.log(It-yn)
if (E && (!yn || It - yn >= 1e3 / T.clientSendRate)) {
yn = It;
const a = vs();
xr !== a && (xr = a)
// ee.send("D", a))
}
let vals = (!spyBot?.bot && !spectator.isDoing) ? E : spectator.isDoing ? spectator?.rPlayer /*: isVis?.visible? isVis */:spyBot?.bot
//console.log(spectator.player);
if (mi < 120 && (mi += .1 * be,Wt.style.fontSize = min(round(mi), 120) + "px"),vals) {
const a = C.getDistance(Re, _e, vals.x, vals.y)
, u = C.getDirection(vals.x, vals.y, Re, _e)
, p = min(a * .01 * be, a);
a > .05 ? (Re += p * cos(u),
_e += p * sin(u)) : (Re = vals.x,
_e = vals.y)
} else
Re = T.mapScale / 2,
_e = T.mapScale / 2;
const o = It - timeBetweenTick;
for (var e, t = 0,animALL = J.concat(fakePlayers, spyBot.players, spectator.rPlayers); t < animALL.length + ye.length; ++t)
if ((y = animALL[t] || ye[t - animALL.length]) && y && (y?.visible||y?.fake||y?.spectate && y.specVis))
if (y.forcePos)
y.x = y.x2,
y.y = y.y2,
y.dir = y.d2;
else {
var a = y.t2 - y.t1
, p = (o - y.t1) / a
, h = 170;
y.dt += be;
var m = min(1.7, y.dt / h);
var e = y.x2 - y.x1;
y.x = y.x1 + e * m,
e = y.y2 - y.y1,
y.y = y.y1 + e * m,
y.lastx = y.x//_.x1 + u * h
y.lasty = y.y//_.y1 + u * h
y.dir = Math.lerpAngle(y.d2, y.d1, min(1.2, p))
if(y?.bot){
// console.log('ez')
let player = modBots[spyIndex?.val]?.findPlayer(y.sid)
player && (player = y)
};
}
const l = Re - se / 2 + camX
, c = _e - re / 2 + camY;
// console.log(l,c)
T.snowBiomeTop - c <= 0 && T.mapScale - T.snowBiomeTop - c >= re ? (M.fillStyle = "#b6db66",
M.fillRect(0, 0, se, re)) : T.mapScale - T.snowBiomeTop - c <= 0 ? (M.fillStyle = "#dbc666",
M.fillRect(0, 0, se, re)) : T.snowBiomeTop - c >= re ? (M.fillStyle = "#fff",
M.fillRect(0, 0, se, re)) : T.snowBiomeTop - c >= 0 ? (M.fillStyle = "#fff",
M.fillRect(0, 0, se, T.snowBiomeTop - c),
M.fillStyle = "#b6db66",
M.fillRect(0, T.snowBiomeTop - c, se, re - (T.snowBiomeTop - c))) : (M.fillStyle = "#b6db66",
M.fillRect(0, 0, se, T.mapScale - T.snowBiomeTop - c),
M.fillStyle = "#dbc666",
M.fillRect(0, T.mapScale - T.snowBiomeTop - c, se, re - (T.mapScale - T.snowBiomeTop - c))),
Ei || (ct += wn * T.waveSpeed * be,
ct >= T.waveMax ? (ct = T.waveMax,
wn = -1) : ct <= 1 && (ct = wn = 1),
M.globalAlpha = 1,
M.fillStyle = "#dbc666",
Tr(l, c, M, T.riverPadding),
M.fillStyle = "#91b2db",
Tr(l, c, M, (ct - 1) * 250)),
M.lineWidth = 4,
M.strokeStyle = "#000",
M.globalAlpha = .06,
M.beginPath();
if(!regGrid.checked && !regVis.checked){
for (var pP = (14400-l) % 1440; pP < se; pP += 1440)
pP > 0 && (M.moveTo(pP, 0),
M.lineTo(pP, re));
for (var g = (14400-c) % 1440; g < re; g += 1440)
g > 0 && (M.moveTo(0, g),
M.lineTo(se, g));
} else{
for (var i = -Re; i < se; i += re / 18)
i > 0 && (M.moveTo(i, 0),
M.lineTo(i, re));
for (let a = -_e; a < re; a += re / 18)
i > 0 && (M.moveTo(0, a),
M.lineTo(se, a));
}
M.stroke(),
M.globalAlpha = 1,
M.strokeStyle = ei,
zt(-1, l, c),
M.globalAlpha = 1,
M.lineWidth = Xe,
br(0, l, c),
Ir(l, c, 0),
// Ir(l, c, 0),
M.globalAlpha = 1;
for (var t = 0; t < ye.length; ++t)
y = ye[t],
y.active && y.visible && (y.animate(be),
M.save(),
M.translate(y.x - l, y.y - c),
M.rotate(y.dir + y.dirPlus - PI / 2),
Jf(y, M),
M.restore());
if (zt(0, l, c),
br(1, l, c),
zt(1, l, c),
Ir(l, c, 1),
zt(2, l, c),
zt(3, l, c),
M.fillStyle = "#000",
M.globalAlpha = .09,
l <= 0 && M.fillRect(0, 0, -l, re),
T.mapScale - l <= se) {
var s = max(0, -c);
M.fillRect(T.mapScale - l, s, se - (T.mapScale - l), re - s)
}
if (c <= 0 && M.fillRect(-l, 0, se + l, -c),
T.mapScale - c <= re) {
var n = max(0, -l);
let a = 0;
T.mapScale - l <= se && (a = se - (T.mapScale - l)),
M.fillRect(n, T.mapScale - c, se - n - a, re - (T.mapScale - c))
}
if(E && Tach?.goal?.pathing){
M.globalAlpha = 1;
M.save();
M.translate(-l, -c);
Pathfinder?.drawPath(M, '#ffffff', E, "#00FF00");
Tach?.drawWaypoints(M, E.skinRot);
M.restore();
}
M.fillStyle = lightmode.checked ? `rgba(15, 0, 70, 0.39)` : regVis.checked ? `rgba(10, 0, 25, 0.6)` : `rgba(15, 0, 70, 0.59)`; // 10, 0, 25, 0.6
M.globalAlpha = 1,
M.fillRect(0, 0, se, re),
M.strokeStyle = kr;
let animALL2 = J.concat(spyBot.players, spectator.rPlayers)
for (var t = 0; t < animALL2.length + ye.length; ++t)
if (y = animALL2[t] || ye[t - animALL2.length],
y?.visible && (y?.skinIndex != 10 ||y?.skinIndex == 10|| y == E || y?.team && y?.team == E.team)) { // username
const u = (y.team ? "[" + y.team + "] " : "") + (y.name || "");
if (!hideName.unchecked && !botIDS.includes(y.sid) && allVisuals.checked) {
if (u !== "") {
M.font = (y.nameScale || 30) + "px Lilita One";
M.fillStyle = y.isAI ? "#fff" : (y === E || (y.team && y.team === E.team) ? "#6bed5f" : "#c9346b");
M.textBaseline = "middle";
M.textAlign = "center";
M.lineWidth = y.nameScale ? 11 : 8;
M.lineJoin = "round";
const textX = y.x - l;
const textY = y.y - c - y.scale - T.nameY;
M.strokeText(u, textX, textY);
M.fillText(u, textX, textY);
if (y.isLeader && Vt.crown.isLoaded) {
const crownScale = T.crownIconScale;
const crownX = textX - crownScale / 2 - M.measureText(u).width / 2 - T.crownPad;
M.drawImage(Vt.crown, crownX, textY - crownScale / 2 - 5, crownScale, crownScale);
}
if (y.iconIndex === 1 && Vt.skull.isLoaded) {
const skullScale = T.crownIconScale;
const skullX = textX + M.measureText(u).width / 2 + T.crownPad - skullScale / 2;
M.drawImage(Vt.skull, skullX, textY - skullScale / 2 - 5, skullScale, skullScale);
}
}
}
if(y.isPlayer && allVisuals.checked /*&& !regVis.checked*/) {
M.globalAlpha = 1;
M.textAlign = "center"
M.fillStyle = y.customColor;
M.font = "19px Lilita One"
M.strokeStyle = "#212123"
M.lineWidth = 6
M.strokeText((y.sid) ,y.x - l,y.y - c)
M.fillText((y.sid) ,y.x - l,y.y - c)
}
if(y.isPlayer && allVisuals.checked && !botIDS.includes(y.sid)){
if(!botIDS.includes(y.sid)||spyIndex?.do&&spyBot?.bot?.sid == y.sid){
if(y.sid!=E.sid){
M.globalAlpha = 1;
M.textAlign = "center",
M.fillStyle = "#fff",
M.font = "20px Lilita One",
M.strokeStyle = "#212123",
M.lineWidth = 3,
M.strokeText(`[${y.gainSpeed?round(y.gainSpeed):0} / ${y.leakSpeed?round(y.leakSpeed):0}]`,y.x - l,y.y - c-50 /*+ y.scale + T.nameY-(70)*/)
M.fillText(`[${y.gainSpeed?round(y.gainSpeed):0} / ${y.leakSpeed?round(y.leakSpeed):0}]` ,y.x - l,y.y - c-50 /*+ y.scale + T.nameY-(70)*/);
}
if(shameCount.checked){
const poopy = legacy.checked ? 29 : 12;
M.textAlign = "center",
M.fillStyle = "#fff",//"#fff",
M.font = "18px Lilita One",
M.strokeStyle = kr,
M.lineWidth = 5,
M.strokeText(!y.clowned?(y.shameCount): y.shameTimer >0 ?round(1000*y.shameTimer)/1000 :0,y.x - l,y.y - c + y.scale + T.nameY+poopy),
M.fillText(!y.clowned?(y.shameCount): y.shameTimer >0 ?round(1000*y.shameTimer)/1000 :0,y.x - l,y.y - c + y.scale + T.nameY+poopy)
//M.lineCap = "round"
}
// packet bar
if(reloadBars.checked && E.sid == y.sid/*&& allVisuals.checked && !regVis.checked*/){
// Smooth interpolation for the packet counter
let targetPackets = packets;
let currentPackets = 0;
currentPackets += (targetPackets - currentPackets) * 0.75;
// Interpolated color calculation
const maxPackets = 120;
const percentage = currentPackets / maxPackets;
let r, g, b;
if (percentage < 0.5) {
// Green to Yellow
r = Math.floor(510 * percentage);
g = 255;
b = 0;
} else {
// Yellow to Red
r = 255;
g = Math.floor(510 * (1 - percentage));
b = 0;
}
const fillColor = `rgb(${r},${g},${b})`;
// Drawing code
M.fillStyle = kr;
M.roundRect(y.x - l - T.healthBarWidth - T.healthBarPad + 34.7, y.y - c + y.scale - 170 + T.nameY, T.healthBarWidth * 2 / 3.25 + T.healthBarPad * 2, 17, 8);
M.fill();
M.fillStyle = fillColor;
M.roundRect(y.x - l - T.healthBarWidth + 34.7, y.y - c + y.scale - 170 + T.nameY + T.healthBarPad, T.healthBarWidth * 2 / 3.25 * (currentPackets / 120), 17 - T.healthBarPad * 2, 7);
M.fill();
/*M.fillStyle = kr,
M.roundRect(y.x - l - T.healthBarWidth - T.healthBarPad, y.y - c + y.scale-15 + T.nameY, T.healthBarWidth * 2 / 3.25 + T.healthBarPad * 2, 17, 8),
M.fill(),
M.fillStyle = `hsl(${100 - (y.pr) * 405 },100%,50%)`// :"rgba(0, 0, 70, 0.35)"//`hsl(${(y.pr) * 1000 },40%,10%)`
// M.fillStyle = y == E || y.team && y.team == E.team ? "#8ecc51" : "#cc5151",
M.roundRect(y.x - l - T.healthBarWidth, y.y - c + y.scale -15+ T.nameY + T.healthBarPad, T.healthBarWidth * 2 / 3.25 * (gE('smooth reloads').checked ? (y.lastpr+(y.pr-y.lastpr)*Math.min(1,y.dt/y.delta)) : y.pr), 17 - T.healthBarPad * 2, 7),
M.fill()
M.fillStyle = kr,
M.roundRect(y.x - l - T.healthBarWidth - T.healthBarPad+(69.5), y.y - c + y.scale-15 + T.nameY, T.healthBarWidth * 2 / 3.25 + T.healthBarPad * 2, 17, 8),
M.fill(),
M.fillStyle = `hsl(${100 - (y.sr) * 405 },100%,50%)`//:"rgba(0, 0, 70, 0.35)"//`hsl(${(y.sr) * 1000 },40%,10%)`
// M.fillStyle = y == E || y.team && y.team == E.team ? "#8ecc51" : "#cc5151",
M.roundRect(y.x - l - T.healthBarWidth+(69.5), y.y - c + y.scale -15+ T.nameY + T.healthBarPad, T.healthBarWidth * 2 / 3.25 * (gE('smooth reloads').checked ? (y.lastsr+(y.sr-y.lastsr)*Math.min(1,y.dt/y.delta)) : y.sr), 17 - T.healthBarPad * 2, 7),
M.fill()
M.fillStyle = kr,
M.roundRect(y.x - l - T.healthBarWidth - T.healthBarPad+34.7, y.y - c + y.scale-15 + T.nameY, T.healthBarWidth * 2 / 3.25 + T.healthBarPad * 2, 17, 8),
M.fill(),
M.fillStyle = `hsl(${100 - (y.tr) * 405 },100%,50%)`//:"rgba(0, 0, 70, 0.35)"//`hsl(${(y.tr) * 1000},40%,10%)`
// M.fillStyle = y == E || y.team && y.team == E.team ? "#8ecc51" : "#cc5151",
M.roundRect(y.x - l - T.healthBarWidth+34.7, y.y - c + y.scale -15+ T.nameY + T.healthBarPad, T.healthBarWidth * 2 / 3.25 * (gE('smooth reloads').checked ? (y.lasttr+(y.tr-y.lasttr)*Math.min(1,y.dt/y.delta)) : y.tr), 17 - T.healthBarPad * 2, 7),
M.fill()*/
}
// console.log(T.healthBarWidth - T.healthBarPad)
}// reloads reload bars
if(nEnemy&& y.sid==nEnemy.sid&& typeof pushCoords=== "object"&&pushing){//ste,pte,tte
/* M.fillStyle = "#fff";
M.strokeStyle = "#fff"
M.lineWidth = 5;
M.globalAlpha = .4;
M.beginPath()
M.arc((E.x2+nEnemy.x2+pushVector.x)/2-l,(E.y2+nEnemy.y2+pushVector.y)/2-c,35,0,Math.PI*2)
M.fill()*/
M.globalAlpha = .3;
M.fillStyle = "#5f6ee7";
M.strokeStyle = "#5f6ee7"
M.beginPath()
M.arc((pushCoords.x)-l,(pushCoords.y)-c,35,0,PI2)
M.arc((nEnemy.x2+pushVector.x)-l,(nEnemy.y2+pushVector.y)-c,35,0,PI2)
M.fill()
}
}
M.font = "20px Lilita One"; // Set the font size to 20px, adjust as needed
const textWidth = M.measureText(y.name).width;
if (nEnemy && y.isPlayer && y.sid == nEnemy.sid) {
const distance = dist(E, nEnemy) - 35;
if (distance > 150) {
M.globalAlpha = 0;
M.fillStyle = "black";
M.strokeStyle = "black";
M.lineWidth = 5;
M.beginPath();
M.moveTo(E.x - l, E.y - c);
M.lineTo(y.x - l, y.y - c);
M.stroke();
//M.globalAlpha = 1;
M.globalAlpha = distance > 450 ? 1 : (distance - 150) / 330;
M.fillStyle = 'white';
M.lineWidth = 5;
const midX = (y.x + E.x) / 2 - l;
const midY = (y.y + E.y) / 2 - c;
const nameTextX = midX - textWidth / 2;
const nameTextY = midY + 15;
M.strokeText(y.name, nameTextX, nameTextY);
M.fillText(y.name, nameTextX, nameTextY);
}
}
if(y.isAI){
M.globalAlpha = 1;
M.textAlign = "center",
M.fillStyle = "#fff",
M.font = "20px Lilita One",
M.strokeStyle = "#212123",
M.lineWidth = 3,
M.strokeText((y.health) ,y.x - l,y.y - c),
M.fillText((y.health) ,y.x - l,y.y - c)
}
if(clearing?.length&&y.sid==E.sid){
M.globalAlpha = .4;
M.lineWidth = 5
M.strokeStyle = 'black'
M.beginPath();
M.arc(clearRadius.x-l, clearRadius.y-c, clearRadius.scale,0,PI2)
M.stroke()
M.globalAlpha = 1;
}
if (nEnemy && y.sid == nEnemy.sid && y.isPlayer && (instaToggle || oneTickToggle && primary == 5)) {
M.globalAlpha = 1;
if (y.scaler === undefined) {
y.scaler = 0;
y.scalerR = false;
y.rotater = 0;
y.rotaterR = false;
}
y.scalerR ? y.scaler -= 0.05 : y.scaler += 0.05;
y.rotaterR ? y.rotater -= 1.8 : y.rotater += 1.8;
if (y.rotater >= 360) y.rotater = 0;
if (Math.round(y.scaler * 10) / 10 >= 1 || Math.round(y.scaler * 10) / 10 <= -1) y.scalerR = !y.scalerR;
M.strokeStyle = "#ba5e69";
M.lineWidth = 5;
let radius = y.scale + 15 + y.scaler * 5;
let gapAngle = Math.PI / 6;
let segmentAngle = (2 * Math.PI / 3) - gapAngle;
for (let i = 0; i < 3; i++) {
let startAngle = (2 * Math.PI / 3) * i + toRad(y.rotater);
let endAngle = startAngle + segmentAngle;
M.beginPath();
M.arc(y.x - l, y.y - c, radius, startAngle, endAngle);
M.stroke();
}
M.fillStyle = "#ba5e69";
let numTriangles = 3;
let triangleBase = 20 + y.scaler * 4;
let triangleHeight = 30 + y.scaler * 6;
let gapAngles = [
toRad(y.rotater) + segmentAngle / 2 + PI / 3,
toRad(y.rotater) + (2 * PI / 3) + segmentAngle / 2 + PI / 3,
toRad(y.rotater) + (4 * PI / 3) + segmentAngle / 2 + PI / 3
];
for (let i = 0; i < numTriangles; i++) {
let angle = gapAngles[i];
let tip = calculatePoint(y.x, y.y, angle, radius);
let leftBase = calculatePoint(tip.x, tip.y, angle + PI / 6, triangleHeight);
let rightBase = calculatePoint(tip.x, tip.y, angle - PI / 6, triangleHeight);
M.beginPath();
M.moveTo(tip.x - l, tip.y - c);
M.lineTo(leftBase.x - l, leftBase.y - c);
M.lineTo(rightBase.x - l, rightBase.y - c);
M.closePath();
M.fill();
}
}
// --- VelTick Target Marker (i added)---
if (nEnemy && y.sid == nEnemy.sid && y.isPlayer && document.getElementById("VelTick")?.checked) {
M.globalAlpha = 1;
if (y.velTickScaler === undefined) {
y.velTickScaler = 0;
y.velTickScalerR = false;
y.velTickRotater = 0;
}
y.velTickScalerR ? y.velTickScaler -= 0.05 : y.velTickScaler += 0.05;
y.velTickRotater += 2.2;
if (y.velTickRotater >= 360) y.velTickRotater = 0;
if (Math.round(y.velTickScaler * 10) / 10 >= 1 || Math.round(y.velTickScaler * 10) / 10 <= -1) y.velTickScalerR = !y.velTickScalerR;
// coler
let markerColor = "#00FFFF";
M.strokeStyle = markerColor;
M.lineWidth = 5;
let radius = y.scale + 15 + y.velTickScaler * 5;
let gapAngle = Math.PI / 6;
let segmentAngle = (2 * Math.PI / 3) - gapAngle;
for (let i = 0; i < 3; i++) {
let startAngle = (2 * Math.PI / 3) * i + toRad(y.velTickRotater);
let endAngle = startAngle + segmentAngle;
M.beginPath();
M.arc(y.x - l, y.y - c, radius, startAngle, endAngle);
M.stroke();
}
M.fillStyle = markerColor;
let numTriangles = 3;
let triangleHeight = 30 + y.velTickScaler * 6;
let gapAngles = [
toRad(y.velTickRotater) + segmentAngle / 2 + Math.PI / 3,
toRad(y.velTickRotater) + (2 * Math.PI / 3) + segmentAngle / 2 + Math.PI / 3,
toRad(y.velTickRotater) + (4 * Math.PI / 3) + segmentAngle / 2 + Math.PI / 3
];
for (let i = 0; i < numTriangles; i++) {
let angle = gapAngles[i];
let tip = calculatePoint(y.x, y.y, angle, radius);
let leftBase = calculatePoint(tip.x, tip.y, angle + Math.PI / 6, triangleHeight);
let rightBase = calculatePoint(tip.x, tip.y, angle - Math.PI / 6, triangleHeight);
M.beginPath();
M.moveTo(tip.x - l, tip.y - c);
M.lineTo(leftBase.x - l, leftBase.y - c);
M.lineTo(rightBase.x - l, rightBase.y - c);
M.closePath();
M.fill();
}
}
if(y.sid===E.sid && !y.isAI){
fakePlayers.forEach(x=> {
if(x.purpose === "formation" && x.showSID){
M.globalAlpha = 1;
M.textAlign = "center"
M.fillStyle = 'white'
M.font = "19px Lilita One"
M.strokeStyle = "black"
M.lineWidth = 6
M.strokeText((x.sid) ,x.x - l,x.y - c)
M.fillText((x.sid) ,x.x - l,x.y - c)
}
})
/*
M.globalAlpha = 1;
M.lineWidth = 5;
for (let i = 0; i < nearObjects.length; i++) {
if (
nearObjects[i].group !== undefined &&
nearObjects[i].type === null &&
nearObjects[i].distance <= 300 &&
buildHP.checked &&
nearObjects[i].health !== nearObjects[i].maxHealth
) {
const animated = nearObjects[i].health;
M.fillStyle = legacy.checked ? "black" : E.sid == nearObjects[i].owner.sid
? darken("#657ba3", 0.35)
: (clan(nearObjects[i].owner.sid) && nearObjects[i].owner.sid !== E.sid)
? darken("#657ba3", 0.35)
: darken("#a4628a", 0.35);
// Draw the background bar
M.roundRect(
nearObjects[i].x - l - 33 - T.healthBarPad,
nearObjects[i].y - c + nearObjects[i].scale + T.nameY - 90,
1.45 * 45 + 2 * T.healthBarPad,
17,
10
);
M.fill();
M.fillStyle = legacy.checked ? (E.sid == nearObjects[i].owner.sid ? "#2693c7" : clan(nearObjects[i].owner.sid) && nearObjects[i].owner.sid != E.sid ? "#2693c7" : "#c9346b") : E.sid == nearObjects[i].owner.sid
? "#93d1fa"
: (clan(nearObjects[i].owner.sid) && nearObjects[i].owner.sid !== E.sid)
? "#93d1fa"
: "#d38595";
M.roundRect(
nearObjects[i].x - l - 33,
nearObjects[i].y - c + nearObjects[i].scale + T.nameY - 90 + T.healthBarPad,
1.45 * 45 * (nearObjects[i].health / nearObjects[i].maxHealth),
17 - 2 * T.healthBarPad,
10
);
M.fill();
}
if (
nearObjects[i].group !== undefined &&
nearObjects[i].owner?.sid > 0 &&
nearObjects[i].active !== 0 &&
buildOwner.checked
) {
M.fillStyle = legacy.checked ? (clan(nearObjects[i].owner.sid) ? "#2693c7":"#c9346b") : clan(nearObjects[i].owner.sid)? "#93d1fa" : "#d38595";
M.textBaseline = "middle";
M.textAlign = "center";
M.font = "13px Lilita One";
M.strokeStyle = legacy.checked ? "black" : "#212123";
M.strokeText(nearObjects[i].owner.sid.toString(), nearObjects[i].x - l, nearObjects[i].y - c + nearObjects[i].scale - 20);
M.fillText(nearObjects[i].owner.sid.toString(), nearObjects[i].x - l, nearObjects[i].y - c + nearObjects[i].scale - 20);
}
}
*/
M.globalAlpha = 1;
M.lineWidth = 5;
for (let i = 0; i < nearObjects.length; i++) {
const e = nearObjects[i];
if (
e.group !== undefined &&
e.owner?.sid > 0 &&
e.active !== 0 &&
buildOwner.checked
) {
M.globalAlpha = e.assumeBreak ? .45 : .52;
M.fillStyle = /*e.assumeBreak ? "#c9346b" : */(clan(e.owner.sid) ? "#6bed5f":"#c9346b");
M.beginPath();
M.arc(
e.x - l,
e.y - c,
8, 0, 2 * Math.PI
);
M.fill();
M.strokeStyle = e.assumeBreak ? darken((clan(e.owner.sid) ? "#6bed5f":"#c9346b"), 0.35) : 'rgba(0,0,0,0.1)';
M.lineWidth = 2;
M.stroke();
}
}
M.globalAlpha = 1;
if(placeDurations.length && placeDuration.checked){
M.globalAlpha = 1;
M.textAlign = "center";
M.fillStyle = "#fff";
M.font = "20px Lilita One";
M.strokeStyle = "#212123";
M.lineWidth = 3;
M.strokeText(JSONStringify(placeDurations), y.x - l, y.y - c - 50)
M.fillText(JSONStringify(placeDurations) , y.x - l, y.y - c - 50);
}
}
if(y.sid == E.sid&& allVisuals.checked && pcKT.checked /*&& !regVis.checked*/){
M.globalAlpha = 1;
M.textAlign = "center",
M.fillStyle = "#fff",
M.font = "20px Lilita One"
M.strokeStyle = "black"
M.lineWidth = 3
M.strokeText((packets) ,y.x - l,y.y - c - 100 + y.scale + T.nameY-(70))
M.fillText((packets) ,y.x - l,y.y - c - 100 + y.scale + T.nameY-(70))
}
if(paths && paths.length&&y.sid==E.sid) {
M.lineCap = "round";
M.strokeStyle = 'white'
M.lineWidth = 3;
M.beginPath();
var length = paths.length;
M.moveTo(paths[0] - l, paths[1] - c);
for(let i = 0; i < length; i += 2) {
M.lineTo(paths[i] - l, paths[i + 1] - c);
M.stroke();
}
}
M.strokeStyle = kr
M.globalAlpha = 1;
y.health2 += (y.health - y.health2) * 0.5;
if(y.health > 0&&!y.isAI&&(!botIDS.includes(y.sid))||spyIndex?.do&&spyBot?.bot?.sid == y.sid){
let setter = 0;
M.fillStyle = kr;
M.roundRect(y.x - l - T.healthBarWidth - T.healthBarPad, y.y - c + y.scale + T.nameY - setter, T.healthBarWidth * 2 + T.healthBarPad * 2, 17, 8);
M.fill();
/*M.fillStyle = legacy.checked ? kr : darken, 0.35);
M.roundRect(y.x - l - T.healthBarWidth, y.y - c + y.scale + T.nameY + T.healthBarPad - setter, T.healthBarWidth * 2, 17 - T.healthBarPad * 2, 7);
M.fill();*/
M.fillStyle = y === E || (y.team && y.team == E.team) ? "#6bed5f" : "#c9346b";
let animatedHealth = !legacy.checked ? (y.isAI ? y.health2 : (y.lastHealth == undefined || y.animatedHealth == undefined) ? y.health2 : y.lastHealth + (y.health - y.lastHealth) * min(1, max(0, 1 - pow(1 - min(1, (Date.now() - y.animatedHealth) / 250), 2)))) : y.health;
let healthRatio = animatedHealth / y.maxHealth;
let healthBarWidth = T.healthBarWidth * 2 * healthRatio;
M.roundRect(y.x - l - T.healthBarWidth, y.y - c + y.scale + T.nameY + T.healthBarPad - setter, healthBarWidth, 17 - T.healthBarPad * 2, 7);
M.fill();
}
}
//VelTick Visuals (x18k copycat)
if (nEnemy && E.alive && document.getElementById("VelTick")?.checked) {
let ping = window.pingTime || 0;
let activeMin = (ping > 140) ? 230 : (ping > 110) ? 210 : (ping > 85) ? 190 : 170;
let activeMax = 245;
let drawMin = 160;
let drawMax = 270;
let distToEnemy = dist(E, nEnemy);
let lineColor = "rgba(0, 0, 0, 0.3)";
if (distToEnemy >= 170 && distToEnemy <= 230) {
lineColor = "rgba(0, 255, 0, 0.3)";
}
if (distToEnemy > activeMin && distToEnemy <= activeMax) {
lineColor = "rgba(255, 0, 0, 0.3)";
}
M.save();
M.translate(nEnemy.x - l, nEnemy.y - c);
let angle = Math.atan2(E.y - nEnemy.y, E.x - nEnemy.x);
let startX = Math.cos(angle) * drawMin;
let startY = Math.sin(angle) * drawMin;
let endX = Math.cos(angle) * drawMax;
let endY = Math.sin(angle) * drawMax;
M.beginPath();
M.moveTo(startX, startY);
M.lineTo(endX, endY);
M.lineWidth = 4;
M.lineCap = "round";
M.strokeStyle = lineColor;
M.stroke();
M.restore();
}
Hn.update(be, M, l, c);
let animALLS = J.concat(spyBot.players, spectator.rPlayer);
for (var t = 0; t < animALLS.length; ++t){
if (y = animALLS[t],
y?.visible && !botIDS.includes(y?.sid) && y.chatCountdown > 0) {
y.chatCountdown -= be,
y.chatCountdown <= 0 && (y.chatCountdown = 0);
M.font = "32px Lilita One";
const u = M.measureText(y.chatMessage);
M.strokeStyle = "2d3030"; //"black";
M.textBaseline = "middle",
M.textAlign = "center";
var n = y.x - l
, s = y.y - y.scale - c - 90;
const m = 47
, w = u.width + 17;
M.lineWidth = 11;
M.strokeStyle = "black";
M.fillStyle = M.color;
M.strokeText(y.chatMessage,n,s)
M.fillStyle = "rgba(0,0,0,0.2)"
M.roundRect(n - w / 2, s - m / 2, w, m, 6)
M.fill()
M.fillStyle = "#fff"
M.fillText(y.chatMessage, n, s)
//
}
//if(!y?.spectate) {
if (teamMessage.time > 0&&(y = animALLS[t])?.sid==E?.sid&&amAlive){
teamMessage.time -= be
//teamMessage.time <= 0
M.font = "32px Lilita One";
M.strokeStyle = "#2d3030";
var xx = M.measureText(teamMessage.message);
M.textBaseline = "middle",
M.textAlign = "center",
n = y.x - l,
s = y.y - y.scale - c - 140;
var SS = xx.width + 17;
M.fillStyle = "rgba(0,0,0,.5)",
M.roundRect(n - SS / 2, s - 23.5, SS, 47, 6),
M.fill(),
M.fillStyle = "#fff",
M.fillText(teamMessage.message, n, s)
}
}
//}
if (!shaderToggle.checked) {
incr += (1 - incr) / 160;
const trans = M.getTransform();
M.setTransform(1, 0, 0, 1, 0, 0);
M.fillStyle = `rgba(${[24, 0, 82, .3].map(e => e * incr).join(", ")})`;
M.fillRect(0, 0, xt.width, xt.height);
M.setTransform(trans);
}
}
lf(be)
}
function br(e, t, i) {
for (let s = 0; s < Mt.length; ++s)
y = Mt[s],
y.active && y.layer == e && (y.update(be),
y.active && Bo(y.x - t, y.y - i, y.scale) && (M.save(),
M.translate(y.x - t, y.y - i),
M.rotate(y.dir),
Zn(0, 0, y, M),
M.restore()))
}
const Sr = {};
/*function Zn(e, t, i, s, n) {
if (i.src) {
const r = R.projectiles[i.indx].src;
let o = Sr[r];
o || (o = new Image,
o.onload = function() {
this.isLoaded = !0
}
,
o.src = "./img/weapons/" + r + ".png",
Sr[r] = o),
o.isLoaded && s.drawImage(o, e - i.scale / 2, t - i.scale / 2, i.scale, i.scale)
} else
i.indx == 1 && (s.fillStyle = "#939393",
Q(e, t, i.scale, s))
}*/
function Zn(e, t, n, i, r) {
if (n.src) {
var s = R.projectiles[n.indx].src,
a = Sr[s];
if (!a) {
a = new Image();
a.onload = function() {
this.isLoaded = true;
// Cache the composite image
compositeImages.weapons[s] = generateCompositeImage(1,this, n.scale);
};
a.src = ".././img/weapons/" + s + ".png";
Sr[s] = a;
} else if(a && compositeImages.weapons[s]==undefined){
a = new Image();
a.onload = function() {
this.isLoaded = true;
// Cache the composite image
compositeImages.weapons[s] = generateCompositeImage(1,this, n.scale);
};
a.src = ".././img/weapons/" + s + ".png";
Sr[s] = a;
}
if (a.isLoaded) {
var compositeImage = shadowToggle.checked?compositeImages.weapons[s]:a;
if (compositeImage) {
// Draw the cached composite image onto the canvas
i.drawImage(compositeImage, e - n.scale / 2, t - n.scale / 2, n.scale, n.scale);
}
}
} else if (n.indx === 1) {
i.fillStyle = "#939393";
Q(e, t, n.scale, i)
}
}
function calculatePoint(x, y, angle, distance) {
return {
x: x + distance * cos(angle),
y: y + distance * sin(angle)
};
}
function Rf() {
const e = Re - se / 2
, t = _e - re / 2;
Me.animationTime += be,
Me.animationTime %= T.volcanoAnimationDuration;
const i = T.volcanoAnimationDuration / 2
, s = 1.7 + .3 * (abs(i - Me.animationTime) / i)
, n = T.innerVolcanoScale * s;
M.drawImage(Me.land, Me.x - T.volcanoScale - e, Me.y - T.volcanoScale - t, T.volcanoScale * 2, T.volcanoScale * 2),
M.drawImage(Me.lava, Me.x - n - e, Me.y - n - t, n * 2, n * 2)
}
function Tr(e, t, i, s) {
const n = T.riverWidth + s
, r = T.mapScale / 2 - t - n / 2;
r < re && r + n > 0 && i.fillRect(0, r, se, n)
}
const fadeInSpeed = 0.05;
const fadeOutSpeed = 0.025;
const minOpacity = 0.1;
const maxOpacity = 1.0;
function fader(obj) {
if (!obj.fadingOut) {
obj.opacity2 += fadeInSpeed;
if (obj.opacity2 >= maxOpacity) {
obj.opacity2 = maxOpacity;
obj.fadingOut = true;
}
} else {
obj.opacity2 -= fadeOutSpeed;
if (obj.opacity2 <= minOpacity) {
obj.opacity2 = minOpacity;
obj.fadingOut = false;
}
}
return obj.opacity2;
}
function zt(e, t, i, ezzz) {
let s, n, r, eP;
ezzz = amAlive ? renderObjects.concat(showPlace, spyBot.builds, spectator.rBuilds) : et;
eP = ezzz.length;
for (let o = 0; o < eP; ++o) {
y = ezzz[o];
if (!y || !y.active) continue;
n = y.x + y.xWiggle - t;
r = y.y + y.yWiggle - i;
if (e === 0) y.update(be);
breakObjs
if (y.layer === e && Bo(n, r, y.scale + (y.blocker || 0))) {
if (breakObjs.some(obj => obj.sid === y.sid)) {
fader(y);
M.globalAlpha = y.hideFromEnemy ? 0.6 :
y.preplace ? 0.7 : y.fake ? 0.3 : y.opacity2;
} else {
M.globalAlpha = y.hideFromEnemy ? 0.6 :
y.preplace ? 0.7 : y.fake ? 0.3 : y.opacity;
}
//M.globalAlpha = globalAlpha;
if (y.isItem) {
if (y.fake && !noArcs.checked) {
M.save();
M.translate(n, r);
M.rotate(y.dir);
M.beginPath();
M.arc(0, 0, y.scale, 0, PI2);
M.fillStyle = y.restricter ? "#6bed5f" : y.preplace ? "#d4577c" : "#7da7b1";
M.fill();
M.stroke();
M.restore();
} else {
s = Ss1(y, false/*y.fake*/, false, y);
M.save();
M.translate(n, r);
M.rotate(y.dir);
M.drawImage(s, -(s.width / 2), -(s.height / 2));
if (y.blocker) {
M.strokeStyle = "#db6e6e";
M.globalAlpha = 0.3;
M.lineWidth = 6;
Q(0, 0, y.blocker, M, false, true);
}
M.restore();
}
} else if (y.type === 4) {
Rf();
} else {
s = Hf(y);
M.drawImage(s, n - s.width / 2, r - s.height / 2);
}
}
}
}
async function gatherAnimation(e, t, i, ws, _) {
if(!ws){
if(_ = findPlayerSID(e)) {
_.startAnim(t, i);
reloadConfiguration(e,t,i,false);
_.hitBuild = t;
}
await nextTick()
if(t){
_ = findPlayerSID(e)
hitList.forEach((e) => {e.attemptResolve(_, _.skinIndex,tick)})
}
}else{
_ = ws.findPlayer(e)
_.startAnim(t,i)
}
}
function reloadConfiguration(id,weapon,hit,bool,player,_){
if(!bool) return updater.push({id: reloadConfiguration, data: [id, hit, weapon, true]});
_ = findPlayerSID(id);
if(_ === null) return;
weapon>9?_.sr = 0: _.pr=0
_.slowMult -= (R.weapons[weapon].hitSlow || 0.3);
if (_.slowMult < 0) _.slowMult = 0;
_.sid==E.sid&&(E.invisTime = 1000);
_.skinIndex == 20 && (weapon >9)? (_.samRS = .78) : (_.samRS = 1)
_.skinIndex == 20 && (weapon<9) ? (_.samRP = .78) : (_.samRP = 1);
player = findPlayerSID(id)
let allEnt = J.concat(ye)
allEnt.filter((e)=> {
// C.getAngleDist(this.dir, player.d2) <= Math.PI / 2.6
let bool = e.sid!=player.sid&&dist(player,e,"player")<=R.weapons[weapon].range&&(player.team&&player.team!=e.team||!player.team)&&C.getAngleDist(getDir(player,e), player.d2) <= gatherAng ? true : false
if(!e.isAI&&bool){
if((weapon>=9&&(player.secondaryVar===3||player.skinIndex==21)||weapon<9&& (player.primaryVar===3||player.skinIndex==21)))e.poison = 5
}
if(bool){
//58,55,18 acc
if(player.skinIndex == 58 || player.skinIndex == 55 || player.tailIndex == 18){
player.gatherHeal = {dmg:R.weapons[weapon].dmg,tick:tick}
}
// console.log(`${player.name}[${player.sid}] poisoned ${e.name}[${e.sid}]`)
}
})
}
/* Mr, Er (skinSprites, skinPointers)
Pr, Cr (accessSprites, accessPointers)
jn (toolSprites)
*/
function Ir(e, t, i, ez) {
//console.log(J, spectator?.rPlayers);
for (let s = 0, animALL = J.concat(fakePlayers, spyBot.players, spectator.rPlayers); s < animALL.length; ++s) {
let y = animALL[s];
if(y) {
if (y?.zIndex == i) {
y.animate(be); // un comment this if tryna use spectate. fix bug soon
if (y.fake) {
M.globalAlpha = y.vals && (y.vals = max(0, y.vals -= y.decay));
} else if (ez) {
M.globalAlpha = 0.55;
} else if (botIDS.includes(y.sid)) {
M.globalAlpha = 0.295; // This line remains unchanged
} else {
M.globalAlpha = !seeThrough.checked ? 1 : 0.67;
}
if ((y.visible || y.fake || y.spectate)) {
y.skinRot += 0.002 * be;
let lr = (y == E ? vs() : y.dir) + y.dirPlus;
M.save();
M.translate(y.x - e, y.y - t);
M.rotate(lr);
Bf(y, M);
M.restore();
}
}
}
}
}
/*let lastFrame = {
dir: 0,
};
function renderWithMotionBlur(e, offsetX, offsetY) {
const blurSteps = 2; // Number of steps for motion blur
if(e.lastFrame === undefined) e.lastFrame = e.dir
for (let step = 0; step < blurSteps; step++) {
M.save();
// Interpolate between the last frame and the current frame
const alpha = step === 0 ? 1 : 0.5;
M.globalAlpha = alpha;
const interpolatedX = e.x//lastFrame.x + (e.x - lastFrame.x) * (step / blurSteps);
const interpolatedY = e.y//lastFrame.y + (e.y - lastFrame.y) * (step / blurSteps);
const interpolatedDirection = (step ? e.dir : e.lastFrame)// * (step / blurSteps);
M.translate(interpolatedX - offsetX, interpolatedY - offsetY);
M.rotate(interpolatedDirection);
Bf(e, M);
M.restore();
}
// Save the current frame for the next iteration
e.lastFrame = e.dir
}*/
function Q(e, t, i, s, n, r) {
s = s || M;
s.beginPath();
s.arc(e, t, i, 0, PI2);
r || s.fill();
n || s.stroke();
}
function Bf(e, t) { // function for motion blur pretty sure this, function Ar, Bf, Ir, _o. thats it.
t = t || M,
t.lineWidth = Xe,
t.lineJoin = "miter";
/*t.shadowColor = e.customColor
t.shadowBlur = 5;
t.shadowOffsetY = 5;*/
const i = PI / 4 * (R.weapons[e.weaponIndex].armS || 1)
, s = e.buildIndex < 0 && R.weapons[e.weaponIndex].hndS || 1
, n = e.buildIndex < 0 && R.weapons[e.weaponIndex].hndD || 1;
if (e.tailIndex > 0 && zf(e.tailIndex, t, e),
e.buildIndex < 0 && !R.weapons[e.weaponIndex].aboveHand && (Ar(R.weapons[e.weaponIndex], T.weaponVariants[e.weaponVariant]?.src, e.scale, 0, t),
R.weapons[e.weaponIndex].projectile != null && !R.weapons[e.weaponIndex].hideProjectile && Zn(e.scale, 0, R.projectiles[R.weapons[e.weaponIndex].projectile], M)),
t.fillStyle = e.customColor,//T.skinColors[e.skinColor],
Q(e.scale * cos(i), e.scale * sin(i), 14),
Q(e.scale * n * cos(-i * s), e.scale * n * sin(-i * s), 14),
e.buildIndex < 0 && R.weapons[e.weaponIndex].aboveHand && (Ar(R.weapons[e.weaponIndex], T.weaponVariants[e.weaponVariant]?.src, e.scale, 0, t),
R.weapons[e.weaponIndex].projectile != null && !R.weapons[e.weaponIndex].hideProjectile && Zn(e.scale, 0, R.projectiles[R.weapons[e.weaponIndex].projectile], M)),
e.buildIndex >= 0) {
const r = Ss(R.list[e.buildIndex]);
t.drawImage(r, e.scale - R.list[e.buildIndex].holdOffset, -r.width / 2)
}
Q(0, 0, e.scale, t),
e.skinIndex > 0 && (t.rotate(PI / 2),
_o(e.skinIndex, t, null, e));
drawTarget(e,t)
}
const Mr = {}
, Er = {};
let De;
// null = filler slots
// so apparently if you remove this, this means the recorder actually works again (as in the shop texture and alliance menu work again now, meaning the script will render lol).
function _o(t, n, i, r) {
if (!(De = Mr[t])) {
var s = new Image();
s.onload = function() {
this.isLoaded = true;
this.onload = null;
compositeImages.hats[t] = generateCompositeImage(1, this, a.scale);
};
s.src = ".././img/hats/hat_" + t + ".png";
Mr[t] = s;
De = s;
}
var a = i || Er[t];
if (!a) {
for (var o = 0; o < Xt.length; ++o) {
if (Xt[o].id == t) {
a = Xt[o];
break;
}
}
Er[t] = a;
}
if (De.isLoaded) {
var imageToDraw = gE('shadows')?.checked ? compositeImages.hats[t] : De;
if (imageToDraw) {
n.drawImage(imageToDraw, -a.scale / 2, -a.scale / 2, a.scale, a.scale);
}
if (!i && a.topSprite) {
n.save();
n.rotate(r.skinRot);
_o(t + "_top", n, a, r);
n.restore();
}
}
}
function drawCompositeImage(e, t, n, i, r, scale, type) {
let imageCache = e[t];
if (!imageCache) {
const image = new Image();
image.onload = function() {
this.isLoaded = true;
this.onload = null;
e[t] = generateCompositeImage(type, this, scale);
};
image.src = i + t + r;
imageCache = image;
}
const imageToDraw = gE('shadows')?.checked ? e[t] : imageCache;
if (imageToDraw) {
n.drawImage(imageToDraw, -r.scale / 2, -r.scale / 2, r.scale, r.scale);
}
if (!i && r.topSprite) {
n.save();
n.rotate(scale.skinRot);
drawCompositeImage(e, t + "_top", n, i, r, scale, type);
n.restore();
}
}
function drawTarget(e, t){
if(nEnemy&&e.sid == nEnemy?.sid&&pushing){
t.strokeStyle = "blue"
t.fillStyle = "blue"
/* for(let i = 0;i < 4;i++){
t.save();
t.rotate(i*Math.PI/2+e.skinRot);
t.beginPath();
t.arc(0,0,35, -Math.PI/7, Math.PI/7);
t.stroke();
t.beginPath();
t.moveTo(0, 25);
t.lineTo(0, 40);
t.stroke();
t.restore();
}*/
if(fastHypot(pushVector.x, pushVector.y) > 10){
t.beginPath();
t.moveTo(0, 0);
t.lineTo(pushVector.x, pushVector.y);
t.stroke();
}
}
}
const Pr = {}
, Cr = {};
function zf(e, t, i) {
let s = Cr[e];
if (!(De = Pr[e])) {
var n = new Image();
n.onload = function() {
this.isLoaded = true;
// Cache the composite image
compositeImages.accessories[e] = generateCompositeImage("accessory",this, s.scale, s.scale, i.fake);
};
n.src = ".././img/accessories/access_" + e + ".png";
Pr[e] = n;
De = n;
}
if (!s) {
for (let n = 0; n < Gt.length; ++n)
if (Gt[n].id == e) {
s = Gt[n];
break
}
Cr[e] = s
}
if (De.isLoaded) {
var compositeImage = gE('shadows')?.checked?compositeImages.accessories[e]:De;
if (compositeImage) {
t.save();
t.translate(-20 - (s.xOff || 0), 0);
if (s.spin) {
t.rotate(i.skinRot);
}
t.drawImage(compositeImage, -s.scale / 2, -s.scale / 2, s.scale, s.scale);
t.restore();
}
}
}
var jn = {};
function Ar(e, t, n, i, r) {
var s = e.src + (t || ""),
a = jn[s];
if (!a) {
a = new Image();
a.onload = function() {
this.isLoaded = true;
// Cache the composite image
compositeImages.weapons[s] = generateCompositeImage('weapon',this, e.length, e.width);
};
a.src = ".././img/weapons/" + s + ".png";
jn[s] = a;
} else if(a && compositeImages.weapons[s]==undefined){
a = new Image();
a.onload = function() {
this.isLoaded = true;
// Cache the composite image
compositeImages.weapons[s] = generateCompositeImage('weapon',this, e.length, e.width);
};
a.src = ".././img/weapons/" + s + ".png";
jn[s] = a;
}
if (a.isLoaded) {
var compositeImage = gE('shadows')?.checked?compositeImages.weapons[s]:a;
if (compositeImage) {
// Draw the cached composite image onto the canvas
r.drawImage(compositeImage, n + e.xOff - e.length / 2, i + e.yOff - e.width / 2, e.length, e.width);
}
}
}
const Dr = {};
function Hf(e) {
const t = e.y >= T.mapScale - T.snowBiomeTop ? 2 : e.y <= T.snowBiomeTop ? 1 : 0
, i = e.type + "_" + e.scale + "_" + t;
let shadow = shadowToggle.checked && !t ? 0 : 54;
let s = Dr[i + shadow];
if (!s) {
let SD = shadowToggle.checked;
const r = document.createElement("canvas");
r.width = r.height = e.scale * 2.1 + Xe;
const o = r.getContext("2d");
if (o.translate(r.width / 2, r.height / 2),
o.rotate(C.randFloat(0, PI)),
o.strokeStyle = ei,
o.lineWidth = Xe,
e.type == 0) {
let l;
for (var n = 0; n < 2; ++n){
// console.log(n)
//o.shadowBlur = n === 0 && SD ? 21 : 0;
//o.shadowColor = n === 0 && SD ? "rgba(0, 0, 0, 1)" : 0;
l = y.scale * (n ? .5 : 1),
Ie(o, y.sid % 2 === 0 ? 5 : 7, l, l * .7),
o.fillStyle = t ? n ? "#fff" : "#e3f1f4" : n ? "#b4db62" : "#9ebf57",
o.fill(),
n || o.stroke()
}
} else if (e.type == 1){
if (t == 2)
o.fillStyle = "#606060",
Ie(o, 6, e.scale * .3, e.scale * .71),
o.fill(),
o.stroke(),
o.fillStyle = "#89a54c",
Q(0, 0, e.scale * .55, o),
o.fillStyle = "#a5c65b",
Q(0, 0, e.scale * .3, o, !0);
else {
//o.shadowBlur = SD ? 22 : 0;
//o.shadowColor = SD ? "rgba(0, 0, 0, 1)" : null;
Uf(o, 6, y.scale, y.scale * .7),
o.fillStyle = t ? "#e3f1f4" : "#89a54c",
o.fill(),
//o.shadowBlur = 0;
//o.shadowColor = null;
o.stroke(),
o.fillStyle = t ? "#6a64af" : "#c15555";
let l;
const c = 4
, a = Ze / c;
for (var n = 0; n < c; ++n)
l = C.randInt(y.scale / 3.5, y.scale / 2.3),
Q(l * cos(a * n), l * sin(a * n), C.randInt(10, 12), o)
}
}else{
(e.type == 2 || e.type == 3)
// o.shadowBlur = SD ? 12 : 0
//o.shadowColor = SD ? "rgba(0, 0, 0, 1)" : null
o.fillStyle = e.type == 2 ? t == 2 ? "#938d77" : "#939393" : "#e0c655",
Ie(o, 3, e.scale, e.scale),
o.fill(),
o.stroke(),
o.fillStyle = e.type == 2 ? t == 2 ? "#b2ab90" : "#bcbcbc" : "#ebdca3",
// o.shadowBlur = 0;
//o.shadowColor = null;
Ie(o, 3, e.scale * .55, e.scale * .65),
o.fill()
//o.shadowBlur = 0;
//o.shadowColor = null;
}
s = r,
Dr[i + shadow] = s
}
return s
}
function Or(e, t, i) {
const s = e.lineWidth || 0;
i /= 2,
e.beginPath();
let n = PI2 / t;
for (let r = 0; r < t; r++)
e.lineTo(i + (i - s / 2) * cos(n * r), i + (i - s / 2) * sin(n * r));
e.closePath()
}
function Ff() {
const t = T.volcanoScale * 2
, i = document.createElement("canvas");
i.width = t,
i.height = t;
const s = i.getContext("2d");
s.strokeStyle = "#3e3e3e",
s.lineWidth = Xe * 2,
s.fillStyle = "#7f7f7f",
Or(s, 10, t),
s.fill(),
s.stroke(),
Me.land = i;
const n = document.createElement("canvas")
, r = T.innerVolcanoScale * 2;
n.width = r,
n.height = r;
const o = n.getContext("2d");
o.strokeStyle = ei,
o.lineWidth = Xe * 1.6,
o.fillStyle = "#f54e16",
o.strokeStyle = "#f56f16",
Or(o, 10, r),
o.fill(),
o.stroke(),
Me.lava = n
}
Ff();
const Rr = [];
function Ss(e, t, action, obj) {
let shadow = shadowToggle.checked&&!action&&!t ? 0 : 54
let i = Rr[e.id + shadow];
if (!i || t || e.lastAnim != allVisuals.checked) {
const c = document.createElement("canvas");
c.width = c.height = e.scale * 2.5 + Xe + (R.list[e.id].spritePadding || 0);
const a = c.getContext("2d");
let shadows = shadowToggle.checked && !action ? true : 0
//a.shadowBlur = shadows?15:0//10
//a.shadowColor = `rgba(0, 0, 0, 0.35)`
if (a.translate(c.width / 2, c.height / 2),
a.rotate(t ? 0 : PI / 2),
a.strokeStyle = ei,
a.lineWidth = Xe * (t ? c.width / 81 : 1),
e.name == "apple") {
a.fillStyle = "#c15555",
Q(0, 0, e.scale, a),
a.fillStyle = "#89a54c";
const u = -(PI / 2);
Vf(e.scale * cos(u), e.scale * sin(u), 25, u + PI / 2, a)
} else if (e.name == "cookie") {
a.fillStyle = "#cca861",
Q(0, 0, e.scale, a),
a.fillStyle = "#937c4b";
for (var s = 4, n = Ze / s, r, o = 0; o < s; ++o)
r = C.randInt(e.scale / 2.5, e.scale / 1.7),
Q(r * cos(n * o), r * sin(n * o), C.randInt(4, 5), a, !0)
} else if (e.name == "cheese") {
a.fillStyle = "#f4f3ac",
Q(0, 0, e.scale, a),
a.fillStyle = "#c3c28b";
for (var s = 4, n = Ze / s, r, o = 0; o < s; ++o)
r = C.randInt(e.scale / 2.5, e.scale / 1.7),
Q(r * cos(n * o), r * sin(n * o), C.randInt(4, 5), a, !0)
} else if (e.name == "wood wall" || e.name == "stone wall" || e.name == "castle wall") {
a.fillStyle = e.name == "castle wall" ? "#83898e" : e.name == "wood wall" ? "#a5974c" : "#939393";
const u = e.name == "castle wall" ? 4 : 3;
Ie(a, u, e.scale * 1.1, e.scale * 1.1),
a.fill(),
a.stroke(),
a.fillStyle = e.name == "castle wall" ? "#9da4aa" : e.name == "wood wall" ? "#c9b758" : "#bcbcbc",
Ie(a, u, e.scale * .65, e.scale * .65),
a.fill()
} else if (e.name == "spikes" || e.name == "greater spikes" || e.name == "poison spikes" || e.name == "spinning spikes") {
let val = e.name == "spikes" ? 8 : 8.5
let val2 = e.name == "spikes" ? .6 : .65
//a.shadowBlur = shadows ? val: 0//8.5
//a.shadowColor = `rgba(0, 0, 0, ${val2})`
a.fillStyle = e.name == "poison spikes" ? "#7b935d" : "#79A9CA";
var l = e.scale * .6;
if(action || (noOutline.checked ? true : !obj?.fake)){
Ie(a, e.name == "spikes" ? 5 : 6, e.scale, l);
a.fill();
a.stroke();
a.fillStyle = "#a5974c";
//(a.shadowBlur = 0, a.shadowColor = null);
Q(0, 0, l, a);
a.fillStyle = "#c9b758";
Q(0, 0, l / 2, a, !0);
} else if(obj?.fake) {
a.strokeStyle = !obj?.fake ? "#525252" : obj?.restricter ? "#6bed5f" : obj?.preplace ? "#d4577c" : "#000000", // packet save place = green, normal place = blue, preplace = pinkish red
Ie(a, e.name == "spikes" ? 5 : 6, e.scale, l);
a.stroke();
//(a.shadowBlur = 0, a.shadowColor = null);
if(!obj?.fake){
a.beginPath();
a.arc(0, 0, l, 0, PI2);
a.stroke();
}
}
/*let val = e.name == "spikes" ? 8 : 8.5
let val2 = e.name == "spikes" ? .6 : .65
a.shadowBlur = shadows ? val: 0//8.5
a.shadowColor = `rgba(0, 0, 0, ${val2})`
a.fillStyle = e.name == "poison spikes" ? "#7b935d" : "#79A9CA";
var l = e.scale * .6;
//if(action || !gE("all visuals").checked){
Ie(a, e.name == "spikes" ? 5 : 6, e.scale, l);
a.fill();
a.stroke();
a.fillStyle = "#a5974c";
(a.shadowBlur = 0, a.shadowColor = null);
Q(0, 0, l, a);
a.fillStyle = "#c9b758";
Q(0, 0, l / 2, a, !0);
//}*/
} else if (e.name == "windmill" || e.name == "faster windmill" || e.name == "power mill")
a.fillStyle = "#a5974c",
Q(0, 0, e.scale, a),
a.fillStyle = "#c9b758",
En(0, 0, e.scale * 1.5, 29, 4, a),
//(a.shadowBlur = 0, a.shadowColor = null),
a.fillStyle = "#a5974c",
Q(0, 0, e.scale * .5, a);
else if (e.name == "mine")
a.fillStyle = "#939393",
Ie(a, 3, e.scale, e.scale),
a.fill(),
a.stroke(),
a.fillStyle = "#bcbcbc",
Ie(a, 3, e.scale * .55, e.scale * .65),
a.fill();
else if (e.name == "sapling")
for (var o = 0; o < 2; ++o) {
var l = e.scale * (o ? .5 : 1);
Ie(a, 7, l, l * .7),
a.fillStyle = o ? "#b4db62" : "#9ebf57",
a.fill(),
o || a.stroke()
}
else if (e.name == "pit trap") {
//a.shadowBlur = shadows ? 8.5 : 0;//8.5
//a.shadowColor = `rgba(0, 0, 0, ${0.65})`;
if(action || (noOutline.checked ? true : !obj?.fake)){
a.fillStyle = "#a5974c",
Ie(a, 3, e.scale * 1.1, e.scale * 1.1),
a.fill(),
a.stroke(),
a.fillStyle = ei,
Ie(a, 3, e.scale * .65, e.scale * .65),
a.fill();
} else if(obj?.fake || obj?.preplace) {
a.strokeStyle = !obj?.fake ? "#525252" : obj?.restricter ? "#6bed5f" : obj?.preplace ? "#d4577c" : "#5e79db",
Ie(a, 3, e.scale * 1.1, e.scale * 1.1),
a.stroke();
if(!obj?.fake){
Ie(a, 3, e.scale * .65, e.scale * .65),
a.stroke();
}
}
/*a.shadowBlur = shadows ? 8.5 : 0,//8.5
a.shadowColor = `rgba(0, 0, 0, ${0.65})`,
a.fillStyle = "#a5974c",
Ie(a, 3, e.scale * 1.1, e.scale * 1.1),
a.fill(),
a.stroke(),
a.fillStyle = ei,
Ie(a, 3, e.scale * .65, e.scale * .65),
a.fill();*/
} else if (e.name == "boost pad")
a.fillStyle = "#7e7f82",
kt(0, 0, e.scale * 2, e.scale * 2, a),
a.fill(),
a.stroke(),
a.fillStyle = "#dbd97d",
Lf(e.scale * 1, a);
else if (e.name == "turret") {
a.fillStyle = "#a5974c",
Q(0, 0, e.scale, a),
a.fill(),
a.stroke(),
a.fillStyle = "#939393";
const u = 50;
kt(0, -u / 2, e.scale * .9, u, a),
Q(0, 0, e.scale * .6, a),
a.fill(),
a.stroke()
} else if (e.name == "platform") {
a.fillStyle = "#cebd5f";
const u = 4
, p = e.scale * 2
, h = p / u;
let m = -(e.scale / 2);
for (var o = 0; o < u; ++o)
kt(m - h / 2, 0, h, e.scale * 2, a),
a.fill(),
a.stroke(),
m += p / u
} else
e.name == "healing pad" ? (a.fillStyle = "#7e7f82",
kt(0, 0, e.scale * 2, e.scale * 2, a),
a.fill(),
a.stroke(),
a.fillStyle = "#db6e6e",
En(0, 0, e.scale * .65, 20, 4, a, !0)) : e.name == "spawn pad" ? (a.fillStyle = "#7e7f82",
kt(0, 0, e.scale * 2, e.scale * 2, a),
a.fill(),
a.stroke(),
a.fillStyle = "#71aad6",
Q(0, 0, e.scale * .6, a)) : e.name == "blocker" ? (a.fillStyle = "#7e7f82",
Q(0, 0, e.scale, a),
a.fill(),
a.stroke(),
a.rotate(PI / 4),
a.fillStyle = "#db6e6e",
En(0, 0, e.scale * .65, 20, 4, a, !0)) : e.name == "teleporter" && (a.fillStyle = "#7e7f82",
Q(0, 0, e.scale, a),
a.fill(),
a.stroke(),
a.rotate(PI / 4),
a.fillStyle = "#d76edb",
Q(0, 0, e.scale * .5, a, !0));
i = c,
t || (Rr[e.id + shadow] = i)
}
e.lastAnim = allVisuals.checked
return i
}
function Ss1(e, t, action, obj) {
let shadow = shadowToggle.checked&&!action&&!t ? 0 : 54
let i = Rr[e.id + shadow];
if (!i || t || e.lastAnim != allVisuals.checked) {
const c = document.createElement("canvas");
c.width = c.height = e.scale * 2.5 + Xe + (R.list[e.id].spritePadding || 0);
const a = c.getContext("2d");
let shadows = shadowToggle.checked && !action ? true : 0
//a.shadowBlur = shadows?15:0//10
//a.shadowColor = `rgba(0, 0, 0, 0.35)`
if (a.translate(c.width / 2, c.height / 2),
a.rotate(t ? 0 : PI / 2),
a.strokeStyle = ei,
a.lineWidth = Xe * (t ? c.width / 81 : 1),
e.name == "apple") {
a.fillStyle = "#c15555",
Q(0, 0, e.scale, a),
a.fillStyle = "#89a54c";
const u = -(PI / 2);
Vf(e.scale * cos(u), e.scale * sin(u), 25, u + PI / 2, a)
} else if (e.name == "cookie") {
a.fillStyle = "#cca861",
Q(0, 0, e.scale, a),
a.fillStyle = "#937c4b";
for (var s = 4, n = Ze / s, r, o = 0; o < s; ++o)
r = C.randInt(e.scale / 2.5, e.scale / 1.7),
Q(r * cos(n * o), r * sin(n * o), C.randInt(4, 5), a, !0)
} else if (e.name == "cheese") {
a.fillStyle = "#f4f3ac",
Q(0, 0, e.scale, a),
a.fillStyle = "#c3c28b";
for (var s = 4, n = Ze / s, r, o = 0; o < s; ++o)
r = C.randInt(e.scale / 2.5, e.scale / 1.7),
Q(r * cos(n * o), r * sin(n * o), C.randInt(4, 5), a, !0)
} else if (e.name == "wood wall" || e.name == "stone wall" || e.name == "castle wall") {
a.fillStyle = e.name == "castle wall" ? "#83898e" : e.name == "wood wall" ? "#a5974c" : "#939393";
const u = e.name == "castle wall" ? 4 : 3;
Ie(a, u, e.scale * 1.1, e.scale * 1.1),
a.fill(),
a.stroke(),
a.fillStyle = e.name == "castle wall" ? "#9da4aa" : e.name == "wood wall" ? "#c9b758" : "#bcbcbc",
Ie(a, u, e.scale * .65, e.scale * .65),
a.fill()
} else if (e.name == "spikes" || e.name == "greater spikes" || e.name == "poison spikes" || e.name == "spinning spikes") {
let val = e.name == "spikes" ? 8 : 8.5
let val2 = e.name == "spikes" ? .6 : .65
// a.shadowBlur = shadows ? val: 0//8.5
//a.shadowColor = `rgba(0, 0, 0, ${val2})`
a.fillStyle = e.name == "poison spikes" ? "#7b935d" : "#79A9CA";
var l = e.scale * .6;
if(action || (noOutline.checked ? true : !obj?.fake)){
Ie(a, e.name == "spikes" ? 5 : 6, e.scale, l);
a.fill();
a.stroke();
a.fillStyle = "#a5974c";
//(a.shadowBlur = 0, a.shadowColor = null);
Q(0, 0, l, a);
a.fillStyle = "#c9b758";
Q(0, 0, l / 2, a, !0);
} else if(obj?.fake) {
a.strokeStyle = !obj?.fake ? "#525252" : obj?.restricter ? "#6bed5f" : obj?.preplace ? "#d4577c" : "#000000", // packet save place = green, normal place = blue, preplace = pinkish red
Ie(a, e.name == "spikes" ? 5 : 6, e.scale, l);
a.stroke();
//(a.shadowBlur = 0, a.shadowColor = null);
if(!obj?.fake){
a.beginPath();
a.arc(0, 0, l, 0, PI2);
a.stroke();
}
}
/*let val = e.name == "spikes" ? 8 : 8.5
let val2 = e.name == "spikes" ? .6 : .65
a.shadowBlur = shadows ? val: 0//8.5
a.shadowColor = `rgba(0, 0, 0, ${val2})`
a.fillStyle = e.name == "poison spikes" ? "#7b935d" : "#79A9CA";
var l = e.scale * .6;
//if(action || !gE("all visuals").checked){
Ie(a, e.name == "spikes" ? 5 : 6, e.scale, l);
a.fill();
a.stroke();
a.fillStyle = "#a5974c";
(a.shadowBlur = 0, a.shadowColor = null);
Q(0, 0, l, a);
a.fillStyle = "#c9b758";
Q(0, 0, l / 2, a, !0);
//}*/
} else if (e.name == "windmill" || e.name == "faster windmill" || e.name == "power mill")
a.fillStyle = "#a5974c",
Q(0, 0, e.scale, a),
a.fillStyle = "#c9b758",
En(0, 0, e.scale * 1.5, 29, 4, a),
//(a.shadowBlur = 0, a.shadowColor = null),
a.fillStyle = "#a5974c",
Q(0, 0, e.scale * .5, a);
else if (e.name == "mine")
a.fillStyle = "#939393",
Ie(a, 3, e.scale, e.scale),
a.fill(),
a.stroke(),
a.fillStyle = "#bcbcbc",
Ie(a, 3, e.scale * .55, e.scale * .65),
a.fill();
else if (e.name == "sapling")
for (var o = 0; o < 2; ++o) {
var l = e.scale * (o ? .5 : 1);
Ie(a, 7, l, l * .7),
a.fillStyle = o ? "#b4db62" : "#9ebf57",
a.fill(),
o || a.stroke()
}
else if (e.name == "pit trap") {
//a.shadowBlur = shadows ? 8.5 : 0;//8.5
//a.shadowColor = `rgba(0, 0, 0, ${0.65})`;
if(action || (noOutline.checked ? true : !obj?.fake)){
a.fillStyle = "#a5974c",
Ie(a, 3, e.scale * 1.1, e.scale * 1.1),
a.fill(),
a.stroke(),
a.fillStyle = ei,
Ie(a, 3, e.scale * .65, e.scale * .65),
a.fill();
} else if(obj?.fake || obj?.preplace) {
a.strokeStyle = !obj?.fake ? "#525252" : obj?.restricter ? "#6bed5f" : obj?.preplace ? "#d4577c" : "#5e79db",
Ie(a, 3, e.scale * 1.1, e.scale * 1.1),
a.stroke();
if(!obj?.fake){
Ie(a, 3, e.scale * .65, e.scale * .65),
a.stroke();
}
}
/*a.shadowBlur = shadows ? 8.5 : 0,//8.5
a.shadowColor = `rgba(0, 0, 0, ${0.65})`,
a.fillStyle = "#a5974c",
Ie(a, 3, e.scale * 1.1, e.scale * 1.1),
a.fill(),
a.stroke(),
a.fillStyle = ei,
Ie(a, 3, e.scale * .65, e.scale * .65),
a.fill();*/
} else if (e.name == "boost pad")
a.fillStyle = "#7e7f82",
kt(0, 0, e.scale * 2, e.scale * 2, a),
a.fill(),
a.stroke(),
a.fillStyle = "#dbd97d",
Lf(e.scale * 1, a);
else if (e.name == "turret") {
a.fillStyle = "#a5974c",
Q(0, 0, e.scale, a),
a.fill(),
a.stroke(),
a.fillStyle = "#939393";
const u = 50;
kt(0, -u / 2, e.scale * .9, u, a),
Q(0, 0, e.scale * .6, a),
a.fill(),
a.stroke()
} else if (e.name == "platform") {
a.fillStyle = "#cebd5f";
const u = 4
, p = e.scale * 2
, h = p / u;
let m = -(e.scale / 2);
for (var o = 0; o < u; ++o)
kt(m - h / 2, 0, h, e.scale * 2, a),
a.fill(),
a.stroke(),
m += p / u
} else
e.name == "healing pad" ? (a.fillStyle = "#7e7f82",
kt(0, 0, e.scale * 2, e.scale * 2, a),
a.fill(),
a.stroke(),
a.fillStyle = "#db6e6e",
En(0, 0, e.scale * .65, 20, 4, a, !0)) : e.name == "spawn pad" ? (a.fillStyle = "#7e7f82",
kt(0, 0, e.scale * 2, e.scale * 2, a),
a.fill(),
a.stroke(),
a.fillStyle = "#71aad6",
Q(0, 0, e.scale * .6, a)) : e.name == "blocker" ? (a.fillStyle = "#7e7f82",
Q(0, 0, e.scale, a),
a.fill(),
a.stroke(),
a.rotate(PI / 4),
a.fillStyle = "#db6e6e",
En(0, 0, e.scale * .65, 20, 4, a, !0)) : e.name == "teleporter" && (a.fillStyle = "#7e7f82",
Q(0, 0, e.scale, a),
a.fill(),
a.stroke(),
a.rotate(PI / 4),
a.fillStyle = "#d76edb",
Q(0, 0, e.scale * .5, a, !0));
i = c,
t || (Rr[e.id + shadow] = i)
}
e.lastAnim = allVisuals.checked
return i
}
function Vf(e, t, i, s, n) {
const r = e + i * cos(s)
, o = t + i * sin(s)
, l = i * .4;
n.moveTo(e, t),
n.beginPath(),
n.quadraticCurveTo((e + r) / 2 + l * cos(s + PI / 2), (t + o) / 2 + l * sin(s + PI / 2), r, o),
n.quadraticCurveTo((e + r) / 2 - l * cos(s + PI / 2), (t + o) / 2 - l * sin(s + PI / 2), e, t),
n.closePath(),
n.fill(),
n.stroke()
}
function Q(e, t, i, s, n, r) {
s = s || M,
s.beginPath(),
s.arc(e, t, i, 0, PI2),
r || s.fill(),
n || s.stroke()
}
function Ie(e, t, i, s) {
let n = PI / 2 * 3, r, o;
const l = PI / t;
e.beginPath(),
e.moveTo(0, -i-.0000250)//-2.1); // removes the dumb building triangle on edge bug
for (let c = 0; c < t; c++)
r = cos(n) * i,
o = sin(n) * i,
e.lineTo(r, o),
n += l,
r = cos(n) * s,
o = sin(n) * s,
e.lineTo(r, o),
n += l;
e.lineTo(0, -i),
e.closePath()
}
function kt(e, t, i, s, n, r) {
n.fillRect(e - i / 2, t - s / 2, i, s),
r || n.strokeRect(e - i / 2, t - s / 2, i, s)
}
function En(e, t, i, s, n, r, o) {
r.save(),
r.translate(e, t),
n = ceil(n / 2);
for (let l = 0; l < n; l++)
kt(0, 0, i * 2, s, r, o),
r.rotate(PI / n);
r.restore()
}
function Uf(e, t, i, s) {
let n = PI / 2 * 3;
const r = PI / t;
let o;
e.beginPath(),
e.moveTo(0, -s);
for (let l = 0; l < t; l++)
o = C.randInt(i + .9, i * 1.2),
e.quadraticCurveTo(cos(n + r) * o, sin(n + r) * o, cos(n + r * 2) * s, sin(n + r * 2) * s),
n += r * 2;
e.lineTo(0, -s),
e.closePath()
}
function Lf(e, t) {
t = t || M;
const i = e * (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()
}
function Nf() {
const e = T.mapScale / 2;
ue.add(0, e, e + 200, 0, T.treeScales[3], 0),
ue.add(1, e, e - 480, 0, T.treeScales[3], 0),
ue.add(2, e + 300, e + 450, 0, T.treeScales[3], 0),
ue.add(3, e - 950, e - 130, 0, T.treeScales[2], 0),
ue.add(4, e - 750, e - 400, 0, T.treeScales[3], 0),
ue.add(5, e - 700, e + 400, 0, T.treeScales[2], 0),
ue.add(6, e + 800, e - 200, 0, T.treeScales[3], 0),
ue.add(7, e - 260, e + 340, 0, T.bushScales[3], 1),
ue.add(8, e + 760, e + 310, 0, T.bushScales[3], 1),
ue.add(9, e - 800, e + 100, 0, T.bushScales[3], 1),
ue.add(10, e - 800, e + 300, 0, R.list[4].scale, R.list[4].id, R.list[10]),
ue.add(11, e + 650, e - 390, 0, R.list[4].scale, R.list[4].id, R.list[10]),
ue.add(12, e - 400, e - 450, 0, T.rockScales[2], 2)
}
function loadObject(e, playr) {
// console.log(Date.now()-time)
for (var i = 0; i < e.length; i += 8) {
ue.add(...e.slice(i, i + 6), R.list[e[i + 6]], true, (e[i + 7] >= 0 ? { sid: e[i + 7] } : null));
playr = findPlayerSID(e[i+7])
if(e[i+7]!==null&&playr!=null&&inRender(E,playr)){
loadoutSort(findPlayerSID(e[i+7]).loadout, e[i+6])
}
}
}
async function objectHit(e, t) {
await nextTick();
if (y = findBuildingBySID(t)) {
y.xWiggle += T.gatherWiggle * cos(e);
y.yWiggle += T.gatherWiggle * sin(e);
//y.wiggleDirs.push(e);
//thisTick.objectsWiggled.push(y);
y.tick = tick;
hitList.push(new resolveHit(e, y));
y.lastHealth = y.health;
y.animatedHealth = Date.now();
/*serverconnected && socketer.send(JSONStringify({
msg:"sendWiggleData",
sender: E?.sid, // add + 1 for testing purposes
sendX: E?.x2,
sendY: E?.y2,
build: t,
wiggleDir: e,
time: Date.now(),
server: location.href
}));*/
}
}
function turretShot(e, t) {
if (y = findBuildingBySID(e)) {
y.dir = t;
y.xWiggle += T.gatherWiggle * cos(t + PI);
y.yWiggle += T.gatherWiggle * sin(t + PI);
}
}
function addProjectile(e, t, i, s, n, r, o, l,ws) {
ds && (po.addProjectile(e, t, i, s, n, r, null, null, o).sid = l)
if(!ws){
projectileDetection(e,t,i,s,n,r);
//projs.push({x:e,y:t,ang:i,range:s,speed:n,type:r,travel:0,owner:null,turret:null})
}
}
function onPlatform(_, objs){
objs = renderObjects.filter(x => x.name == "platform")
if(!objs.length) return 0;
for(let i = 0; i < objs.length; i++){
if(dist2(objs[i],_) <= 35 + objs[i].scale){
return 1
}
}
return 0;
}
async function projectileDetection(e, t, n, i, r,s,bot,bool,get,_){
if(bot&&!bool&&!get) return bot.updater.push({id: projectileDetection, data: [e, t, n, i,r,s,bot,true]});
if(!bot&&!bool&&!get) return updater.push({id: projectileDetection, data: [e, t, n, i,r,s,false,true]});
if(s==1){
let ez = findTurret(e,t)
if(get&&ez)return ez
if(ez) return;
}
//console.log(e, t, n, i, r);
// x, y, angle, range, speed, projectile type
let min = Infinity;
let id = -1;
let player = null;
let newXY = calcPoint(e, t, n + PI, 70)
for(let i=0;i<J.length;i++){
_ = J[i];
if(r == 1.5 && s == 1){
if(_.visible&&_.skinIndex==53&&dist({x:e,y:t},_)<=2){
player = _
break;
}
}
if(!(r==1.5&&s==1)){
if(_.visible && _?.weaponIndex == _?.secondary&& _.d2 === n && R.weapons[_.weaponIndex].projectile == s &&dist2(newXY,_)<=20){
player = _
break;
}
}
}
// console.log(player.sid,player.name)
if(get) return player
//if(nEnemy&&player?.sid==E?.sid){
//console.log(dist({x:e,y:t},nEnemy)-35,r.projectiles[s].speed*111,tick,`will hit in ${calcprojHit({x:e,y:t},nEnemy,s,R.projectiles[s].speed)} tick/s`)
//}
//if(player?.sid == E.sid){
// ee.send("6",String(dist({x:e,y:t},E)))
//}
if(player){
projs.push({x: player.x2, y: player.y2, dir: n, spd: r * (player.skinIndex === 1 ? 1.3 : 1), avoid: r == 1.5 || onPlatform(player) ? 1 : 0, max: R.projectiles[s].range, dmg: R.projectiles[s].dmg, traveled: 0, owner: player, building: null, hit: null, info: R.projectiles[s]});
let findPlayer = whoShot.find(x=> x.player.sid === player.sid)
if(!findPlayer){
whoShot.push({player:player,projs:[s],amt:1,tick:tick})
} else {
if(!findPlayer.projs.includes(s)) findPlayer.amt++;
findPlayer.projs.push(s)
findPlayer.tick = tick
}
}
if(r == 1.5 &&s == 1 && player){
if (primaryReloads[player.sid] === 1 &&!clan(player.sid) &&dist(player, E) <= 300 &&(player.primary === 5 &&player.primaryVar >= 2 || player.primary === undefined)) {
antiOneTick = 1;
// recently added, uncomment if needed
antiOneTicks();
}
player.tr = 0;
}
if((r!=1.5&& s!=1) && player){
player.skinIndex == 20 ? (player.samRS = .78) : (player.samRS = 1)
player.sr=0;
}
if(player&& !clan(player.sid)){
let direction = getDir({x:e,y:t},E)
let direction2 = getDir(E,{x:e,y:t})
let findPlayer = whoShot.find(x => x.player?.sid == player.sid)
if(dAng(n,direction)<.6 && findPlayer?.amt >= 3){
addChatLog(`anti bow insta ${player.name}[${player.sid}]`,'', 'red',false,true);
place(millType,direction2);
place(wallType,direction2);
if(!E.inTrap){
ee.send('9', n + toRad(90));
}
instaing = true
Hg(6,11)
setTimeout(() => {
place(foodType)
}, timeBetweenTick)
setTimeout(() => {
place(foodType)
place(foodType)
ee.send('9', undefined);
instaing = false
},222)
}
}
}
var whoShot = [];
function remProjectile(e, t) {
for (let i = 0; i < Mt.length; ++i)
Mt[i].sid == e && (Mt[i].range = t)
}
async function animateAnimal(e) {
if(y = zo(e)) {
//thisTick.playerHits.push(y);
//y.gatherWeapon = { dmg: 200 };
//y.variant = { val: 1 };
y.startAnim();
await nextTick();
hitList.forEach((e) => {e.attemptResolve(1, 1, tick, 0, y)})
}
}
function animalUpdate(e) {
moostafaAI = undefined;
moofieAI = undefined;
treasureAI = undefined;
for (var i = ye.length; i--;) {
ye[i].forcePos = !ye[i].visible;
ye[i].visible = false;
}
if(e) {
for (let i = 0, tmpTime = Date.now(); i < e.length; i += 7) {
if (y = zo(e[i])) {
y.index = e[i + 1];
y.t1 = (y.t2 === undefined) ? tmpTime : y.t2;
y.t2 = tmpTime;
y.x1 = y.x;
y.y1 = y.y;
y.x2 = e[i + 2];
y.y2 = e[i + 3];
y.d1 = (y.d2 === undefined) ? e[i + 4] : y.d2;
y.d2 = e[i + 4];
y.health = e[i + 5];
y.dt = 0;
y.visible = true;
} else {
y = ar.spawn(e[i + 2], e[i + 3], e[i + 4], e[i + 1]);
y.x2 = y.x;
y.y2 = y.y;
y.d2 = y.dir;
y.health = e[i + 5];
if (!ar.aiTypes[e[i + 1]].name)
y.name = T.cowNames[e[i + 6]];
y.forcePos = true;
y.sid = e[i];
y.visible = true;
}
if (y.id < 6) continue;
if (y.name === "MOOSTAFA") moostafaAI = y;
else if (y.name === "MOOFIE") moofieAI = y;
else if (y.name === "Treasure") treasureAI = y;
}
}
// post tick
//postTick();
}
function postTick() {
let { playerGathers, playerHits, objectsWiggled, newBuilds } = thisTick;
let playerHitsLength = playerHits.length;
// all of this monstrosity all in the name of building hp and hit detection ._.
/*for (let i = newBuilds.length, build, tmp; i--;) {
if ((build = newBuilds[i]).type !== "spikeType") continue;
if ((moostafaAI && sqrt((moostafaAI.x - build.x) ** 2 + (moostafaAI.y - build.y) ** 2) - (80 + build.getScale()) <= 0) ||
(moofieAI && sqrt((moofieAI.x - build.x) ** 2 + (moofieAI.y - build.y) ** 2) - (90 + build.getScale()) <= 0)) {
tmpObj.health -= 100;
} else if (treasureAI && sqrt((treasureAI.x - build.x) ** 2 + (treasureAI.y - build.y) ** 2) - (70 + build.getScale()) <= 0) {
tmpObj.health -= 200;
}
}*/
for (let i = objectsWiggled.length; i--;) {
spliceIncludes((y = objectsWiggled[i]).ignoreWiggleDirs, y.wiggleDirs);
let moostafaDir = moostafaAI ? atan2(moostafaAI.y - y.y, moostafaAI.x - y.x) : undefined;
let moofieDir = moofieAI ? atan2(moofieAI.y - y.y, moofieAI.x - y.x) : undefined;
let treasureDir = treasureAI ? atan2(treasureAI.y - y.y, treasureAI.x - y.x) : undefined;
for (let i = y.wiggleDirs.length, dir, e, player; i--;) {
for (e = playerHitsLength, dir = y.wiggleDirs[i]; e--;) {
// moomoo uses dir.toFix(1)
//console.log("DIR", dir);
if (C.getAngleDist(atan2(y.y - (player = playerHits[e]).y2, y.x - player.x2), dir) <= 0.05) {
y.wiggleDirs[i] = undefined; // used angle
y.health -= player.gatherWeapon.dmg; /* * player.variant.val **/ (player.gatherWeapon.sDmg || 1) * (player.skinObj?.bDmg || 1);
Hn.showText(y.x, y.y, 20, .085, 350, round(player.gatherWeapon.dmg * /* * player.variant.val **/ (player.gatherWeapon.sDmg || 1) * (player.skinObj?.bDmg || 1)), "#00aaff");
break;
}
}
// its ok if its set to undefined, UTILS.getAngleDist(undefined, dir) === NaN, (NaN <= 0.05) === false
if (C.getAngleDist(dir, moostafaDir) <= 0.05 || C.getAngleDist(dir, moofieDir) <= 0.05) {
y.wiggleDirs[i] = undefined; // used angle, set it to undefined
y.health -= 100; // moostafa or moofie (both do 100 collision dmg)
Hn.showText(y.x, y.y, 20, .085, 350, 100,"#00aaff")
break;
} else if (C.getAngleDist(dir, treasureDir) <= 0.05) {
y.wiggleDirs[i] = undefined; // used angle
y.health -= 200; // treasure does 200 coldmg
Hn.showText(y.x, y.y, 20, .085, 350, 200, "#00aaff")
break;
}
}
}
let i = objectsWiggled.length;
for (;i--;) {
objectsWiggled[i].ignoreWiggleDirs.length = 0;
}
objectsWiggled.length = playerHits.length = playerGathers.length = newBuilds.length = 0;
}
const _r = {};
function Jf(e, t) {
const i = e.index;
let s = _r[i];
if (!s) {
const n = new Image;
n.onload = function() {
this.isLoaded = !0,
this.onload = null
}
,
n.src = "./img/animals/" + e.src + ".png",
s = n,
_r[i] = s
}
if (s.isLoaded) {
const n = e.scale * 1.2 * (e.spriteMlt || 1);
t.drawImage(s, -n, -n, n * 2, n * 2)
}
}
function Bo(e, t, i) {
return e + i >= 0 && e - i <= se && t + i >= 0 && t - i <= re
}
function playerEncounter(e, t,ws) {
let i = findPlayerID(e[0]);
if(!ws){
!i &&!t&&!ws&& addChatLog(`Encountered ${e[2]}[${e[1]}]`,'', '#15c283');
i || (i = new _c(e[0],e[1],T,C,po,ue,J,ye,R,Xt,Gt),
J.push(i)),
i.spawn(t ? xi : null),
i.visible = !1,
i.x2 = void 0,
i.y2 = void 0,
i.setData(e,i),
t && (E = i,
Re = E.x,
_e = E.y,
itemUpdate(),
resourceCount(),
ageUpdate(),
updateUpdate(0),
us.style.display = "block")
} else {
let XDD = ws.findPlayer(e[1])
XDD||(XDD = new _c(e[0],e[1],T,C,po,ue,ws.players,ye,R,Xt,Gt),ws.players.push(XDD))
XDD.spawn(t ? xi : null)
XDD.visible = !1
XDD.x2 = void 0
XDD.y2 = void 0
XDD.setData(e,XDD,true)
return;
}
!i.customColor && (i.customColor = Array.from(allColors)[floor(Math.random() * allColors.size)])
!i.color && (i.color = generateRandomColor(J));
primaryReloads[e[1]] = 1,
secondaryReloads[e[1]] = 1,
i.pr = 1,
i.sr = 1;
!i.seenCount? i.seenCount=1:i.seenCount++,
i.primary = null;
i.secondary = null;
i.samRP = 1;
i.didDeath = false;
i.samRS = 1;
i.noAntiList = i.noAntiList ?? new Array(10).fill(0);
i.healArr = [];
i.loadout = {
spike: R.list[9],
spawnpad: false,
utility: undefined,
windmill: undefined,
trap: true,
wall: R.list[3],
food: R.list[0]
}
turretReloads[e[1]] = 1
i.deathDmgs = []
i.dmgsNow = []
!i.trackLeak && (i.trackLeak = [])
!i.trackGain && (i.trackGain = [])
i.tr = 1;
i.shameCount = 0;
i.healTrack = [];
i.Alive = true;
if(i.seenCount>1&&!t)addChatLog(`Encountered ${e[2]}[${e[1]}] ${getOrdinalNumber(i.seenCount)} time`,'', '#15c283')
if(i.sid === E.sid && serverconnected) socketer.send(JSONStringify({updating:E, server:location.href}));
}
function removePlayer(e) {
modBots.length && (modBots = modBots.filter(x => x.HERE))
projs.length && (projs = projs.filter(x => x.owner.sid != e))
Pt = Pt.filter(x=> x.sid != e)
for (let t = 0; t < J.length; t++)
if (J[t].id == e) {
addChatLog(`${J[t].name}[${J[t].sid}] has left`,' ',"red")
J.splice(t, 1);
break
}
}
function resourceUpdate(e, t) {
E && (E.itemCounts[e] = t)
displayItemCount(e)
}
var itemSet = [];
function displayItemCount(index = undefined) {
for (let i = 3; i < R.list.length; ++i) {
let id = R.list[i].group.id;
let tmpI = R.weapons.length + i;
if (!itemSet[tmpI]) {
itemSet[tmpI] = document.createElement("div");
itemSet[tmpI].id = "itemCount" + tmpI;
gE("actionBarItem" + tmpI).appendChild(itemSet[tmpI]);
itemSet[tmpI].style = `
display: block;
position: absolute;
padding-left: 5px;
font-size: 2em;
color: #fff;
`;
itemSet[tmpI].innerHTML = E.itemCounts[id] || 0;
} else {
if (index == id)
itemSet[tmpI].innerHTML = E.itemCounts[index] || 0;
}
}
}
let plyVals = ["food", "stone", "wood"];
async function updatePlayerValue(e, t, i) {
if(E) {
E[e] = t;
if(plyVals.includes(e.toString())) {
const val = parseInt(document.getElementById(`${e}Display`).innerText), XP = t - val;
await nextTick();
if(XP > 0) {
if (!E.weaponXP[E.weaponIndex]) E.weaponXP[E.weaponIndex] = 0;
E.weaponXP[E.weaponIndex] += XP;
}
} /*else if (e == "kills") {
playerKills++; // reset to 0 when died()
}*/
i && resourceCount();
}
}
function healthUpdate(e, t) {
if (!(y = findPlayerSID(e))) return;
let dater = Date.now();
let d=t-y.health;
//console.log(d + "this tick " + ticks)
y.isPlayer &&y.healArr.push([d,t,dater]);
y.lastHealth = y.health;
y.animatedHealth = Date.now();
y.health = t;
/*Qz(_, t,dater)*/
}
function removeDuplicates(arr1, arr2) {
const combinedArray = arr1.concat(arr2);
const uniqueArray = combinedArray.filter((item, index, self) => {
return index === self.findIndex((el) => el.sid === item.sid);
});
return uniqueArray;
}
/*function bestAim(main, range, objs = nearObjects) {
let possibleTargets = objs.filter(obj =>
dist(E, obj, "object") <= range //&& dAng(getDir(main, obj), getDir(main, main)) <= 1.5708
);
//ex. use: C.getAngleDist(getDir(player,e), player.d2) <= Math.PI / 2.6
return getDir(E,main)
if (possibleTargets.length > 1) {
return calcAvgObj(E,possibleTargets)
} else if (possibleTargets.length === 1) {
// Only one target, return it
return getDir(E,main)// possibleTargets[0];
} else {
// No valid targets
return null;
}*/
//}*/
// new shit, but replace with one below
function bestAimer(main, range, objs = nearObjects) {
// Filter objects within the specified range
let possibleTargets = objs.filter(obj => dist(E, obj, "object") <= range);
// Default aim direction towards the main target
let bestAim = getDir(E, main);
let concatObj = [main];
// Initialize max hit count and best hit count that includes the main target
let maxHitCount = 0;
let bestHitCountIncludingMain = 0;
for (let i = 0; i < 36; i++) {
let aimer = getDir(E, main) + toRad(i * 10);
let hitObjs = [];
let hitCount = possibleTargets.reduce((count, target) => {
if (C.getAngleDist(getDir(E, target), aimer) <= gatherAng &&
C.getAngleDist(getDir(E, main), aimer) <= gatherAng) {
hitObjs.push(target);
return count + 1;
}
return count;
}, 0);
// Update best aim if more targets are hit and it hits the main target
if (C.getAngleDist(getDir(E, main), aimer) <= gatherAng) {
if (hitCount > bestHitCountIncludingMain) {
bestHitCountIncludingMain = hitCount;
bestAim = aimer;
concatObj = hitObjs;
}
}
// Update max hit count
if (hitCount > maxHitCount) {
maxHitCount = hitCount;
}
}
// Flatten breakObjs array
breakObjs.push(concatObj);
breakObjs = breakObjs.flat();
return bestAim;
}
function bestAimS(main, range, objs = nearObjects) {
let possibleTargets = objs.filter(obj =>
dist(E, obj, "object") <= range
);
let bestAim = getDir(E, main); // Default to the current aim
let concatObj = [main];
if (possibleTargets.length > 1) {
let maxHitCount = 0;
for (let i = 0; i < 36; i++) {
let aimer = getDir(E, main) + toRad(i*10);
let hitObjs = [];
let hitCount = possibleTargets.reduce((count, target) => {
if (C.getAngleDist(getDir(E, target), aimer) <= gatherAng &&
C.getAngleDist(getDir(E, main), aimer) <= gatherAng) {
hitObjs.push(target)
return count + 1;
}
return count;
}, 0);
if (hitCount > maxHitCount) {
maxHitCount = hitCount;
bestAim = aimer;
concatObj = hitObjs
}
}
}
breakObjs.push(concatObj);
breakObjs = breakObjs.flat();
return bestAim;
}
function bestAim(main, range, objs = nearObjects) {
let possibleTargets = objs.filter(obj =>
dist(E, obj, "object") <= range
);
let bestAim = getDir(E, main); // Default to the current aim
let concatObj = [main];
if (possibleTargets.length > 1) {
let maxHitCount = 0;
for (let i = 0; i < 36; i++) {
let aimer = getDir(E, main) + toRad(i*10);
let hitObjs = [];
let hitCount = possibleTargets.reduce((count, target) => {
if (C.getAngleDist(getDir(E, target), aimer) <= gatherAng &&
C.getAngleDist(getDir(E, main), aimer) <= gatherAng) {
hitObjs.push(target)
return count + 1;
}
return count;
}, 0);
if (hitCount > maxHitCount) {
maxHitCount = hitCount;
bestAim = aimer;
concatObj = hitObjs
}
}
}
breakObjs.push(concatObj);
breakObjs = breakObjs.flat();
return bestAim;
}
function distSquared(point1, point2) {
const dx = point1.x2 - point2.x;
const dy = point1.y2 - point2.y;
return dx * dx + dy * dy;
}
function calcAvgObj(e,objs,type) {
const averageX = objs.reduce((sum, obj) => sum + obj.x, 0) / objs.length;
const averageY = objs.reduce((sum, obj) => sum + obj.y, 0) / objs.length;
const angle = atan2(averageY - e.y2, averageX - e.x2);
if(!type)return angle;
if(type) return {x:averageX,y:averageY}
}
function calcAvg(e,players,type) {
const averageX = players.reduce((sum, player) => sum + player.x2, 0) / players.length;
const averageY = players.reduce((sum, player) => sum + player.y2, 0) / players.length;
const angle = atan2(averageY - e.y2, averageX - e.x2);
if(!type)return angle;
if(type) return {x:averageX,y:averageY}
}
/*function dR(e){
return Math.round(e*1000)/1000
}
var testing = false;
async function testVel(ez,e){
if(testing) return;
e = multiCalcVel(E,4,moveDirection)//calcVel(E,333)
testing = true;
ez = e[3]
await nextTick();
await nextTick();
await nextTick();
await nextTick();
// await nextTick();
console.log(e, "all vels")
console.log({x:dR(ez.accel.x),y:dR(ez.accel.y)},dR(ez.vel),dR(ez.xVel),dR(ez.yVel), "future vels",)
console.log({x:E.x2,y:E.y2},dR(E.movSpd),dR(E.xVel),dR(E.yVel),"my player")
console.log("___________________________________________")
testing = false;
}*/
//class Action
var turretdoer;
function visualizeVelocity(x,y,dir,ticks,player){
if(!(tick>5&&!fakePlayers.length)) return;
// let fE = multiCalcVel(E,x)////E.np.real
// console.log(fE)
// let fP = fE[ticks-1]
//console.log(fP
// let thisE = {...E}
player.x = x//fP.accel.x
player.x2 = y// fP.accel.x
player.x1 = x// fP.accel.x
player.y = y//fP.accel.y
player.y1 = y// fP.accel.y
player.y2 = y// fP.accel.y
player.sid = 1000
player.distance = 10000
//console.log(dist(E,thisE))
//createFake(player,0,0,E.skinIndex,E.tailIndex,0,ticks,player);
}
function objDmgPot(_, o){
nearObjects.forEach(x => {x.assumeBreak = false})
for(let x = 0; x < J.length; x++){
if(!J[x].visible||E.sid === J[x].sid) continue;
_ = J[x]
_.bDmg = _?.secondary === 10 && (_.sr === 1 || placeTickInAdvance && nreload(_, placeTickInAdvance) === 1) ?
{dmg:10*(Variants[_.secondaryVar] * 7.5 * 3.3), wep: 10} :
_?.primary && (_?.pr === 1 || _.weaponIndex == _.primary && placeTickInAdvance && nreload(_, placeTickInAdvance) === 1) ?
{dmg:R.weapons[_?.primary]?.dmg * 3.3 * Variants[_.primaryVar], wep: _.primary} : 0
if(_.bDmg === 0) continue;
for(let i = 0; i < nearObjects.length; i++){
if(nearObjects[i].type !== null || !nearObjects[i]?.owner?.sid) continue;
let d_o = dist(_,nearObjects[i],"object") <= R.weapons[_.bDmg.wep].range
d_o && (!nearObjects[i].dmgpot || nearObjects[i].dmgpot < _.bDmg.dmg) && (nearObjects[i].dmgpot = _.bDmg.dmg)
// d_o && (nearObjects[i].maxDmg += _.bDmg.dmg)
if(nearObjects[i].dmgpot >= nearObjects[i].health && d_o/* && C.getAngleDist(getDir(_,nearObjects[i]), _.d2) <= Math.PI / 2.6*/){
nearObjects[i].assumeBreak = true
// console.log(nearObjects[i].dmgpot,nearObjects[i].maxDmg, _.bDmg);
continue;
}
}
}
}
// this is for reflect dmg pot
/*
/*if(nEnemy) {
const hat = Xt.find(x => x.id === nEnemy.skinIndex);
const tail = Gt.find(x => x.id === nEnemy.tailIndex);
const hReflectMult = (E.skinIndex === 11) ? 0.45 : 0;
const tReflectMult = (E.tailIndex === 21) ? 0.25 : (E.tailIndex === 16) ? 0.15 : 0;
const incomingDamage = R.weapons[nEnemy.weaponIndex].dmg * (hat?.dmgMultO || 1) * (tail?.dmgMultO || 1) * T.weaponVariants[nEnemy.weaponVariant].val;
const reflectedDamage = incomingDamage * (hReflectMult + tReflectMult);
console.log(`Incoming Damage: ${incomingDamage}, Reflected Damage: ${reflectedDamage}`);
// 100% accurate...?????
}
*/
function hitPlayer(angle, wep, variant, hat, acc, type, o, dir, incoming, reflected, hReflectMult, tReflectMult) {
if(!enemies.length) return;
for(let i = enemies.length; i--;){
//console.log("ran");
//if(enemies[i].skinIndex != 11 || enemies[i].tailIndex != 21 || enemies[i].tailIndex != 16) continue;
if(enemies[i].skinIndex == 11 || enemies[i].tailIndex == 21 || enemies[i].tailIndex == 16) {
dir = getDir(E, enemies[i]);
if(dist(E, enemies[i], "player") <= (R.weapons[wep]?.range) && C.getAngleDist(dir, angle) <= gatherAng) {
incoming = R.weapons[wep].dmg * (Xt.find(x => x.id === hat)?.dmgMultO || 1) * (Gt.find(x => x.id === acc)?.dmgMultO || 1) * Variants[variant];
hReflectMult = (enemies[i].skinIndex === 11) ? 0.45 : 0;
tReflectMult = (enemies[i].tailIndex === 21) ? 0.25 : (enemies[i].tailIndex === 16) ? 0.15 : 0;
reflected = incoming * (hReflectMult + tReflectMult)
if(wep === 10 && E.sr === 1 || wep != 10 && E.pr === 1){
Hn.showText(enemies[i].x2, enemies[i].y2, 20, .18, 300, reflected, "#fff");
}
}
}
}
}
function breakBuild(angle, wep, variant, hat, force, type, o, t, dmg){
for(let i = 0; i < nearObjects.length; i++){
// o = nearObjects[i]
t = getDir(E,nearObjects[i])
if(dist(E, nearObjects[i],"object") <= (R.weapons[wep]?.range) && C.getAngleDist(t, angle) <= gatherAng && nearObjects[i].type === null){
dmg = R.weapons[wep].dmg * (wep === 10 ? 7.5 : 1) * (hat === 40 ? 3.3 : 1) * Variants[variant]
let conditions = (wep === 10 && E.sr === 1 || wep != 10 && E.pr === 1) && nearObjects[i].dmgpot+dmg >= nearObjects[i].health
if(force && !conditions) breakObjs.push(nearObjects[i]);
if(conditions){
nearObjects[i].assumeBreak = true;
nearObjects[i].manualBreak = true;
breakObjs.push(nearObjects[i]);
}
}
}
}
//r.lineInRect(c.x - c.scale, c.y - c.scale, c.x + c.scale, c.y + c.scale, this.x, this.y, this.x + p * Math.cos(this.dir), this.y + p * Math.sin(this.dir))
//hitList.forEach((e) => {e.attemptResolve(_, _.skinIndex,tick)})
function botProjSync(_, target, range){
if((keys.q>=1 || Qsync) && bSync.checked) return true;
if(!aProjSync.checked) return false;
if(!advSync.checked) return true;
let visibleAnimals = ye.filter(x => x.visible)
let all = renderObjects.concat(visibleAnimals,_.enemies)
let closestIntersection = Infinity;
let closestEntity = null;
all.forEach((x) => {
let scale = x.realScale ? x.realScale : x.scale
if (C.lineInRect((x.x2||x.x) - scale, (x.y2||x.y) - scale, (x.x2||x.x) + scale, (x.y2||x.y) + scale, _.x2, _.y2, _.x2 + range * cos(_.dir), _.y2 + range * sin(_.dir))){
const distance = dist2(_,x)
if (distance < closestIntersection) {
closestIntersection = distance;
closestEntity = x;
}
}
});
return closestEntity.isPlayer && target.sid == closestEntity.sid;
}
let projHitPlayers = []
function projHits(val){
let visibleAnimals = ye.filter(x => x.visible)
let hitInfo = []
for(let i = 0; i < projs.length; i++){
let closestIntersection = Infinity;
let closestIntersection2 = Infinity;
let conditions = []
let proj = projs[i]
let _ = findPlayerSID(proj.owner.sid)
if(!_){
projs.splice(i, 1)
continue;
}
let teamPlayers = J.filter(x => x.visible && !(typeof _.team == "string" && x.team ==_.team) && x.sid != _.sid);
let all = renderObjects.filter(x=> !x.ignoreCollision && x.elevation > proj.avoid).concat(visibleAnimals, teamPlayers);
for(let PP = 0; PP < all.length; PP++){
let x = all[PP]
// all.forEach((x) => {
let scale = x.realScale ? x.realScale : x.scale
const distance = dist2(proj,x)
conditions[0] = C.lineInRect((x.x2||x.x) - scale, (x.y2||x.y) - scale, (x.x2||x.x) + scale, (x.y2||x.y) + scale, proj.owner.x2, proj.owner.y2, proj.x + proj.spd * timeBetweenTick * cos(proj.dir), proj.y + proj.spd * timeBetweenTick * sin(proj.dir))
conditions[1] = C.lineInRect((x.x2||x.x) - scale, (x.y2||x.y) - scale, (x.x2||x.x) + scale, (x.y2||x.y) + scale, proj.owner.x2, proj.owner.y2, proj.x + proj.spd * timeBetweenTick2 * cos(proj.dir), proj.y + proj.spd * timeBetweenTick2 * sin(proj.dir))
if(conditions[0]){
if (distance < closestIntersection) {
closestIntersection = distance;
projs[i].hit = x;
if(x.realScale){ projs[i].building = x} else projs[i].building = null;
}
}
if(conditions[1]){
if(distance < closestIntersection2){
closestIntersection2 = distance
projs[i].futureHit = x
}
}
}
if(projs[i].futureHit && !projs[i].hit){
if(projs[i].futureHit.isPlayer){
findPlayerSID(projs[i].futureHit.sid).hitProjs+= projs[i].dmg
if(E.sid == projs[i].futureHit.sid)addChatLog(`updated projectile dmgpot`, '', 'red');
if(logProj.checked)addChatLog(`${projs[i].futureHit.name}[${projs[i].futureHit.sid}] getting hit next tick ${tick+1} by ${projs[i].info.src}[${projs[i].owner.sid}]`, '', 'red');
// add sync proj hit later
if(projs[i].owner.sid != E.sid && clan(projs[i].owner.sid) && nEnemy && projs[i].futureHit.sid == nEnemy.sid) {
Hn.showText(findPlayerSID(projs[i].futureHit.sid).x2, findPlayerSID(projs[i].futureHit.sid).y2, 20, .18, 300, "sync ally proj hit", "#fff");
if(primary == 5 && nEnemy && !instaing&&(dist(E.np.accel,nEnemy.np.real,"player")<=R.weapons[primary].range||dist(E,nEnemy,"player")<=R.weapons[primary].range)&&E.pr==1&&E.sr==1&&amAlive&&shieldBypass(E,nEnemy)){
instaToggle = false;
// console.log("regular insta");
instaing = true;
Hg(7,18)
aim[0] = getDir(E,nEnemy)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client");
ee.send("z",primary,true)
hold = primary
setTimeout(() => {
instaing = false;
}, 120);
}
//console.log("ally projectile");
}
}
}
// });
projs[i].x += proj.spd * timeBetweenTick * cos(proj.dir);
projs[i].y += proj.spd * timeBetweenTick * sin(proj.dir);
projs[i].traveled += proj.spd * timeBetweenTick;
if(projs[i].hit && logProj.checked)addChatLog(`${projs[i].info.src}[${projs[i].owner.sid}] has hit ${projs[i].hit.name} [${projs[i].hit.sid}] on ${tick}`, '', 'red');
}
projs.forEach((x) => {
if(x.building){
setTimeout(() => {
hitList.forEach((e) => {e.attemptResolve(1, 1,tick, x)})
}, 10)
}
})
projs = projs.filter(x => {
if(x.hit || x.traveled >= x.max) return
if(!x.hit && x.traveled < x.max) return x
})//!x.hit && x.traveled < x.max)
//return closestUnit;
}
function actions(){
}
function breakers(){
}
function macros(){
//setTimeout(() => {
keys.f>=1&&place(E.items[4])
keys.v>=1&&place(E.items[2])
keys.h>=1&&place(utilityType)
keys.m>=1&&place(spawnpadType)
keys.i>=1&&place(wallType,vs2())
keys.j>=1 &&mineType!=null&&place(mineType)
//keys.c>=1 && bowInsta();
//},111-pingavg);
}
// new gen shit
function hatTracker(post, current = {}, param) {
const oldData = { ...post, tick: tick };
current.skinIndex = post.skinIndex;
current.skinTick = tick;
current.tailIndex = post.tailIndex;
current.tailTick = tick;
if (post.skinIndex !== current.skinIndex) {
console.log(param, "OLD", oldData.skinIndex, "NEW", current.skinIndex);
}
if (post.tailIndex !== current.tailIndex) {
console.log(param, "OLD", oldData.tailIndex, "NEW", current.tailIndex);
}
//console.log(oldData.
}
//const circularData = {};
//circularData.self = circularData;
//ee.send(circularData); // maybe potential msg pack crash lololol
// when sending move packet it activates the next tick so you move the tick after u send the move packet;
async function playerUpdate(e) {
ppT = 0;
bowInstaing = false;
antiOneTicks();
breaker = false;
time = Date.now();
tick++;
if (!(tick % 9)) {
ppsAvgs.push(packets);
if (ppsAvgs.length > 5) ppsAvgs.shift();
ppsAvg = ceil(ppsAvgs.reduce((a, b) => a + b) / ppsAvgs.length);
packets = 0;
}
nearEnemies.length = nearSpikes.length = nearTraps.length = enemies.length = allies.length = 0;
hold = null;
for (var n = J.length; n--;) {
J[n].visible ? (J[n].vis2 = true) : (J[n].vis2 = false);
(y = J[n]).forcePos = !y.visible;
y.visible = false;
}
let delta = timeBetweenTick, dataLength = e.length;
for (let n = 0, t = Date.now(); n < dataLength; n += 13) {
if (!(y = findPlayerSID(e[n]))) continue;
y.t1 = void 0 === y.t2 ? t : y.t2,
ltt[y.sid] = y,
y.t2 = t,
y.x1 = y.x,
y.y1 = y.y,
y.preX = y.x2,
y.preY = y.y2,
y.pmovDir = y.movDir,
y.x2 = e[n + 1],
y.y2 = e[n + 2],
y.d1 = void 0 === y.d2 ? e[n + 3] : y.d2,
y.d2 = e[n + 3],
y.delta = y.dt,
y.dt = 0,
y.buildIndex = e[n + 4],
y.weaponIndex = e[n + 5],
y.xVel = y.x2 - y.preX,
y.xVel2 = y.x2 - y.x1,
y.yVel = y.y2 - y.preY,
y.yVel2 = y.x2 - y.x1,
y.weaponVariant = e[n + 6],
y.team = e[n + 7],
y.isLeader = e[n + 8],
y.skinIndex = e[n + 9],
y.skinIndex != 45 && (y.shameTimer = 30,y.clowned = false),
y.skinIndex == 45 &&y.shameTimer == 30 && Shame(y),
y.tailIndex = e[n + 10],
y.iconIndex = e[n + 11],
y.zIndex = e[n + 12],
y.visible = true,
y.slowMult = max(1, y.slowMult + 0.0008 * delta),
(y.movSpd = sqrt((y.preY - y.y2)**2 + (y.preX - y.x2)**2)),
(y.movSpd2 = sqrt((y.y1 - y.y2)**2 + (y.x1 - y.x2)**2)),
(y.movDir = atan2(y.y2 - y.preY, y.x2 - y.preX)),
((y.movDir == 0 && y.movSpd==0||y.preX == y.x2 && y.preY==y.y2) && (y.movDir=undefined)),
y.weaponIndex >= 9 ? (y.secondary = y.weaponIndex) : (y.primary = y.weaponIndex),
y.weaponIndex == y.primary && (y.primaryVar = y.weaponVariant),
y.weaponIndex == y.secondary &&(y.secondaryVar= y.weaponVariant),
y.lastpr = y.pr,
y.lastsr = y.sr,
y.lasttr = y.tr,
y.tick = tick,
reloadWeapon(y),
y.weaponE = (y.weaponIndex ==y.secondary? y.sr:y.pr),
y.multpr = y.lastpr == y.pr &&y.pr==0? (y.multpr=.015,y.lastpr=.015):y.pr,
y.multsr = y.lastsr == y.sr &&y.sr==0? (y.multsr=.015,y.lastsr=.015):y.sr,
y.hitProjs = 0,
y.hitSpike = false,
y.np = calcVel(y),
y.inWater = y.y2 >= T.mapScale / 2 - T.riverWidth / 2 && y.y2 <= T.mapScale / 2 + T.riverWidth / 2,
y.buildIndex!=-1 && loadoutSort(y.loadout,y.buildIndex),
// y.positions = y.sid == targetID.ID ? multiCalcVel(y,6) : null,
y.assumeAge = ageCheck(y);
if(clan(y.sid)) {
allies.push(y)
} else {
enemies.push(y);
}
}
mouseXY();
getInventory();
if(E.d1==E.dir&&E.d2==E.dir&&aim[0]===null)visAim=false;
modBots.length && (modBots = modBots.filter(x => x.HERE))
E.shameLeak = false;
macros()
await wait(1);
renderObjects = et.filter(e => (e.distance = fHypot(e.x - E.x2, e.y - E.y2)) <= 2000);
nearObjects = renderObjects.filter(e => e.distance <= 800);
restrictPlace = restrictPlace.filter((t)=>ue.checkItemLocation(t.x,t.y,t.scale,.6,t.id,false)&&tick-t.sid<=3)
prioLoc = [];
prioSync = false;
managePromises.forEach((e) => e());
managePromises = [];
updater.forEach(e => e.id(...e.data));
updater = [];
Pathfinder?.setPos(E.x2, E.y2);
Tach?.setSend(ee.send.bind(ee));
Tach?.setSelf(E);
Tach?.updatePlayers(J);
//console.log(spectator)
amPlacing = false;
for(let i = J.length; i--;) { // make it exclude bot ids
//if(botIDS.includes(J[i].sid)) continue;
if((e = J[i])) {
e.visible&&(e.weaponR = (e.weaponIndex ==e.secondary? e.sr:e.pr))
if(isNaN(e.poison)) e.poison = 0;
e.poison>0 && (e.poison=max(0,e.poison-(e.delta/1000)))
if (!e?.Alive2 && !e?.Alive) {
let string = "";
e.deathDmgs.forEach((x, index) => {
string += `${JSONStringify(x)}`;
if (index < e.deathDmgs.length - 1) {
string += ", ";
}
});
string = string.replace(/,/g, ', ');
addChatLog(`${e.name}[${e.sid}] has died ${string}`, '', '#ed5a55');
e.deaths++;
}
e.Alive2 = true;
if(stackedDmgs.checked){
if(e.dmgs>=0 && e.dmgs<100&&(!botIDS.includes(e.sid)||spyIndex.do&& spyBot?.bot?.sid===e.sid)) Hn.showText(e.x2,e.y2, 50, .18, 700, round(abs(e.dmgs)), e.customColor);
if(e.dmgs>=100) Hn.showText(e.x2,e.y2, 60, .18, 1000, skullIcon.checked?"☠️":round(e.dmgs),e.customColor);
}
e.dmgs = "XD";
if(e.vis2==false&&e.visible&&e.buildIndex==-1){if(e.weaponIndex!=e?.primary&&e.primaryVar<=2){e.primaryVar=3} else if(e.weaponIndex!=e?.secondary&&e.secondaryVar<=2&&(e.secondary==10||e.secondary==14))e.secondaryVar = 3}
if(e.healArr.length) {
e.healArr.forEach((g)=>Qz(e.sid,g[0],g[1],g[2])),e.healArr=[]
}
if(e.dmgsNow.length)e.deathDmgs.push(e.dmgsNow)
e.dmgsNow = [];
if(e.health === 100) e.deathDmgs = [];
e.bleed = e.lastBull ? ((tick - e.lastBull + (e.sid === E.sid ? failsafe : 0)) % 9 + 9) % 9 : undefined;
}
}
if(autoQ.checked && window.pingTime >= 95){
E.Qheal = false;
if(amAlive&&E?.dmgpot?.add+E?.dmgpot?.turretGear>=100&&E.shameCount < 6&& !E.shameLeak){
Qheal()
addChatLog(`AutoQ`,'', '#5c0620',false,true);
E.Qheal = true;
} else if(E.health<100&&amAlive&&E.skinIndex!=45){
await nextTick()
if(autoQ.checked&&E.health<100&&(E.health>E.dmgpot?.hp*(E.skinIndex==6&&!E.hitting&&!instaing? .75:1)||E.shameCount>=7)) heal();
}
}
if (amAlive && stackedText.length > 0) {
stackedHealVal = stackedText.reduce((sum, text) => sum + abs(text.value), 0);
Hn.showText(stackedText[0].x, stackedText[0].y, 50, 0.18, 500, stackedHealVal, "#8ecc51");
stackedText = [];
}
if(!E.dmgpots) E.dmgpots = [];
if(enemies.length){
for(let i = enemies.length; i--;) enemies[i].distance = sqrt((enemies[i].x2 - E.x2) ** 2 + (enemies[i].y2 - E.y2) ** 2);
enemies = enemies.sort((a,b)=> a.distance - b.distance)
}
nEnemy = enemies[0];
// nEnemy && (nEnemy.positions = multiCalcVel(nEnemy, 6))
targetID.player = J.find(x => x.sid === targetID.ID && x.visible)
if(targetID.player){
targetID.player.positions = multiCalcVel(targetID.player, 6)
} else if(nEnemy){
targetID.player = nEnemy;
targetID.player.positions = multiCalcVel(targetID.player, 6)
}
E.antiOneTickBowInsta = false;
E.hitting = false;
E.movSpd!=0 && (E.invisTime = 1000);
E.movSpd == 0 && (E.invisTime-=E.delta);
turretTimer()
if(!modBots.length||!spyIndex.do)spyBot = {players:[],bot:null,builds:[],realBuilds:[]}
botMovement();
renderFake();
doSpy()
doSpectate();
botIDS = modBots.map((obj) => obj?.sid);
Pathfinder?.setBuildings(et);
reloadFailSafe();
Pathfinder?.setSpeed(55*speedMult(E));
findAvailableAngles(spikeType, 1, 0, PI / placeAccuracy.value);
let busycheck = (instaing == true ||E.hitting) ? true : false;
meleeSync.checked && sendWS.checked && nEnemy && serverconnected&&(socketer.send(JSONStringify({team:E,busy:busycheck,msg:"status",move:moveDirection,server:location.href})))
botClear();
brokenObjects =brokenObjects.filter(e=>tick-e.TICK<=200&&!inRender(E,e)&&!modBots.find(x => inRender(x,e)))
if(displayer){
serverconnected && sendWS.checked&&socketer.send(JSONStringify({msg:"ping",player:E,time:time,server:location.href}))
displayer = max(displayer-E.delta,0)
}
stealAnimal();
doInsta(instaToggle);
projHits()
destroyedTraps = destroyedTraps.filter((x) => tick - x.destroyedAt <= 2);
//console.log(destroyedTraps);
//restrictPlace = restrictPlace.filter((t)=>ue.checkItemLocation(t.x,t.y,t.scale,.6,t.id,false)&&tick-t.sid<=3)
for(let i = enemies.length; i--;) {
if((e = enemies[i])) {
if(e.distance <= 275) nearEnemies.push(e);
e.kbpot = knockBack(e, E,getDir(e,E));
e.KB = knockBack(E, e,getDir(E,e));
e.placePot = e.distance <= 300 ? enemyPlacement(e,e.loadout.spike.id, getDir(e,E)) : {onPlayer:[],possible:[],placeRange:null}
e.dmgpot = playerdmgs(e);
e.inTrap = false;
e.globalTrap = false;
for (let m = renderObjects.length; m--;) {
if(renderObjects[m].name === "pit trap" && dist2(e, renderObjects[m]) <= 47 && clan(renderObjects[m]?.owner?.sid)) {
e.inTrap = renderObjects[m];
break;
}
}
for (let m = renderObjects.length; m--;) {
if(renderObjects[m].name === "pit trap" && dist2(e, renderObjects[m]) <= 47 && (clan(renderObjects[m]?.owner?.sid) || (!e.team && renderObjects[m]?.owner?.sid != e.sid))) {
e.globalTrap = renderObjects[m];
break;
}
}
if(e.inTrap) e.inTrap.angToMe = getDir(E, e.inTrap);
const dir = getDir(E, e),distance = dist(E, e);
if(dist(E,e.np.accel)<dist(E,e)&& dist(e.np.accel,E)<200 &&dAng(getDir(e,E),e.movDir)<1&& e.movSpd>=114 && E.delta<123&&tick-ltt[e.sid].tick<=1){
if(utilityType!=null&&R.list[utilityType]?.name == "blocker"&&E.canBuild(R.list[utilityType])){
for(let i=0;i<18;i++){
Hq(utilityType,dir+toRad(i*20))
Hq(utilityType,dir-toRad(i*20))
}
console.log('anti boost blocker')
// ee.send("6", "Anti Nigger Faggot")
} else if(E.canBuild(R.list[spikeType])){
Hq(spikeType,dir+toRad(90))
Hq(spikeType,dir-toRad(90))
Hq(spikeType,dir+toRad(180))
console.log('anti boost spike')
// ee.send("6", "Anti Nigger Faggot")
} else if(boostType!=null&&E.canBuild(R.list[boostType])){
for(let i=0;i<18;i++){
Hq(boostType,dir+toRad(i*20))
Hq(boostType,dir-toRad(i*20))
}
console.log('anti boost trap')
// ee.send("6", "Anti Nigger Faggot")
} else{
for(let i=0;i<18;i++){
Hq(wallType,dir+toRad(i*20))
Hq(wallType,dir-toRad(i*20))
}
console.log('anti boost wall')
// ee.send("6", "Anti Nigger Faggot")
}
}
if (e.movSpd <= 5 && E.movSpd <= 5 && (e.secondary == 9 || e.secondary == null || e.secondary == undefined) && (distance >= 665 && distance <= 705)) {
E.antiOneTickBowInsta = true;
}
}
}
E.dmgpot = dmgpot();
breakObjs = [];
objDmgPot()
kbInsta()
breakShit();
(E.primaryVar > 1 && primary == 5 && secondary == 10) ? breakShit() : spikeTickAids();
spikeSyncer();
//daggerKB();
syncTeam = allies.find(e=>e.sid == teamID)
whoShot = whoShot.filter(x => tick - x?.tick <= 4)
//spikeKBTest()
//E.spikeTrap = null;
inTrap = false;
for(let i = nearObjects.length; i--;) {
if(sqrt((nearObjects[i].x - E.x2) ** 2 + (nearObjects[i].y - E.y2) ** 2) > 350 && (/*!clan(nearObjects[i]?.owner?.sid) &&*/ !(nearObjects[i].dmg || nearObjects[i].trap)
|| nearObjects[i]?.type !== 1 && nearObjects[i].y < 12000)) continue;
if(nearObjects[i].dmg || nearObjects[i]?.type === 1 && nearObjects[i].y >= 12000) {
nearSpikes.push(nearObjects[i]);
} else if(nearObjects[i].trap) {
nearTraps.push(nearObjects[i]);
}
}
for (let i = nearObjects.length; i--;) {
if ((y = nearObjects[i]).trap) {
if (sqrt((y.x - E.x2) ** 2 + (y.y - E.y2) ** 2) <= 47 && !clan(y?.owner?.sid)) {
inTrap = y;
//ue.checkItemLocation4(E.x2 + cos(t) * i, E.y2 + sin(t) * i, e.scale, .6, n.id,false,n)
break;
}
}
}
E.spikeTrap = nearObjects
.filter(e => inTrap && e?.group?.name === 'spikes' && (nEnemy && dist(E,nEnemy)<= 130 && dAng(getDir(nEnemy,e),getDir(nEnemy,E)) <= 3|| dist(E,e) <= 35 + e.realScale + 2)&& !clan(e.owner.sid) && dist(E, e, 'object') <= (secondary === 10 ? 75 : R.weapons[primary]?.range))
.sort((a, b) => dist(E, a, 'object') - dist(E, b, 'object'))[0]; // remove [0] for multi spike, and do some editing.
/*for (let i = nearObjects.length; i--;) {
if (inTrap && (y = nearObjects[i]).dmg) {
if ((nEnemy && sqrt((nEnemy.x2 - E.x2) ** 2 + (nEnemy.y2 - E.y2) ** 2) <= 130 && dAng(getDir(nEnemy, y), getDir(nEnemy, E)) <= 3 || dist(E, y) <= 35 + y.realScale + 2) && !clan(y.owner.sid) && dist(E, y, 'object') <= (secondary === 10 ? 75 : R.weapons[primary]?.range)) {
E.spikeTrap = y;
break;
}
}
}*/
aPush.checked ? autopush() : wyndAP();
if(appleInsta.checked && primary == 5 && secondary == 10 && nEnemy && !(nEnemy.inTrap && polePlacer(R.list[spikeType],getDir(E,nEnemy.inTrap),nEnemy.inTrap) && pushing && primary == 5 && E.primaryVar > 0) && !breaking && nreload(nEnemy) == 1&&!instaing&& nEnemy.weaponR!=1&&!autobreakBuild&&(nEnemy.weaponIndex<=10&& nEnemy.weaponIndex!=9&&nEnemy)){
if(inrange(E,nEnemy,R.weapons[secondary].range,true) &&shieldBypass(E,nEnemy)&& (E.primaryVar >= 1 || E.secondaryVar >= 1 && E.primaryVar < 1 && (tick - nEnemy?.lastBull) % 9 == 8) && nEnemy.skinIndex==6&& E.pr==1 && E.sr == 1&&E.tr==1&&nEnemy){
visAim = true;
addChatLog(`AI on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
instaing = true;
hold = secondary
Hg(53);
ee.send("z",secondary,true);
aim[0] = getDir(E,nEnemy)
ee.send("D",aim[0], "client")
setTimeout(() => {
hold = primary;
ee.send("z",primary,true);
Hg(7);
aim[0] = getDir(E,nEnemy)
ee.send("D",aim[0], "client")
}, timeBetweenTick);
setTimeout(() => {
instaing = false;
visAim = false;
aim[0] = null;
}, timeBetweenTick2)
}
}
//ruby PH
if(nEnemy &&!breaking&&!instaing&&secondary==10&&primary==5&&bleedInsta.checked /*&& E.pr==1 &&E.tr==1*/){
/*let rr = R.weapons[secondary].range
if(nEnemy&&inrange(E,nEnemy,rr,true)&&nEnemy&&shieldBypass(E,nEnemy)&&(tick - nEnemy?.lastBull) % 9 == 8 && nreload(nEnemy) == 1 && nEnemy.skinIndex == 6 && nEnemy.weaponR!=1&&(nEnemy.weaponIndex<=10&& nEnemy.weaponIndex!=9&&nEnemy)){
addChatLog(`Berry Insta on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
Hg(53,19);
setTimeout(() => {
instaing = true;
hold = primary;
ee.send("z",primary,true)
Hg(7,19)
aim[0] = getDir(E,nEnemy)
ee.send("D",aim[0], "client")
},111);
setTimeout(() => {
instaing = false;
visAim = false;
hold = null
}, 222)
}*/
// berry insta test, code below = original bleed insta
let rr = R.weapons[secondary].range
if(nEnemy&&inrange(E,nEnemy,rr,true)&&nEnemy&&shieldBypass(E,nEnemy)&&(tick - nEnemy?.lastBull) % 9 == 8&&(E.primaryVar==3||E.primaryVar>=2 && E.secondaryVar==3)&& nEnemy.skinIndex!=6&& E.pr===1 && E.sr===1){
instaing = true
addChatLog(`Bleed Insta on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
hold = secondary
visAim = true
ee.send("z",secondary,true)
aim[0] = getDir(E,nEnemy)
Hg(7,18);
ee.send("D",aim[0], "client")
setTimeout(() => {
hold = primary;
ee.send("z",primary,true)
Hg(7,18)
aim[0] = getDir(E,nEnemy)
ee.send("D",aim[0], "client")
}, timeBetweenTick);
setTimeout(() => {
instaing = false;
visAim = false;
hold = null
}, timeBetweenTick2)
}
}
serverconnected && socketer.send(JSONStringify({fixer:E, server:location.href, time: Date.now()}));
turretdoer = aEmp.checked ? renderObjects.filter((b)=>b.name=='turret'&&dist(E,b)<=700+E.movSpd&&b?.time==2200&&!clan(b?.owner?.sid)) : []
E.doAssassin = assassin.checked&&!turretdoer.length&&bH.includes(56)&&E.invisTime <= 0 && "chatbox" !== document.activeElement.id.toLowerCase() && E.health === 100 && (moveDirection === undefined || moveDirection === null) && E.movSpd == 0 ? true : false
aim[0] = null;
Mi();
E.selectedWeapon = null;
if(inTrap && !instaing && !meleesyncing && aBreak.checked){
let aimer;
if(!(E.spikeTrap && breakSpike.checked)){
aimer = getDir(E,inTrap)
E.selectedWeapon = (secondary == 10 && (inTrap.health - (R.weapons[primary].dmg * T.weaponVariants[E.primaryVar].val) <= 0) && (primary == 7 ? true : E.pr === 1));
} else {
aimer = getDir(E,E.spikeTrap);
E.selectedWeapon = (secondary == 10 && (E.spikeTrap.health - (R.weapons[primary].dmg * T.weaponVariants[E.primaryVar].val) <= 0) && (primary == 7 ? true : E.pr === 1));
/*let ppa = E.spikeTrap;
for (let z = 0; z < ppa.length; z++) {
let obj = ppa[z];
E.selectedWeapon = (secondary == 10 && (E.spikeTrap.health - (R.weapons[primary].dmg * T.weaponVariants[E.primaryVar].val) <= 0) && (primary == 7 ? true : E.pr === 1));
let multiTargets = bestAimS(obj, E.selectedWeapon ? R.weapons[primary].range : 75, ppa);
aimer = multiTargets//getDir(E,inTrap)
break;
}*/
//aimer = getDir(E,E.spikeTrap);
}
if(E.selectedWeapon ? E.pr === 1 : (E.pr==1&&secondary!=10||E.sr==1&&secondary==10)){
aim[0] = aimer;
}
breakBuild(aimer, E.selectedWeapon ? primary : secondary === 10 ? secondary : primary, E.selectedWeapon ? E.primaryVar : secondary === 10 ? E.secondaryVar : E.primaryVar, E?.dmgpot?.forceSoldier ? 6 : E.selectedWeapon ? 0 : bH.includes(40) ? 40 : 0, 1)
}
if(inTrap&&!instaing&&!meleesyncing&&aBreak.checked){
hold = E.selectedWeapon ? primary : secondary!=10?primary:10 //ee.send("z",secondary!=10?primary:10,true);
if(E.selectedWeapon ? E.pr === 1 : (E.sr==1&&secondary==10||E.pr==1&&secondary!=10)){
Hg(turretdoer.length?22: E?.dmgpot?.forceSoldier ? 6 : E.selectedWeapon ? 6 : 40, 11);
E.hitting = true;
}
}
if(!instaing&&!autobreakBuild&&!meleesyncing){
if(!inTrap){
if(keys.lc){
hold = primary;
if(E.weaponIndex!=primary||E.buildIndex!=null)ee.send("z",primary,true);
if(E.pr == 1){
if(E.tailIndex===11){
//hitPlayer(vs2(), hold, E.primaryVar, E.dmgpot?.soldier ? 6 : turretdoer.length?22:7, 18);
storeEquip(bT.includes(18) ? 18 : 0,1)
} else{
Hg(E.dmgpot?.soldier ? 6 : turretdoer.length?22:7,18)
//hitPlayer(vs2(), hold, E.primaryVar, E.dmgpot?.soldier ? 6 : turretdoer.length?22:7, 18);
}
E.hitting = true;
}
breakBuild(vs2(), hold, E.primaryVar, 0, 1)
}
if(keys.rc){
(!keys.ShiftLeft&&secondary==10) ?(hold = secondary):(hold=primary)
if(E.sr == 1&&secondary==10&&E.weaponIndex==secondary&&!keys.ShiftLeft||E.pr == 1 &&(E.weaponIndex==primary||keys.ShiftLeft)){
Hg(E.dmgpot?.soldier ? 6 : turretdoer.length?22:failsafe<2 ?40:7,11,1)
E.hitting = true;
}
breakBuild(vs2(), hold, hold === 10 ? E.secondaryVar : E.primaryVar, bH.includes(40) ? 40 : 0, 1)
}
if(keys.mc){
for (let z = nearObjects.filter(e => e.health && dist(E, e, "object") <= ((!keys.ShiftLeft && secondary===10?75:R.weapons[primary].range))).sort((a,b)=>fastHypot(E.x2-a.x,E.y2-a.y)-fastHypot(E.x2-b.x,E.y2-a.y)), i = z.length; i--;) {
let obj = z[i];
let multiTargets = bestAimS(obj,secondary===10?75:R.weapons[primary].range, z);
(!keys.ShiftLeft&&secondary==10) ?(hold = secondary):(hold=primary)
if(E.sr == 1&&secondary==10&&E.weaponIndex==secondary&&!keys.ShiftLeft||E.pr == 1 &&(E.weaponIndex==primary||keys.ShiftLeft)){
Hg(E.dmgpot?.soldier ? 6 : turretdoer.length?22:failsafe<2 ?40:7,11,1)
E.hitting = true;
}
aim[0] = multiTargets;
breakBuild(multiTargets, hold, hold === 10 ? E.secondaryVar : E.primaryVar, bH.includes(40) ? 40 : 0, 1)
break;
}
}
}
//.filter(e => keys.rc&&(e.health>10*7.5*3.3*(Variants[E.secondaryVar]||!keys.rc)))
if (!velTickActive) {
autohat();
}
}
if(E.lastBull&&bH.includes(7)&&!E.hitSpike&&E.dmgpot?.hp<80&& E.shameCount>0&&E.poison<=0&&!E.dmgpot?.soldier&&E.bleed === 0&&amAlive&&!turretdoer.length&&lastHat!=7){
if(E.lastDamage==0&&E.skinIndex!=45){
E.shameLeak = true;
failsafe++;
Hg(7,11)
}
}
if(E.hitSpike && inTrap || !inTrap && E.hitSpike && E?.dmgpot?.shouldHeal){ // added this incase u touch spike and bounce or something, also add soldier mult to the primary i guess, could addd if movSpd is higher than usual an i hit spike, then i assume it could be kb spike
if((E.health <= E.hitSpike.dmg) || (E.hitSpike.dmg + E?.dmgpot?.primary + E?.dmgpot?.turretGear >= E.health)) Qheal();
} else if(autoHeal.checked){
if(E.alive&&E.health<=E.dmgpot?.hp*(E.skinIndex==6&&!E.hitting&&!instaing&&!turretdoer.length&&!autobreakBuild&&!E.shameLeak? .75:1)&&E.skinIndex!=45&&E.shameCount<6){
heal();
}else if(E.health<100&&amAlive&&E.skinIndex!=45){
if(E.health > 30){
await nextTick()
heal();
} else {
heal();
}
}
}
showPlace = [];
// autoplacing = nearObjects.concat(restrictPlace)
autoplacers();
autoplacing = nearObjects.concat(restrictPlace);
if(!instaing && !meleesyncing && !autobreakBuild){
if(aim[0]) visAim = true;
if(E.dir!=aim[0]&&aim[0]!==null)ee.send("D",aim[0])//else ee.send("D", ln(true));
if(hold&&(hold==primary||hold==secondary)&&(E.weaponIndex!=hold||E.buildIndex!=-1))ee.send("z",hold,true);
if(aim[0]===null&&E.dir!=vs2())ee.send("D",vs2());
}
if(E.dmgpots.length>=4) E.dmgpots.pop();
if(E.dmgpot) E.dmgpots.unshift({ping: window.pingTime, tick:tick,dmgpot:E.dmgpot,health:E.health,packets:packets,currentHat:E.skinIndex, nextHat: lastHat,shameCount: E.shameCount,spikeTrap:E.hitSpike&&inTrap});
lpo[1] = false;
reload()
fastwep()
if(autohit||instaing||meleesyncing&&!bowInstaing&&!oneTick||keys.rc||keys.lc||keys.mc||E.hitting||autobreakBuild||breaker){
if(hitPacket % 2 == 0&&amAlive){
ee.send("K", 1)
}
} else {
if(hitPacket % 2 == 1){
ee.send("K", 1)
}
}
miller()
handleVelTick();
autobuyer()
}
function aimNextPos(player, target, projSpd, targetSID, amount = 6) {
let playerPos = botIDS.includes(player.sid) ? calcVel(player,player.moveDirection,player,1).real : player.np.real;
let positions = {norm:{dir:null,ticks:null,dist:null},marks:{dir:null,ticks:null,dist:null}}
let fT = Array.isArray(target) ? target : multiCalcVel(targetSID, 6)
for (let x = 0; x < fT.length; x++) {
let t = {dir:getDir(playerPos, fT[x].real), dist:dist(playerPos, fT[x].real)-105,position: fT[x]};
if(calculateFits(t.dist, projSpd * 111) === x && !positions.norm.dir){
positions.norm.dir = t.dir
positions.norm.ticks = x
positions.norm.dist = t.dist + 105
positions.position = t.position
}
if(calculateFits(t.dist, projSpd * 111 * 1.3) === x && !positions.marks.dir){
positions.marks.dir = t.dir
positions.marks.ticks = x
positions.marks.dist = t.dist + 105
positions.position = t.position
}
}
if(positions.norm.dir || positions.marks.dir) return positions;
return null;
function calculateFits(dividend, divisor) {
if (divisor === 0) {
throw new Error("Cannot divide by zero.");
}
const wholeFits = Math.floor(dividend / divisor);
const remainder = dividend % divisor;
const additionalFit = remainder > 0 ? 1 : 0;
return wholeFits + additionalFit;
}
}
let forceShadow = false;
// i changed this (velocity specification)
function autohat(test, ang = moveDirection) {
if ((breaker && !E.dmgpot.soldier && !test)) return;
let bestTail = E.tails[11] ? 11 : 0;
if (nEnemy && dist(E, nEnemy) <= 300) {
if (E.tails[19]) {
bestTail = 19;
}
}
let doSoldier = nEnemy && dist(E, nEnemy) <= sDist && !E.inWater && strictSoldier.checked ? true : false;
if (!strictSoldier.checked) {
if (E.dmgpot?.add >= 100 || E.dmgpot?.secondary >= 100 || E.dmgpot?.soldier || ang === undefined) {
if (test) return {
skinIndex: 6,
tailIndex: bestTail
};
doSoldier = true;
}
}
if (aHat.checked || test) {
if (!E.antiOneTickBowInsta && E.doAssassin) {
Hg(56, 0);
if (test) return {
skinIndex: 56,
tailIndex: 0
};
} else {
if (!E.antiOneTickBowInsta && !E.hitting && We.style.display == "none" && !bowInstaing) {
if (!turretdoer.length && !(failsafe >= 2 && !E.dmgpot.soldier) && (ang === undefined || doSoldier || inTrap && aBreak.checked) && !E.doAssassin) {
let wearSkin = 6;
if (test) return {
skinIndex: wearSkin,
tailIndex: bestTail
};
Hg(wearSkin, bestTail);
}
else if (!antiOneTick && !turretdoer.length && !(failsafe >= 2 && !E.dmgpot.soldier) && !E.doAssassin) {
let runHat = 12;
if(E.y2 <= T.snowBiomeTop) runHat = 15;
else if(E.inWater) runHat = 31;
if (test) return {
skinIndex: runHat,
tailIndex: bestTail
};
Hg(runHat, bestTail);
}
else if (failsafe >= 2 && !E.antiOneTickBowInsta && !antiOneTick) {
if (test) return {
skinIndex: 7,
tailIndex: E.tailIndex
};
Hg(7);
}
else if (!antiOneTick) {
if (test) return {
skinIndex: 22,
tailIndex: bestTail
};
Hg(22, bestTail);
}
}
if (test) return { skinIndex: 12, tailIndex: bestTail };
}
}
}
function autoHat(test){
if(forceHat){
Hg(forceHat)
}
}
function findPlayerID(e) {
for (let t = 0; t < J.length; ++t)
if (J[t].id == e)
return J[t];
return null
}
function findPlayerSID(e) {
for (let t = 0; t < J.length; ++t)
if (J[t].sid == e)
return J[t];
return null
}
function zo(e) {
for (let t = 0; t < ye.length; ++t)
if (ye[t].sid == e)
return ye[t];
return null
}
function findBuildingBySID(e) {
for (let i = et.length; i--;) {
if (et[i].sid === e) {
return et[i];
}
}
return null;
}
function findSpectatorPlayer(e) {
for (let t = 0; t < spectator.players.length; ++t) {
//console.log("found", spectator.builds[t]);
if (spectator.players[t].sid == e) {
return spectator.players[t];
}
}
return null
}
function findSpectatorBuild(e) {
for (let t = 0; t < spectator.builds.length; ++t) {
//console.log("found", spectator.builds[t]);
if (spectator.builds[t].sid == e) {
return spectator.builds[t];
}
}
return null
}
let Fo = -1;
// Get the fake ping checkbox
const fakePingCheckbox = document.getElementById("fakePing");; // Assuming 'fakePing' is the id of your checkbox
// Add event listener to toggle slider visibility
fakePingCheckbox.addEventListener('change', function() {
const sliderContainer = document.getElementById('sliderContainer');
if (this.checked) {
sliderContainer.style.display = 'block';
} else {
sliderContainer.style.display = 'none';
}
});
// Get the slider and its value display element
const pingSlider = document.getElementById('pingSlider');
const pingSliderValue = document.getElementById('pingSliderValue');
// Add event listener to update the value display when slider value changes
pingSlider.addEventListener('input', function() {
pingSliderValue.innerText = this.value;
});
const hidePingCheckbox = false; //gE('Hide Ping'); // Assuming 'Hide Ping' is the id of your checkbox
function pingSocketResponse() {
const e = Date.now() - Fo;
window.pingTime = e;
pingval = e;
if (!hidePingCheckbox || !hidePingCheckbox.checked) {
if (!fakePingCheckbox.checked) {
io = e;
} else {
const sliderValue = parseInt(pingSlider.value);
io = floor(Math.random() * sliderValue) + parseInt(pingSlider.value) + 90;
}
Qt.innerText = e + (fakePingCheckbox.checked ? io : '') + ' ms';
pingarr.push(e);
if (pingarr.length >= 4) {
pingarr.shift();
}
pingavg = pingarr.reduce((a, b) => a + b, 0) / pingarr.length;
} else {
Qt.innerText = "Hidden";
}
}
let Pn;
function Vo() {
Pn && clearTimeout(Pn),
cs() && (Fo = Date.now(),
ee.send("0")),
Pn = setTimeout(Vo, 1000)
}
function serverShutdown(e) {
if (e < 0)
return;
const t = floor(e / 60);
let i = e % 60;
i = ("0" + i).slice(-2),
dr.innerText = "Server restarting in " + t + ":" + i,
dr.hidden = !1
}
/*window.requestAnimFrame = function () {
return null;
};*/
window.requestAFrame = function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(e) {
window.setTimeout(e, 1e3 / 60)
}
}();
function Uo() {
It = Date.now(),
be = It - or,
or = It,
Of(),
requestAFrame(Uo)
}
Nf();
Uo();
function Lo(e) {
window.open(e, "_blank")
}
window.openLink = Lo;
window.aJoinReq = handleClanRequest;
window.follmoo = Bh;
window.kickFromClan = kickPlayer;
window.sendJoin = sendClanRequest;
window.leaveAlliance = leaveClan;
window.createAlliance = createClan;
window.storeBuy = storeBuy;
window.storeEquip = storeEquip;
window.showItemInfo = Se;
window.selectSkinColor = selectSkinColor;
window.changeStoreIndex = cf;
window.config = T;
/*
| variables |
y = universal player object, __
J array = All players array
ee = my player packet sender ex. ee.send(<packet>, <input>, etc)
6 = chat packet ex. ee.send("6", "chat packet")
ye = All animals array
et = all building array
E = my player object
R = alR.weapons array
| functions |
Ho = loop through buildings
_i = find player/ loop through players
show text animation = Hn.showText()
Zf = remove player from all players array
Mf = my player healing and damage text displayer
[ Game functions ]
zt = render Objects
To = addProjectile
qh = setInitData
bn = disconnect
If = setupGame
Qf = playerEncounter
Zf = removePlayer
iu = playerUpdate
Df = updateLeaderboard
qf = loadObject
Kf = animalUpdate
$f = animateAnimal
_f = gatherAnimation
Wf = objectHit
Xf = turretShot
eu = updatePlayerValue
tu = healthUpdate
Ef = died
Cf = removeObject
Pf = removeInactivePlayerObjects
jf = resourceUpdate
Ro = ageUpdate
Oo = updateUpdate
To = itemUpdate
Gf = addProjectile
Yf = remProjectile
ru = serverShutdown
Zh = addAlliance
tf = deleteAlliance
Qh = allianceNotification
jh = setPlayerTeam
ef = setAlliancePlayers
ff = storebuy
gf = receive chat
af = update minimap
Mf = showText
rf = ping minimap
0 = pingSocketResponse
| packets |
d = click packet => "c"
D = aim packet => "2"
K = hit packet => "7"
a = move packet => "33"
G = change weapon packet => '5'
c = equip/unequip/buy hat packet => "13c"
0 = "pp" packet
M = spawn packet = "sp"
H = upgrade loadout packet => "6"
L = create clan packet
N = delete clan packet
P = accept/decline clan request packet
Q = kick clan member packet
b = request join clan packet
e = "rmd" not sure what that packet does or is
"rmd" is resetMoveDir packet lol - illusion
*/
async function kbInsta(e){
if(!nEnemy||primary!=5||E.tr!=1||E.pr!=1||instaing||breaking||!kbInstaToggle.checked) return
if(nEnemy&&inrange(E,nEnemy,R.weapons[primary].range,true)&&shieldBypass(E,nEnemy)&&!nEnemy?.inTrap){
//console.log('can')
//instaing = true;
let e = [checkKB(nEnemy,getDir(E.np.real,nEnemy.np.real),dist(nEnemy,nEnemy.KB.fpriTKB),true,1),checkKB(nEnemy,getDir(E.np.real,nEnemy.np.real),dist(nEnemy,nEnemy.KB.fsecKB),true,1)]
if(!e[0]) return;
let obj = { newPos: {...nEnemy}}
let distance = fastHypot(nEnemy.np.real.x-e[0].x, nEnemy.np.real.y - e[0].y)//dist2(enemy,objs[i])
let closestPoint = calcPoint(nEnemy.np.real.x, nEnemy.np.real.y, getDir(E,nEnemy), min(distance, 170))
obj.newPos.NEWX = closestPoint.x;
obj.newPos.NEWY = closestPoint.y;
obj.originDir = getDir(E,nEnemy);
obj.newPos.dstSpd = distance;
obj.newPos.static = true;;
obj.newPos.expire = 3;
createSpikeKB(obj.newPos);
// console.log(e[0])
addChatLog(`KnockBack Insta on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
oneTick = true;
instaing = true;
Hg(53,11)
//if(e[1])ee.send('6', String(Math.round(e[1])));
aim[0] = getDir(E,nEnemy)
visAim = true;
//ee.send("D",getDir(R,nEnemy));
ee.send("z",secondary,true)
hold = secondary
// console.log(nEnemy.np.real.type);
await nextTick();
if(nEnemy){
instaing = true;
oneTick = false;
hold = primary
ee.send("z",primary,true)
aim[0] = getDir(E,nEnemy);
ee.send("D",getDir(E,nEnemy), "client");
Hg(7,18);
} else {
instaing = false
return
}
await nextTick();
instaing = false;
}
}
function toRad(degree) {
return degree * (PI / 180);
}
function toDeg(radians) {
return radians * 180 / PI;
}
var primary,secondary,foodType,wallType,spikeType,millType,mineType,boostType,spawnpadType,utilityType,clanMates=[]
function isElementVisible(e) {
return (e.offsetParent !== null);
}
function gE(e) {
return document.getElementById(e)
}
function clan(e){
if(e == E.sid)return true
for(let i = 0; i < clanMates.length; i += 2){
if(e == clanMates[i]) return true
};
return false;
}
function getInventory() {
primary=null;
foodType = null;
secondary = null;
mineType = null;
wallType = null;
spikeType = null;
millType = null;
spawnpadType = null;
utilityType = null;
for (let i=0;i<9;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
primary = i;
}
}
for (let i=9;i<16;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
secondary = i;
}
}
for (let i=16;i<19;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
foodType = i - 16;
}
}
for (let i=19;i<22;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
wallType = i - 16;
}
}
for (let i=22;i<26;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
spikeType = i - 16;
}
}
for (let i=26;i<29;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
millType = i - 16;
}
}
for (let i=29;i<31;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
mineType = i - 16;
}
}
for (let i=31;i<33;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i))){
boostType = i - 16;
}
}
//11 is sapling
if (isElementVisible(document.getElementById("actionBarItem" + 36))){
spawnpadType = 36 - 16;
}
for (let i=33;i<39;i++){
if (isElementVisible(document.getElementById("actionBarItem" + i)) && i != 36){
utilityType = i - 16;
}
}
//console.log(isElementVisible(document.getElementById("actionBarItem" + String(wallType+16))))
function e(e) {
return null !== e.offsetParent
}
!secondary && (ww=primary)
}
function reloadWeapon(_,bot){
if(botIDS.includes(_.sid) && !bot) return;
if(bot) {
_ = findPlayerSID(_.sid)
}
if(bot && _ ===null) return;
if(_.buildIndex == -1) {
if(_.weaponIndex <= 8) {
let { speed } = R.weapons[_.primary];
_.pr = min(1, _.pr + ((_.delta>190) ? _.delta : timeBetweenTick) / (speed * _.samRP));
}else if(_.weaponIndex > 8) {
let { speed } = R.weapons[_.secondary];
_.sr = min(1, _.sr + ((_.delta>190)? _.delta: timeBetweenTick) / (speed * _.samRS));
}
}
_.tr = min(1, _.tr+_.delta/2400);
primaryReloads[_.sid] = _.pr;
secondaryReloads[_.sid] = _.sr;
turretReloads[_.sid] = _.tr
if(_.sid != E.sid) {
if(!_.hasSoldier && _.skinIndex == 6) {
_.hasSoldier = true;
}
if(!_.hasTank && _.skinIndex == 40) {
_.hasTank = true;
}
}
}
function checkIfVisible(e){
for(let i =0;i<modBots.length;i++){
for(let x=0; x<modBots[i].players.length;x++){
let target = modBots[i].players[x]
if((e.name && !e.sid && target.name == e.name||e.sid && e.sid == target.sid)&&target.visible){
if(!e.spotted){
let msg = `${target.name}[${target.sid}]` //: `${target.name}`
if(!inRender(E,target))addChatLog(`bot ID: [${modBots[i].sid}] spotted ${msg}`,'', e.color,false,true);
}
e.spotted = true;
return target;
}
}
}
return false;
}
function reloadFailSafe(_){
for(let i=0;i<J.length;i++){
if(!J[i].visible&&J[i].sid!=E.sid&&!botIDS.includes(J[i].sid)){
_ = J[i]
// console.log(pThisTick[i])
_.pr!=undefined&&_.pr!== 1&&( _.pr = min(1, _.pr + timeBetweenTick/(R.weapons[_?.primary]?.speed * _.samRP)));
_.sr!=undefined&&_.sr!== 1&&(_.sr = min(1, _.sr + timeBetweenTick/(R.weapons[_?.secondary]?.speed * _.samRS)));
_.tr!=undefined&&_.tr!==1&&(_.tr = min(1, _.tr + timeBetweenTick/2500));
primaryReloads[_.sid] = _.pr
secondaryReloads[_.sid] = _.sr
turretReloads[_.sid] = _.tr
} //else{console.log("fail")}
//}
}
}
function getEuclideanDistance(node1, node2){
return dist(node1,node2)//Math.sqrt(Math.pow(node1.x - node2.x, 2) + Math.pow(node1.y - node2.y, 2));
}
function getDistance(nodeA, nodeB) {
return abs(nodeA.x - nodeB.x) + abs(nodeA.y - nodeB.y);
}
function dAng(ang1, ang2){
let d = abs(ang1 - ang2);
d = d % PI2;
if(d > PI){
d = PI2 - d;
}
// console.log(d);
return d;
}
function autobuyer(){
if(bH.length+bT.length>=66||!amAlive||!sandbox||We.style.display!="none"||!autoBuy.checked) return;
if(buyer.length){
if(!Array.isArray(buyer[0]) && E.points>=Xt.find(e => e.id==buyer[0]).price) storeBuy(buyer[0],0);
if(Array.isArray(buyer[0]) && E.points>=Gt.find(e => e.id==buyer[0][0]).price) storeBuy(buyer[0][0],1);
}
if(buyer.length==0&&bH.length!=Xt.length-1){
let hat = Xt.find(e => e.id!=45 && !bH.includes(e.id)&&E.points>=e.price)
if(hat) storeBuy(hat.id,0);
let acc = Gt.find(e => !bT.includes(e.id)&&E.points>=e.price)
if(acc) storeBuy(acc.id,1);
}
// console.log(buyer.length,bH.length,bT.length)
}
// const pathfindingWorker = new Worker("ezpz");
function avgAng(a1, a2) {
const r1 = a1 * (PI / 180);
const r2 = a2 * (PI / 180);
const aR = (r1 + r2) / 2;
let aA = aR % PI2;
if (aA < 0) {
aA += PI2;
}
aA = aA * (180 / PI);
return aA;
}
var dopushcalc = false
async function getPush(e,ang,x,y,x2,y2,abs = Math.abs,r = Math.round){
if(!nEnemy||dopushcalc) return;
let di = getDir(E,nEnemy),
fp = calcVel(E,di),
dir = getDir(fp.accel,nEnemy),
xV = fp.accel.x - nEnemy.x2,
yV = fp.accel.y - nEnemy.y2,
plyrDist = dist(fp.accel,nEnemy);
ee.send("9",di, "client")
if(abs(xV) <= 70 || abs(yV) <= 70){
const distanceSquared = xV * xV + yV * yV;
var eR = Math.sqrt(distanceSquared) - 70;
if(eR <= 0){
dopushcalc = true;
eR = eR * -.5
x = nEnemy.x2 - eR * Math.cos(dir)
y = nEnemy.y2 - eR * Math.sin(dir)
x2 = x + eR * Math.cos(dir)
y2 = y + eR * Math.sin(dir)
console.log({x:x,y:y},{x:x2,y:y2},'did',tick)
console.log(r(nEnemy.movSpd),r(E.movSpd),eR)
//return {x:x,y:y}
}
}
await nextTick()
console.log(dist({x,y},nEnemy))
dopushcalc = false;
// console.log({x:nEnemy.x2,y:nEnemy.y2},{x:E.x2,y:E.y2},tick)
console.log('_____________________________')
// return false;
/*if (o.getDistance(e.x, e.y, t.x, t.y), t.isPlayer ? (f = -1 * f / 2, e.x += f *
r(d), e.y += f * s(d),
t.x -= f * r(d),
t.y -= f * s(d)) :
(e.x = t.x + u * r(d),
e.y = t.y + u * s(d),
e.xVel *= .75, e
.yVel *= .75)*/
}
function Hg(e, t){
if(!isNaN(e)){
if(!bH.includes(e)){
if(lastHat!=0) storeEquip(0, 0),skin=0, nHat = 0;
} else{
if(lastHat!=e)storeEquip(e, 0),skin = e, nHat = e;
}
}
if(!isNaN(t)){
if(!bT.includes(t)){
if(lastTail!=0)storeEquip(0, 1),tail=0, nTail = 0;
}else{
if(lastTail!=t)storeEquip(t, 1),tail=t, nTail = t;
}
}
}
function distance(a, b){
if(a.x2&&b.x2)return sqrt(pow((b.y2-a.y2), 2) + pow((b.x2-a.x2), 2));
if(!a.x2==undefined && !b.x2)return sqrt(pow((b.y-a.y), 2) + pow((b.x-a.x), 2));
if(a.x2 && !b.x2)return sqrt(pow((b.y-a.y2), 2) + pow((b.x-a.x2), 2));
if(!a.x2&&b.x2)return sqrt(pow((b.y2-a.y), 2) + pow((b.x2-a.x), 2));
}
function spliceIncludes(arr1, arr2) {
for (let i = 0, tmp, e; i < arr1.length; i++) {
for (e = arr2.length, tmp = arr1[i]; e--;) {
if (tmp === arr2[e]) {
arr1.splice(i, 1);
arr2.splice(e, 1);
i--;
break;
}
}
}
}
function getDir(a, b){ // point, target
return atan2((b.y2||b.y) - (a.y2||a.y), (b.x2||b.x) - (a.x2||a.x)) // Math.atan2(y, x) parameters
}
// this function is why it broke
//const objDist = (a, b) => sqrt((a.x2 || a.x - b.x2 || b.x) ** 2 + (a.y2 || a.y - b.y2 || b.y) ** 2);
function objDist(a, b){
return hypot((a.x2||a.x) - (b.x2||b.x), (a.y2||a.y) - (b.y2||b.y));
}
function dot(a, x, y){
return (a.x*x+a.y*y)/(a.x*y-a.y*x)
}
var mySpeed,DefaultSpeed = 65,pushVector = {x:null,y:null,objs:[],dev:null,dir:null},pushCoords = {x:null,y:null}
/* let hatSpeed = (function(e){for(let i=0;i<Xt.length;i++)if(e==Xt[i].id){return Xt[i].spdMult}})(lastHat) || 1;
let accSpeed = (function(e){for(let i=0;i<Gt.length;i++)if(e==Gt[i].id){return Gt[i].spdMult}})(lastTail) || 1;
let wepSpeed = R.weapons[E.weapons[E.weaponIndex] || E.weapons[0]].spdMult || 1;
mySpeed = DefaultSpeed * wepSpeed * hatSpeed * accSpeed * (E.y2 < T.snowBiomeTop && lastHat != 15 ? T.snowSpeed : 1);*/
function wyndAP(Z,t,b,GG,_,enemyV,useVel){
if (!nEnemy?.inTrap || !nEnemy || !autopusher||nEnemy && E.skinIndex==45&& dist(E,nEnemy)>90) {
pushing = false;
pusher = false;
pushPosition = 'not';
pushVector = 'not'
pushCoords = 'not'//{x:null,y:null}
moveAuto == 'autopush' && ee.send('9', undefined)
return false;
}
// addChatLog(`${dist(nEnemy,nEnemy.np.decel)} ${tick}`,'', '#5c0620',false,true);
let virtualPos;
let overrideDir;
pushing = false;
pusher = false;
// useVel = true;
// enemyV = useVel ? nEnemy.np.decel : nEnemy
Z = getDir(E,nEnemy)
pushVector = {x:cos(Z), y:sin(Z),objs:[],dev:null,dir:null};
let objs = nearObjects.sort((a, b) => dist(a, nEnemy) - dist(b, nEnemy));
for(let i = 0;i < objs.length;i++){
_ = objs[i];
if(nEnemy.inTrap.sid === _.sid) continue;
// id 6-9 are all spikes
if(dist(nEnemy.inTrap, _) <= 50 + (_.type == 1 ? _.scale * 0.55 : _.scale) + 26 && ((clan(_?.owner?.sid) && _?.group?.name == 'spikes') || (!nEnemy.team && _?.group?.name == 'spikes' && _?.owner?.sid != nEnemy.sid) || (_?.type === 1 && _.y >= 12000))
|| pushVector.objs.length === 1 && dist(_, nEnemy.inTrap) <= 50 + _.scale + 22.5 && dist(_,pushVector.objs[0]) <= pushVector.objs[0].scale + _.scale + 42.5 && !_.ignoreCollision){
let a = atan2(_.y - nEnemy.y2, _.x - nEnemy.x2);
let d = 170 - objDist(_, nEnemy);
if(pushVector.objs[0] && dAng(getDir(_,nEnemy.inTrap),getDir(pushVector.objs[0],nEnemy.inTrap)) <= 1.9 && dist(_,pushVector.objs[0])<=_.scale+pushVector.objs[0].scale+67.5|| !pushVector.objs.length){
pushVector.x += d * cos(a);
pushVector.y += d * sin(a);
if(pushVector.objs[0])console.log(dAng(getDir(_,nEnemy.inTrap),getDir(pushVector.objs[0],nEnemy.inTrap)),Math.round(dist(_,pushVector.objs[0]))-(pushVector.objs[0].scale + _.scale));
// console.log(pushVector.objs.length, dist(_, nEnemy.inTrap) <= 50 + _.scale + 15 , pushVector.objs.length && dist(_,pushVector.objs[0]) <= pushVector.objs[0].scale + _.scale + 21, !_.ignoreCollision)
pushVector.objs.push(_)
}
if(dot(pushVector, nEnemy.inTrap.x - nEnemy.x2, nEnemy.inTrap.y - nEnemy.y2) > 0){
pushVector.x += (nEnemy.inTrap.x - nEnemy.x2)*2;
pushVector.y += (nEnemy.inTrap.y - nEnemy.y2)*2;
}
}
}// 36 lowest so far
if(fastHypot(pushVector.x, pushVector.y) > 5){
let distToEnemy = objDist(nEnemy,E)
let tau = dAng(Z, atan2(pushVector.y, pushVector.x));
let spike = pushVector.objs[0]
let decide = dist(nEnemy,spike)<=spike.scale+38.75
let opposite = 3600 + pow(distToEnemy, 2) - (28.5+(decide ? 71.5 : 0)) * distToEnemy * cos(tau);
let deviance = Math.acos((pow(distToEnemy, 2) + opposite - 3600)/(2 * distToEnemy * sqrt(opposite)));
if(deviance){
overrideDir = Z - Math.sign((nEnemy.x2 - E.x2) * (pushVector.y) - (nEnemy.y2 - E.y2) * (pushVector.x)) * deviance;
let distanceToTarget = dist(E,nEnemy) + 30
pushCoords = {x: E.x2 + distanceToTarget * cos(overrideDir),
y: E.y2 + distanceToTarget * sin(overrideDir)};
/*let futurePos = calcVel(E, overrideDir, E, 1);
let threat = nearObjects.filter(e => e?.group?.name == 'spikes' && !clan(e?.owner?.sid)).sort((a,b)=>fastHypot(E.x2-a.x,E.y2-a.y)-fastHypot(E.x2-b.x,E.y2-a.y))[0];
let decelVels = [getDecelDist(futurePos.vel), getDecelDist(E.movSpd)];
let closestPoints = [calcPoint(E.x2, E.y2, overrideDir, decelVels[0]), calcPoint(E.x2, E.y2, overrideDir, decelVels[1])];
let isIntersecting = (dist(closestPoints[0], threat) <= threat.scale + 35|| dist(closestPoints[1], threat) <= threat.scale + 35);
let dists = [dist(E,threat,"object")<= 75, dist(E.np.decel,threat,"object")<=75]
let canReach = (dists[0] || dists[1]);
if(isIntersecting && canReach && secondary === 10) {
alert("STOPPED");
ee.send('9',null,'autopush')
} else*/
let pushThreat = runInto(E, overrideDir, calcVel(E, overrideDir, E, 1));
let align = dAng(getDir(nEnemy, spike), getDir(E, nEnemy)) <= 2;
if( ((!nEnemy.hitSpike||dist(E,pushCoords)>100&& nEnemy.hitSpike) && stopOnColl.checked|| !stopOnColl.checked && align && !pushThreat)){
ee.send('9',overrideDir,'autopush')
pushVector.dev = deviance
pushVector.dir = overrideDir;
}else{
// overrideDir = null;
ee.send('9',null,'autopush')
}
pushing = true;
pusher = true;
}
}
}
function autopush(ez, e, t) {
if (!nEnemy?.inTrap || !nEnemy || !autopusher) {
pushing = false;
pusher = false;
pushPosition = 'not';
pushCoords = 'not'
moveAuto == 'autopush' && ee.send('9', undefined)
pushVector = 'not';
return false;
}
if (!ez) ez = [];
let s = nearObjects
.filter(e => !ez.includes(e.sid) && dist(nEnemy.inTrap, e) <= 50 + (e.type == 1 ? e.scale * 0.55 : e.scale) + 26 && ((clan(e?.owner?.sid) && e?.group?.name == 'spikes') || (!nEnemy.team && e?.group?.name == 'spikes' && e?.owner?.sid != nEnemy.sid) || (e?.type == 1 && e.y >= 12000)))
.sort((a, b) => dist(a, nEnemy) - dist(b, nEnemy));
if (!s.length || dist(E, nEnemy) >= 400) {
pusher = false;
pushing = false;
pushPosition = 'not';
pushVector = 'not';
pushCoords = 'not'
moveAuto == 'autopush' && ee.send('9', undefined)
return false;
}
nEnemy = findPlayerSID(nEnemy.sid);
const sx = nEnemy.x2 - s[0].x;
const sy = nEnemy.y2 - s[0].y;
const px = nEnemy.x2 - E.x2;
const py = nEnemy.y2 - E.y2;
const tx = nEnemy.x2 - nEnemy.inTrap.x;
const ty = nEnemy.y2 - nEnemy.inTrap.y;
const tsx = s[0].x - nEnemy.inTrap.x;
const tsy = s[0].y - nEnemy.inTrap.y;
const sm = sqrt(sx * sx + sy * sy);
sTE = {
x: sx / sm,
y: sy / sm
};
const pm = sqrt(px * px + py * py);
pTE = {
x: px / pm,
y: py / pm
};
const tm = sqrt(tx * tx + ty * ty);
tTE = {
x: tx / tm,
y: ty / tm
};
const tsm = sqrt(tsx * tsx + tsy * tsy);
let tTS = {
x: tsx / tsm,
y: tsy / tsm
};
const a = [atan2(sTE.y, sTE.x), atan2(tTE.y, tTE.x), atan2(pTE.y, pTE.x)];
const aa = [(a[0] + a[1]) / 2, (a[0] + a[2]) / 2];
const av = [
{ x: cos(aa[0]), y: sin(aa[0]) },
{ x: cos(aa[1]), y: sin(aa[2]) }
];
dPAP =(sTE.x * pTE.x) + (sTE.y * pTE.y)// (av[0].x * pTE.x) + (av[0].y * pTE.y);
sos3 = s[0]?.type == 1 ? (s[0].scale * 0.55, s[0].realScale = s[0].scale * 0.55) : s[0].scale;
apS = s[0];
pushPosition = {
x: nEnemy.x2 + sTE.x * (dPAP + sos3),
y: nEnemy.y2 + sTE.y * (dPAP + sos3)
};
const ang = getDir(E, pushPosition);
const distToPos= dist(E, pushPosition);
const angDiff = dAng(ang, getDir(E, nEnemy));
t = distToPos<= 100 && angDiff <= 2; // 2 or 2.3
let collider = ue.checkCollision2(nEnemy, s[0]);
let ar = { x: nEnemy.x2, y: nEnemy.y2, scale: 35, do: true };
// let o = nearObjects;
let obstacles = t ? nearObjects : nearObjects.concat(ar);
let tX = Date.now();
paths = [];
if (collider) {
doSpikeInsta();
}
if(nEnemy.hitSpike && !moveOnColl.checked){
pushing = false;
pusher = false;
pushPosition = 'not';
pushCoords = 'not'
moveAuto == 'autopush' && ee.send('9', undefined)
pushVector = 'not';
return;
}
if(t){
wyndAP()
}
/* if ((c && nEnemy.hitSpike == false) || !c) {
if (t) {
if (moveDirection !== ang) {
// ee.send("9", ang,'autopush');
}
pushing = true;
pusher = true;
}
} else {
if (moveDirection !== null) {
ee.send("9", null,'autopush');
}
pushing = true
pusher = true;
}*/
if(!t){
// changed + 30 to + 35, let's see if better
pathfind({
player: E,
target: { x: nEnemy.x2 + sTE.x * (dPAP + sos3 + 35), y: nEnemy.y2 + sTE.y * (dPAP + sos3 + 35) },
buildings: obstacles,
clan: clanMates
}).then(foundPath => {
let p = foundPath;
nEnemy = findPlayerSID(nEnemy.sid);
pusher = false;
pushing = true;
if (!p) {
pusher = false;
pushing = false;
pushPosition = 'not';
pushVector = 'not';
pushCoords = 'not'
// ez.push(s[0].sid);
// autopush(ez);
return false;
}
e = moveToPath(tX, 360,true);
if (!e) {
pusher = false;
pushing = false;
pushPosition = 'not';
pushVector = 'not';
pushCoords = 'not'
// ez.push(s[0].sid);
paths = [];
// autopush(ez);
return;
}
}).catch(error => {
pushing = false;
pusher = false;
pushPosition = 'not';
return false;
});
}
}
async function doSpikeInsta(){
if(nEnemy&&(nEnemy.weaponR==1||nEnemy.skinIndex!=6)&&!instaing&&(dist(E.np.accel,nEnemy.np.real,"player")<=R.weapons[primary].range||dist(E,nEnemy,"player")<=R.weapons[primary].range)&&E.pr==1&&amAlive&&(nEnemy.weaponIndex==11&&C.getAngleDist(getDir(E,nEnemy)+PI,nEnemy.dir)>PI / 3||nEnemy.weaponIndex!=11)){
instaToggle = false;
instaing = true;
if(E.skinIndex != 11){Hg(7,18)} else storeEquip(19, 1)
aim[0] = getDir(E,nEnemy)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client");
ee.send("z",primary,true)
hold = primary
await nextTick()
Hg(53)
// console.log(nEnemy.np.real.type);
await nextTick();
instaing = false;
}
}
function nreload(e,t){
if(!e) return;
!t&&(t=111)
return min(1, e.weaponR + t/R.weapons[e.weaponIndex]?.speed)
}
function inrange(e,t,r,v){
return dist(e,t,"player")<=r||v&&dist(e?.np?.real,t?.np?.real,"player")<=r
}
function calcprojHit(start,target,projectileType,projectileSpeed,d,t){
d = dist(start,target)-35;
t = d / (projectileSpeed*111)
return t;
}
function syncproj(players, target,type,speed) {
const pP = players.map(player => {
let coords = calcPoint(player.x2,player.y2,getDir(player,target),35)
const musketTicks = calcprojHit(coords,target,5,3.6);
const turretBallTicks = calcprojHit(coords,target,1,1.54);
return { player, musketTicks, turretBallTicks };
});
pP.sort((a, b) => a.musketTicks - b.musketTicks);
const maxTurretBallTicks = max(...pP.map(proj => proj.turretBallTicks));
pP.forEach(proj => {
proj.waitTicksForTurretBall = maxTurretBallTicks - proj.turretBallTicks;
});
const syncOrder = pP.map(proj => proj.player.name);
pP.forEach(proj => {
proj.waitTimeForMusket = proj.musketTicks * 111;
proj.waitTimeForTurretBall = proj.waitTicksForTurretBall * 111;
});
return { pP, syncOrder };
}
function generateRandomColor(existingColors) {
const hue = floor(Math.random() * 360);
const saturation = floor(Math.random() * 81) + 20; // Saturation range: 20-100
const lightness = floor(Math.random() * 61) + 20; // Lightness range: 20-80
const newColor = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
if(!existingColors) return newColor;
if(existingColors.some(({color}) => color &&isSimilarColor(color, newColor))) {
// If a similar color exists in the array, recursively generate a new color
return generateRandomColor(existingColors);
}
return newColor;
}
function isSimilarColor(color1, color2) {
// Calculate the color difference using the CIE76 formula
const [h1, l1, s1] = colorToHsl(color1);
const [h2, l2, s2] = colorToHsl(color2);
const hueDiff = abs(h1 - h2);
const lightnessDiff = abs(l1 - l2);
const saturationDiff = abs(s1 - s2);
return hueDiff <= 60 && lightnessDiff <= 20 && saturationDiff <= 20;
}
function colorToHsl(color) {
const div = color.indexOf(",") > -1 ? "," : " ";
const [r, g, b] = color
.substr(color.indexOf("(") + 1)
.split(")")[0]
.split(div)
.map(Number);
const rRatio = r / 255;
const gRatio = g / 255;
const bRatio = b / 255;
const max = Math.max(rRatio, gRatio, bRatio);
const min = Math.min(rRatio, gRatio, bRatio);
let hue, saturation, lightness;
if (max === min) {
hue = 0;
} else if (max === rRatio) {
hue = 60 * ((gRatio - bRatio) / (max - min)) + 0;
} else if (max === gRatio) {
hue = 60 * ((bRatio - rRatio) / (max - min)) + 120;
} else {
hue = 60 * ((rRatio - gRatio) / (max - min)) + 240;
}
lightness = (max + min) / 2;
if (max === min) {
saturation = 0;
} else if (lightness <= 0.5) {
saturation = (max - min) / (max + min);
} else {
saturation = (max - min) / (2 - max - min);
}
return [round(hue), round(lightness * 100), round(saturation * 100)];
}
function bScale(e){
return e.type === 1 && e.y >= 12000? e.scale * .55 : e.type === 1 ? e.scale * .6 : e.type === 0 ? e.scale * .7 : e.scale
}
const WorkerCode = `
self.onmessage = (msg) => {
const bitmap = msg.data.bitmap;
const player = JSON.parse(msg.data.R)
const time = msg.data.time
const size = msg.data.size
const res = msg.data.res
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
ctx.clearRect(Math.floor(bitmap.width/2), Math.floor(bitmap.height/2), 1, 1);
const endpoints = [];
const data = ctx.getImageData(0,0,bitmap.width, bitmap.height).data;
const map = new Map(canvas,player,size,res);
for(let i = 0;i < data.length;i += 4){
let l = i / 4;
map.graph[l % bitmap.width][Math.floor(l / bitmap.width)].cost = data[i]
if(data[i + 2]){
endpoints.push({
x: l % bitmap.width,
y: Math.floor(l / bitmap.width),
});
}
}
bitmap.close();
if(!endpoints.length){
endpoints.push(map.getCentreNode());
}
//begin the pathfinding
let openSet = new BinHeap();
openSet.setCompare = (a, b) => a.f > b.f;
openSet.push(map.getCentreNode());
let currentNode;
while(openSet.length){
currentNode = openSet.remove(0)
if(endpoints.some((goal) => goal.x == currentNode.x && goal.y == currentNode.y)){
break;
}
let neighbors = map.getNeighbor(currentNode.x, currentNode.y,player,size,res);
for(let i = 0;i < neighbors.length;i++){
let neighbor = neighbors[i];
if(neighbor && neighbor.cost == 0){//make weighted later
let tempG = currentNode.g + Map[i % 2 == 0 ? "DiagonalCost" : "TraversalCost"];
if(tempG < neighbor.g){
neighbor.parent = currentNode;
neighbor.g = tempG;
neighbor.h = Math.min.apply(Math, endpoints.map((goal) => fastHypot(neighbor.x - goal.x, neighbor.y - goal.y)));
if(!neighbor.inset){
openSet.insert(neighbor);
}
}
}
}
}
//recontruct path
if(!endpoints.some((goal) => goal.x == currentNode.x && goal.y == currentNode.y)){
currentNode = map.getLowest('h',player,size,res);
}
let output = [];
while(currentNode.parent){
let nextNode = currentNode.parent;
let d = Math.round(Math.atan2(nextNode.y - currentNode.y, nextNode.x - currentNode.x) / Math.PI * 4);
if(d < 0){d+=8};
output.push(d);
currentNode = nextNode;
}
output = new Uint8Array(output.reverse()).buffer;
self.postMessage(output, [output]);
}
//approximate hypot
function fastHypot(a, b){
const c = Math.SQRT2-1;
a = Math.abs(a);
b = Math.abs(b);
if(a > b){
let temp = a;
a = b;
b = temp;
}
return (c * a) + b
}
//Map Constructor for object
class Map{
static TraversalCost = 1;
static DiagonalCost = Math.sqrt(2) * 1;
constructor(canvas,player,size,res){
//init variables
this.width = canvas.width;
this.height = canvas.height;
this.middleWidth = Math.floor(this.width / 2);
this.middleHeight = Math.floor(this.height / 2);
this.graph = new Array(canvas.width);
for(let x = 0;x < this.width;x++){
this.graph[x] = new Array(this.height);
for(let y = 0;y < this.height; y++){
this.graph[x][y] = new Node(x, y);
}
}
this.getCentreNode(player,size,res).g = 0;
this.getCentreNode(player,size,res).pending = false;
}
getLowest(type,player,size,res){
let lowestNode = this.graph[0][0];
for(let x = 0;x < this.width;x++){
for(let y = 0;y < this.height; y++){
let node = this.getNode(x, y, player,size,res)
if(lowestNode[type] > node[type]){
lowestNode = node;
}
}
}
return lowestNode;
}
getNode(x, y, player,size,res){
let X = x*res+ player.x2-size, Y = y*res + player.y2-size
if(X<0||Y<0||X>14400||Y>14400){
if(this.graph[x] && this.graph[x][y]?.cost!=undefined){
this.graph[x][y].cost = 100
return this.graph[x][y];
}
return undefined
}
if(this.graph[x]){
return this.graph[x][y];
}
}
getCentreNode(player,size,res){
return this.graph[this.middleWidth][this.middleHeight];
}
getNeighbor(x, y,player,size,res){
return [
this.getNode(x - 1, y - 1,player,size,res),
this.getNode(x + 0, y - 1,player,size,res),
this.getNode(x + 1, y - 1,player,size,res),
this.getNode(x + 1, y + 0,player,size,res),
this.getNode(x + 1, y + 1,player,size,res),
this.getNode(x + 0, y + 1,player,size,res),
this.getNode(x - 1, y + 1,player,size,res),
this.getNode(x - 1, y + 0,player,size,res),
]
}
lineOfSight(node1, node2) {
let x0 = node1.x;
let y0 = node1.y;
let x1 = node2.x;
let y1 = node2.y;
let dx = Math.abs(x1 - x0);
let dy = Math.abs(y1 - y0);
let sx = x0 < x1 ? 1 : -1;
let sy = y0 < y1 ? 1 : -1;
let err = dx - dy;
while (x0 !== x1 || y0 !== y1) {
if (this.graph[x0][y0].cost !== 0) {
return false; // Line-of-sight blocked
}
let e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
x0 += sx;
}
if (e2 < dx) {
err += dx;
y0 += sy;
}
}
return true; // Line-of-sight clear
}
}
//Node for Map
class Node{
constructor(x, y){
this.x = x;
this.y = y;
this.g = Number.POSITIVE_INFINITY;//distance to start
this.h = Number.POSITIVE_INFINITY;//estimated distance to end
this.parent;//where it came from
}
get f(){
return this.h + this.g;
}
}
//binary heap object constructor
class BinHeap extends Array {
//private variable declaration
#compare = (a, b) => a < b;
//constuctor
constructor(len = 0) {
super(len);
}
//change compare function
set setCompare(func) {
if (typeof func == "function") {
this.#compare = func;
} else {
throw new Error("Needs a function for comparing")
}
}
//sort into a binary heap
sort() {
for (let i = Math.trunc(this.length / 2); i >= 0; i--) {
this.siftDown(i)
}
}
//old array sort
arraySort(compare) {
super.sort(compare)
}
//sift down
siftDown(index) {
let left = index * 2 + 1;
let right = index * 2 + 2;
let max = index;
if (left < this.length && this.#compare(this[max], this[left])){
max = left;
}
if (right < this.length && this.#compare(this[max], this[right])){
max = right;
}
if (max != index) {
this.swap(index, max);
this.siftDown(max);
}
}
//sift up
siftUp(index) {
let parent = (index - (index % 2 || 2)) / 2;
if (parent >= 0 && this.#compare(this[parent], this[index])) {
this.swap(index, parent);
this.siftUp(parent);
}
}
//inserts element into the binary heap
insert(elem) {
this.push(elem);
this.siftUp(this.length - 1);
}
//removes elem at index from binary heap
remove(index) {
if (index < this.length) {
this.swap(index, this.length - 1);
let elem = super.pop();
this.siftUp(index);
this.siftDown(index);
return elem;
} else {
throw new Error("Index Out Of Bounds")
}
}
//changes elem at index
update(index, elem) {
if (index < this.length) {
this[index] = elem;
this.siftUp(index);
this.siftDown(index);
} else {
throw new Error("Index Out Of Bounds")
}
}
//swap two elem at indexes
swap(i1, i2) {
let temp = this[i1];
this[i1] = this[i2];
this[i2] = temp;
}
}
`;
//pathfinding instance
var Timer;
var genTime;
class WorkerAStar{
constructor(size, resolution){
//setup essential variables
this.size = size;
this.res = resolution;
this.prevPos = {};
this.prevPath = [];//might change
addChatLog(`Default pathfinder | radius: ${size} resolution: ${resolution} `,'', '#5c0620',false,true);
addChatLog(`use !help, !commands to navigate hack.`,'', '#5c0620',false,true);
//helpCommands()
//setup worker
this.blob = new Blob([
WorkerCode
], {
type: "application/javascript"
})
this.url = URL.createObjectURL(this.blob);
this.worker = new Worker(this.url);
this.worker.url = this.url;
//message receiving
this.worker.onmessage = (msg) => {
genTime = Date.now()-Timer
this.attemptFulfil(new Uint8Array(msg.data));
}
//error handling
this.worker.onerror = (err) => {
throw err;
}
this.initiateCanvas();
//test canvas
// var canvasMap = document.createElement("CANVAS");
// canvasMap.id = 'canvasMap';
// document.body.append(canvasMap);
// canvasMap.style.zIndex = "-1";
// canvasMap.style = "position:absolute; left: 50%; top: 60px;margin-left:-100px; pointer-events: none; border-style:solid;";
// this.mapWriter = canvasMap.getContext("2d");
// canvasMap.width = Math.ceil(this.size * 2 / this.res) + 1;
// canvasMap.height = Math.ceil(this.size * 2 / this.res) + 1;
}
close() {
this.worker.terminate();
URL.revokeObjectURL(this.url);
Tach = null;
}
//attempts to recieve a message
attemptFulfil(msg, depth = 0){
if(this.resolve){
//relay message onward
this.resolve(msg);
this.resolve = null;
}else{
//allow 5 attempts to recieve
if(depth < 10){
setTimeout(() => {
//could have just passed function as param, but this is more "consistent"
this.attemptFulfil(msg, depth + 1);
}, 0);
}else{
console.error("Unexpected Message from Worker at ", this);
}
}
}
//gets new canvas
initiateCanvas(){
this.width = ceil(this.size * 2 / this.res) + 1;
if(this.canvas){
this.canvas.width = this.width;
this.canvas.height = this.width;
}else{
this.canvas = new OffscreenCanvas(this.width, this.width);
//console.log(this.canvas,this.width)
this.ctx = this.canvas.getContext("2d");
}
}
//setter for buildings
setBuildings(buildings){
this.buildings = buildings;
}
//set estimates speed
setSpeed(spd){
this.estimatedSpeed = spd;
}
//set pos in real time
setPos(x, y){
this.x = x;
this.y = y;
}
//clear the previous path to force a recalculation
clearPath(){
this.prevPath = [];
}
pathBlocked(e){
if(dist(e[0],Tach.finalGoal)>=30){
this.pathBlocked = true;
}
}
async drawPath(ctx, pathColor = "#0000FF", myPos = this, dirColor = "#00FF00"){
if(this.prevPath.length){
//draw path
// ctx.strokeStyle = "#00ffb3";
/* ctx.lineWidth = 5;
ctx.globalAlpha = 1;
ctx.beginPath();
for(let i = 0;i < this.prevPath.length;i++){
const hue = (i / (this.prevPath.length)) * 360;
ctx.strokeStyle = `hsl(${hue}, 100%, 50%)`;
// ctx.strokeStyle = "#00ffb3";
ctx.lineTo(this.prevPath[i].x, this.prevPath[i].y);
ctx.moveTo(this.prevPath[i].x, this.prevPath[i].y);
}
ctx.stroke();
*/
/*ctx.lineWidth = 5;
const colorSpeed = 0.0004; // Adjust this value to control the color movement speed
const currentTime = Date.now() * colorSpeed;
for (let i = 0; i < this.prevPath.length - 1; i++) {
const t1 = i / (this.prevPath.length - 1);
const t2 = (i + 1) / (this.prevPath.length - 1);
const offset = (currentTime % 1);
const colorStop1 = (t1 + offset) % 1;
const colorStop2 = (t2 + offset) % 1;
const gradient = ctx.createLinearGradient(
this.prevPath[i].x, this.prevPath[i].y,
this.prevPath[i + 1].x, this.prevPath[i + 1].y
);
// gradient.addColorStop(colorStop2, #20A4F3);
gradient.addColorStop(colorStop2, "#03191E");
gradient.addColorStop(colorStop2, "#20A4F3");
// gradient.addColorStop(colorStop1, "rgba(163, 0, 133, 10)"); // Dark Magenta
// gradient.addColorStop(colorStop2, "rgba(0, 255, 204, 10)"); // Bright Turquoise
ctx.beginPath();
ctx.strokeStyle = gradient;
ctx.moveTo(this.prevPath[i].x, this.prevPath[i].y);
ctx.lineTo(this.prevPath[i + 1].x, this.prevPath[i + 1].y);
ctx.stroke();
}*/
const currentTime = Date.now() * .3;
ctx.lineWidth = 5;
ctx.globalAlpha = 1;
for (let i = 0; i < this.prevPath.length - 1; i++) {
const hue1 = ((i / (this.prevPath.length - 1) * 360) + currentTime) % 360;
const hue2 = (((i + 1) / (this.prevPath.length - 1) * 360) + currentTime) % 360;
const [r1, g1, b1] = hslToRgb(hue1 / 360, 1, 0.55);
const [r2, g2, b2] = hslToRgb(hue2 / 360, 1, 0.55);
const gradient = ctx.createLinearGradient(
this.prevPath[i].x, this.prevPath[i].y,
this.prevPath[i + 1].x, this.prevPath[i + 1].y
);
gradient.addColorStop(0, `rgba(${r1}, ${g1}, ${b1}, 1)`);
gradient.addColorStop(1, `rgba(${r2}, ${g2}, ${b2}, 1)`);
ctx.beginPath();
ctx.moveTo(this.prevPath[i].x, this.prevPath[i].y);
ctx.lineTo(this.prevPath[i + 1].x, this.prevPath[i + 1].y);
ctx.strokeStyle = gradient;
ctx.stroke();
}
//draw movement dir
if(myPos.x && myPos.y){
ctx.lineWidth = 5;
ctx.globalAlpha = 1;
ctx.strokeStyle = "#ffffff";
ctx.beginPath();
for(let point of this.prevPath){
ctx.globalAlpha = 1;
let dist = Math.hypot(myPos.x - point.x, myPos.y - point.y);
if(dist < this.estimatedSpeed + this.res * 2){
if(dist > this.estimatedSpeed){
ctx.moveTo(myPos.x, myPos.y);
ctx.lineTo(point.x, point.y);
}
break;
}
}
ctx.stroke();
}
}
}
//async function for recieving response
async response(){
return await new Promise((resolve) => {
this.resolve = resolve;
});
}
//attempt to get a path
checkBoundaries(x,y){
return (x>=0&&y>=0&&x<=14400&&y<=14400)
}
fastHypot(a, b){
const c = Math.SQRT2-1;
a = Math.abs(a);
b = Math.abs(b);
if(a > b){
let temp = a;
a = b;
b = temp;
}
return (c * a) + b
}
getPath(){
window.pf = this;
for(let i in this.prevPath){
let point = this.prevPath[i];
// console.log(this.prevPath)if (point.x < 0 &&point.y < 0 &&point.x > 14400 &&point.y > 14400) continue;
let dist = Math.hypot(E.x2 - point.x, E.y2 - point.y);
if(dist < this.estimatedSpeed + this.res * 2){
if(dist > this.estimatedSpeed){
return {
ang: Math.atan2(point.y - E.y2, point.x - E.x2),
dist: parseInt(i),
};
}else{
break;
}
}
}
}
//makes position on the canvas(may improve, repl.it/@pyrwynd, project:test map)
norm(value){
// console.log(this)
return Math.max(0, Math.min(this.width - 1, value));
}
async initCalc(positions, append = false,force){
//prevents multiple instances of calculation
if(this.resolve){
return;
}
//sets last position
this.prevGoal = positions.map((elem) => {
return {
x: elem.x,
y: elem.y,
}
})
//modify position values
if(append&&!force){
this.prevPos = this.prevPath[0];
}else{
this.prevPos = {
x: this.x,
y: this.y,
}
}
positions = positions.map((elem) => {
// console.log(elem.x,this.prevPos.x,this.norm((elem.x - this.prevPos.x + this.size) / this.res))
return {x: this.norm((elem.x - this.prevPos.x + this.size) / this.res),
y: this.norm((elem.y - this.prevPos.y + this.size) / this.res)}
})
//put buildings on canvas here
const Circle = PI2;
this.ctx.fillStyle = "#FF0000";
for(let obj of this.buildings){
let x = (obj.x - this.prevPos.x + this.size) / this.res;
let y = (obj.y - this.prevPos.y + this.size) / this.res;
let r = obj.pathScale
this.ctx.beginPath();
this.ctx.arc(x, y, r / this.res, 0, Circle);
this.ctx.fill();
}
//draw destination on canvas
this.ctx.fillStyle = "#0000FF";
for(let goal of positions){
this.ctx.fillRect(Math.round(goal.x), Math.round(goal.y), 1, 1);
}
//test canvas draw
// this.mapWriter.clearRect(0, 0, this.width, this.width);
// this.mapWriter.drawImage(this.canvas, 0, 0);
//instant data transfer(saves 10ms)
let bitmap = await createImageBitmap(this.canvas, 0, 0, this.width, this.width);
this.worker.postMessage({bitmap, R:JSONStringify(E),time:Date.now(),res:this.res,size:this.size});
Timer = Date.now();
// console.log(this.res,this.size)
//meanwhile get a new canvas
this.initiateCanvas();
//wait until recieve data
let data = await this.response();
//turn into list of points
const xTable = [-1, -1, 0, 1, 1, 1, 0, -1];
const yTable = [0, -1, -1, -1, 0, 1, 1, 1];
if(!append||force){
this.prevPath = [];
}
let currPos = {
x: this.prevPos.x,
y: this.prevPos.y,
};
/* let displayPos = {
x: Math.floor(this.width/2),
y: Math.floor(this.width/2),
}*/
for(let i = 0;i < data.length;i++){
// this.mapWriter
// console.log(currPos,"1")
currPos = {
x: currPos.x + xTable[data[i]] * this.res,
y: currPos.y + yTable[data[i]] * this.res,
}
// console.log(currPos,"D")
/* displayPos = {
x: displayPos.x + xTable[data[i]],
y: displayPos.y + yTable[data[i]],
}*/
// let condition = currPos.x >=0 && currPos.y>=0 &&currPos.x<=14400&&currPos.y<=14400 ? true : false
//)&& this.mapWriter.fillRect(displayPos.x, displayPos.y, 1, 1);
// condition&&
this.checkBoundaries(currPos.x,currPos.y)&&this.prevPath.unshift(currPos);
}
return;
}
//requests a path/calculation
async pathTo(positions,force){
//fix positions
if(!(positions instanceof Array)){
positions = [positions];
}
//remove path if not matching
if(this.prevGoal?.length == positions.length && this.prevGoal.every((elem, i) => elem.x == positions[i].x && elem.y == positions[i].y)||force){
//reuse previous path if nearby
let path = this.getPath();
if(path){
if(path.dist < 150||force/*this.estimatedSpeed / this.res * 5*/){
this.initCalc(positions, true,force);
}
return path;
}
}
await this.initCalc(positions,false,force);
return this.getPath();
}
}
Pathfinder = new WorkerAStar(2000,10);
//an interface to interact with the pathfinder
class Tachyon{
constructor(pathfinder){
this.pathfinder = pathfinder;
this.goal = {
pathing: false,
type: null,
entity: null,
pos: {
x: null,
y: null,
},
hasGoal:false,
}
this.finalGoal = {x:null,y:null}
this.waypoints = {
death: {
x: null,
y: null,
},
quick: {
x: null,
y: null,
},
}
}
setWaypoint(name, pos){
if(pos.x && pos.y){
this.waypoints[name] = {
x: pos.x,
y: pos.y,
}
}
}
drawWaypointMap(mapCtx, canvas){
mapCtx.font = "34px Lilita One";
mapCtx.textBaseline = "middle";
mapCtx.textAlign = "center";
for(let tag in this.waypoints){
if(tag == "death"){
mapCtx.fillStyle = "#E44";
}else if(tag == "quick"){
mapCtx.fillStyle = "#44E";
}else{
mapCtx.fillStyle = "#fff";
}
if(this.waypoints[tag].x && this.waypoints[tag].y){
mapCtx.fillText("x", this.waypoints[tag].x / 14400 * canvas.width, this.waypoints[tag].y / 14400 * canvas.height);
}
}
mapCtx.strokeStyle = "#4E4";
if(this.goal.type == "xpos"){
mapCtx.beginPath();
mapCtx.moveTo(this.goal.pos.x / 14400 * canvas.width, 0);
mapCtx.lineTo(this.goal.pos.x / 14400 * canvas.width, canvas.height);
mapCtx.stroke();
}else if(this.goal.type == "ypos"){
mapCtx.beginPath();
mapCtx.moveTo(0, this.goal.pos.y / 14400 * canvas.height);
mapCtx.lineTo(canvas.width, this.goal.pos.y / 14400 * canvas.height);
mapCtx.stroke();
}else if(this.goal.pos.x && this.goal.pos.y){
mapCtx.fillStyle = "#4E4";
mapCtx.fillText("x", this.goal.pos.x / 14400 * canvas.width, this.goal.pos.y / 14400 * canvas.height);
// console.log(this.goal.pos.x/14400*canvas.width,canvas.width)
}
}
drawWaypoints(ctx, theta){
//waypoints
for(let tag in this.waypoints){
if(tag == "death"){
ctx.strokeStyle = "#E44";
}else if(tag == "quick"){
ctx.strokeStyle = "#44E";
}else{
ctx.strokeStyle = "#fff";
}
if(this.waypoints[tag].x && this.waypoints[tag].y){
ctx.save();
ctx.translate(this.waypoints[tag].x, this.waypoints[tag].y);
ctx.rotate(theta);
ctx.globalAlpha = 0.6;
ctx.lineWidth = 8;
for(let i = 0;i < 4;i++){
//spinning thing
ctx.rotate(i * Math.PI / 2);
ctx.beginPath();
ctx.arc(0, 0, 50, 0, Math.PI / 4);
ctx.stroke();
}
//pulsing thing
ctx.lineWidth = 6;
ctx.globalAlpha = Math.min(0.4, 1 - Math.pow(Math.sin(theta / 2), 2) / 1.2);
ctx.beginPath();
ctx.arc(0, 0, 50 + Math.max(0, Math.tan(theta / 2)), 0, PI2);
ctx.stroke();
ctx.restore();
}
}
//goal
ctx.strokeStyle = "#4F4";
ctx.lineWidth = 10;
ctx.globalAlpha = 0.8;
if(this.goal.type == "xpos"){
ctx.beginPath();
ctx.moveTo(this.goal.pos.x, 0);
ctx.lineTo(this.goal.pos.x, 14400);
ctx.stroke();
}else if(this.goal.type == "ypos"){
ctx.beginPath();
ctx.moveTo(0, this.goal.pos.y);
ctx.lineTo(14400, this.goal.pos.y);
ctx.stroke();
}else if(this.goal.pos.x && this.goal.pos.y){
ctx.save();
ctx.translate(this.goal.pos.x, this.goal.pos.y);
ctx.beginPath();
ctx.arc(0, 0, 10, 0, PI2)
ctx.stroke();
ctx.beginPath();
ctx.rotate(theta / 3);
let r = Math.cos(theta) * 10;
for(let i = 0;i < 3;i++){
ctx.rotate(PI2 / 3);
ctx.moveTo(60 + r, 0);
ctx.lineTo(120 + r, -20);
ctx.lineTo(100 + r, 0);
ctx.lineTo(120 + r, 20);
ctx.closePath();
}
ctx.stroke();
ctx.restore();
}
}
setSelf(self){
this.self = self;
}
setSend(sender){
this.send = sender;
}
//ideas: https://github.com/cabaletta/baritone/blob/master/USAGE.md
/**Current Commands
* path
* stop
* goal
* <goal/goto> x [Number: x position]
* <goal/goto> y [Number: y position]
* <goal/goto> [x: Number] [y: Number]
* waypoint set [name: String]
* waypoint del [name: String]
* waypoint goto [name: String]
* follow player <[ID/Name: Any]/all(default)>
* follow animal <[ID/Name: Any]/all(default)>
* wander
**Planned Commands
* multigoal [wp1: String] ...
* find [id: Number]
* find [name: String] [owner(optional): Number]
*/
abort(){
this.goal.pathing = false;
}
updateChat(txt, ownerID){
//handle commands here
if(ownerID != this.self.sid){
return;
}
let args = txt.trimEnd().split(" ");
if(args[0] == "path"){
//start pathfinding(assuming there is a goal)
if(this.goal.type){
this.goal.pathing = true;
this.pathfinder.clearPath();
}
}else if(args[0] == "stop"){
if(this.goal.pathing){
this.goal.pathing = false;
this.pathfinder.clearPath();
ee.send("9", null, "client");
}
}else if(args[0] == "goal" || args[0] == "goto"){
//goal sets goal
//goto sets a path and starts walking towards it
if(isNaN(parseInt(args[1]))){
if(args[1] == "x"){
//get to a x position
//<goal/goto> x [Number: x position]
let pos = parseInt(args[2]);
if(pos >= 0 && pos <= 14400){
this.goal.pathing = args[0] == "goto";
this.goal.type = "xpos";
this.goal.pos.x = pos;
}
}else if(args[1] == "y"){
//get to a y position
//<goal/goto> y [Number: y position]
let pos = parseInt(args[2]);
if(pos >= 0 && pos <= 14400){
this.goal.pathing = args[0] == "goto";
this.goal.type = "ypos";
this.goal.pos.y = pos;
}
}else if(args[0] == "goal" && !args[1]){
this.goal.type = "pos";
this.goal.pos.x = this.self.x;
this.goal.pos.y = this.self.y;
}
}else{
//get to a x and y position
//<goal/goto> [x: Number] [y: Number]
let xPos = parseInt(args[1]);
let yPos = parseInt(args[2]);
if(xPos >= 0 && xPos <= 14400 && yPos >= 0 && yPos <= 14400){
this.goal.pathing = args[0] == "goto";
this.goal.type = "pos";
this.goal.pos.x = xPos;
this.goal.pos.y = yPos;
}
}
}else if(args[0] == "thisway" || args[0] == "project"){
//project my position x distance from my position
//thisway [distance: Number] [angle(optional): Number]
let amt = parseInt(args[1]);
let dir = parseFloat(args[2]) || this.self.dir;
if(!isNaN(amt) && this.self.x && this.self.y && this.self.dir){
this.goal.type = "pos";
this.goal.pos.x = Math.max(0, Math.min(14400, this.self.x + Math.cos(dir) * amt));
this.goal.pos.y = Math.max(0, Math.min(14400, this.self.y + Math.sin(dir) * amt));
}
}else if(args[0] == "follow" || args[0] == "flw"){
if(args[1] == "player" || args[1] == "ply"){
//follow player <[ID: Number]/all(default)>
this.goal.pathing = true;
this.goal.type = "player";
if(args[2]){
this.goal.entity = args.slice(2).join(" ");
}else{
this.goal.entity = -1;
}
}else if(args[1] == "team"){
//follow team
this.goal.pathing = true;
this.goal.type = "team";
}else if(args[1] == "animal"){
this.goal.pathing = true;
this.goal.type = "animal";
if(args[2]){
this.goal.entity = args[2];
}else{
this.goal.entity = -1;
}
}
}else if(args[0] == "find" || args[0] == "fnd"){
//finds a object: natural or placed
//find [id: Number]
//find [name: String] [owner(optional): Number]
}else if(args[0] == "waypoint" || args[0] == "wp"){
if(args[1] == "set"){
//waypoint set [name: String]
if(Boolean(args[2]) && !this.waypoints[args[2]]){
this.waypoints[args[2]] = {
x: this.self.x,
y: this.self.y,
}
}
}else if(args[1] == "del"){
//waypoint del [name: String]
delete this.waypoints[args[2]];
}else if(args[1] == "goto"){
//waypoint goto [name: String]
if(this.waypoints[args[2]]?.x && this.waypoints[args[2]]?.y){
this.goal.pathing = true;
this.goal.type = "pos";
this.goal.pos.x = this.waypoints[args[2]].x;
this.goal.pos.y = this.waypoints[args[2]].y;
}
}
}else if(args[0] == "wander" || args[0] == "wnd"){
this.goal.pathing = true;
this.goal.type = "wander";
this.goal.pos.x = Math.random() * 14400;
this.goal.pos.y = Math.random() * 14400;
}
}
//determines if we are nearing goal
reachedGoal(){
// const lastPoint = this.pathfinder.prevPath[this.pathfinder.prevPath.length - 1];
// console.log( Math.hypot(lastPoint.x - this.goal.pos.x, lastPoint.y - this.goal.pos.y) === 0)
if(this.goal.type == "xpos"){
return Math.abs(this.self.x - this.goal.pos.x) < this.pathfinder.estimatedSpeed;
}else if(this.goal.type == "ypos"){
return Math.abs(this.self.y - this.goal.pos.y) < this.pathfinder.estimatedSpeed;
}else if(this.goal.type == "pos" || this.goal.type == "wander"){
return Math.hypot(this.self.x - this.goal.pos.x, this.self.y - this.goal.pos.y) < this.pathfinder.estimatedSpeed;
}
}
async updatePlayers(players){
console.log(testeroo == E.skinIndex)
ticks++;
if(this.goal.pathing){
let finalGoal;
if(this.goal.type == "xpos"){
//go towards x position
finalGoal = [];
for(let i = -this.pathfinder.size; i <= this.pathfinder.size; i++){
finalGoal.push({
x: this.goal.pos.x,
y: this.self.y + i * this.pathfinder.res,
})
}
}else if(this.goal.type == "ypos"){
//go towards y position
finalGoal = [];
for(let i = -this.pathfinder.size; i <= this.pathfinder.size;i += 3){
finalGoal.push({
x: this.self.x + i * this.pathfinder.res,
y: this.goal.pos.y,
})
}
}else if(this.goal.type == "pos" || this.goal.type == "wander"){
//simple go towards position
finalGoal = {
x: this.goal.pos.x,
y: this.goal.pos.y,
};
}else if(this.goal.type == "player"){
//do pathfinding for following player
if(this.goal.entity === -1){
finalGoal = [];
for(let player of players){
if(player.visible && player.sid != this.self.sid){
finalGoal.push(player)
}
}
if(!finalGoal.length){
finalGoal = null;
}
}else{
for(let player of players){
if(player.visible && player.sid != this.self.sid && (player.sid == this.goal.entity || player.name == this.goal.entity)){
finalGoal = player;
break;
}
}
}
}else if(this.goal.type == "team"){
//follow teammates
finalGoal = [];
for(let player of players){
if(player.team == this.self.team && player.sid != this.self.sid){
finalGoal.push(player)
}
}
if(!finalGoal.length || !this.self.team){
finalGoal = null;
}
}
if(finalGoal && ! pushing){
if(this.reachedGoal()){
if(this.goal.type == "wander"){
this.goal.pos.x = Math.random() * 14400;
this.goal.pos.y = Math.random() * 14400;
}else{
this.goal.pathing = false;
}
this.pathfinder.clearPath();
ee.send("9", undefined,"pathfinder");
}else{
let path = await Pathfinder.pathTo(finalGoal);
if(path){
ee.send("9", path.ang,"pathfinder");
}else{
ee.send("9", undefined,"pathfinder");
}
}
}
this.finalGoal = finalGoal
}
}
async updateAnimals(animals){
if(this.goal.type == "animal" && this.goal.pathing){
let finalGoal;
if(this.goal.entity === -1){
finalGoal = [];
for(let animal of animals){
if(animal.visible && animal.sid != this.self.sid){
finalGoal.push(animal)
}
}
if(!finalGoal.length){
finalGoal = null;
}
}else{
for(let animal of animals){
if(animal.visible && (animal.sid == this.goal.entity || animal.name == this.goal.entity)){
finalGoal = animal;
break;
}
}
}
if(this.reachedGoal()){
this.pathfinder.clearPath();
this.goal.pathing = false;
ee.send("9", undefined, "client");
}else if(finalGoal){
let path = await this.pathfinder.pathTo(finalGoal);
if(path){
ee.send("9", path.ang,"pathfinder");
}else{
ee.send("9", undefined,"pathfinder");
}
}
this.finalGoal = finalGoal
}
}
async addBuilding(obj){
await new Promise((resolve) => {
let id = setInterval(() => {
if(!this.pathfinder.resolve){
resolve();
clearInterval(id);
}
})
})
let path = this.pathfinder.getPath();
let dist = path?.dist + this.pathfinder.estimatedSpeed / this.pathfinder.res + 3;
dist = Math.min(this.pathfinder.prevPath.length - 1, Math.trunc(dist));
if(dist&&!pushing){
for(let i = dist; i >= 0; i--){
let point = this.pathfinder.prevPath[i];
if(Math.hypot(point.x - obj.x, point.y - obj.y) < obj.pathScale){
this.pathfinder.prevPath = this.pathfinder.prevPath.slice(i);
let ez = await this.pathfinder.pathTo(this.finalGoal,true)
ez&&ee.send("9",ez.ang,"pathfinder")
break;
}
}
}
}
}
Tach = new Tachyon(Pathfinder);
function hslToRgb(h, s, l) {
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [round(r * 255), round(g * 255), round(b * 255)];
}
async function antiOneTicks(){
if(antiOneTick) {
Hg(6,11);
await nextTick()
await nextTick()
await nextTick()
antiOneTick = false
}
}
function botMovement(){
if(cBots.checked && !clearXY){
const dAng = (ang1, ang2) => ((d) => (d > PI) ? PI2 - d : d)(abs(ang1 - ang2) % PI2);
//2 * Math.PI * botSockets.length/RADIUS;
const dist = (point, target) => sqrt(((target.x2 ?? target.x) - (point.x2 ?? point.x)) ** 2 + ((target.y2 ?? target.y) - (point.y2 ?? point.y)) ** 2);
const count = modBots.filter((e) => dist(E,e)<=RADIUS+80 && !((Qsync || keys.q) && dist(E,e) < 900 && e.sr === 1&& bSync.checked) && !e.inTrap && (e.millCount ===299||e.upgraded>=7));
const avgSpd = count.reduce((sum, bot) => {
const botSpeedMult = speedMult(bot);
return sum + botSpeedMult;
}, 0) / count.length;
let incrementer = !isNaN(PI2*count.length*avgSpd/RADIUS) ?(PI2*count.length*avgSpd/RADIUS) : 0
XDD += xdIncrement;
const angles = Array.from({ length: count.length }, (_, i) => XDD+ (PI2 * i) / count.length);
const positions = angles.map(angle => ({
x: E.x2 + RADIUS * cos(angle),
y: E.y2 + RADIUS * sin(angle)
}));
count.forEach((e,t) =>{
e.emit("9", getDir(e,positions[t]))
e.emit("D", getDir(E,e))
e.bh(1)
})
const increment = PI2 / count.length;
modBots.forEach((e,t) =>{
let distance = dist(E,e), dir = getDir(e,E)
if(distance>RADIUS+80 && !e.inTrap && (e.millCount === 299||e.upgraded >= 7)){
e.bh();
e.emit("9", dir)
e.emit("D", dir)
e.emit("F", 1,dir)
e.emit("F", 0,dir)
}
})
}
}
function botClear(){
if(!modBots.length||!clearXY){
clearXY = null
clearing = null
return
};
clearing = et.filter(x => {
const g = clearXY.r ? dist(clearXY, x) >= clearXY.value : dist(clearXY, x) <= clearXY.value
// if(g) x.opacity = .15;
if (g &&(clearXY.types!= 'all' &&(x.group?.name === 'spikes' || x.name === 'pit trap' || x?.name == 'turret' && botBreakUtil.checked || x?.name == 'teleporter' && botBreakUtil.checked)||clearXY.types == 'all'||x?.name == clearXY.types ||x?.group?.name == clearXY.types) &&(x.type === null || x.type === undefined)) {
if((clearXY.IDS == "team" || clearXY.IDS == "clan") && clan(x?.owner?.sid)){
x.opacity = .15
return true
};
if((clearXY.IDS == "enemy"||clearXY.IDS == "enemies"||clearXY.IDS == "hostile"||clearXY.IDS == "nEnemy") && !clan(x?.owner?.sid)){
x.opacity = .15
return true
};
if(typeof clearXY.IDS === "number" && x?.owner?.sid === clearXY.IDS){
x.opacity = .15
return true
};
if(clearXY.IDS == "all"||clearXY.IDS == "every"||clearXY.IDS =="everything"){
x.opacity = .15
return true
};
if(!clearXY.IDS && x?.owner?.sid === E.sid){
x.opacity = .15
return true
};
}
return false;
});
if(!clearing?.length){
clearXY = null
clearing = null
Hn.showText(E.x2, E.y2, 25, .35, 1500, 'cleared buildings',"#fff")
/* et.forEach(e=>{
if(e.name == "pit trap"){
e.opacity = .7
} else{
e.opacity = 1;
}
})*/
}
}
function fastwep(XD,wep){
// packet spam is going here thats why, because we don't have secondary just yet
if(!fastWep.checked || oneTickToggle) return
if(meleesyncing) {
ee.send("z", primary, true)
return;
}
wep = (R.weapons[primary]?.spdMult >= R.weapons[secondary]?.spdMult) || secondary == null ? wep = primary : wep = secondary
//wep = R.weapons[primary]?.spdMult >= R.weapons[secondary]?.spdMult ? wep = primary : wep = secondary
//console.log(wep);
if(XD && E.buildIndex !=-1) return wep
if(instaing || breaking || oneTick || hold || autobreakBuild|| E.pr!=1 || E.sr !=1||E.hitting||bowInstaing||autohit||E.buildIndex!=-1) return;
if(E.weaponIndex!= wep) ee.send("z", wep, true)
if(XD) return wep;
}
function bestLoadout() {
return calcVel(E,0, {
buildIndex: -1,
weaponIndex: E.weaponIndex,
skinIndex: E.skinIndex,
tailIndex: E.tailIndex,
y2: E.y2,
zIndex: null
})
}
allWeapons = R.weapons
var xdIncrement = .2;
var RADIUS = 300;
let XDD = 0;
const decayRate = pow(0.993, 111);
const threshold = .5//.45;//.5;
function getDecelDist(x,t){
if(isNaN(x)||x==Infinity) return null;
let value = x;
while (value >= .5) {
value = value * decayRate;
x += value;
}
return x
}
function doLoadout(wep,skinIndex,tailIndex,buildIndex){
return {
buildIndex: !buildIndex ? -1 : buildIndex,
weaponIndex: wep,
skinIndex: skinIndex,
tailIndex: tailIndex,
y: E.y2,
zIndex: null
}
}
// Set up initial variables
const spinDuration = 1000; // Duration of the spin effect in milliseconds
const initialSpinSpeed = Math.PI; // Initial spin speed in radians per millisecond
const spinAcceleration = (2 * Math.PI) / spinDuration; // Spin acceleration rate
function renderFake(e){
function isMaxExpire(newExpire, existingExpire) {
return typeof newExpire === 'number' && (newExpire > existingExpire || existingExpire === undefined);
}
const sidMap = new Map();
fakePlayers.forEach(player => {
if (player.sid) {
const existingPlayer = sidMap.get(player.sid);
// Check if the current player has a higher expire value or if there is no existing player for the sid
if (!existingPlayer || isMaxExpire(player.expire, existingPlayer.expire)) {
sidMap.set(player.sid, { ...player });
}
}
});
fakePlayers = Array.from(sidMap.values());
fakePlayers.forEach(XD => {
if(XD.deathAnim === true){
let coords = calcPoint(XD.x,XD.y,XD.originDir,XD.dstSpd)
XD.t1 = void 0 === XD.t2 ? Date.now() : XD.t2;
XD.t2 = Date.now()
XD.distance-=XD.dstSpd
XD.dt = 0
XD.d1 = XD.d2// += .1
// XD.d2 +=.3//XD.spinSpd
// console.log(XD.spinSpd)
//console.log(XD.decay)
// !isNaN(XD.expire) && XD.expire--;
XD.spinSpd ? (XD.d2+= XD.spinSpd) : (XD.d2 = E.d2)//toRad(40)
XD.x1 = XD.x
XD.y1 = XD.y
XD.x2 = coords.x
XD.y2 = coords.y
if(XD.tick === tick+1&&XD.dstSpd === 0){
// console.log(tick-XD.tick)
Hn.showText(E.x2, E.y2, 50, .1, 500, round((dist({x:XD.positions.accel.x,y:XD.positions.accel.y},E)-0)*100)/100, "#fff",true)
}
}else if(!isNaN(XD.expire)){
// let coords = calcPoint(XD.x,XD.y,XD.originDir,XD.dstSpd)
XD.t1 = void 0 === XD.t2 ? Date.now() : XD.t2;
XD.t2 = Date.now()
XD.distance-=XD.dstSpd
XD.dt = 0
XD.d1 = XD.d2
XD.expire-=1
XD.x1 = XD.x
XD.y1 = XD.y
XD.x2 = XD.NEWX
XD.y2 = XD.NEWY
}
})
for(let ez = 0; ez < fakePlayers.length; ez++){
e = fakePlayers[ez]
if(!e.deathAnim) continue;
if(e.distance<=0|| e.tick<tick+1&&e.dstSpd ===0 || e.vals === 0)fakePlayers.splice(ez,1);
}
fakePlayers = fakePlayers.filter(x => (x.expire >=0 || x.expire === undefined))
//fakePlayers = fakePlayers.filter(e => e.distance < 0 || e.tick <= tick && e.dstSpd === 0);
}
var lastVisualTime = 0;
function createSpikeKB(_, dstSpd, dir) {
if (!kbVisual || (Date.now() - lastVisualTime) < 730) return;
var fakePlayer = { ..._ };
fakePlayer.vals = 0.5;
fakePlayer.expire = 3;
fakePlayer.decay = 0;
fakePlayer.distance = dstSpd;
fakePlayer.fake = true;
fakePlayer.dstSpd = dstSpd;
fakePlayer.orginDir = dir;
fakePlayers.push(fakePlayer);
lastVisualTime = Date.now();
}
function createDeathAnim(_,dstSpd,spinSpd, skin,tail,decay,xtick,predict){
var fakePlayer = {..._}
fakePlayer.skinIndex = skin
fakePlayer.tailIndex = tail;
fakePlayer.vals = .8
fakePlayer.deathAnim = true;
fakePlayer.spinSpd = spinSpd || 0
fakePlayer.decay = decay || 0
fakePlayer.distance = 3000;
fakePlayer.fake = true;
fakePlayer.dstSpd = dstSpd
fakePlayer.tick = tick+xtick+1;
fakePlayer.positions = predict;
fakePlayer.originDir = _.sid === E.sid ? Math.random() * 1000 : getDir(E,_)
fakePlayers.push(fakePlayer);
}
function createPlayerInfo(player, x, y, skin, tail, wep){
var info = {...player}
// info.sid = 10000
info.x1 = x
info.y1 = y
info.x2 = x
info.y2 = y
info.showSID = true;
info.skinIndex = skin || 0
info.tailIndex = tail || 0
info.weaponIndex = wep || 0
console.log(info)
return info
}
function createFakePlayer(player, purpose, move, spin){
var fakePlayer = {...player}
fakePlayer.purpose = purpose
fakePlayer.moving = move
fakePlayer.spinning = spin
fakePlayers.push(fakePlayer)
}
async function doSpy(){
// await wait(10)//()//wait(10)
if(!spyIndex.do||!modBots.length||!modBots[spyIndex?.val]) return;
let obj3 = modBots[spyIndex.val]
let isVis = findPlayerSID(obj3.sid)
if(Date.now() - obj3.spawnTime<300) return;
const isDuplicate = (obj, array) => array.some(item => item.sid === obj.sid);
const isDuplicate2 = (player, array) => array.some(item => item.visible && player.visible && item.sid===player.sid&&item.sid!=obj3.sid||player.sid==obj3.sid&&item.sid===obj3.sid&&item.visible);
const builds = obj3.builds.filter(obj => !isDuplicate(obj, renderObjects));
const players = obj3.players.filter(obj => !isDuplicate2(obj, J));
spyBot = {players:players,bot:isVis?.visible?isVis:obj3.findPlayer(obj3.sid),builds:builds}
}
async function doSpectate() {
if(specID == E.sid) {
serverconnected&&sendWS.checked&&socketer.send(JSONStringify({msg:"spectateData", sender: E?.sid, player: E, players: J, builds: et, time:time,server:location.href}))
}
if(!spectator.isDoing) {
spectator.rPlayer = null;
spectator.players = [];
spectator.builds = [];
} else {
spectator.rBuilds = spectator?.builds.filter(obj => !isDupe(obj, renderObjects));
spectator.rPlayer = spectator?.player
spectator.rPlayers = spectator?.players;
}
}
/*function kbSpikes(target,angle, dist,z,x,y) {
let current = {x: Infinity, y: Infinity, fake: true}
// z=renderObjects.concat(W,Y)
z = nearObjects.filter(e => e?.group?.name == 'spikes'&& (clan(e?.owner?.sid)||target?.team === null&&e?.owner?.sid!=target.sid))
for(let i in z) {
let obj = z[i];
// if(!obj.ignoreCollision) {
let dist1 = getDistance(target.x2, target.y2, obj.x, obj.y);
let point1 = calcPoint(target.x2, target.y2, angle, dist1);
let dist2 = getDistance(point1.x, point1.y, obj.x, obj.y);
if(dist2 < obj.scale && dist1 - obj.scale-35 < dist) {
let p = calcPoint(x, y, angle, dist1 - obj.scale-35);
if(getDistance(current.x, current.y, target.x2, target.y2) > getDistance(p.x, p.y, target.x2, target.y2)) {
current = p;
// console.log('can do')
}
}
//}
}
if(current.fake) {
return false;
} else {
return current;
}
}*/
function checkKB(target, angle, distance, vel,insta, z, x, y, scale) {
let current = {x: Infinity, y: Infinity, fake: true}
z = nearObjects.filter(e => e?.group?.name == 'spikes'&& (target.sid != E.sid ? (clan(e?.owner?.sid)||target?.team === null&&e?.owner?.sid!=target.sid): !clan(e?.owner?.sid))||(e?.type == 1 && e.y >= 12000))
if(!z) return false
if(vel){
x = target.np.real.x
y = target.np.real.y
} else{
x = target.x2
y = target.y2;
}
for(let i in z) {
let obj = z[i];
scale = obj.type === 1 ? scale = obj.scale*.55 +35: obj.scale +35
let dist1 = dist(target,obj)//getDistance(nEnemy.x2, nEnemy.y2, obj.x, obj.y);
let point1 = calcPoint(x, y, angle, dist1);
let dist2 = dist(point1,obj)//getDistance(point1.x, point1.y, obj.x, obj.y);
if(dist2 < (scale) && dist1 - (scale) < distance&&(insta&&obj.dmg>=35||obj.type===1||!insta)) {
let p00 = calcPoint(x, y, angle, dist1 - (scale));
return {x:p00.x, y: p00.y, obj: obj};
}
}
return false;
}
function checkKBTrap(target, angle, distance, vel,insta, z, x, y, scale) {
let current = {x: Infinity, y: Infinity, fake: true}
z = nearObjects.filter(e => e.name == 'pit trap'&& (target.sid != E.sid ? (clan(e?.owner?.sid)||target?.team === null&&e?.owner?.sid!=target.sid): !clan(e?.owner?.sid)))
if(!z) return false
if(vel){
x = target.np.real.x
y = target.np.real.y
} else{
x = target.x2
y = target.y2;
}
for(let i in z) {
let obj = z[i];
scale = obj.scale + 35//obj.type === 1 ? scale = obj.scale*.55 +35: obj.scale +35
let dist1 = dist(target,obj)//getDistance(nEnemy.x2, nEnemy.y2, obj.x, obj.y);
let point1 = calcPoint(x, y, angle, dist1);
let dist2 = dist(point1,obj)//getDistance(point1.x, point1.y, obj.x, obj.y);
if(dist2 < (scale) && dist1 - (scale) < distance) {
let p00 = calcPoint(x, y, angle, dist1 - (scale));
return {x:p00.x, y: p00.y, obj: obj};
}
}
return false;
}
let moveTicks = 0;
let didStop = {time:Date.now(),type:null}//Date.now();;
var stopHit = 0;
function runInto(player, angle, vel,MAX, z, scale) {
// console.log('ez')
if(!amAlive) return;
z = nearObjects.filter(e => e?.group?.name == 'spikes' && (!clan(e?.owner?.sid)) || (e?.type == 1 && e.y >= 12000)||e.name == "teleporter").sort((a,b)=>fastHypot(player.x2-a.x,player.y2-a.y)-fastHypot(player.x2-b.x,player.y2-a.y));
if (!z.length) return false;
for (let i = 0, obj; i < z.length; i++) {
scale = (obj = z[i]).type === 1 ? obj.scale * 0.6 + 35: obj.teleport ? obj.scale * .75 + 35 : obj.scale + 35;
let decelVels = [getDecelDist(vel.vel), getDecelDist(player.movSpd)];
let closestPoints = [calcPoint(player.x2, player.y2, angle, decelVels[0]), calcPoint(player.x2, player.y2, angle, decelVels[1])];
let isIntersecting = (dist(closestPoints[0], obj) <= scale || dist(closestPoints[1], obj) <= scale);
isNaN(MAX) === true && (MAX = 0);
let ranger = secondary === 10 ? 75 : R.weapons[primary].range;
let dists = [dist(player,obj,"object")<=ranger, dist(player.np.decel,obj,"object")<=ranger]
let canBreak = stopBreak.checked && (dists[0] || dists[1]) && isIntersecting && obj.type !== 1;
let conditions = (isIntersecting || ((dists[0] || dists[1]) && isIntersecting && obj.type !== 1));
if (conditions) {
let aimer;
if(canBreak){
aimer = bestAim(obj,secondary===10?75:R.weapons[primary].range,z);
}
if(!keys.ShiftLeft){
//ee.send("e");
ee.send("9", undefined);
if(Date.now()-didStop.time >= 250 && didStop.type == "static" || didStop.type != 'static')Hn.showText(player.x2, player.y2, 30, .1, 500, "stop", "#fff",true),didStop = {time:Date.now(),type:'static'}//Date.now();
if(canBreak&&(secondary===10&&player.sr===1||player.pr===1&&secondary!=10&&primary!=8)){
//ee.send("z",secondary===10?10:primary,true)
hold = secondary===10?10:primary
breaker = true;
stopHit = tick;
aim[0] = aimer;
breakBuild(aimer, secondary === 10 ? secondary : primary, secondary === 10 ? E.secondaryVar : E.primaryVar, bH.includes(40) && !E.dmgpot.soldier ? 40 : 6, 1);
visAim = true;
if(lastHat!=40)Hg(E.dmgpot.soldier ? 6 : 40 ,11);
nHat = E.dmgpot.soldier ? 6 : 40;
}
} else if(Date.now()-didStop.time >= 250 && didStop.type == 'override' || didStop.type != 'override')Hn.showText(player.x2, player.y2, 20, .22, 500, "override", "#fff"),didStop = {time:Date.now(),type:'override'}//Date.now();
return obj;
}
}
return false;
}
function lineIntersectsCircle(lineStart, lineEnd, circleCenter, circleRadius) {
const dx = lineEnd[0] - lineStart[0];
const dy = lineEnd[1] - lineStart[1];
const lineLengthSquared = dx * dx + dy * dy;
if (lineLengthSquared === 0) {
// Line is just a point, check if it's inside the circle
const distanceSquared = (lineStart[0] - circleCenter[0]) ** 2 + (lineStart[1] - circleCenter[1]) ** 2;
return distanceSquared <= circleRadius ** 2;
}
const t = max(0, min(1, ((circleCenter[0] - lineStart[0]) * dx + (circleCenter[1] - lineStart[1]) * dy) / lineLengthSquared));
const projectionX = lineStart[0] + t * dx;
const projectionY = lineStart[1] + t * dy;
const distanceSquared = (projectionX - circleCenter[0]) ** 2 + (projectionY - circleCenter[1]) ** 2;
return distanceSquared <= circleRadius ** 2;
}
function runIntoBot(player, angle, z, scale) {
// console.log('ez')
if(player.inTrap|| !sWalk.checked) return;
z = player.builds.filter(e =>(e?.group?.name == 'spikes' && !player.teamer(e?.owner?.sid))||e.name == "teleporter").sort((a,b)=>fastHypot(player.x2-a.x,player.y2-a.y)-fastHypot(player.x2-b.x,player.y2-a.y));
player.np = calcVel(player,angle,player,1);
if (!z.length) return false;
for (let i = 0; i < z.length; i++) {
let obj = z[i];
scale = obj.type === 1 ? obj.scale * 0.6: obj.teleport ? obj.scale * .8 : obj.scale;
scale += 35
let decelVel = getDecelDist(player.np.vel);
let closestPoint = calcPoint(player.x2, player.y2, angle, min(scale, decelVel));
let isIntersecting = dist(closestPoint, obj) <= scale;
let ranger = player.weapons[1] === 10 ? R.weapons[10].range: R.weapons[player.weapons[0]].range
let canBreak = sBreak.checked&& (isIntersecting||(player.tick-player.stopHit<=3&&(dist(player,obj,"object")<=ranger||dist(player.np.decel,obj,"object")<=ranger)&&obj.type!==1&&player.skinIndex===40)) ? true : false
if(canBreak){
player.emit('9', null)
player.break(obj)
player.stopHit = player.tick
}
if(isIntersecting)return {obj:obj, break:canBreak};
}
return false;
}
function runInto3(overrideDir,virtualPos,_){
let hatSpeed = (function(e){for(let i=0;i<Xt.length;i++)if(e==Xt[i].id){return Xt[i].spdMult}})(lastHat) || 1;
let accSpeed = (function(e){for(let i=0;i<Gt.length;i++)if(e==Gt[i].id){return Gt[i].spdMult}})(lastTail) || 1;
let wepSpeed = R.weapons[E.weapons[E.weaponIndex] || E.weapons[0]].spdMult || 1;
mySpeed = DefaultSpeed * wepSpeed * hatSpeed * accSpeed * (E.y2 < T.snowBiomeTop && lastHat != 15 ? T.snowSpeed : 1);
if(moveDirection !== undefined){
virtualPos = {x2:E.x2 + mySpeed * cos(moveDirection) + (E.x2 - E.x1) / 100, y2:E.y2 + mySpeed * sin(moveDirection) + (E.y2 - E.y1) / 100}
for(let i = 0;i < nearObjects.length;i++){
_ = nearObjects[i];
if(dist(R,_) > mySpeed + 100){
break;
}
if(_?.group?.name == "spikes" && !clan(_.owner.sid)||_.type === 1 &&_.y >= 12000){
let d = objDist(_, virtualPos);
if(objDist(_, virtualPos) < _.scale + 40){
overrideDir = null;
ee.send('9',overrideDir)
return true;
break;
}
}
}
}
if(moveDirection === undefined){
virtualPos = {x2:E.x2 + mySpeed * cos(moveDirection) + (E.x2 - E.x1) / 90, y2:E.y2 + mySpeed * sin(moveDirection) + (E.y2 - E.y1) / 90}
for(let i = 0;i < nearObjects.length;i++){
_ = nearObjects[i];
if(dist(R,_) > mySpeed + 100){
break;
}
if(_?.group?.name == "spikes" && !clan(_.owner.sid)||_.type === 1 &&_.y >= 12000){
let d = objDist(_, virtualPos);
if(objDist(_, virtualPos) < _.scale + 40){
if(objDist(nEnemy, E) > R.weapons[E.weapons[E.weapons[1] == 10 ? 1 : 0]].range + 200 && E.skins[40]){
let tempSpeed = mySpeed * 0.3 / hatSpeed;
virtualPos = {x2:E.x2 + tempSpeed * cos(moveDirection) + (E.x2 - E.x1) / 90, y2:E.y2 + tempSpeed * sin(moveDirection) + (E.y2 - E.y1) / 90}
if(objDist(_, virtualPos) > _.scale + 60){
}else{
overrideDir = null;
ee.send('9',overrideDir)
return true;
}
}else{
overrideDir = null;
ee.send('9',overrideDir)
return true;
}
break;
}
}
}
}
return false
}
function projPath(x, y, angle, dist,z) {
let current = {x: Infinity, y: Infinity, fake: true}
z=renderObjects.concat(J,ye)
for(let i in z) {
let obj = z[i];
if(!obj.ignoreCollision) {
let dist1 = getDistance(x, y, obj.x, obj.y);
let point1 = calcPoint(x, y, angle, dist1);
let dist2 = getDistance(point1.x, point1.y, obj.x, obj.y);
if(dist2 < obj.scale && dist1 - obj.scale < dist) {
let p = calcPoint(x, y, angle, dist1 - obj.scale);
if(getDistance(current.x, current.y, E.x, E.y) > getDistance(p.x, p.y, E.x, E.y)) {
current = p;
}
}
}
}
if(current.fake) {
return false;
} else {
return current;
}
}
function calcPoint(x, y, angle, dist) {
if(angle==undefined) {return {x:E.x,y:E.y}} else{
x = x + dist * cos(angle);
y = y + dist * sin(angle);
return {x: x, y: y};
}
}
function projCollision(x, y , angle, dist){
let p3 = dist(E,{x:x,y:y});
let p = calcPoint(x, y, angle, dist);
let p2 = dist(E,p)
if(p2 < 35 && p3 - 35 < dist) {
let p4 = calcPoint(x, y, angle, p3 - 35);
return true;
} else {
return false;
}
}
function isPointWithinRange(center, point, radius) {
return point <= center + radius / 2 && point >= center - radius / 2 || (center >= 0 ? center + radius / 2 > 3.14 && point <= -3.14 + (center + radius / 2 - 3.14) : center - radius / 2 < -3.14 && point >= 3.14 + (center - radius / 2 + 3.14));
}
function Gd(a, b) {
return Math.atan2(b.y - a.y, b.x - a.x);
}
class resolveHit{
constructor(dir, building){
this.dir = dir;
this.building = building;
this.building.players = [];
let $this = this;
new Promise(function(resolve, reject){
$this.resolve = resolve;
setTimeout(function(){
reject();
},111)
}).then(function(e){
/*if($this.building.group!=undefined && $this.building.name!="sapling"&&$this.building.name!="mine"){
}
if($this.building.owner==null || $this.building.name=="sapling"||$this.building.name=="mine"){
}*/
$this.building.health -= e
$this.remove();
}).catch(function(){
$this.remove();
})
}
remove(){
for(let i = 0;i < hitList.length;i++){
if(hitList[i] == this){
hitList.splice(i, 1);
break;
}
}
}
attemptResolve(player, hat, tick, proj, isBoss){
if(proj && this.building.sid == proj.building.sid && tick === this.building.tick){
this.resolve(this.building.projDmg ? proj.dmg : 0)
} else if(isBoss && !proj && tick === this.building.tick) {
// moostafa hit
//let dir2 = atan2(this.building.y - isBoss.y2, this.building.x - isBoss.x2);
//let thisDir = getDir(isBoss, this.building);
//if((round(dir2 * 10) / 10 == this.dir || dAng(round(dir2 * 10) / 10, this.dir) <= .1005) && dist(isBoss, this.building, "object") <= (210) && C.getAngleDist(thisDir, isBoss.d2) <= gatherAng) {
this.resolve(200);
if(allVisuals.checked) Hn.showText(this.building.x, this.building.y, 20, .085, 350, 200,"#00aaff")
//}
} else if(!proj && this.building.owner!=null&&this.building.name!="mine"&&this.building.name!="sapling"){
let dir2 = atan2(this.building.y - player.y2, this.building.x - player.x2);
let thisDir = getDir(player,this.building);
let dst = Math.hypot(player.x2 - this.building.x, player.y2 - this.building.y);
let prj = {
x: player.x2 + Math.cos(player.d2) * 35 * (dst > this.building.scale),
y: player.y2 + Math.sin(player.d2) * 35 * (dst > this.building.scale)
};
//console.log(dst, prj, isPointWithinRange(player.d2, Gd(prj, this.building), 3.14));
// maybe remove dAng(round(dir2 * 10) / 10, this.dir) <= .1005
if((round(dir2 * 10) / 10 == this.dir || dAng(round(dir2 * 10) / 10, this.dir) <= .1005) /*&& isPointWithinRange(player.d2, Gd(prj, this.building), 3.14)*/ && tick == this.building.tick &&
dist(player, this.building, "object") <= (R.weapons[player.weaponIndex].range) && C.getAngleDist(thisDir, player.d2) <= gatherAng &&
!this.building.players.includes(player.sid)){
this.resolve(Variants[player.weaponVariant] * (hat == 40 ? 3.3 : 1) * (R.weapons[player.weaponIndex].dmg) * (player.weaponIndex == 10 ? 7.5 : 1))
this.building.players.push(player.sid)
if(!botIDS.includes(player.sid) && allVisuals.checked)Hn.showText(this.building.x, this.building.y, 20, .085, 350, round(Variants[player.weaponVariant] * (hat == 40 ? 3.3 : 1) * (R.weapons[player.weaponIndex].dmg) * (player.weaponIndex == 10 ? 7.5 : 1)),"#00aaff")
}
}
}
}/*(Math.round(dir2*10)/10==this.dir || dAng(Math.round(dir2*10)/10,this.dir)<=.1005)&&*/
function inRender(e,t){
// return <= T.maxScreenWidth / 2 * 1.3 && m <= T.maxScreenHeight / 2 * 1.3
let height = abs((e.x2||e.x)-(t.x2||t.x))
let width = abs((e.y2||e.y)-(t.y2||t.y))
if(height<=T.maxScreenWidth / 2 * 1.3 && width<=T.maxScreenHeight / 2 * 1.3){
return true;
}
return false;
}
const workerScript = "(" + (() => {
const { sqrt, abs, floor } = Math;
const { MAX_VALUE } = Number;
const sqrt2 = sqrt(2);
const mapSize = 900;
const intervalSize = 12;
const interval = intervalSize / 2;
const cleanMap = JSON.stringify(new Array(Math.round(mapSize / intervalSize)).fill([]));
const length = JSON.parse(cleanMap).length;
const points = [0, -1, 0, 1, -1, 0, 1, 0, 1, 1, 1, -1, -1, 1, -1, -1];
const pointsLength = points.length;
const colArray = ["boost pad", "teleporter"];
function calculateDistance(x1, y1, x2, y2) {
return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);
}
function calculateCost(x1, y1, x2, y2) {
const dx = abs(x1 - x2);
const dy = abs(y1 - y2);
return ((dx === 0) + (dy === 0)) * intervalSize + (dx !== 0 && dy !== 0) * intervalSize * sqrt2;
}
function generateMap(x, y, buildings, tx, ty) {
let map = JSON.parse(cleanMap),
targetNode = 0,
startNode = 0;
for (let i = 0; i < length; i++) {
let row = map[i];
for (let i2 = 0; i2 < length; i2++) {
let obj = (row[i2] = {
x: i * intervalSize - mapSize / 2 + x,
y: i2 * intervalSize - mapSize / 2 + y,
obstacle: false,
available: 1,
n: i * length + i2,
});
if (
obj.x < 0 ||
obj.x > 14400 ||
obj.y < 0 ||
obj.y > 14400
) {
obj.obstacle = 1;
continue;
}
for (let e = buildings.length, tmp; e--, (tmp = buildings[e]); ) {
if (
(obj.obstacle =
abs(tmp.x - obj.x) <= tmp.scale2 + 20 &&
abs(tmp.y - obj.y) <= tmp.scale2 + 20 &&
sqrt((tmp.x - obj.x) ** 2 + (tmp.y - obj.y) ** 2) -
tmp.scale2 -
20 <=
0)
)
break;
}
obj.target = abs(obj.x - tx) <= interval && abs(obj.y - ty) <= interval;
targetNode = obj.target * obj.n + !obj.target * targetNode;
obj.start = abs(obj.x - x) <= interval && abs(obj.y - y) <= interval;
startNode = obj.start * obj.n + !obj.start * startNode;
obj.fCost = obj.start * -MAX_VALUE;
obj.gCost = !obj.start * MAX_VALUE;
// obj.hCost = calculateDistance(obj.x, obj.y, tx, ty);
if (obj.target + obj.start > 0) continue;
}
}
return { map: map, targetNode: targetNode, startNode: startNode };
}
onmessage = function (message) {
let { player, target, buildings, clan, } = message.data;
if (calculateDistance(player.x2, player.y2, target.x, target.y) <= 0)
return postMessage("reached target");
let { map, startNode, targetNode } = generateMap(
player.x2,
player.y2,
buildings.filter((building) => {
building.scale2 =
(building.owner == null || building.name == "sapling") && building.type === 0
? building.scale * 0.7
: building.dmg &&
!clan.includes(building?.owner?.sid) &&
building?.owner?.sid != player.sid
? building.scale + 40
: building.type===1&&building.y<12000&&(building.teleport||building.boostSpeed)? building.scale+35:building.do?building.scale:building.scale-10;
return (
(building.ignoreCollision
? building.name === "pit trap"
? building?.owner?.sid != player.sid && !(clan.includes(building.owner?.sid))
: building.name === "boost pad" || building.name === "teleporter"
: true) &&
calculateDistance(building.x, building.y, player.x2, player.y2) < mapSize
);
}),
target.x,
target.y
);
let openNodes = [],
closedNodes = [],
currentNode,
maxIterations = 100000;
openNodes.push(startNode);
while (openNodes.length * maxIterations--) {
let lowest = Infinity,
index;
for (let i = openNodes.length, tmp; i--; ) {
tmp = map[floor(openNodes[i] / length)][openNodes[i] % length];
if (tmp.fCost < lowest) {
currentNode = tmp;
lowest = tmp.fCost;
index = i;
}
}
openNodes.splice(index, 1);
closedNodes.push(currentNode.n);
if (currentNode.target) break;
for (let i = 0, module; i < pointsLength; i++) {
module = map[floor(currentNode.n / length) + points[i]]?.[currentNode.n % length + points[i + 1]];
if (!module || closedNodes.includes(module.n)) continue;
let gCost = currentNode.gCost + calculateCost(points[i], points[i + 1], 0, 0);
if (!module.obstacle && module.available === 1) {
if (!openNodes.includes(module.n)) {
module.parent = currentNode.n;
module.gCost = gCost;
module.hCost = calculateDistance(module.x, module.y, target.x, target.y);
module.fCost = gCost + module.hCost;
openNodes.push(module.n);
} else if (gCost < module.gCost) {
module.parent = currentNode.n;
module.gCost = gCost;
module.fCost = gCost + module.hCost;
}
}
}
}
if (maxIterations === 0) return postMessage("reached max iterations");
if (!openNodes.length) return postMessage("couldn't reach target");
openNodes = [];
while (!currentNode.start) {
openNodes.push(currentNode.y, currentNode.x);
currentNode = map[floor(currentNode.parent / length)][currentNode.parent % length];
}
postMessage(openNodes.reverse());
};
}).toString() + ")();";
var workers = [];
var available = [];
function pathfind(info) {
return new Promise((resolve, reject) => {
info = JSON.parse(JSONStringify(info));
let workerIndex = -1;
for (let i = 0; i < available.length; i++) {
if (available[i]) {
workerIndex = i;
available[i] = false;
workers[i].postMessage(info);
break;
}
}
if (workerIndex === -1) {
createWorker();
workerIndex = workers.length - 1;
available.push(false);
workers[workerIndex].postMessage(info);
}
function onMessage(message) {
let pathFound = false;
if (typeof message.data === "string") {
paths = []
pathFound = false;
} else {
paths = message.data
pathFound = message.data.length > 0;
}
setAvailable(workers[workerIndex]);
resolve(pathFound);
}
function onError(error) {
reject(error);
}
workers[workerIndex].onmessage = onMessage;
workers[workerIndex].onerror = onError;
});
}
function createWorker() {
let worker = new Blob([workerScript]);
let url = URL.createObjectURL(worker);
worker = new Worker(url);
workers.push(worker);
available.push(true);
}
function setAvailable(worker) {
for (let i = workers.length; i--; ) {
if (workers[i] === worker) {
available[i] = true;
return;
}
}
}
var info,
generatePathTime;
var paths = [];
// var enemies = [];
var target;
var lastLength = Infinity;
var logDistance;
var invisMode = 0;
var clanWait = 0;
var websocket, modBots = [];
var botInfo = [], botEnemies = [], myPlayer = {x: 0, y: 0}, nearestEnemy = [];
// CSS Styles
const styleElem = document.createElement('style');
styleElem.innerHTML = `
#customMenu {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 600px;
height: 600px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
border-radius: 10px;
display: none;
padding: 20px;
box-sizing: border-box;
overflow-y: auto; /* Vertical scroll bar */
}
#botPanelText {
margin-bottom: 10px;
font-size: 1.5em;
font-weight: bold;
}
#botCount {
margin-bottom: 20px;
font-size: 1.2em;
color: #4CAF50; /* Green color */
font-weight: bold;
}
.tabContainer {
display: flex;
flex-direction: column; /* Display tabs vertically */
align-items: center; /* Center-align tabs */
width: 100%;
}
.menuTab {
margin: 5px;
padding: 15px 30px;
background-color: #007BFF;
color: white;
text-align: center;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
font-size: 1.2em;
position: relative; /* Positioning for relative elements */
}
#backBtn {
margin-top: 20px; /* Add margin to separate from tabs */
padding: 15px 30px;
background-color: #FF5733;
color: white;
text-align: center;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
display: none;
font-size: 1.2em;
}
.pageContent {
display: none;
text-align: center;
width: 100%;
height: 100%;
overflow: auto;
position: relative; /* Positioning for relative elements */
}
.pageContent h1 {
margin-top: 0;
}
.disconnectBtn {
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
background-color: #FF5733;
color: white;
border: none;
padding: 8px 16px;
border-radius: 5px;
cursor: pointer;
font-size: 1em;
}
.navBtn {
position: absolute;
bottom: 10px;
font-size: 1em;
padding: 8px 16px;
border-radius: 5px;
cursor: pointer;
}
.prevBtn {
left: 20px;
background-color: #FFA500; /* Orange color */
color: white;
}
.nextBtn {
right: 20px;
background-color: #FFA500; /* Orange color */
color: white;
}
`;
document.head.appendChild(styleElem);
// Create the menu
const menuElem = document.createElement('div');
menuElem.id = 'customMenu';
// Create top panel text
const topPanelTextElem = document.createElement('div');
topPanelTextElem.id = 'botPanelText';
topPanelTextElem.innerText = '0chance b8 Bot Panel'; // Text for top panel
menuElem.appendChild(topPanelTextElem);
// Create bot count
const botCountElem = document.createElement('div');
botCountElem.id = 'botCount';
botCountElem.innerText = 'Bot Count: 0'; // Text for bot count
menuElem.appendChild(botCountElem);
// Create tab container
const tabContainerElem = document.createElement('div');
tabContainerElem.className = 'tabContainer';
menuElem.appendChild(tabContainerElem);
// Create back button
const backBtnElem = document.createElement('a');
backBtnElem.id = 'backBtn';
backBtnElem.innerText = 'Back to Menu';
backBtnElem.href = '#';
backBtnElem.onclick = function(event) {
event.preventDefault();
displayMenu();
};
menuElem.appendChild(backBtnElem);
document.body.appendChild(menuElem);
// Global variable to track the current tab
let currentTab = 0;
// Toggle menu visibility when ` is pressed
document.addEventListener('keydown', function(event) {
if (event.key === '`') {
if (menuElem.style.display === 'none' || menuElem.style.display === '') {
menuElem.style.display = 'flex';
displayMenu();
} else {
menuElem.style.display = 'none';
}
}
});
// Function to create a new tab dynamically
// Global variables to store references to section elements
let ageSection;
let windmillCountSection;
let goldSection;
function createTab(id) {
const tabElem = document.createElement('a');
tabElem.className = 'menuTab';
tabElem.innerText = `Bot ${id}`;
tabElem.href = `#page${id}`;
tabElem.id = `tab${id}`; // Set the id attribute
tabElem.onclick = function(event) {
event.preventDefault();
displayPage(id);
};
menuElem.appendChild(tabElem);
// Create page content
const pageContentElem = document.createElement('div');
pageContentElem.className = 'pageContent';
pageContentElem.id = `page${id}`;
ageSection = document.createElement('p');
ageSection.id = `age${id}`;
ageSection.innerText = `Age: 0`;
pageContentElem.appendChild(ageSection);
windmillCountSection = document.createElement('p');
windmillCountSection.id = `windmillCount${id}`;
windmillCountSection.innerText = `Windmill Count: 0`;
pageContentElem.appendChild(windmillCountSection);
goldSection = document.createElement('p');
goldSection.id = `gold${id}`;
goldSection.innerText = `Gold: 0`;
pageContentElem.appendChild(goldSection);
const botText = document.createElement('p');
botText.innerText = `You are Viewing: Bot ${id}`;
pageContentElem.appendChild(botText);
const disconnectBtn = document.createElement('button');
disconnectBtn.className = 'disconnectBtn';
disconnectBtn.innerText = 'Disconnect';
disconnectBtn.onclick = function() {
removeTab(id);
vr(`!dc ${id}`);
};
pageContentElem.appendChild(disconnectBtn);
const prevBtn = document.createElement('button');
prevBtn.className = 'navBtn prevBtn';
prevBtn.innerText = 'Prev';
prevBtn.onclick = function() {
if (id > 1) {
displayPage(id - 1);
}
};
pageContentElem.appendChild(prevBtn);
const nextBtn = document.createElement('button');
nextBtn.className = 'navBtn nextBtn';
nextBtn.innerText = 'Next';
nextBtn.onclick = function() {
const maxTabs = document.querySelectorAll('.menuTab').length;
if (id < maxTabs) {
displayPage(id + 1);
}
};
pageContentElem.appendChild(nextBtn);
menuElem.appendChild(pageContentElem);
}
// Function to remove a tab by its ID
function removeTab(tabId) {
const tabToRemove = document.getElementById(`tab${tabId}`);
if (tabToRemove) {
tabToRemove.remove();
// Optionally, you may want to remove the associated page content as well
const pageToRemove = document.getElementById(`page${tabId}`);
if (pageToRemove) {
pageToRemove.remove();
}
}
}
// Function to remove tabs
function removeTabs() {
// Remove tab buttons and associated content
tabContainerElem.innerHTML = '';
const pages = document.querySelectorAll('.pageContent');
pages.forEach(page => page.remove());
}
// Function to display page content
function displayPage(pageNum) {
// Hide all tab buttons except the back button
const tabs = document.querySelectorAll('.menuTab');
tabs.forEach(tab => tab.style.display = 'none');
backBtnElem.style.display = 'block';
// Hide all page content and show the selected one
const pages = document.querySelectorAll('.pageContent');
pages.forEach(page => page.style.display = 'none');
const selectedPage = document.getElementById(`page${pageNum}`);
if (selectedPage) {
selectedPage.style.display = 'block';
}
currentTab = pageNum; // Update the current tab
}
// Function to display menu
function displayMenu() {
// Show all tab buttons and hide the back button
const tabs = document.querySelectorAll('.menuTab');
tabs.forEach(tab => tab.style.display = 'block');
backBtnElem.style.display = 'none';
// Hide all page content
const pages = document.querySelectorAll('.pageContent');
pages.forEach(page => page.style.display = 'none');
}
const botCountElement = document.getElementById('botCount');
// Example: Change the bot count to 1000
// Example usage: Call createTab with the ID of the tab you want to create
/*createTab(1);
createTab(2);
createTab(3);
createTab(4);
createTab(5);
*/
// Example usage: Call removeTabs to remove tabs
// removeTabs();
// Example usage: Call removeTab with the ID of the tab you want to remove
// removeTab(3);
let enmY;
const wait = async ms => new Promise(action => setTimeout(action, ms))
const toBytes = b64 => Uint8Array.from(atob(b64), (c => c.charCodeAt(0)));
class Altcha {
code=null;
coreCount=Math.min(16, navigator.hardwareConcurrency || 4);
tokenEncode="IWZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2xldCBlPW5ldyBUZXh0RW5jb2Rlcjthc3luYyBmdW5jdGlvbiB0KHQsbixyKXt2YXIgbDtyZXR1cm4gbD1hd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdChyLnRvVXBwZXJDYXNlKCksZS5lbmNvZGUodCtuKSksWy4uLm5ldyBVaW50OEFycmF5KGwpXS5tYXAoZT0+ZS50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpKS5qb2luKCIiKX1mdW5jdGlvbiBuKGUsdD0xMil7bGV0IG49bmV3IFVpbnQ4QXJyYXkodCk7Zm9yKGxldCByPTA7cjx0O3IrKyluW3JdPWUlMjU2LGU9TWF0aC5mbG9vcihlLzI1Nik7cmV0dXJuIG59YXN5bmMgZnVuY3Rpb24gcih0LHI9IiIsbD0xZTYsbz0wKXtsZXQgYT0iQUVTLUdDTSIsYz1uZXcgQWJvcnRDb250cm9sbGVyLGk9RGF0ZS5ub3coKSx1PShhc3luYygpPT57Zm9yKGxldCBlPW87ZTw9bCYmIWMuc2lnbmFsLmFib3J0ZWQmJnMmJnc7ZSsrKXRyeXtsZXQgdD1hd2FpdCBjcnlwdG8uc3VidGxlLmRlY3J5cHQoe25hbWU6YSxpdjpuKGUpfSxzLHcpO2lmKHQpcmV0dXJue2NsZWFyVGV4dDpuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUodCksdG9vazpEYXRlLm5vdygpLWl9fWNhdGNoe31yZXR1cm4gbnVsbH0pKCkscz1udWxsLHc9bnVsbDt0cnl7dz1mdW5jdGlvbiBlKHQpe2xldCBuPWF0b2IodCkscj1uZXcgVWludDhBcnJheShuLmxlbmd0aCk7Zm9yKGxldCBsPTA7bDxuLmxlbmd0aDtsKyspcltsXT1uLmNoYXJDb2RlQXQobCk7cmV0dXJuIHJ9KHQpO2xldCBmPWF3YWl0IGNyeXB0by5zdWJ0bGUuZGlnZXN0KCJTSEEtMjU2IixlLmVuY29kZShyKSk7cz1hd2FpdCBjcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixmLGEsITEsWyJkZWNyeXB0Il0pfWNhdGNoe3JldHVybntwcm9taXNlOlByb21pc2UucmVqZWN0KCksY29udHJvbGxlcjpjfX1yZXR1cm57cHJvbWlzZTp1LGNvbnRyb2xsZXI6Y319bGV0IGw7b25tZXNzYWdlPWFzeW5jIGU9PntsZXR7dHlwZTpuLHBheWxvYWQ6byxzdGFydDphLG1heDpjfT1lLmRhdGEsaT1udWxsO2lmKCJhYm9ydCI9PT1uKWwmJmwuYWJvcnQoKSxsPXZvaWQgMDtlbHNlIGlmKCJ3b3JrIj09PW4pe2lmKCJvYmZ1c2NhdGVkImluIG8pe2xldHtrZXk6dSxvYmZ1c2NhdGVkOnN9PW98fHt9O2k9YXdhaXQgcihzLHUsYyxhKX1lbHNle2xldHthbGdvcml0aG06dyxjaGFsbGVuZ2U6ZixzYWx0OmR9PW98fHt9O2k9ZnVuY3Rpb24gZShuLHIsbD0iU0hBLTI1NiIsbz0xZTYsYT0wKXtsZXQgYz1uZXcgQWJvcnRDb250cm9sbGVyLGk9RGF0ZS5ub3coKSx1PShhc3luYygpPT57Zm9yKGxldCBlPWE7ZTw9byYmIWMuc2lnbmFsLmFib3J0ZWQ7ZSsrKXtsZXQgdT1hd2FpdCB0KHIsZSxsKTtpZih1PT09bilyZXR1cm57bnVtYmVyOmUsdG9vazpEYXRlLm5vdygpLWl9fXJldHVybiBudWxsfSkoKTtyZXR1cm57cHJvbWlzZTp1LGNvbnRyb2xsZXI6Y319KGYsZCx3LGMsYSl9bD1pLmNvbnRyb2xsZXIsaS5wcm9taXNlLnRoZW4oZT0+e3NlbGYucG9zdE1lc3NhZ2UoZSYmey4uLmUsd29ya2VyOiEwfSl9KX19fSgpOw==";
workerBlob=new Blob([ toBytes(this.tokenEncode) ], {
type: "text/javascript;charset=utf-8"
});
static createPayload(data, result) {
return btoa(JSON.stringify({
algorithm: data.algorithm,
challenge: data.challenge,
number: result.number,
salt: data.salt,
signature: data.signature,
test: !!data || void 0,
took: result.took
}));
}
createWorker(name = "alt_worker") {
try {
const url = URL.createObjectURL(this.workerBlob);
const worker = new Worker(url, {
name
});
worker.addEventListener("error", (() => URL.revokeObjectURL(url)));
return worker;
} catch (e) {
return new Worker(`data:text/javascript;base64,${this.tokenEncode}`, {
name
});
}
}
async fetchChallenge() {
const res = await fetch("https://api.moomoo.io/verify");
if (!res.ok) {
throw new Error("Failed to fetch challenge.");
}
return res.json();
}
async getWorkerSolution(task, total, count = this.coreCount) {
const workerCount = Math.min(16, Math.max(1, count));
const workers = Array.from({
length: workerCount
}, (() => this.createWorker()));
const chunkSize = Math.ceil(total / workerCount);
const results = await Promise.all(workers.map(((worker, index) => {
const start = index * chunkSize;
return new Promise((resolve => {
worker.onmessage = msg => {
if (msg.data) {
workers.forEach((w => {
if (w !== worker) {
w.postMessage({
type: "abort"
});
}
}));
}
resolve(msg.data ?? null);
};
worker.onerror = () => resolve(null);
const message = {
type: "work",
payload: task,
start,
max: start + chunkSize
};
worker.postMessage(message);
}));
})));
workers.forEach((worker => worker.terminate()));
return results.find((r => !!r)) ?? null;
}
async validateChallenge(data) {
const solution = await this.getWorkerSolution(data, data.maxnumber);
if (!solution) {
throw new Error("Failed to solve challenge.");
}
return {
challengeData: data,
solution
};
}
async generate() {
try {
const challengeData = await this.fetchChallenge();
const {solution} = await this.validateChallenge(challengeData);
const encoded = Altcha.createPayload(challengeData, solution);
this.code = `alt:${encoded}`;
return encodeURIComponent(this.code);
} catch (error) {
console.error("Token generation failed:", error);
throw error;
}
}
}
const altcha = new Altcha;
const connectBot = async (code, thebot) => {
const token = await altcha.generate();
const botUrl = websocket.url.split("token=")[0] + "token=" + token;
console.log(botUrl);
let ws = new WebSocket(botUrl);
ws.binaryType = "arraybuffer";
ws.botType = thebot;
// ws.pathfind = new WorkerAStar()
// ws.tach = new Tachyon(ws.pathfind)
ws.healTimeout = Date.now();
ws.builds = []
ws.primary = null
ws.secondary = null
ws.invisTime = 1000;
ws.players = [];
ws.oldCoords = {};
ws.millCount = 0
ws.spawnTime = Date.now();
ws.HERE = true;
ws.enemies = [];
ws.pingTime = -1;
ws.holdItem = 0;
ws.aimAt = 0;
ws.nEnemy = null
ws.kys = false;
ws.alive = false;
ws.deaths = 0;
ws.clanMates = [];
ws.samRS = 1;
ws.samRP = 1;
ws.breaker = false;
ws.stopHit = false;
ws.upgraded = 0;
ws.moveDir = 0;
ws.moveDirection = 0;
ws.health = 100;
ws.gold = 100;
ws.doMills = true;
ws.fS = false;
ws.x2 = 0
ws.sid = null
ws.y2 = 0
ws.buyer = [[11],40,1,53,6,7,56,12,15,31,[21],22,26,11,20,[18],[19],[13]]
ws.x = 0
ws.y = 0
ws.getCrossBow = false;
ws.ping = 0
ws.pingavg = 0
ws.pingarr = []
ws.weaponIndex = 0;
ws.packets = 0;
ws.autoHit = false;
ws.hitPacket = 0;
ws.player = [];
ws.skins = [0]
ws.tails = []
ws.pr = 1;
ws.sr = 1;
ws.tr = 1;
// ws.updater.forEach(e => e.id(...e.data));
ws.updater = [];
ws.moveRan = {
angle: getRandomAng(),
x: 0,
y: 0,
lastChange: 0,
}
ws.justShot = Date.now();
ws.emit = (packet, val, bool, val2) => {
if (!ws.fS) {
ws.fS = true;
setTimeout(()=>{
ws.fS = false;
ws.packets = 0;
}
, 1000);
}
ws.packets++;
if(ws.packets>=85) return;
if(packet == "9") ws.moveDir = val;
if(packet === "K"){
ws.hitPacket++;
}
ws.send(window.msgpack.encode( [packet, [val ,bool, val2] ] ));
}
ws.findPlayer = function(ID){
for(let i = 0; i < ws.players.length; i++){
if(ws.players[i].sid ==ID) return ws.players[i]
}
return null;
}
ws.findBuilding = function(ID){
for(let i = 0; i < ws.builds.length; i++){
if(ws.builds[i].sid ==ID) return ws.builds[i]
}
return null;
}
ws.spawn = function(p) {
// return;
// console.log('spawned')
ws.wood = 100
ws.stone = 100
ws.food = 100
ws.points = 100
ws.upgraded = 0;
ws.alive = true;
ws.kys = false;
ws.sr = 1;
ws.pr = 1;
ws.weapons = [0];
ws.primary = 0;
ws.secondary = null;
ws.items = [0, 3, 6, 10];
p = round(Math.random() * 11);
ws.emit("M", {
name: generateRandomBotName(),
moofoll: 1,
skin: 0//p == 11 ? "constructor" : p
});
ws.health = 100;
/* setTimeout(()=>{
plc();
}
, 1000);*/
}
ws.storeEquip = function(id, index) {
ws.emit("c", 0, id, index);
}
ws.checkMove = function(target, angle, distance, vel, z, x, y, scale){
let current = {x: Infinity, y: Infinity, fake: true}
// z = ws.builds.filter(e => e.)
if(vel){
x = target.np.real.x
y = target.np.real.y
} else{
x = target.x2
y = target.y2;
}
for(let i in z) {
let obj = z[i];
scale = obj.real.scale+35+30//obj.type === 1 ? scale = obj.scale*.55 +35: obj.scale +35
if(nEnemy.team==null) {
let dist1 = dist(target,obj)//getDistance(nEnemy.x2, nEnemy.y2, obj.x, obj.y);
let point1 = calcPoint(x, y, angle, dist1);
let dist2 = dist(point1,obj)//getDistance(point1.x, point1.y, obj.x, obj.y);
if(dist2 < (scale) && dist1 - (scale) < distance+scale) {
let p00 = calcPoint(x, y, angle, dist1 - (scale));
return {x:p00.x, y: p00.y, obj: obj};
}
}
}
return false;
}
ws.storeBuy = function(id, index) {
ws.emit("c", 1, id, index);
}
ws.wait = async function(ms){
await wait(ms)
}
ws.buyEquip = function(id, index) {
if (index == 0) {
if (ws.skins.includes(id)) {
if (ws.skinIndex != id) {
ws.storeEquip(id, 0);
}
} else {
let price = Xt.find(e => e.id == id)?.price
if(ws.gold>= price){
ws.storeBuy(id,0)
}
/* if (id == 40 && ws.gold >= 15000) {
ws.storeBuy(id, 0);
} else if (id == 7 && ws.gold >= 6000) {
ws.storeBuy(id, 0);
} else if (id == 6 && ws.gold >= 4000) {
ws.storeBuy(id, 0);
}*/
}
} else if (index == 1) {
if (ws.tails.includes(id)) {
if (ws.tailIndex != id) {
ws.storeEquip(id, 1);
}
} else {
if (id == 11) {
Gt.find(e => ws.gold>=e?.price)
if (ws.gold >= 2000) {
ws.storeBuy(id, 1);
} else {
if (ws.tailIndex != 0) {
ws.storeEquip(0, 1);
}
}
}
}
}
}
ws.Hg = function(skin, tail){
if(ws.kys) skin = 7;
if(skin) ws.buyEquip(skin,0);
if(tail) ws.buyEquip(keys.ShiftLeft ? (ws.skins.includes(19) ? 19 : 0) : tail, 1);
}
ws.bh = function(e){
//let force = keys.ShiftLeft ? 0 : 11;
//console.log(force);
let soldier = ws.nEnemy && ws.nEnemy.distance < 300 || ws.health <= 80 || ws.moveDirection === null || ws.moveDirection === undefined ? true : false
if(ws.y < 2400){
ws.Hg(soldier ? 6 : 15, keys.ShiftLeft ? 0 : 11);
}else if(ws.y >= T.mapScale / 2 - T.riverWidth / 2 && ws.y <= T.mapScale / 2 + T.riverWidth / 2){
ws.Hg(31, 11);
}else{
ws.Hg(soldier ? 6 : 12, keys.ShiftLeft ? 0 : 11);
}
}
ws.checkPlace = function(id, ang, offset, obj) {
obj = R.list[id]
offset = obj.scale +35 + (obj.placeOffset||0)
var tmpX = ws.x2 + (offset * cos(ang));
var tmpY = ws.y2 + (offset * sin(ang));
if (ue.checkItemLocationBot(tmpX, tmpY, obj.scale, 0.6, obj.id, false, ws.builds)) {
ws.emit("z", id);
ws.emit("F", 1, ang);
ws.emit("z", ws.weaponIndex, 1);
}
}
function plc() {
ws.emit("z", ws.items[0]);
ws.emit("z", 1);
ws.emit("z", ws.weaponIndex, true);
}
ws.autobuy = function(){
if(ws.skins.length+ws.tails.length>=66) return;
if(ws.buyer.length){
if(!Array.isArray(ws.buyer[0]) && ws.gold>=Xt.find(e => e.id==ws.buyer[0]).price) ws.storeBuy(ws.buyer[0],0);
if(Array.isArray(ws.buyer[0]) && ws.gold>=Gt.find(e => e.id==ws.buyer[0][0]).price) ws.storeBuy(ws.buyer[0][0],1);
}
if(ws.buyer.length==0&&ws.skins.length!=Xt.length-1){
let hat = Xt.find(e => e.id!=45 && !ws.skins.includes(e.id)&&ws.gold>=e.price)
if(hat) ws.storeBuy(hat.id,0);
let acc = Gt.find(e => !ws.tails.includes(e.id)&&ws.gold>=e.price)
if(acc) ws.storeBuy(acc.id,1);
}
// console.log(buyer.length,bH.length,bT.length)
}
function rad(ang) {
return ang * (PI / 180);
}
ws.upgrade = function(e) {
ws.emit("H", e);
// ws.emit(["H", [17]]);
// ws.emit(["H", [31]]);
// ws.emit(["H", [23]]);
// ws.emit(["H", [10]]);
// ws.emit(["H", [38]]);
// ws.emit(["H", [4]]);
// if(document.getElementById("botConfig").value == 1) {
// ws.emit(["H", [15]]);
// }else if(document.getElementById("botConfig").value == 2) {
// ws.emit(["H", [13]]);
// }
}
ws.mill = {
x: 0,
y: 0,
};
ws.old = {
x: 0,
y: 0,
};
ws.miller = function(){
if ((ws.old.x != ws.x || ws.old.y != ws.y) && !(ws.y >= T.mapScale / 2 - T.riverWidth / 2 && ws.y <= T.mapScale / 2 + T.riverWidth / 2)) {
if (Math.hypot(ws.mill.y - ws.y, ws.mill.x - ws.x) > 94) {
// let ang = Math.atan2(ws.old.y - ws.y, ws.old.x - ws.x);
ws.place(ws.items[3], ws.moveDirection - rad(94 / 1.25) + PI);
ws.place(ws.items[3], ws.moveDirection + rad(94 / 1.25) + PI);
ws.place(ws.items[3], ws.moveDirection + PI);
ws.emit("z", ws.primary, true)
ws.mill.x = ws.x;
ws.mill.y = ws.y;
}
ws.old.x = ws.x;
ws.old.y = ws.y;
}
}
ws.weapons = [0];
ws.items = [0, 3, 6, 10];
ws.autoaiming = false;
ws.tick = 0;
ws.time = Date.now();
ws.teamer = function(e){
if(e == ws.sid) return true;
return ws.clanMates.includes(e);
}
ws.mapping = Date.now();
ws.mapFix = function(){
// console.log('did')
ws.oldCoords = {x: ws.x, y: ws.y}
}
ws.doProjectileSync = (e,t)=>{
let found = findPlayerSID(targetID ? targetID : nEnemy.sid)
if(targetID && (!found || !found.visible)) found = nEnemy;
// let target = found?.visible ? found : findPlayerSID(nEnemy.sid)
let positions = found.sid === nEnemy.sid ? nEnemy.positions : found
let future = found ? aimNextPos(ws,positions,R.weapons[ws.weapons[1]].projSpd,found) : null
let dirs;
let doEquip = []
let updatePos = {...found}
updatePos.sid = 100000
if(future === null) return false
if(smartAim.checked){
if((future.norm.dist > 700 || ws.secondary === 12)){
updatePos.x2 = future.marks.pos.x
updatePos.x2 = future.marks.pos.y
if(botProjSync(ws, updatedPos, t)){
dirs = future.marks.dir
doEquip = [1,11]
}
}
if(!doEquip.length&& future.norm.dist <= 700){
updatePos.x2 = future.norm.pos.x
updatePos.x2 = future.norm.pos.y
if(botProjSync(ws, updatedPos, t)){
dirs = future.norm.dir
doEquip = [53,11]
}
}
} else{
dirs = getDir(ws,nEnemy)
doEquip = [53,11]
}
ws.Hg(doEquip[0],doEquip[1])
// let dirs = getDir(ws,nEnemy)
ws.emit('6',[qSyncChat]); // chat sync
ws.emit("z",ws.weapons[1],true)
ws.emit('D',dirs)
if(ws.items[5] == 18){
ws.place(ws.items[5],dirs,ws.weapons[1])
ws.place(ws.items[5],dirs+toRad(180),ws.weapons[1])
ws.place(ws.items[5],dirs-toRad(90),ws.weapons[1])
ws.place(ws.items[5],dirs+toRad(90),ws.weapons[1])
}
ws.emit("F", 1, dirs);
ws.emit("F", 0, dirs);
}
ws.place = function (id, angle,wep) {
!wep && (wep = ws.weaponIndex)
ws.emit("z", id, null);
ws.emit("F", 1, angle);
// ws.emit(["d", [0, angle]]);
wep && ws.emit("z", wep, true);
}
ws.pingSocketResponse = function(){
ws.pingTime = Date.now();
console.log(ws.pingTime);
//ws.emit(["pp"])
}
ws.health = 100;
ws.onopen = async () => {
ws.HERE = true;
await wait(111);
ws.spawn();
ws.pingSocketResponse();
}
ws.break = function(obj){
let objDir = getDir(ws,obj)
ws.emit("D",objDir)
ws.emit("F", 1, objDir)
ws.emit("F", 0, objDir)
ws.Hg(40,11)
}
ws.onclose = () => {
ws.HERE = false;
ws.ISHERE&& modBots.length && (modBots = modBots.filter(x => x.HERE))
if(ws.ISHERE)addChatLog(`Bot count is ${modBots.length}, -1`,'', generateRandomColor(),false,true);
botCountElement.innerText = `Bot Count: ${modBots.length}`;
botInfo[ws.botType] = [];
botEnemies[ws.botType] = [];
removeTab(ws.sid);
}
ws.heal = function(e,t = [20, 40, 30]){
for(var n = e; n < 100; n += t[ws.items[0]])ws.place(ws.items[0],null)
}
//ws.autobreak
ws.reloadConfig = function(id,weapon,hit,bool,player,_){
if(!bool) return ws.updater.push({id: ws.reloadConfig, data: [id, hit, weapon, true]});
_ = ws.findPlayer(id)//findPlayerSID(id);
if(ws.sid == id){
weapon > 9 ? ws.sr = 0 : ws.pr = 0
ws.invisTime = 1000
ws.skinIndex == 20 && (weapon > 9) ? (ws.samRS = .78) : (ws.samRS = 1);
ws.skinIndex == 20 && (weapon < 9) ? (ws.samRP = .78) : (ws.samRP = 1);
}
weapon > 9 ? _.sr = 0 : _.pr = 0
_.skinIndex == 20 && (weapon >9)? (_.samRS = .78) : (_.samRS = 1);
_.skinIndex == 20 && (weapon<9) ? (_.samRP = .78) : (_.samRP = 1);
}
ws.projDetect = function(e, t, n, i, r, s, bool, _){
if(!bool)ws.updater.push({id: ws.projDetect, data: [e, t, n, i, r, s, true]})
// x, y, angle, range, speed, projectile type
let player = null;
if(r == 1.5 && s == 1){
if(ws.skinIndex==53&&dist({x:e,y:t},ws)<=2){
player = ws
}
}
if(!(r==1.5&&s==1)){
if(ws?.weaponIndex == ws?.secondary&& ws.dir === n && R.weapons[ws.weaponIndex].projectile == s){
let newXY = calcPoint(e, t, n + PI, 70)
if(dist2(newXY,ws)<=20)player = ws;
// break;
}
}
// }
if(!player) return;
if(player){
if(r == 1.5 &&s == 1){
if(ws.sid == player.sid)ws.tr = 0;
player.tr = 0
} else {
if(player.sid === ws.sid){
ws.sr = 0
ws.samRS = ws.skinIndex === 20 ? .78 : 1;
};
player.sr = 0;
player.samRS = player.skinIndex === 20 ? .78 : 1;
}
}
}
ws.reloadWeapon = function(_, me){
if(!me){
if(_.buildIndex == -1){
if(_.weaponIndex <=8){
_.pr = min(1, _.pr + 111 / (R.weapons[_.primary].speed * _.samRP));
}else if(_.weaponIndex>8){
_.sr = min(1, _.sr + 111 / (R.weapons[_.secondary].speed * _.samRS));
// _.sid!=E.sid&&Math.min(1, _.sr + 111 / (R.weapons[_.secondary].speed * _.samRS));
}
}
_.tr = min(1, _.tr + 111/2400);
} else {
if(ws.buildIndex == -1){
if(ws.weaponIndex <=8){
ws.pr = min(1, ws.pr + 111 / (R.weapons[ws.primary].speed * ws.samRP));
}else if(ws.weaponIndex>8){
ws.sr = min(1, ws.sr + 111 / (R.weapons[ws.secondary].speed * ws.samRS));
// _.sid!=E.sid&&Math.min(1, _.sr + 111 / (R.weapons[_.secondary].speed * _.samRS));
}
}
ws.tr = min(1, ws.tr + 111/2400);
}
}
// even if assassin if the bot is connected to game it will send constant player update packets if there are no players present just an empty array tho
ws.doAll = function(bot, invis){
if(!invis&& bot.length){
botInfo[ws.botType] = bot;
ws.sid = bot[0]
ws.speed = fastHypot(ws.x-bot[1],ws.y-bot[2])//{x:playerInfo[1],y:playerInfo[2]});
ws.speed!=0 && (ws.invisTime = 1000);
ws.speed == 0 && (ws.invisTime-=E.delta);
ws.xVel = bot[1] - ws.x
ws.yVel = bot[2] - ws.y
ws.sid = bot[0];
ws.x2 = bot[1]
ws.y2 = bot[2]
ws.x = bot[1]
ws.y = bot[2]
ws.dir = bot[3];
ws.dt = 0;
ws.buildIndex = bot[4];
ws.weaponIndex = bot[5];
ws.team = bot[7];
ws.isLeader = bot[8];
ws.skinIndex = bot[9];
ws.tailIndex = bot[10];
ws.isSkull = bot[11];
ws.visb = true;
ws.enemies.length && (ws.enemies = ws.enemies.map(enemy => ({ enemy, distance: dist2(enemy, ws) })).sort((a, b) => a.distance - b.distance));
ws.nEnemy = ws.enemies[0]
ws.doMills = window.location.hostname != "sandbox.moomoo.io" || ws.upgraded >= 7 && (ws.buyer.length <= 8 || ws.millCount >= 230 || botMove == "Summon" || botMove == "Static" || cBots.checked || botSummon.value == "Cursor" && botMove == "Summon") || ws.millCount === 299 ? false : true;
}
ws.reloadWeapon(ws,1)
ws.updater.forEach(e => e.id(...e.data));
ws.updater = [];
if (ws.tick % 7 === 0 && !(spyIndex.do && spyIndex.play && spyBot?.bot?.sid === ws.sid)) {
if(botChat.value) ws.emit("6", botChat.value);
// const spamMessage = document.getElementById('spamMessage').value;
// ws.emit('6', spamMessage);
}
if(ws.doMills && (Date.now() - ws.moveRan.lastChange >= 10000) || (sqrt(pow((ws.moveRan.y - ws.y), 2) + pow((ws.moveRan.x - ws.x), 2)) > 3300)||ws.speed===0) {
ws.moveRan.angle = getRandomAng(ws.moveRan.angle)
ws.moveRan.y = ws.y;
ws.moveRan.x = ws.x;
ws.moveRan.lastChange = Date.now();
}
ws.autobuy();
ws.ownerDist = botSummon.value == "Cursor" && botMove == "Summon" ? fastHypot(cursor.x2-ws.x,cursor.y2-ws.y) : fastHypot(E.x2-ws.x,E.y2-ws.y)
if(spyIndex.do && spyBot?.bot?.sid === ws.sid) {
targetID.player = ws.players.find(x => x.sid === targetID.ID && x.visible);
if(targetID.player){
targetID.player.positions = multiCalcVel(targetID.player, 6);
} else if(ws.nEnemy){
//console.log(ws.nEnemy.enemy.sid); // what is this retarded shit lmao
targetID.player = ws.nEnemy.enemy;//ws.players.find(x => x.sid === ws.nEnemy.enemy.sid);//enmY;
targetID.player.positions = multiCalcVel(targetID.player, 6);
}
}
if(spyIndex.do&&spyIndex.play &&spyBot?.bot?.sid === ws.sid){
ws.moveDirection = botMD;
}else if(ws.doMills && window.location.hostname == "sandbox.moomoo.io" || botMove === "Wander"){
ws.moveDirection = ws.moveRan.angle
} else if(botMove === "Static"){
ws.moveDirection = null
} else if(botMove === "Summon"){
if(botSummon.value == "Cursor"){
ws.moveDirection = getDir(ws,cursor)
} else if(botSummon.value == "Towards"){
ws.moveDirection = getDir(ws,E.np.real);
} else{
if(ws.ownerDist<=botDist){
if(botSummon.value == "Copy"){
ws.moveDirection = moveDirection
} else ws.moveDirection = null;
} else ws.moveDirection = getDir(ws,E.np.real);
}
}
//ws.updater.forEach(e => e.id(...e.data));
// ws.updater = [];
ws.inTrap = ws.builds.find((e) => e.name === "pit trap" && e.owner?.sid!=ws.sid && !ws.teamer(e.owner?.sid)&& fastHypot(e.x-ws.x,e.y-ws.y) <= 50)
//ws.trapAngle = getDir(ws,ws,inTrap);
modBots.forEach((e, index) => {
if (e.sid == ws.sid) {
ws.botType = index;
modBots[index] = ws;
// doSpy()
}
});
// console.log(Date.now()-time,tick, 'bot')
ws.doingAll = ws.upgraded >= 7 || window.location.hostname != "sandbox.moomoo.io"
// console.log(ws.wood,ws.stone,ws.food,ws.points)
// doSpy()
if(ws.alive){
let collides; //= runIntoBot(ws,ws.moveDirection,calcVel(ws,ws.moveDirection))
if(!(botMove === "Summon" && cBots.checked && ws.doingAll) && !(clearing?.length && ws.doingAll)) {
collides = runIntoBot(ws,ws.moveDirection)
!collides && ws.emit("9",ws.moveDirection)
}
// console.log(ws.moveDirection,ws.sid)
!collides && !ws.inTrap && ws.emit("D", ws.moveDirection);
if(keys.z && R.list[ws?.items[4]]?.name === "pit trap"){
ws.place(ws.items[4],ws.moveDirection)
ws.place(ws.items[4],ws.moveDirection+toRad(180))
ws.place(ws.items[4],ws.moveDirection-toRad(90))
ws.place(ws.items[4],ws.moveDirection+toRad(90))
ws.emit("z", ws.weaponIndex, true)
}
if(ws.inTrap && APB.checked){
ws.autohit = true;
let tDir = getDir(ws,ws.inTrap)
ws.emit("z",ws.weapons[0],true)
ws.emit('D',tDir)
ws.emit("F", 1, tDir);
ws.emit("F", 0, tDir);
if(ws.pr === 1){
ws.Hg(40, 11)
} else ws.Hg(6, 11);
} else if(collides){
}else if(ws.secondary && (spyIndex.do ? true : ws.ownerDist < 900) && (keys.q||Qsync) && ws.sr === 1 && targetID.player && bSync.checked){
// let found = findPlayerSID(targetID.ID ? targetID : nEnemy.sid)
// if(targetID && (!found || !found.visible)) found = nEnemy;
// let target = found?.visible ? found : findPlayerSID(nEnemy.sid)
let positions = targetID.player.positions//found.sid === nEnemy.sid ? nEnemy.positions : found
let future = aimNextPos(ws,positions,R.weapons[ws.weapons[1]].projSpd,targetID.player)
let dirs;
let doEquip = []
if(smartAim.checked && future){
if((future.norm.dist > 700 || ws.weapons[1] === 12)){
dirs = future.marks.dir
doEquip = [1,11]
}
if(!doEquip.length&& future.norm.dist <= 700){
dirs = future.norm.dir
doEquip = [53,11]
}
} else {
dirs = getDir(ws, nEnemy);
doEquip = [53,11]
}
ws.Hg(doEquip[0],doEquip[1])
// let dirs = getDir(ws,nEnemy)
// ws.emit(['6',[qSyncChat]]); // chat sync
if(ws.items[5] == 18){
ws.place(ws.items[5],dirs)
ws.place(ws.items[5],dirs+toRad(180))
ws.place(ws.items[5],dirs-toRad(90))
ws.place(ws.items[5],dirs+toRad(90))
}
ws.emit("z",ws.weapons[1],true)
ws.emit("F", 1, dirs);
ws.emit("F", 0, dirs);
ws.emit('D',dirs)
} else if(clearing?.length && ws.doingAll){
ws.weaponIndex!=ws.primary && ws.emit("z",ws.primary,true)
const closestBuilding = clearing?.reduce((closest, building) => {
const distance = fastHypot(ws.x-building.x,ws.y-building.y);
if (closest === null || distance < closest.distance) {
return { building, distance };
} else {
return closest;
}
}, null).building;
let dir = getDir(ws,closestBuilding);
let range = closestBuilding.name === "pit trap" && !ws.teamer(closestBuilding.owner.sid) ? 0 : R.weapons[ws.weapons[0]].range
if(dist(ws,closestBuilding,"object") <= range){
ws.emit("9",null)
if(ws.pr === 1){
ws.emit('D',dir)
ws.emit("F", 1, dir)
ws.emit("F", 0, dir);
ws.Hg(40,11)
}
} else{
ws.emit("9",dir)
ws.bh()
//ws.emit(["a",[dir]])
ws.emit("F", 1, dir)
ws.emit("F", 0, dir);
ws.emit('D',dir)
}
}else if(inTrap && dist(ws,inTrap, "object")<= R.weapons[ws.weapons[0]].range){
if(ws.pr === 1){
ws.break(inTrap)
} else{
ws.Hg(6,11)
}
} else {
let wep = ws.sr != 1 ? ws.secondary : ws.primary;
(ws.weaponIndex!=wep || ws.buildIndex != -1) && ws.emit("z", wep, true);
if(ws.doMills){
ws.miller()
}
if(wep != ws.secondary && ws.invisTime<=0 && aBots.checked && ws.health === 100 && (ws.ownerDist<=botDist || botMove == "Static" && !ws.doMills)){
ws.Hg(56,0)
} else {
if(wep!= ws.secondary && ws.weaponIndex!=ws.secondary && botMove !== "Static" && !(botMove == "Summon" && ws.ownerDist <= botDist)|| botSummon.value == "Cursor" && botMove == "Summon" && ws.weaponIndex!=ws.secondary){
ws.emit("F", 1, ws.moveDirection);
ws.emit("F", 0, ws.moveDirection);
}
ws.bh()
}
// }
}
if(ws.skinIndex!=45&&ws.alive&&ws.health!=100&&!ws.kys){
if(ws.health>=64.5){
setTimeout(() => {
ws.heal(ws.health)
},85)
} else{
ws.heal(ws.health);
}
}
}
if(ws.sid === currentTab) {
//console.log("UPDATE");
// add update to only update if theres a change from the last, so its not as impactful on performance.
document.getElementById(`age${ws.sid}`).innerText = `Age: ${ws.upgraded}`;
document.getElementById(`windmillCount${ws.sid}`).innerText = `Windmills: ${ws.millCount}`;
document.getElementById(`gold${ws.sid}`).innerText = `Gold: ${ws.gold}`;
}
}
ws.onmessage = message => {
let temp = window.msgpack.decode(new Uint8Array(message.data));
let data;
// console.log(data,"bot")
if(temp.length > 1) {
data = [temp[0], ...temp[1]];
if (data[1] instanceof Array){
data = data;
}
} else {
data = temp;
}
if(!data) return;
if(data[0] == "O") {
ws.findPlayer(data[1]).health = data[2]
if(data[1] == ws.sid) ws.health = data[2];
}
if (data[0] == "A") {
ws.team = data[1].teams;
}
/* if (data[0] == "ac") {
ws.team.push(data[1]);
}*/
/* if (data[0] == "ad") {
for (var i = ws.alliances.length - 1; i >= 0; i--) {
if (ws.team.length&&ws.team[i].sid == data[1]){
ws.team.splice(i, 1);
}
}
}*/
if (data[0] == "4") {
ws.alliancePlayers = data[1];
ws.clanMates = data[1]
// console.log(data, 'sa')
}
if(data[0] == "0"){
ws.ping = Date.now()-ws.pingTime
// console.log(ws.ping,'did ping')
setTimeout(() => {
//ws.pingSocketResponse()
}, 350)
}
if(data[0] == "K") {
ws.reloadConfig(data[1],data[2],data[3])
if(data[1] == ws.sid){
ws.invisTime = 1000
// data[3] >= 9 ? (ws.pr = 0) : (ws.sr = 0)
};
// console.log(data)*/
if(spyIndex.val === ws.botType)gatherAnimation(data[1],data[2],data[3],ws);
}
if(data[0] == "X") {
ws.projDetect(data[1],data[2],data[3],data[4],data[5],data[6])
if(inRender(E,{x:data[1],y:data[2]})) return;
addProjectile(data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],ws)
// if(spyIndex.val === ws.botType)addProjectile(data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],ws);
}
//
if(data[0] == "L") {
if(spyIndex.val == ws.botType){
(y = ws.findBuilding(data[2]))&& (y.xWiggle += T.gatherWiggle * cos(data[1]),
y.yWiggle += T.gatherWiggle * sin(data[1]))
}
// console.log(data)
}
if(data[0] == '3'){
//console.log(data, 'st')
if(data[1] == undefined && data[2] == undefined||data[1] == null&&data[2]==false)ws.clanMates= [];
}
if(data[0] == 'P') {
ws.health = 100;
ws.alive = false;
ws.deaths++;
setTimeout(() => {
ws.spawn();
},220)
}
if(data[0] == "C") {
ws.sid = data[1];
!ws.ISHERE && modBots.push(ws) && addChatLog(`Bot count is ${modBots.length}`,'', generateRandomColor(),false,true);
ws.ISHERE = true;
botCountElement.innerText = `Bot Count: ${modBots.length}`;
createTab(ws.sid);
}
if(data[0] == "V") {
if(data[1]) {
if(data[2]){
ws.weapons = data[1];
ws.primary = data[1][0];
ws.secondary = data[1][1];
}else ws.items = data[1];
}
}
if (data[0] == "S") {
if (data[1] == 3) {
ws.millCount = data[2];
}
}
if(data[0] == "I"){
//console.log(data)
}
if (data[0] === "H") {
for (var t = 0; t < data[1].length;){
let e = data[1]
// if(!botBuilds.some(x => x.sid === e[t])){
ue.add(e[t], e[t + 1], e[t + 2], e[t + 3], e[t + 4], e[t + 5], R.list[e[t + 6]], !0, e[t + 7] >=
0 ? {
sid: e[t + 7]
} : null,ws)
// }
t += 8
}
}
if (data[0] == "D") {
playerEncounter(data[1],data[2],ws)
}
if(data[0] == "R"){
ws.players = ws.players.filter(e=>e.sid!=data[1])
ws.builds = ws.builds.filter(e =>e?.owner?.sid != data[1])
}
if(data[0] == "6"){
let player = ws.findPlayer(data[1])
player.chatMessage = data[2];
player.chatCountdown = 3500;
}
if (data[0] == "N") {
if(data[1] == "wood") ws.wood = data[2];
if(data[1] == "food") ws.food = data[2];
if(data[1] == "stone") ws.stone = data[2];
if (data[1] == "points") ws.gold = data[2];
}
if (data[0] == "U") { // upgrader
if (data[1] > 0) {
if (ws.upgraded == 0) {
ws.upgrade(6) // short sword(3) dagger (7)
} else if (ws.upgraded == 1) {
ws.upgrade(17) // cookie
} else if (ws.upgraded == 2) {
ws.upgrade(31); // trap or boost
} else if (ws.upgraded == 3) {
ws.upgrade(23); // greater spikes
} else if (ws.upgraded == 4) {
ws.upgrade(9); // hunting bow
} else if (ws.upgraded == 5) {
ws.upgrade(34); // platform
} else if (ws.upgraded == 6) {
ws.upgrade(12); // crossbow
} else if (ws.upgraded == 7) {
ws.upgrade(ws.getCrossBow ? 25 : 15); // musket = 15, crossbow = 12, spinning spikes = 25
}
ws.upgraded++;
}
}
if (data[0] == "5") {
if (data[3]) {
if (!data[1]){
ws.tails.push(data[2])
}else ws.tailIndex = data[2];
} else {
if (!data[1]){
ws.skins.push(data[2])//[data[2]] = 1;
}else ws.skinIndex = data[2];
}
if(ws.buyer.length && (data[3]==0||data[3]==1)){
for(let ccc =0;ccc<ws.buyer.length;ccc++){
if(data[3]==0&&!Array.isArray(ws.buyer[ccc]) && ws.buyer[ccc] == data[2]){
ws.buyer.splice(ccc,1)
}
if(data[3]==1&&Array.isArray(ws.buyer[ccc])&& ws.buyer[ccc][0] == data[2]){
ws.buyer.splice(ccc,1)
}
}
}
}
if(data[0]=="Q"){
ws.builds = ws.builds.filter((e) => e.sid!=data[1])
}
if(data[0] == "a") {
ws.tick++;
ws.time = Date.now();
ws.players.forEach(x =>{
x.forcePos = false,x.visible = !1
})
let botter = [];
enmY = null;
for(let i = 0; i < data[1].length / 13; i++) {
let playerInfo = data[1].slice(13*i, 13*i+13);
ws.enemies = [];
let player = ws.findPlayer(playerInfo[0]);
player.t1 = void 0 === player.t2 ? Date.now() : player.t2;
player.t2 = Date.now()//R.t2
if(player!=null){
if(spyIndex.do && ws.botType!=spyIndex.val||!spyIndex.do){
player.x = playerInfo[1]
player.y = playerInfo[2]
}
player.x1 = player.x
player.y1 = player.y
player.speed = fastHypot(player.x2-playerInfo[1],player.y2-playerInfo[2])
player.xVel = playerInfo[1] - player.x2
player.yVel = playerInfo[2] - player.y2
player.x2 = playerInfo[1]
player.y2 = playerInfo[2]
player.d1 = void 0 === player.d2 ? playerInfo[3] : player.d2;
player.d2 = playerInfo[3];
player.dt = 0;
player.buildIndex = playerInfo[4];
player.weaponIndex = playerInfo[5];
player.weaponIndex >= 9 ? (player.secondary = player.weaponIndex) : (player.primary = player.weaponIndex);
player.weaponVariant = playerInfo[6];
player.team = playerInfo[7];
player.isLeader = playerInfo[8];
player.skinIndex = playerInfo[9];
player.tailIndex = playerInfo[10];
player.isSkull = playerInfo[11];
player.visible = true;
//console.log(calcVel(player));
//console.log(player.x,player.y)
!botIDS.includes(player.sid) && !ws.teamer(player.sid) && ws.enemies.push(player);
if(!(playerInfo[0] == ws.sid || playerInfo[7] && playerInfo[7] == ws.clan)) {
botEnemies[ws.botType] = playerInfo;
}
}
if(playerInfo[0] === ws.sid){ botter = playerInfo}
ws.reloadWeapon(player)
// if(playerInfo[0] === ws.sid)ws.doAll(playerInfo);
}
// ws.doAll(playerInfo)
ws.doAll(botter,ws.skinIndex == 56 && !botter ? true : false)
//console.log(Date.now())
if(ws.autohit){
if(ws.hitPacket % 2 == 0&&ws.alive){
// ws.emit(["K", [1]])
}
} else {
if(ws.hitPacket % 2 == 1){
// ws.emit(["K", [1]])
}
}
if(spyIndex.do&&spyBot?.bot?.sid === ws.sid){
//spyBot.realBuilds = removeDuplicates(spyBot.builds,et)
}
if (E.team&&ws.team!=E.team) {
if (ws.team && ws.team != E.team) {
// ws.emit("Q", undefined);
} else {
if (ws.team != E.team) {
ws.emit("b", E.team);
handleBotRequest(ws.sid)
}
}
}
}
}
//ws.onopen
}
function getRandomAng(e,t){
t = Math.random() * PI2;
if(e&&dAng(e,t)<=2){
return getRandomAng(e)
}
return t
}
function isInPath(e){
if(paths.length &&(pusher == false && pushing) && e.name != "pit trap"){
for(let i = 0; i< paths.length; i+=2){
if(dist({x:paths[i],y:paths[i+1]},e)<=e.scale-7.5){
return true;
}
}
}
return false;
}
function moveToPath(time,distance, x){
if (paths && paths.length && (keys.z || pusher==false&&pushing)) {
let spliceIndex = 0,startIndex=0;;
if(pushing&&paths.length*7>=distance) return;
while (startIndex < paths.length) {
const pointX = paths[startIndex];
const pointY = paths[startIndex + 1];
const distanceToPlayer = sqrt((E.x2 - pointX) ** 2 + (E.y2 - pointY) ** 2);
let threshold = x ? 10 : 35
if (distanceToPlayer <= threshold) {
spliceIndex += 2;
} else{
if(!pushing) break;
}
if(pushing&&distanceToPlayer>distance){
return false
}
startIndex += 2;
}
if (spliceIndex + 2 < paths.length) {
const nextPoint = { x: paths[spliceIndex], y: paths[spliceIndex + 1] };
ee.send("9", getDir(E, nextPoint),'pathfinder');
paths.splice(0, spliceIndex);
}
}
//console.log(Date.now()-time,"generate time")
return true;
}
function randomItem(e){
e = round(Math.random()*E.items.length-1)
if(e == 0) return randomItem()
return e
}
function sortPlayers(e,merge,ids =[]){
for(let i=0;i<e.length;i+=13){
ids.push(e[i])
for(let f=0;f<merge.length;f+=13){
if(ids.includes(merge[f]))merge.splice(f,13);
}
}
return e.concat(merge)
}
urls = R.list;
/*function findLoadout(e,t,dir,s=[],v=[],x){
s[0] = {
buildIndex: -1,
weaponIndex: primary,
skinIndex: e,
tailIndex: 0,
y: R.y2,
zIndex: null
}
s[1] = {
buildIndex: -1,
weaponIndex: secondary,
skinIndex: e,
tailIndex: 0,
y: R.y2,
zIndex: null
}
s[2] = {
buildIndex: 3,
weaponIndex: R.primary,
skinIndex: e,
tailIndex: 0,
y: R.y2,
zIndex: null
}
x = nEnemy.np.real
v[0] = {pos:calcVel(R,111,getDir(R,nEnemy),s[0]),move:dir,loadout:s[0]}
v[0].dist = dist(v[0].pos.accel,x),v[0].x2 = v[0].pos.accel.x,v[0].y2=v[0].pos.accel.y
v[1] = {pos:calcVel(R,111,getDir(R,nEnemy),s[1]),move:dir,loadout:s[1]}
v[1].dist = dist(v[1].pos.accel,x),v[1].x2 = v[1].pos.accel.x,v[1].y2=v[1].pos.accel.y
v[2] = {pos:calcVel(R,111,getDir(R,nEnemy),s[2]),move:dir,loadout:s[2]}
v[2].dist = dist(v[2].pos.accel,x),v[2].x2 = v[2].pos.accel.x,v[2].y2=v[2].pos.accel.y
if(speedTails.includes(11)){
s[0].tailIndex = 11
s[1].tailIndex = 11
s[2].tailIndex = 11
v[3] = {pos:calcVel(R,111,getDir(R,nEnemy),s[0]),move:dir,loadout:s[0]}
v[3].dist = dist(v[3].pos.accel,x),v[3].x2 = v[3].pos.accel.x,v[3].y2=v[3].pos.accel.y
v[4] = {pos:calcVel(R,111,getDir(R,nEnemy),s[1]),move:dir,loadout:s[1]}
v[4].dist = dist(v[4].pos.accel,x),v[4].x2 = v[4].pos.accel.x,v[4].y2=v[4].pos.accel.y
v[5] = {pos:calcVel(R,111,getDir(R,nEnemy),s[2]),move:dir,loadout:s[2]}
v[5].dist = dist(v[5].pos.accel,x),v[5].x2 = v[5].pos.accel.x,v[5].y2=v[5].pos.accel.y
}
if(speedTails.includes(19)){
s[0].tailIndex = 19
s[1].tailIndex = 19
s[2].tailIndex = 19
v[6] = {pos:calcVel(R,111,getDir(R,nEnemy),s[0]),move:dir,loadout:s[0]}
v[6].dist = dist(v[6].pos.accel,x),v[6].x2 = v[6].pos.accel.x,v[6].y2=v[6].pos.accel.y
v[7] = {pos:calcVel(R,111,getDir(R,nEnemy),s[1]),move:dir,loadout:s[1]}
v[7].dist = dist(v[7].pos.accel,x),v[7].x2 = v[7].pos.accel.x,v[7].y2=v[7].pos.accel.y
v[8] = {pos:calcVel(R,111,getDir(R,nEnemy),s[2]),move:dir,loadout:s[2]}
v[8].dist = dist(v[8].pos.accel,x),v[8].x2 = v[8].pos.accel.x,v[8].y2=v[8].pos.accel.y
}
v = v.filter((e) => e.dist>=t)
console.log(v)
return v
}
function tGCalc(t,z,loadouts=[],x=[]){
x[0] = {
buildIndex: -1,
weaponIndex: primary,
skinIndex: 53,
tailIndex: 0,
y: R.y2,
zIndex: null
}
x[1] = {
buildIndex: -1,
weaponIndex: secondary,
skinIndex: 53,
tailIndex: 0,
y: R.y2,
zIndex: null
}
x[2] = {
buildIndex: 3,
weaponIndex: primary,
skinIndex: 53,
tailIndex: 0,
y: R.y2,
zIndex: null
}
let q = {pos:R.np.decel,move:undefined}
q.dist = dist(q.pos,x),q.x2 = q.pos.x,q.y2=q.pos.y;
t.push(q)
t = t.forEach((e,c) => {
calcVel(e.pos,111,e.move,x[0])
calcVel(e.pos,111,e.move,x[1])
calcVel(e.pos,111,e.move,x[2])
x[0].tailIndex = 11;
x[1].tailIndex = 11;
x[2].tailIndex = 11;
calcVel(e.pos,111,e.move,x[0])
calcVel(e.pos,111,e.move,x[1])
calcVel(e.pos,111,e.move,x[2])
if(speedTails.include(19)){
x[0].tailIndex = 19;
x[1].tailIndex = 19;
x[2].tailIndex = 19;
calcVel(e.pos,111,e.move,x[0])
calcVel(e.pos,111,e.move,x[1])
calcVel(e.pos,111,e.move,x[2])
}
})
}*/
/*function tGCalc(t, z, loadouts = [], x = []) {
const base = {
buildIndex: -1,
weaponIndex: 0,
skinIndex: 53,
tailIndex: 0,
y: R.y2,
zIndex: null
};
for (let i = 0; i < 3; i++) {
x[i] = { ...base, weaponIndex: i === 0 ? secondary : primary, buildIndex: i === 2 ? 3 : -1};
}
const cV = (pos, move, tailIndex,h,j) => {
const loadout = { ...x[0], tailIndex };
h = calcVel(pos, 111, move, loadout);
j = { ...loadout, x2: pos.accel.x, y2: pos.accel.y, xVel: pos.xVel, yVel: pos.yVel, sid: R.sid }
loadouts.push(j)
};
const q = { pos: R.np.decel, move: undefined };
q.dist = dist(q.pos, x);
q.x2 = q.pos.x;
q.y2 = q.pos.y;
t.push(q);
for (const e of t) {
for (let i = 0; i < 3; i++) {
cV(e.pos, e.move, 0);
cV(e.pos, e.move, 11);
}
if (speedTails.includes(19)) {
for (let i = 0; i < 3; i++) {
x[i].tailIndex = 19;
cV(e.pos, e.move, 19);
}
}
}
return bHCalc(loadouts);
}
function bHCalc(t, z, loadouts = [], x = []) {
const base = {
buildIndex: -1,
weaponIndex: primary,
skinIndex: 53,
tailIndex: 0,
y: R.y2,
zIndex: null
};
for (let i = 0; i < 2; i++) {
x[i] = { ...base, tailIndex: i === 0 ? 19 : 0};
}
const cV = (pos, move, tailIndex,h) => {
const loadout = { ...x[0], tailIndex };
h = calcVel(pos, 111, move, loadout);
h.x2 = h.accel.x
h.y2 = h.accel.y
h.sid = R.sid
loadouts.push(h)
};
const speedTails = [11, 19];
const q = { pos: R.np.decel, move: undefined };
q.dist = dist(q.pos, x);
q.x2 = q.pos.x;
q.y2 = q.pos.y;
t.push(q);
for (const e of t) {
for (let i = 0; i < 3; i++) {
cV(e, e.move, 0);
cV(e, e.move, 11);
}
if (speedTails.includes(19)) {
for (let i = 0; i < 3; i++) {
x[i].tailIndex = 19;
cV(e, e.move, 19);
}
}
}
return loadouts;
}*/
// this version was uncommented, lets try using it though
function findLoadout2(e, t, dirs, type, d, s = [], v = [], p, range = R.weapons[primary].range, prange = R.projectiles[1].range + 35) {
// _,time,ang,set
const base = {
buildIndex: -1,
weaponIndex: 0,
skinIndex: [e, 53, 7][type] || 0,
tailIndex: 0,
y: E.y2,
zIndex: null,
sid: E.sid,
};
type == 2 ? p = 2 : p = 3;
Array.from({ length: p }, (_, i) => {
s[i] = {
...base,
...(type === 0 || type === 1 ? { weaponIndex: [secondary, primary, primary][i], buildIndex: i === 2 ? 3 : -1 } : {}),
...(type === 2 ? { tailIndex: i === 0 ? 19 : 0, weaponIndex: primary } : {}),
};
});
const cV = (i, tI, y, set, x, obj, arr = []) => {
!set && (set = E);
for(let H = 0; H < dirs.length; H++){
const next = calcVel(set, 111, dirs[H], { ...s[i] });
console.log(type,set,dirs[H],{ ...s[i] })
x = y ? next.decel : next.accel;
// console.log(next)
const distance = type === 2 ? dist(x, nEnemy.np.real,"player") : dist(x, nEnemy.np.real);
console.log(dirs[H]);
obj = {
pos: next ,
move: y ? undefined : dirs[H],
...s[i],
distance,
x2: x.x,
y2: x.y,
sid: E.sid,
xVel: next.xVel,
yVel: next.yVel,
type: y ? 'decel' : 'accel',
};
obj.t1 = type == 0 ? obj : set.t1 ? set.t1 : 0;
obj.t2 = type == 1 ? obj : set.t2 ? set.t2 : 0;
if(type == 2) obj.t3 = obj;
//arr.push(obj)
(!type||type === 1) && distance >= prange &&v.push(obj);
type === 2 && distance <= range && v.push(obj);
}
// return;
// return arr
};
looper: for (const tI of speedTails) {
if(tI == 11 && type === 2) continue looper;
for (let O = 0; O < p; O++) {
s[O].tailIndex = tI;
d ? d.forEach((_X) => cV(O, tI, false, _X)) : cV(O, tI)
}
}
// v = v.flat()
// console.log(v)
console.log(v)
console.log("move", v.move);
if(!type) return v//.filter(({ distance }) => distance >= t);
if(type === 1) return findLoadout(7, range, dirs, 2, v)//.filter(({ distance }) => distance >= t));
let avgr = prange + range
// a = v.filter(({ distance }) => distance <= range)
v.length ? v = v.reduce((b, c) => {
const s = c.t2.distance + c.t3.distance;
const cS = b.t2.distance + b.t3.distance;
const cD = Math.abs(cS - avgr);
const curD = Math.abs(s - avgr);
if (curD < cD) {
return c;
} else {
return b;
}
}) : v = null;
return v;
}
// Helper function to create base loadouts
function createBaseLoadout(weaponIndex, buildIndex, skinIndex = 53) {
return {
buildIndex: buildIndex,
weaponIndex: weaponIndex,
skinIndex: skinIndex,
tailIndex: 0,
y: E.y2,
zIndex: null
};
}
// Helper function to calculate velocities
function calculateVelocities(pos, move, tailIndex, baseLoadout) {
const loadout = { ...baseLoadout, tailIndex };
pos = JSON.parse(JSON.stringify(pos));
console.log(pos);
const velocity = calcVel(pos, 111, move, loadout);
return {
...loadout,
x2: velocity.accel.x,
y2: velocity.accel.y,
dist: dist(velocity.accel, pos),
xVel: pos.xVel,
yVel: pos.yVel,
sid: E.sid
};
}
function findLoadoutTest(e, t, dir, s = [], v = [], x) {
// Create initial loadouts
s[0] = createBaseLoadout(primary, -1, e);
s[1] = createBaseLoadout(secondary, -1, e);
s[2] = createBaseLoadout(E.primary, 3, e);
x = nEnemy.np.real;
// Calculate velocities and distances for each loadout
for (let i = 0; i < 3; i++) {
v[i] = { pos: calcVel(E, 111, getDir(E, nEnemy), s[i]), move: dir, loadout: s[i] };
v[i].dist = dist(v[i].pos.accel, x);
v[i].x2 = v[i].pos.accel.x;
v[i].y2 = v[i].pos.accel.y;
}
if (speedTails.includes(11)) {
for (let i = 0; i < 3; i++) {
s[i].tailIndex = 11;
v[i + 3] = { pos: calcVel(E, 111, getDir(E, nEnemy), s[i]), move: dir, loadout: s[i] };
v[i + 3].dist = dist(v[i + 3].pos.accel, x);
v[i + 3].x2 = v[i + 3].pos.accel.x;
v[i + 3].y2 = v[i + 3].pos.accel.y;
}
}
if (speedTails.includes(19)) {
for (let i = 0; i < 3; i++) {
s[i].tailIndex = 19;
v[i + 6] = { pos: calcVel(E, 111, getDir(E, nEnemy), s[i]), move: dir, loadout: s[i] };
v[i + 6].dist = dist(v[i + 6].pos.accel, x);
v[i + 6].x2 = v[i + 6].pos.accel.x;
v[i + 6].y2 = v[i + 6].pos.accel.y;
}
}
// Filter the results based on distance
v = v.filter(e => e.dist >= t);
console.log(`Loadouts ${v}`);
return v;
}
function tGCalc(t, z, loadouts = [], x = []) {
// Create initial loadouts
for (let i = 0; i < 3; i++) {
x[i] = createBaseLoadout(i === 0 ? secondary : primary, i === 2 ? 3 : -1);
}
const q = { pos: E/*.np.decel*/, move: undefined };
console.log(x);
q.dist = dist(q.pos, x);
q.x2 = q.pos.x;
q.y2 = q.pos.y;
t.push(q);
for (const e of t) {
for (let i = 0; i < 3; i++) {
loadouts.push(calculateVelocities(e.pos, e.move, 0, x[i]));
loadouts.push(calculateVelocities(e.pos, e.move, 11, x[i]));
}
if (speedTails.includes(19)) {
for (let i = 0; i < 3; i++) {
loadouts.push(calculateVelocities(e.pos, e.move, 19, x[i]));
}
}
}
return loadouts;
}
function bHCalc(t, z, loadouts = [], x = []) {
// Create initial loadouts
for (let i = 0; i < 2; i++) {
x[i] = createBaseLoadout(primary, -1, 53);
x[i].tailIndex = i === 0 ? 19 : 0;
}
const q = { pos: E/*.np.decel*/, move: undefined };
q.dist = dist(q.pos, x);
q.x2 = q.pos.x;
q.y2 = q.pos.y;
t.push(q);
console.log(q); /// get rid of E.np.decel and make it E
for (const e of t) {
for (let i = 0; i < 3; i++) {
loadouts.push(calculateVelocities(e.pos, e.move, 0, x[i]));
loadouts.push(calculateVelocities(e.pos, e.move, 11, x[i]));
}
if (speedTails.includes(19)) {
for (let i = 0; i < 3; i++) {
loadouts.push(calculateVelocities(e.pos, e.move, 19, x[i]));
}
}
}
return loadouts;
}
// Connect the pieces
function mainFunction(e, t, dir) {
let loadouts = [];
let finalLoadouts = findLoadoutTest(e, t, dir);
console.log(finalLoadouts);
finalLoadouts = tGCalc(finalLoadouts, null, loadouts);
finalLoadouts = bHCalc(finalLoadouts, null, loadouts);
return finalLoadouts;
}
function findLoadout(e, t, dirs, type, d,v = []) {
const base = {
buildIndex: -1,
weaponIndex: 0,
skinIndex: [e, 53, 7][type] || 0,
tailIndex: 0,
y: E.y2,
zIndex: null,
sid: E.sid,
};
const p = type === 2 ? 2 : 3;
const s = Array.from({ length: p }, (_, i) => ({
...base,
...(type === 0 || type === 1 ? { weaponIndex: [secondary, primary, primary][i], buildIndex: i === 2 ? 3 : -1 } : {}),
...(type === 2 ? { tailIndex: i === 0 ? 19 : 0, weaponIndex: primary } : {}),
}));
const calcVelocities = (i, tI, y, set) => {
//console.log(set);
const setObj = !set ? E : { t1: set.t1 || 0, t2: set.t2 || 0, t3: type === 2 ? set : 0 };
//console.log(setObj, setObj);
for (const dir of dirs) {
const next = calcVel(E/*!set ? E : set*/, dir, { ...s[i] });
let nxt = y ? next.decel : next.accel;
(!type || type === 1) && null //console.log(dist(nxt, nEnemy.np.real));
const distance = type === 2 ? dist(nxt, nEnemy.np.real, 'player') : dist(nxt, nEnemy.np.real/*, 'player'*/);
let obj = {
pos: next,
move: y ? undefined : dir,
...s[i],
distance,
x2: next.x,
y2: next.y,
sid: E.sid,
xVel: next.xVel,
yVel: next.yVel,
type: y ? 'decel' : 'accel',
...setObj
};
//console.log(`distance: ${distance}`);
((!type || type === 1) && (distance >= R.projectiles[1].speed*111+35)) && v.push(obj); // R.projectiles[1].speed*111+35
type === 2 && distance <= R.weapons[primary].range && v.push(obj);
}
};
for (const tI of speedTails) {
if (tI == 11 && type === 2) continue;
for (let O = 0; O < p; O++) {
s[O].tailIndex = tI;
d ? d.forEach((_X) => calcVelocities(O, tI, false, _X)) : calcVelocities(O, tI);
}
}
if (!type) return v;
if (type === 1) return findLoadout(7, R.weapons[primary].range, dirs, 2, v);
const avgr = (R.projectiles[1].speed*111+35)/*R.projectiles[1].range*/ + R.weapons[primary].range;
v.length && (v = v.reduce((b, c) => {
const s = c.t2.distance + c.t3.distance;
const cS = b.t2.distance + b.t3.distance;
const cD = Math.abs(cS - avgr);
const curD = Math.abs(s - avgr);
return curD < cD ? c : b;
}));
return v || null;
}
// ORIGIAL VERSION WITH ERORR
function findLoadoutOrig(e, t, dirs, type, d,v = []) {
const base = {
buildIndex: -1,
weaponIndex: 0,
skinIndex: [e, 53, 7][type] || 0,
tailIndex: 0,
y: E.y2,
zIndex: null,
sid: E.sid,
};
const p = type === 2 ? 2 : 3;
const s = Array.from({ length: p }, (_, i) => ({
...base,
...(type === 0 || type === 1 ? { weaponIndex: [secondary, primary, primary][i], buildIndex: i === 2 ? 3 : -1 } : {}),
...(type === 2 ? { tailIndex: i === 0 ? 19 : 0, weaponIndex: primary } : {}),
}));
const calcVelocities = (i, tI, y, set) => {
// const setObj = { tick1: set.tick1 || 0, tick2: set.tick2 || 0, tick3: type === 2 ? set : 0 };
for (const dir of dirs) {
const next = calcVel(E, 111, dir, { ...s[i] });
const typ = y ? next.decel : next.accel;
const distance = type === 2 ? dist(typ, nEnemy.np.real, 'player') : dist(typ, nEnemy.np.real);
console.log("next", next, "dist", distance, "dir", dir);
console.log(y ? 'decel' : 'accel');
const obj = {
pos: next,
move: y ? undefined : dir,
...s[i],
distance,
x2: typ.x,
y2: typ.y,
sid: E.sid,
xVel: next.xVel,
yVel: next.yVel,
type: y ? 'decel' : 'accel',
};
//console.log("obj", obj);
obj.tick1 = type == 0 ? obj : E.tick1 ? E.tick1 : 0;
obj.tick2 = type == 1 ? obj : E.tick2 ? E.tick2 : 0;
if(type == 2) obj.tick3 = obj;
(!type || type === 1) && distance >= R.projectiles[1].range + 35 && v.push(obj);
type === 2 && distance <= R.weapons[primary].range && v.push(obj);
console.log("v", v);
}
};
for (const tI of speedTails) {
if (tI == 11 && type === 2) continue;
for (let O = 0; O < p; O++) {
s[O].tailIndex = tI;
d ? d.forEach((_X) => calcVelocities(O, tI, false, _X)) : calcVelocities(O, tI);
}
}
if (!type) return v;
if (type === 1) return findLoadout(7, R.weapons[primary].range, dirs, 2, v);
const avgr = R.projectiles[1].range + R.weapons[primary].range;
v.length && (v = v.reduce((b, c) => {
const s = c.tick2.distance + c.tick3.distance;
const cS = b.tick2.distance + b.tick3.distance;
const cD = abs(cS - avgr);
const curD = abs(s - avgr);
return curD < cD ? c : b;
}));
return v || null;
}
/*function findloadoutOT(a = [], iteration = 0, info, finisher){
if(!nEnemy) return;
var base = {
buildIndex: -1,
weaponIndex: E.weaponIndex,
skinIndex: E.skinIndex,
tailIndex: E.tailIndex,
y: E.y2,
zIndex: null,
sid: E.sid,
},
projPos = multiCalcVel(nEnemy,3,nEnemy.movDir),
looping = iteration === 0 ? speedHats.concat([19],[0]) : iteration === 1 ? [53] : [7],
dirs = [getDir(E,nEnemy),getDir(nEnemy,E),getDir(E,projPos[2].real),getDir(projPos[2].real,E),undefined],//,undefined],
weps = [primary,secondary,[wallType]],
position;
for(let i=0;i<looping.length;i++){
let equip = {...base}
for(let x = 0; x < dirs.length;x++){
for(let v = 0; v < weps.length; v++){
if(!Array.isArray(looping[i])){
equip.skinIndex = looping[i]
if(!Array.isArray(weps[v]) || iteration === 2){
equip.weaponIndex = iteration === 2 ? primary : weps[v]
} else {
equip.buildIndex = wallType;
}
position = calcVel(E,dirs[x],equip)
} else {
equip.tailIndex = looping[i][0]
if(!Array.isArray(weps[v])){
equip.weaponIndex = weps[v]
} else {
equip.buildIndex = wallType;
};
position = calcVel(E,dirs[x],equip)
}
iteration === 1 && dist(position.real, projPos[1].real) > R.projectiles[1] * 111 - 35 ? a.push(position) :
iteration === 2 && dist(position.real, projPos[2].real, 'player') <= R.weapons[primary].range ? a.push(position) :
iteration === 0 && a.push(position)
}
}
}
const getOrder = function(e, t, skin, tail, wep, build){
e.tick = tick + iteration
e.skinIndex = skin
e.tailIndex = tail
e.weaponIndex = wep
e.buildIndex = build
e.xVel = e.xVel
e.yVel = e.yVel
e.x2 = e.real.x
e.y2 = e.real.y
e.moveAngle = t
e.distance = iteration === 2 ? dist(e, projPos[2], 'player') : dist(e, projPos[iteration])
}
}*/
// add full decel stop restriction, add hat, weapon, acc, buildIndex, at certain ticks or distance restriction
// add restrictions to certain hats, weapons, accessories, buildIndex on certain ticks or for the whole calculation
function velToPosition(a = [], iteration = 0, info, finisher) {
if (!nEnemy) return;
const base = {
buildIndex: -1,
weaponIndex: E.weaponIndex,
skinIndex: E.skinIndex,
tailIndex: E.tailIndex,
y: E.y2,
zIndex: null,
sid: E.sid,
};
const projPos = multiCalcVel(nEnemy, 3, nEnemy.movDir);
const looping = (iteration === 0 ? speedHats.concat([19], [0]) : iteration === 1 ? [53] : [7]);
const dirs = [getDir(E, nEnemy), getDir(nEnemy, E), getDir(E, projPos[2].real), getDir(projPos[2].real, E), undefined];
const weps = [primary, secondary, [wallType]];
let position;
const getOrder = function (e, t, x) {
console.log(e, t, x);
e.tick = tick + iteration;
e.skinIndex = x.skinIndex;
e.tailIndex = x.tailIndex;
e.weaponIndex = x.weaponIndex;
e.buildIndex = x.buildIndex;
e.xVel = e.xVel;
e.yVel = e.yVel;
e.x2 = e.real.x; // not x.
e.y2 = e.real.y; // not x.
e.moveAngle = t;
e.distance = (iteration === 2 ? dist(e, projPos[2], 'player') : dist(e, projPos[iteration]));
console.log(iteration, dist(e, projPos[2], 'player'), dist(e, projPos[iteration]));
//console.log(e.moveAngle, e.distance, e.skinIndex, e.tailIndex, e.weaponIndex, e.buildIndex);
}
for (let i = 0; i < looping.length; i++) {
for (let x = 0; x < dirs.length; x++) {
for (let v = 0; v < weps.length; v++) {
const equip = { ...base };
if (!Array.isArray(looping[i])) {
equip.skinIndex = looping[i];
equip.weaponIndex = (iteration === 2 ? primary : weps[v]);
equip.buildIndex = (!Array.isArray(weps[v]) || iteration === 2) ? -1 : wallType;
position = calcVel(E, dirs[x], equip);
} else {
equip.tailIndex = looping[i][0];
equip.weaponIndex = (!Array.isArray(weps[v])) ? weps[v] : E.weaponIndex;
equip.buildIndex = (Array.isArray(weps[v])) ? wallType : -1;
position = calcVel(E, dirs[x], equip);
}
if ((iteration === 1 && dist(position.real, projPos[1].real) > R.projectiles[1] * 111 - 35) ||
(iteration === 2 && dist(position.real, projPos[2].real, 'player') <= R.weapons[primary].range) ||
(iteration === 0)) {
a.push(position);
getOrder(position, dirs[x], equip); // Call getOrder here
}
}
}
}
}
/*function velToPos(conditions, target, currentIteration = 0, maxIterations = 4){
const base = {
buildIndex: -1,
weaponIndex: null,
skinIndex: null,
tailIndex: null,
y: E.y2,
zIndex: null,
sid: E.sid,
}
const looping = speedHats.concat([19], [0])
for(let XX = 1; XX < conditions.length + currentIteration; XX++){
const projPos = multiCalcVel(target, XX, target.movDir)
const dirs = [getDir(E, target), getDir(nEnemy, E), getDir(E, projPos[XX-1].real), getDir(projPos[XX-1].real, E), undefined];
for(let i = 0; i < conditions.length; i++){
let current = conditions[i]
}
}
const findNext = function(e,t){
// calcVel(E)
}
}*/
function velToPos(conditions, target, currentIteration = 0, maxIterations = 4, loadout = { hat: null, tail: null, weapon: null }, positions = []) {
const base = {
buildIndex: -1,
weaponIndex: null,
skinIndex: null,
tailIndex: null,
y: E.y2,
zIndex: null,
sid: E.sid,
};
const looping = speedHats.concat([19], [0]);
if (currentIteration < maxIterations) {
const projPos = multiCalcVel(target, currentIteration, target.movDir);
const dirs = [getDir(E, target), getDir(nEnemy, E), getDir(E, projPos[currentIteration - 1].real), getDir(projPos[currentIteration - 1].real, E), undefined];
function calcVel(_,ang,set,docalc,time = 111){
looping.forEach((hatOrTail) => {
dirs.forEach((direction) => {
const newLoadout = { ...loadout, skinIndex: hatOrTail, tailIndex: hatOrTail };
/* // Check hat and tail restrictions
if (isValidLoadout(newLoadout, conditions)) {
conditions.forEach((currentCondition) => {
const distance = dist2(projPos[currentIteration - 1], currentCondition.position);
if (currentCondition.operator === '<=' && distance <= currentCondition.value) {
newLoadout.weapon = currentCondition.weapon;
// Check weapon restrictions
if (isValidLoadout(newLoadout, conditions)) {
positions.unshift(projPos[currentIteration - 1]);
velToPos(conditions, target, currentIteration + 1, maxIterations, newLoadout, positions);
}
} else if (currentCondition.operator === '>=' && distance >= currentCondition.value) {
// Similar logic as above
}
});
}*/
});
});
}
// Return the final positions array when reaching the last iteration
if (currentIteration === maxIterations) {
console.log("Final positions:", positions);
}
function tempLoadout(current, hat, tail, x, y, xVel, yVel){
let temp = {...current}
current.x2 = x
current.y2 = y
current.xVel = xVel
current.yVel = yVel
current.skinIndex = hat
current.tailIndex = tail
return current;
}
}
}
function pAC(e,t,n,i,p){
i = hitEnemy(e,t,n)
i&&(p=true)
i = hitEnemy(e,t+toRad(15),n)
i&&(p=true)
i = hitEnemy(e,t-toRad(15),n)
i&&(p=true)
i = hitEnemy(e,t+toRad(30),n)
i&&(p=true)
i = hitEnemy(e,t-toRad(30),n)
i&&(p=true)
i = hitEnemy(e,t+toRad(45),n)
i&&(p=true)
i = hitEnemy(e,t-toRad(45),n)
i&&(p=true)
if(p) return true;
return false
}
function hitEnemy(e, t, n, i) {
i = (35 + e.scale + (e.placeOffset || 0));
let l = nEnemy.x2-(E.x2+cos(t)*i)
, h = nEnemy.y2-(E.y2+sin(t)*i)
, u = 35 + e.scale
, placer = ue.checkItemLocation3(E.x2 + cos(t) * i, E.y2 + sin(t) * i, e.scale, .6, e.id,false)
if(n && placer) {
if ((abs(l) <= u || abs(h) <= u)&&dist(nEnemy,E)<=35+n.scale) {
place(e.id, t)
return true;
}
}
return false;
};
function spikeSyncer(e, t, n, aimer) {
if (!nEnemy || E.pr != 1 || instaing || !spikeTicker.checked ||/*(primary != 5 || primary != 4 || primary != 3)||*/oneTick) return;
if(primary == 3 || primary == 4 || primary == 5) {
for (let i = spikeSync.length - 1; i >= 0; i--) {
e = spikeSync[i];
if (!inRender(E, e)) {
spikeSync.splice(i, 1);
continue;
}
t = ue.checkItemLocation2(e.x, e.y, R.list[spikeType].scale, 0.6, e.id, false);
if (!t) {
spikeSync.splice(i, 1);
continue;
}
console.log(e);
if (t && !instaing && dist(E, e) <= 126 &&dist(nEnemy,e)<=e.scale+35&& dist(E, nEnemy, "player") <= R.weapons[primary].range) {
n = polePlacer/*pAC*/(R.list[spikeType], getDir(E, e), e);
console.log("n", n);
if (!n) {
spikeSync.splice(i, 1);
continue;
}
spikeSync.splice(i, 1);
addChatLog(`Spike tick on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
place(E.items[2], getDir(E, e));
instaing = true;
aimer = getDir(E, nEnemy);
aim[0] = aimer;
ee.send("D", aimer, "client");
visAim = true;
Hg(7, 18);
hold = primary;
ee.send("z", primary, true);
setTimeout(() => {
instaing = false;
visAim = false;
hold = null;
}, 111);
}
}
spikeSync = [];
}
}
function checkPlace(e, t, n,build, i) {
i = (35 + e.scale + (e.placeOffset || 0));
let l = nEnemy.x2-(E.x2+cos(t)*i)
, h = nEnemy.y2-(E.y2+sin(t)*i)
, u = 35 + e.scale
, placer = ue.checkItemLocation4(E.x2 + cos(t) * i, E.y2 + sin(t) * i, e.scale, .6, n.id,false,n)
if(n && placer) {
if ((abs(l) <= u || abs(h) <= u)&&dist(nEnemy,n)<=n.scale+35) {
//place(e, t)
return true;
}
}
return false;
};
function polePlacer(e,t,n,i,p){
i = checkPlace(e,t,n)
i&&(p=true)
i = checkPlace(e,t+toRad(15),n)
i&&(p=true)
i = checkPlace(e,t-toRad(15),n)
i&&(p=true)
i = checkPlace(e,t+toRad(30),n)
i&&(p=true)
i = checkPlace(e,t-toRad(30),n)
i&&(p=true)
if(p) return true;
return false
}
async function spikeTickAids(e,t,g,z,dists) {
if(!poleAids.checked|| !nEnemy||secondary!=10||!nEnemy?.inTrap||autobreakBuild||instaing||oneTick||pushing||E.sr!=1||E.pr!=1) return;
if(primary == 3 || primary == 4 || primary == 5) {
let coords;
t = nEnemy.inTrap
e = getDir(E,t)
g = 75*Variants[E.secondaryVar]*(bH.includes(40)?3.3:1)>=t.health
z = R.weapons
dists = [dist(E,t,"object"),dist(E,nEnemy,"player")]
// new aids concept for diamond katana, use bull hit or even tank hit to kill with spike sync ez. just that only will work with bull on soldier, and tank on no soldier
if((dists[0]<=z[secondary].range&&dists[1]<=z[primary].range)&&polePlacer(R.list[spikeType],e,t)&&shieldBypass(E,nEnemy) && g && (((primary == 5 && E?.primaryVar == 1) || (primary == 4 && E?.primaryVar > 1)) ? (nEnemy.weaponR == 1 && nEnemy.weaponIndex <= 10) : true) && E.tailIndex!=11){
//await nextTick();
//addChatLog(`${nEnemy.health}`,'', '#5c0620',false,true);
autobreakBuild = true;
if(E?.dmgpot?.soldier && nEnemy.pr == 1 && E?.dmgpot?.shouldHeal && [4, 5].includes(nEnemy?.primary)) {
addChatLog(`Cancelled TA due to spike sync threat`,'', '#5c0620',false,true);
Hg(6, 0);
} else {
Hg(40, 0);
}
aim[0] = e
ee.send("D", e)
visAim = true;
hold = secondary;
E.hitting = true;
ee.send("z",secondary,true)
breaking = true;
addChatLog(`TA on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
await nextTick()
addChatLog(`${nEnemy.health}`,'', '#5c0620',false,true);
autobreakBuild = false;
instaing = true;
hold = primary
if(E?.dmgpot?.soldier && nEnemy.pr == 1 && E?.dmgpot?.shouldHeal && [4, 5].includes(nEnemy?.primary)) {
addChatLog(`Cancelled TA due to spike sync threat`,'', '#5c0620',false,true);
Hg(6);
} else {
Hg(7);
}
ee.send("z",primary, true)
e= getDir(E,t)
E.hitting = true;
aim[0] = e;
// pAC(R.list[spikeType],e,t)
ee.send("D",getDir(E,nEnemy))
// place(spikeType,e)
place(spikeType,e+toRad(15),primary)
place(spikeType,e-toRad(15),primary)
place(spikeType,getDir(E,nEnemy),primary)
ee.send("D",getDir(E,nEnemy))
ee.send("z",primary, true)
await nextTick()
//if(nEnemy) addChatLog(`${nEnemy.health}`,'', '#5c0620',false,true);
visAim = false;
hold = null
breaking = false;
aim[0] =null;
instaing = false;
}
}
}
async function breakShit(e,t,g,g2,z,dists){
if(primary!=5||E.primaryVar<2||!poleAids.checked|| !nEnemy||secondary!=10||!nEnemy?.inTrap||autobreakBuild||instaing||meleesyncing||oneTick||E.sr!=1||E.pr!=1) return
let coords;
t = nEnemy.inTrap
e = getDir(E,t)
g = 75*Variants[E.secondaryVar]*(bH.includes(40)?3.3:1)>=t.health
g2 = (75*Variants[E.secondaryVar]*(bH.includes(40)?3.3:1)) + ((nEnemy.secondary == 10 ? 75 : R.weapons[nEnemy.primary].dmg)*Variants[E.secondary == 10 ? nEnemy.secondaryVar : nEnemy.primaryVar] * 3.3) >= t.health
z = R.weapons
dists = [dist(E,t,"object"),dist(E,nEnemy,"player")]
//if(dists[0]<=z[secondary].range+20&&g){
// for(let i=0;i<8;i++){
// coords = calcPoint(t.x,t.y,getDir(t,R),80)
//Tach?.updateChat(`goto ${coords.x} ${coords.y}`, R.sid);
// }
//}
if((dists[0]<=z[secondary].range&&dists[1]<=z[primary].range)&&polePlacer(R.list[spikeType],e,t)&&shieldBypass(E,nEnemy)){
if(g2) { // other version (their tank hit + mine) break trap then I aids (only if they have hammer though)
// trap is brand new...
if((t.health == 500 ? true : (nreload(nEnemy) == 1 && nEnemy.weaponR != 1) && nEnemy.skinIndex != 6 && dists[0]<=z[secondary].range&&dists[1]<=z[primary].range)&&polePlacer(R.list[spikeType],e,t)&&shieldBypass(E,nEnemy)&&E.tailIndex!=11){
autobreakBuild = true;
Hg(40,0);
aim[0] = e
ee.send("D", e, "client")
visAim = true;
hold = secondary;
E.hitting = true;
ee.send("z",secondary,true)
breaking = true;
addChatLog(`Alternate Polearm Aids on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
addChatLog(`Total Dmg ${(75*Variants[E.secondaryVar]*(bH.includes(40)?3.3:1)) + ((nEnemy.secondary == 10 ? 75 : R.weapons[nEnemy.primary].dmg)*Variants[E.secondary == 10 ? nEnemy.secondaryVar : nEnemy.primaryVar] * 3.3)}, Enemy Skin: ${nEnemy.skinIndex}`,'', '#5c0620',false,true);
breakBuild(e,secondary,E.secondaryVar,40,1)
await nextTick()
instaing = true;
hold = primary
Hg(7,18)
ee.send("z",primary, true)
e= getDir(E,t)
E.hitting = true;
aim[0] = e;
// pAC(R.list[spikeType],e,t)
ee.send("D",getDir(E,nEnemy), "client")
// place(spikeType,e)
place(spikeType,e+toRad(15),primary)
place(spikeType,e-toRad(15),primary)
place(spikeType,getDir(E,nEnemy),primary)
ee.send("D",getDir(E,nEnemy), "client")
ee.send("z",primary, true)
await nextTick()
visAim = false;
autobreakBuild = false;
hold = null
breaking = false;
aim[0] =null;
instaing = false;
}
}
if(g) {
autobreakBuild = true;
Hg(40,0);
aim[0] = e
ee.send("D", e, "client")
visAim = true;
hold = secondary;
E.hitting = true;
ee.send("z",secondary,true)
breaking = true;
addChatLog(`PA on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
breakBuild(e,secondary,E.secondaryVar,40,1)
await nextTick()
instaing = true;
hold = primary
Hg(7,18)
ee.send("z",primary, true)
e= getDir(E,t)
E.hitting = true;
aim[0] = e;
// pAC(R.list[spikeType],e,t)
ee.send("D",getDir(E,nEnemy), "client")
// place(spikeType,e)
place(spikeType,e+toRad(15),primary)
place(spikeType,e-toRad(15),primary)
place(spikeType,getDir(E,nEnemy),primary)
place(spikeType,e,primary)
ee.send("D",getDir(E,nEnemy), "client")
ee.send("z",primary, true)
await nextTick()
visAim = false;
autobreakBuild = false;
hold = null
breaking = false;
aim[0] =null;
instaing = false;
} /*else if(g2) { // other version (their tank hit + mine) break trap then I aids
if(((nreload(nEnemy) == 1 && nEnemy.weaponR != 1) && nEnemy.skinIndex != 6 && dists[0]<=z[secondary].range&&dists[1]<=z[primary].range)&&polePlacer(R.list[spikeType],e,t)&&shieldBypass(E,nEnemy)&&E.tailIndex!=11){
autobreakBuild = true;
Hg(40,0);
aim[0] = e
ee.send("D", e, "client")
visAim = true;
hold = secondary;
E.hitting = true;
ee.send("z",secondary,true)
breaking = true;
addChatLog(`Alternate Polearm Aids on ${nEnemy.name}[${nEnemy.sid}]`,'', '#5c0620',false,true);
addChatLog(`Total Dmg ${(75*Variants[E.secondaryVar]*(bH.includes(40)?3.3:1)) + ((nEnemy.secondary == 10 ? 75 : R.weapons[nEnemy.primary].dmg)*Variants[E.secondary == 10 ? nEnemy.secondaryVar : nEnemy.primaryVar] * 3.3)}, Enemy Skin: ${nEnemy.skinIndex}`,'', '#5c0620',false,true);
breakBuild(e,secondary,E.secondaryVar,40,1)
await nextTick()
instaing = true;
hold = primary
Hg(7,18)
ee.send("z",primary, true)
e= getDir(E,t)
E.hitting = true;
aim[0] = e;
// pAC(R.list[spikeType],e,t)
ee.send("D",getDir(E,nEnemy), "client")
// place(spikeType,e)
place(spikeType,e+toRad(15),primary)
place(spikeType,e-toRad(15),primary)
place(spikeType,getDir(E,nEnemy),primary)
ee.send("D",getDir(E,nEnemy), "client")
ee.send("z",primary, true)
await nextTick()
visAim = false;
autobreakBuild = false;
hold = null
breaking = false;
aim[0] =null;
instaing = false;
}
}*/
}
}
function rubyPH(){
if(!nEnemy||!E.pr||!E.sr||!(E.primaryVar===3||E.secondaryVar===3)||secondary!=10||primary!=5) return;
}
/*function shootSync(e,t){
if(!keys.R||!R.sr===1||!R.tr===1||!nEnemy||secondary!=15) return;
aim[0] = getDir(R, nEnemy);
visAim = true;
ee.send("D", getDir(R, nEnemy));
instaing = true;
Hg(53, 0);
const timeDifference = (calcprojHit(R, nEnemy,1, 1.5)) -( calcprojHit(R, nEnemy,5, 3.6));
setTimeout(() => {
aim[0] = getDir(R, nEnemy);
visAim = true;
ee.send("D", getDir(R, nEnemy));
ee.send("z", secondary, true);
hold = secondary;
}, timeDifference-pingavg);
setTimeout(() => {
instaing = false;
}, timeDifference + 111);
/*e = syncproj([R],nEnemy,5,3.6)
console.log(e)
setTimeout(() => {
instaing = true;
Hg(53,11)
hold = primary
ee.send('G',primary,true);
},e.pP[0].waitTimeForTurretBall);
setTimeout(() => {
hold = secondary;
t = getDir(R,nEnemy)
aim[0] = t
ee.send("D",t)
ee.send('K',1)
ee.send('G',secondary,true)
},e.pP[0].waitTimeForMusket)
setTimeout(() => {
instaing = false;
hold = null
},e.pP[0].waitTimeForMusket+111)
}*/
function maxTime() {
if(E&&amAlive&&syncTeam) {
return max(CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy)), CPH6(syncTeam, nEnemy, 1, 1.5, getDir(syncTeam, nEnemy)));
}
}
/* function maxTime3() {
if(R&&amAlive&&syncTeam) {
console.log(Math.max(CPH6(R, nEnemy, 5, 4.68, getDir(R, nEnemy)), CPH6(syncTeam, nEnemy, 5, 4.68, getDir(syncTeam, nEnemy))))
return Math.max(CPH6(R, nEnemy, 5, 4.68, getDir(R, nEnemy)), CPH6(syncTeam, nEnemy, 5, 4.68, getDir(syncTeam, nEnemy)));
}
} */
function maxTime2() {
if (allies.length > 0 && amAlive && nEnemy) {
return max(...allies.map(ally=> CPH6(ally,nEnemy,1,1.5,getDir(ally,nEnemy))))
}
}
// Global variables
let songList = [];// Array to hold the song URLs
let playedSongs = [];// Array to keep track of played songs
let currentSong = null;// Variable to store the current playing song
function playMusic(songs) {
songList = songs; // Update the song list
if (gE('music')?.checked) {
if (currentSong !== null) {
currentSong.pause();
}
if (playedSongs.length === songList.length) {
playedSongs = []; // Reset the played songs list
}
let randomIndex;
do {
randomIndex = floor(Math.random() * songList.length);
} while (playedSongs.includes(randomIndex));
const songUrl = songList[randomIndex];
currentSong = new Audio();
currentSong.src = songUrl;
currentSong.preload = "auto";
currentSong.play();
currentSong.addEventListener('ended', handleSongEnded);
} else {
if (currentSong !== null) {
currentSong.pause();
}
}
}
function handleSongEnded() {
if (currentSong !== null) {
currentSong.removeEventListener('ended', handleSongEnded);
playedSongs.push(songList.indexOf(currentSong.src));
currentSong = null;
}
}
// Command to start playing random songs
function startRandomSongs() {
if (currentSong === null) {
playMusic(songList);
}
}
// Example usage:
const songs = [
'https://example.com/song1.mp3',
'https://example.com/song2.mp3',
'https://example.com/song3.mp3',
// Add more song URLs as needed
];
/* ORIGINAL
function shootSync2(e, g) {
if (R.sr !== 1 || R.tr !== 1 || !nEnemy || !syncTeam || dist(R,nEnemy) > 700 || dist(syncTeam, nEnemy) > 700 || syncTeam.sr !== 1 || syncTeam.tr !== 1) return;
if (R && amAlive && nEnemy && syncTeam) {
var timeDifference;
var myTurret = CPH6(R, nEnemy, 1, 1.5, getDir(R, nEnemy));
var time1 = maxTime();
var time2;
if(R.list[utilityType].name == "platform")place(utilityType,getDir(R,nEnemy));
if(secondary == 15){
time2 = CPH6(R, nEnemy, 5, 3.6, getDir(R, nEnemy));
}
if (secondary == 9) {
time2 = CPH6(R, nEnemy, 0, 1.6, getDir(R, nEnemy));
}
if (secondary == 13) {
time2 = CPH6(R, nEnemy, 3, 2.0, getDir(R, nEnemy));
}
if (secondary == 12) {
time2 = CPH6(R, nEnemy, 2, 2.5, getDir(R, nEnemy));
}
e = (time1 * 111) - (time2 * 111);
g = (time1 * 111) - (myTurret * 111);
}
setTimeout(() => {
instaing = true;
aim[0] = getDir(R, nEnemy);
visAim = true;
ee.send("D", getDir(R, nEnemy));
Hg(53, 0);
}, g);
setTimeout(() => {
instaing = true;
aim[0] = getDir(R, nEnemy);
visAim = true;
ee.send("D", getDir(R, nEnemy));
ee.send("z", secondary, true);
hold = secondary;
}, e);
setTimeout(() => {
instaing = false;
}, 666);
} */
//EXPERIMENTAL
function shootSync2(e, g) {
if (E.sr !== 1 || E.tr !== 1 || !nEnemy || !syncTeam || dist(E,nEnemy) > 700 || dist(syncTeam, nEnemy) > 700 || syncTeam.sr !== 1 || syncTeam.tr !== 1) return;
if (E && amAlive && nEnemy && syncTeam) {
var timeDifference;
var myTurret = CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy));
var time1 = maxTime();
var time2;
if(R.list[utilityType].name == "platform")place(utilityType,getDir(E,nEnemy));
if(secondary == 15&&CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))==CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy))) {
time2 = CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy));
} else if(secondary == 15 && CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))!==CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy))) {
time2 = CPH6(E, nEnemy, 5, 4.68, getDir(E, nEnemy));
}
if (secondary == 9) {
time2 = CPH6(E, nEnemy, 0, 1.6, getDir(E, nEnemy));
}
if (secondary == 13) {
time2 = CPH6(E, nEnemy, 3, 2.0, getDir(E, nEnemy));
}
if (secondary == 12) {
time2 = CPH6(E, nEnemy, 2, 2.5, getDir(E, nEnemy));
}
e = (time1 * 111) - (time2 * 111);
g = (time1 * 111) - (myTurret * 111);
}
setTimeout(() => {
instaing = true;
aim[0] = getDir(E, nEnemy);
visAim = true;
ee.send("D", getDir(E, nEnemy), "client");
Hg(53, 0);
}, g);
setTimeout(() => {
if(CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))!==CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy))) {
Hg(1,0);
}
instaing = true;
aim[0] = getDir(E, nEnemy);
visAim = true;
ee.send("D", getDir(E, nEnemy), "client");
ee.send("z", secondary, true);
hold = secondary;
}, e);
setTimeout(() => {
instaing = false;
}, 666);
}
async function shootSync(e) {
if (!keys.R || E.sr !== 1 || E.tr !== 1 || !nEnemy) return;
if(E&&amAlive&&nEnemy) {
var timeDifference;
var time1 = CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy));
var time2
if(secondary == 15&&CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))==CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy))) {
time2 = CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy));
} else if(secondary == 15 && CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))!==CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy))) {
time2 = CPH6(E, nEnemy, 5, 4.68, getDir(E, nEnemy));
}
if(secondary == 9) {
time2 = CPH6(E, nEnemy, 0, 1.6, getDir(E, nEnemy));
}
if(secondary == 13) {
time2 = CPH6(E, nEnemy, 3, 2.0, getDir(E, nEnemy));
}
if(secondary == 12) {
time2 = CPH6(E, nEnemy, 2, 2.5, getDir(E, nEnemy));
}
e = (time1*111)-(time2*111)
console.log(e)
}
instaing = true
aim[0] = getDir(E, nEnemy);
visAim = true;
ee.send("D", getDir(E, nEnemy));
Hg(53, 0);
await delay(e);
if(CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))!==CPH6(E, nEnemy, 5, 3.6, getDir(E, nEnemy))) {
Hg(1,0);
}
instaing = true;
aim[0] = getDir(E, nEnemy);
visAim = true;
ee.send("D", getDir(E, nEnemy));
ee.send("z", secondary, true);
hold = secondary;
await delay(222);
instaing = false;
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function CPH6(start, target, projectileType, projectileSpeed, ang) {
var ux = projectileSpeed * cos(ang);
var uy = projectileSpeed * sin(ang);
var distanceToTarget = dist(start, target);
var time;
if (projectileType !== 1) {
time = max((distanceToTarget - 105) / sqrt(ux * ux + uy * uy), 0);
} else {
time = max((distanceToTarget - 35) / sqrt(ux * ux + uy * uy), 0);
}
var roundedTime;
roundedTime = floor(time / 111);
return roundedTime;
}
/* function CPH6(start, target, projectileType, projectileSpeed, ang) {
var distanceToTarget = dist(start, target);
var time;
if (projectileType !== 1) {
time = Math.max((distanceToTarget - 105) / projectileSpeed, 0);
} else {
time = Math.max((distanceToTarget - 35) / projectileSpeed, 0);
}
var roundedTime;
roundedTime = Math.floor(time / 111);
return roundedTime;
} */
function CPH2(start, target, projectileType, projectileSpeed, ang) {
var ux = projectileSpeed * cos(ang);
var uy = projectileSpeed * sin(ang);
// let coords = calcPoint(start.x2,start.y2,ang,70)
var distanceToTarget = dist(E,target);
var ticks = (distanceToTarget - 35) / (projectileSpeed*111)/// coorprods//Math.sqrt(ux*ux + uy*uy);
ticks = ticks<1?0:ceil(ticks)
return ticks;
}
function calcProjs(pT, pS, coords) {
coords = calcPoint(E.x2,E.y2,getDir(E,nEnemy),pT == 1 ? 0 :70)
return (dist(coords,nEnemy)-35)/pS
// let coords = calcPoint(start.x2,start.y2,ang,70)
//
// /// var distanceToTarget = dist(R,target);
// var ticks = (distanceToTarget - 35) / (projectileSpeed*111)/// coorprods//Math.sqrt(ux*ux + uy*uy);
//ticks = ticks<1?0:Math.ceil(ticks)
// return ticks;
}
async function Qz(id,d,t,date,bot,_){
// let d = t - _.health;
let cheeser;
_=findPlayerSID(id)
if(_.health<=0&&_.vis2&&!_.visible&&!_.didDeath) createDeathAnim(_,55,.28,48,13,.00215,0), _.deaths++, _.didDeath = true;
if(!E.healths) E.healths = [];
if(_.sid==E.sid){
if(E.healths.length >= 8) E.healths.pop()
if(_.sid == E.sid) E.healths.push({hp:_.health,tick: tick})
}
if(d==-5*(_.skinIndex==6?.75:1)&& _.poison){
_.lastBull = tick-1
//console.log(_.name, "new poison tick")
}
if(_.health<=0)_.Alive=false,_.Alive2 = false;
if(d<0){
if(_.sid!=E.sid&&_.dmgs=="XD"){ _.dmgs=0}
if(_.sid!=E.sid){_.dmgs+=abs(d)}
if(_==E)E.lastDamage3 = date// console.log(Date.now()-R.lastDamage
// _.deathDmgs
}
_.dmgsNow.unshift(round(d * 100) / 100)
if(d > 0){
// console.log(d,TIME0-Date.now())
if(_.skinIndex == 13){
if(_.tailIndex == 13){
d == 6 && (_.lastBull = tick-1)
E == _ && (failsafe = 0);
return;
}else{
d == 3 && (_.lastBull = tick-1)
E == _ && (failsafe = 0);
return;
}
}
if(!isNaN(_.shameCount) && _.lastDamage){
if(date - _.lastDamage<=120){
_.healTime = date - _.lastDamage2;
_.shameCount>=8&&_.assumeAge>=7 && abs(time-date)<=2&&d<=10 &&_.loadout.utility==undefined&& (_.loadout.utility = E.list[2])
cheeser = _.assumeAge>=7 && (_.loadout?.utility?.name=="cheese") && abs(time-date)<=2&&d<=10 ? true:false
if(!cheeser){
_.noAntiList = _.noAntiList.map((a) => a * 0.95);
!_.shameUp && (_.shameUp = [])
_.shameUp.length>=5&&_.shameUp.shift()
_.shameUp.push(_.healTime)
_.gainSpeed = _.shameUp.reduce((a, b) => a + b, 0)/_.shameUp.length
_.prevShameUp = _.shameCount;
if(_.lowHealth <= 40){
_.noAntiList[_.shameCount]--;
}
/*if(_.lowHealth - (R.weapons[primary].dmg * 1.5)) <= 0) {
}*/ // add future sync hit here for syncing with teammates
_.shameCount = min(8, _.shameCount + 1);
/*_.healTrack.push({
type: "gain",
shameUp: _.shameUp,
gainSpeed: _.gainSpeed,
prevShameUp: _.prevShameUp,
shameCount: _.shameCount,
healTime: _.healTime,
dmg: d,
tick: tick
});*/
// if(_.sid === E.sid)console.log(_.healTime);
// _.trackGain.push(_)
}
}else{
cheeser = _.assumeAge>=7 && (_.loadout?.utility?.name=="cheese") && abs(time-date)<=2&&d<=10 ? true:false
if(!cheeser){
_.healTime = date - _.lastDamage2;
!_.shameDown&&(_.shameDown = [])
_.shameDown.length>=5&&_.shameDown.shift()
_.shameDown.push(_.healTime);
_.leakSpeed = _.shameDown.reduce((a, b) => a + b, 0)/_.shameDown.length;
_.prevShameDown = _.shameCount;
// if(_.sid ==R.sid)console.log(R.healTime, " heal leak")
//_.sid==R.sid && console.log(_.healTime, " leak",pingval,125-pingval),console.log(healerTime-_.lastDamage2),console.log(TIME0-G0)
if(_.lowHealth <= 60){
_.noAntiList[_.shameCount]++;
//add grubbs test here?
let sum = _.noAntiList.reduce((a, b)=>a + (b > 0 ? b : 0), 0);
if(sum >= 3){
let index = _.noAntiList.indexOf(Math.max(..._.noAntiList));
if(_.noAntiList[index] * 2 > sum){
_.noAnti = index;
}
}
}
_.shameCount = max(0, _.shameCount-2);
//if(_.sid != E) {
// here we check if they didn't heal the spike and our primary hit can kill them, only when they are not in trap
// console.log("yeah", d);
//}
/*_.healTrack.push({
type: "leak",
shameDown: _.shameDown,
leakSpeed: _.leakSpeed,
prevShameUp: _.prevShameUp,
shameCount: _.shameCount,
healTime: _.healTime,
healed: d,
tick: tick
});*/
// if(nEnemy && _.sid == nEnemy.sid) console.log(_.healTime, "shame Down")
// if(_==R)console.log(R.lastDamage, "qz")// console.log(R.healTime)
// _.trackLeak.push(_)
}
}
//_.sid==R.sid && console.log(_.healTime,pingval,125-pingval,time-date)//,console.log(healerTime-_.lastDamage2),console.log(TIME0-G0)
_.lastDamage = 0;
_.lastDamage2 = 0;
_.thisHealth = undefined;
}
// console.log(cheeser)
}else{
_.lowHealth = t;
//console.log(E.lowHealth, E.noAnti, E.noAntiList);
_.lastDamage = date//tC//Date.now();
_.lastDamage2 = date
_.dmgDate = date
_.thisHealth = _.health;
if(!clan(_.sid)&&nEnemy?.inTrap){
let tmpspk = renderObjects.filter(e => dist(nEnemy.inTrap,e)<=(50+e.scale+35)&&(clan(e?.owner?.sid)&&e?.group?.name=='spikes'||nEnemy&&!nEnemy.team && e?.group?.name=='spikes'&&e?.owner?.sid!=nEnemy.sid||e?.type==1 && e.y>=12000));
if(tmpspk.length&&d==-(tmpspk[0]?.type != 1 ?tmpspk[0]?.dmg:35)*(_.skinIndex==6? .75:1)) _.hitSpike = true
}
if(_.sid===E.sid){
let tmpspk = renderObjects.filter(e => dist(E,e)<=e.scale+35&&(!clan(e?.owner?.sid)&&e?.group?.name=='spikes'||e?.type==1 && e.y>=12000));
if(tmpspk.length&&d==-(tmpspk[0]?.type != 1 ?tmpspk[0]?.dmg:35)*(_.skinIndex==6? .75:1)){
// addChatLog(`${E.name}[${E.sid}] hit spike`,'', E.color,false,true);
//console.log(d);
_.hitSpike = tmpspk[0];
}
}
//if(nEnemy&&_.sid==nEnemy.sid&& (d==-25*(nEnemy.skinIndex==6?.75:1)||d==-50*(nEnemy.skinIndex==6?.75:1))){
//console.log(R.deltas,tick,'proj hit')
//}
//if(nEnemy&&_.sid==nEnemy.sid){
//}
// if(nEnemy&&nEnemy.sid == _.sid&&d==R.list[spikeType].dmg*(nEnemy.skinIndex==6? .75:1))_.hitSpike = true;
if(_.skinIndex == 7){
if(_.tailIndex == 13){
if(d == -2){
_.lastBull = tick-1
_.lastBull2 = Date.now();
_.bTT = 1000;
// _.lastBull = tC//Date.now())
// _.lastBull = tC;
// R == _ && autoheal && (setTimeout(()=>{Sn(R.items[0]), ee.send("d", 1),ee.send("d", 0), Sn(oW, 1)}, 100), FT = 0,FT2=0)
return;
}
}else{
if(d == -5){
// if(_==R && timeTillBleed!=undefined) console.log(Date.now()-timeTillBleed, "qz time lapse")
if(_==E){
failsafe = 0;
// console.log(tC)
//_.bTT = 0;
//bleedTrackTime = 0;
// console.log((tC - R.lastBull) % 9, "qz") timeTillBleed = Date.now()
// bleedDelay = 0;
//console.log((tC-R.lastBull)%9, "qz")
}
if(E.sid === _.sid) console.log(tick - _.lastBull - 1 , Date.now() - _.lastBull2);
_.lastBull2 = Date.now();//tick-1
//if(_.sid == R.sid)console.log(_.bTT, "bled");
_.bTT = 1000;
_.lastBull = tick-1
// _.lastBull = tC//Date.now();
// R == _ &&autoheal&& (setTimeout(()=>{Sn(R.items[0]), ee.send("d", 1),ee.send("d", 0), Sn(oW, 1)}, 100), FT = 0,FT2=0)
return;
}
}
}
}
}
function insta(e){
if(e == "reverse"){
let obj = [
{hit: true,weapon:secondary,hat:53,tail:"none",aim:'closest enemy'},
{hit: true,weapon:primary,hat:7,tail:"none",aim:'closest enemy'}
]
return obj
}
if(e=="apple"){
let obj = [
{hit: true,weapon:primary,hat:"none",tail:"none",restrict:{hat:[7,53],tail:[11]},aim:'closest enemy'},
{hit: true,weapon:secondary,hat:53,tail:"none",aim:'closest enemy'}
]
}
if(e=="no bull"){
let obj = [
{hit: true,weapon:primary,hat:"none",tail:"none",restrict:{hat:[7,53],tail:[11]},aim:'closest enemy'},
{hit: true,weapon:secondary,hat:53,tail:"none",aim:'closest enemy'}
]
return obj
}
if(e=="rubyPH"){
let obj = [
{hit: true,weapon:secondary,hat:7,tail:"none",aim:'closest enemy'},
{hit: true,weapon:primary,hat:7,tail:"none",aim:'closest enemy'}
]
return obj
}
if(e=="applePH"){
let obj = [
{hit: true,weapon:secondary,hat:53,tail:"none",aim:'closest enemy'},
{hit: true,weapon:primary,hat:7,tail:"none",aim:'closest enemy'}
]
return obj
}
if(e=="regular"){
let obj = [
{hit: true,weapon:primary,hat:7,tail:"none",aim:'closest enemy'},
{hit: true,weapon:secondary,hat:53,tail:"none",aim:'closest enemy'}
]
return obj
}
if(e == "age 1"){
let obj = [
{hit:true, weapon:primary,hat:7,tail:"none", aim:"closest enemy"},
{hit:true,weapoon:primary,hat:7,tail:"none", aim:"closest enemy"},
{hit: true,weapon:secondary,hat:53,tail:"none",aim:"closest enemy"},
{hit: true,weapon:secondary,hat:"none",tail:"none",aim:"closest enemy"},
{hit: true,weapon:primary,hat:7,tail:"none",aim:"closest enemy"},
]
return obj;
}
if(e == "bow insta"){
}
}
function miller(){
if(!amAlive||mills.status==false||!E.canBuild(R.list[millType])) return (mills.status = false);
if(dist2(E,mills) > 100) {
if(mills.status) {
place(millType, moveDirection+toRad(180));
place(millType, moveDirection+toRad(180) - toRad(69));
place(millType, moveDirection+toRad(180)+ toRad(69));
}
mills.x = E.x2, mills.y = E.y2;
}
}
function Hq(e, t,override, priority, objInfo,type,n,i,x,y,blocker,isItem,checker) {
// if(n) r = true;
n = R.list[e];
// restrictPlace = []
//restrictPlace.length &&(restrictPlace = restrictPlace.filter((t)=>ue.checkItemLocation3(t.x,t.y,t.scale,.6,t.id,false)==true&&tick-t.tick<1))
n?.name == "blocker"? blocker = 300 :blocker = 0;
// (n.name == "blocker"||n.name=="pit trap"||n.name == "teleporter"||n.name == "boost pad"||n.name == "healing pad"||n.name == "sapling") ?isItem = true:isItem = false;
if(!n) return;
i = (35 + n.scale + (n.placeOffset || 0));
// if(r) return n && ue.checkItemLocation(R.x2 + Math.cos(t) * i, R.y2 + Math.sin(t) * i, n.scale, .6, n.id, false)
x = E.x2 + cos(t) * i
y = E.y2 + sin(t) * i
if(type == "outplace"){
checker = ue.checkItemLocation3(x, y, n?.scale, .6, n?.id, false,true)
} else {
checker = ue.checkItemLocation(x, y, n?.scale, .6, n?.id, false, priority)
}
if(override||checker&&!override)visAim = true;
//override === true&& place(e, t)
if(n && (checker || override)){
place(e, t)
if(objInfo){
ue.add(tick, objInfo.x, objInfo.y, objInfo.angle, objInfo.scale, null, R.list[objInfo.item.id], !0,{sid: E.sid},false, false, true,true)
}
}
let obj = R.list[e]
// console.log(ue.checkItemLocation(x, y, n.scale, .6, n.id, false),n.name)
/* let obj = {x:x,y:y,blocker:blocker,isItem:true,colDiv:n.colDiv,scale:n.scale,type:null,tick:tick,id:n.id}
obj.getScale = function(e, t) {
return e = e || 1, this.scale * (this.isItem || 2 == this.type || 3 == this.type || 4 == this.type ? 1 :
.6 * e) * (t ? 1 : this.colDiv)
}*/
if(checker){
//ue.add(tick, x, y, t, obj.scale, null, R.list[e], !0,{sid: E.sid},false,true,false,true)
}
if(override&&!checker){
// ue.add(tick, x, y, t, obj.scale, null, R.list[e], !0,{sid: E.sid},false,true,false,true)
//restrictPlace.push(obj)
//autoplacing = nearObjects.concat(restrictPlace)//.filter(e => keys.rc&&R.hitting&&(e.health>10*7.5*3.3*(Variants[R.secondaryVar]||1))|| !keys.rc)
}
//console.log(ue.checkItemLocation(R.x2 + Math.cos(t) * i, R.y2 + Math.sin(t) * i, n.scale, .6, n.id, false));
};
function checkItemlocation(e, n, i, r, s, a, l){
for (var h = 0; h < renderObjects.length; ++h) {
let obj = renderObjects[h]
var u = obj.blocker ? obj.blocker : obj.getScale(r, obj.isItem);
if (dist({x:e,y:n},obj)/*s.getDistance(e, n, N[h].x, N[h].y)*/ < i + u) return !1
}
return !(!a && 18 != s && n >= T.mapScale / 2 - T.riverWidth / 2 && n <= T.mapScale / 2 + T.riverWidth /2)
}
function posweps(_){
}
function dmgpot(t){
if(!amAlive) return;
let ez = {
hp: 0,
primary: 0,
secondary: 0,
maxOT: 0,
turretGear: 0,
add:0,
inrange: 0,
spikes: 0,
soldier: 0,
forceSoldier: 0,
shouldHeal: false,
// currentHat: E.skinIndex
}
for(let i = enemies.length, e; i--;) {
//enemies.forEach((e) => {
// for(let i=0;i<enemies.length;i++){
// e = enemies[i]
// const distanceX = E.x2 - e.x2;
// const distanceY = E.y2 - e.y2;
// const distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
//const speedTowardsTarget = Math.abs((e.xVel * distanceX + e.yVel * distanceY) / distance);
t = (e = enemies[i]).dmgpot.range + e.movSpd + E.movSpd + 50;
if(dist(E, e, "player") <= t) {
if(ez.hp == null || ez.hp == undefined) ez.hp = e.dmgpot.min + E.hitProjs;
e.dmgpot.min > ez.hp && (ez.hp = e.dmgpot.min)
ez.primary += e.dmgpot.primary;
ez.secondary+=e?.dmgpot.secondary;
ez.add+= (ez.primary+ez.secondary);
ez.turretGear+=e?.dmgpot.turretGear
ez.inrange+=1;
ez.spikes += ez.spikes;
!ez.soldier && (e.dmgpot.soldier||ez.primary>=100||E.hitProjs>=100) && (ez.soldier = true);
!ez.forceSoldier && (e.dmgpot.forceSoldier) && (ez.forceSoldier = true);
// if(enemyPlacement(e.loadout.spike,getDir(nEnemy,E))) ez.spikeSync = e.primary +
}
}
// }
//})
ez.shouldHeal = ez.hp>=E.health
return ez;
}
function playerdmgs(_){
// if(!amAlive) return;
let dF = {
primary: 0,
secondary: 0,
turretGear: 0,
soldier: false,
forceSoldier: false,
min: 0,
m1: 0,
spikes: 0,
m2: 0,
}
let sndwep = !_.secondary ? 15 : _.secondary;
let prmrywep = !isNaN(_.primary) && _.primary != null ? _.primary : 5;
let ps = R.weapons.filter(e=>e.age>_.assumeAge&&e.id>8&&(null == e?.pre||e.uF.includes(sndwep)&&!e.uF.includes(prmrywep)))
ps.length ? (ps = ps.reduce((prev,curr) => (prev.dmg > curr.dmg) ? prev : curr)):(ps=0);
let pp = R.weapons.filter(e=>e.age>_.assumeAge&&e.id<=8&&(null == e?.pre||e.uF.includes(prmrywep)&& e.uF.includes(sndwep)&&e.uF.includes(ps?.id)))
pp.length ? (pp = pp.reduce((prev,curr) => (prev.dmg > curr.dmg) ? prev : curr)):(pp=0);
let priDmg = pp!==0 && (prmrywep&&_.pr==1 && R.weapons[prmrywep].dmg<pp.dmg||!_.pr&&prmrywep)? pp.dmg*(_.tailIndex===11 ?1 : 1.5):prmrywep &&_.pr==1? R.weapons[prmrywep]?.dmg*Variants[_?.primaryVar]*1.5:0
let secDmg = ps!==0 && (sndwep&&_.sr==1 && R.weapons[sndwep].dmg<ps.dmg||!_.sr&&sndwep)? ps.dmg*(ps.projectile == undefined ?1.5:1):sndwep &&_.sr==1? R.weapons[sndwep].dmg*(R.weapons[sndwep].projectile == undefined ?Variants[_?.secondaryVar]*(_.tailIndex===11 ?1 : 1.5):1):0
if(priDmg&& _.primaryVar == 3&&E.bleed === 0||E.poison>0&&E.bleed === 0) priDmg+=5
if(secDmg&&(_.secondary == 10 || _.secondary == 14) &&E.bleed === 0||E.poison>0&&E.bleed === 0) secDmg+=5
let kbs = checkKB(E,getDir(_.np.real,E.np.real),dist(E,_.kbpot.fpriTKB),true,0)
let kb2 = checkKB(E,getDir(_.np.real,E.np.real),dist(E,_.kbpot.priKB),true,0)
let spikePush = nearObjects
.filter(e => inTrap && e?.group?.name === 'spikes' && (!e.manualBreak || !e.assumeBreak) && (dist(E,_)<= 130 && dAng(getDir(_,e),getDir(_,E)) <= 3)&& !clan(e.owner.sid) && dist(E, e, 'object') <= (secondary === 10 ? 75 : R.weapons[primary]?.range))
.sort((a, b) => dist(E, a, 'object') - dist(E, b, 'object')); // can do some check to see if i'm actually the closest enemy to the person trying to spike hit sync me since MAJORITY of mods do nearestEnemy.
let kbSpike = 0, colSpike = 0;
let spikeNtrap = nearObjects.filter(x => (x.name == "pit trap" || x.group?.name == "spikes" || x.type === 1 && x.y >= 12000) && x.distance <= 450); // if this lags, remove it
// console.log(C.getAngleDist(Math.atan2(_.y2 - E.y2, _.x2 - E.x2), Math.atan2(spikes1[i].y - E.y2, spikes1[i].x - E.x2)));
dF.range = pp?.range!=undefined && pp?.range> R.weapons[prmrywep].range?pp?.range:R.weapons[prmrywep].range;
/* if(_.primary == undefined) {
dF.range = l.weapons[5].range
}*/
dF.primary += priDmg;
if((_.secondary === 10 || _.secondary == 14) && dist(E,_,"player") <= R.weapons[sndwep].range ||
!isNaN(R.weapons[sndwep]?.projectile) && dist(E,_)-105 <= R.projectiles[R?.weapons[sndwep]?.projectile]?.range*111+40){
dF.secondary+=secDmg;
}
if(_.placePot.onPlayer.length && spikeNtrap.length) {
let kbSpiker = knockIntoP(_.placePot.onPlayer, spikeNtrap, E);
if (kbSpiker.building && (kbSpiker.bounce || kbSpiker.building.name != "pit trap")) {
kbSpike = kbSpiker.building.dmg;
createSpikeKB(kbSpiker.newPos);
}
}
if(spikePush.length > 0) for(let m = spikePush.length; m--;) {
let spk = spikePush[m];
if(dist(E, _, "player") <= R.weapons[prmrywep].range && (dist(E, spk) <= 35 + spk.realScale || E.spdMult > 0 && dist(E.np.decel, spk) <= 35 + spk.realScale + 3.5)) { // first condition = im literally already pushed in...
colSpike += spk.dmg;
if(_.pr == 1 && (prmrywep == 3 || prmrywep == 4 || prmrywep == 5) && colSpike + dF.primary >= E.health) dF.forceSoldier = true;
if(dF.forceSoldier) {
Hn.showText(E.x2, E.y2, 20, .18, 800, "anti melee sync test", "#fff");
}
}
// decel kinda useless
//console.log(E.movSpd, `Decel ${dist(E.np.decel, spk)}`, `Reg: ${ dist(E, spk)}`, 35 + spk.realScale);
}
dF.spikes = 0;
// still possible for enemy to have spike collide with u in trap
dF.spikes = /*inTrap ? colSpike + (_.placePot.onPlayer.length ? _.loadout.spike.dmg : 0) :*/ _.placePot.onPlayer.length ? _.loadout.spike.dmg + kbSpike : kbs && !inTrap ? kbs.obj.dmg : 0;
if(_.tr === 1 && seeInRange(E, _, 1.5 * 111 + 60, 0, 1)){
dF.turretGear += 25;
}
dF.m1 = dF.primary;
dF.m2 = (dF.secondary+dF.turretGear);
dF.min = dF.m1>= dF.m2? dF.m1 + dF.spikes: dF.m2 + dF.spikes;
dF.soldier = _.placePot.onPlayer.length ? true : kb2 && _.pr===1 && !inTrap ? true : false
return dF;
}
function move(e){
if(moveDirection!=e){
ee.send("9",e, "client")
}
}
function seeInRange(e, t, min, type = undefined,vel){
if(vel && dist(e.np.real,t.np.real,type) <= min){
return true;
}
if(dist(e,t,type) <= min){
return true
}
return false;
}
async function Shame(_,player = findPlayerSID(_.sid)){
if(_.shameTimer <=0 || _.skinIndex!=45|| player == null||player == undefined) return;
// player = Ii(_.sid);
player.shameCount = 0
player.clowned=true
player.shameTimer -= (_.delta/1000);
await nextTick();
Shame(player);
}
function knockBack(player,target,angle, k){
let priKnock = .3+(R.weapons[player?.primary]?.knock||0)
let secKnock = .3+(R.weapons[player?.secondary]?.knock||0)
!angle && (angle = getDir(player,target))
let cos = Math.cos(angle), sin = Math.sin(angle)
k = {
xP: priKnock * cos * 111,
yP: priKnock * sin * 111,
xS: secKnock * cos * 111,
yS: secKnock * sin * 111,
}
let ez = {
priKB: {x: target.x2 + (target.xVel + k.xP), y: target.y2 + (target.yVel + k.yP)},
secKB: {x: target.x2 + (target.xVel + k.xS), y: target.y2 + (target.yVel + k.yS)},
turKB: {x: target.x2 + (target.xVel + .3 * cos * 111), y: target.y2 + (target.yVel + .3 * sin * 111)},
priTKB: {x: target.x2 + (target.xVel + k.xP + .3), y: target.y2 + (target.yVel + k.xP + .3)},
secTKB: {x: target.x2 + (target.xVel + k.xS + .3), y: target.y2 + (target.yVel + k.xS + .3)},
fpriKB: {x: target.np.real.x + (target.np.xVel + k.xP), y: target.np.real.y + (target.np.yVel + k.yP)},
fsecKB: {x: target.np.real.x + (target.np.xVel + k.xS), y: target.np.real.y + (target.np.yVel + k.yS)},
fturKB: {x: target.np.real.x + (target.np.xVel + .3 * cos * 111),y: target.np.real.y + (target.np.yVel + .3 * sin * 111)},
fpriTKB: {x: target.np.real.x + (target.np.xVel + k.xP + .3), y: target.np.real.y + (target.np.yVel + k.xP + .3)},
fsecTKB: {x: target.np.real.x + (target.np.xVel + k.xS + .3), y: target.np.real.y + (target.np.yVel + k.xS + .3)}
}
return ez
}
function fastHats(test){
if(E.y2 <= T.snowBiomeTop){
if(test) return {skinIndex:15,tailIndex:11}
Hg(15, 11);
}else if(E.inWater){
if(test) return {skinIndex:31,tailIndex:11}
Hg(31, 11);
}else{
if(test) return {skinIndex:12,tailIndex:11}
Hg(12, 11);
}
}
function absolute(){
if(!amAlive) return;
}
if(window.location.href.startsWith('https://sandbox')) sandbox = true;
list = R.list
let lpo = [0,0];
function reload(e = R.weapons){
if(inTrap||instaing||meleesyncing||aim[0]!==null||E.pr===1&&E.sr===1&&lpo[0]||hold||!amAlive||keys.lc||keys.rc || keys.mc || oneTick || boostOT) return;
if(E.sr!=1){
if(E.weaponIndex!=secondary||E.buildIndex!=-1)ee.send("z",secondary,true)
hold = secondary;
lpo[1]=true;
}
if(E.pr!=1&& (E.sr==1||secondary===null)){
if(E.weaponIndex!=primary||E.buildIndex!=-1)ee.send("z",primary,true);
hold = primary;
lpo[1]=true;
}
}
connectToWS()
var connectedIDS = [];
var sendID = false;
var playermerge;// [];
function connectToWS(){
try{
socketer = []; //new WebSocket("wss://maroon-free-square.glitch.me")
let z;
socketer.onmessage = function(event) {
var reader = new FileReader();
if(event.data instanceof Blob){
reader.onload = function(event) {
var data = event.target.result;
try {
var parsedData = JSONParse(data);
z = parsedData
// console.log(z)
if(z?.msg =="jumpscare" && z?.target==E?.sid) {
playVideo();
} else if(z?.msg == "status"&&document.getElementById("melee sync").checked&&z?.server === location.href){
let msg = z
let team = findPlayerSID(msg.team.sid)
let JJ = R.weapons
if(msg.team.sid!=E.sid&&team!=null&& nEnemy&&msg.team.pr==1&&!msg.busy&&!instaing&&E.pr ==1&&shieldBypass(E,nEnemy)&&shieldBypass(msg.team,nEnemy) &&inrange(msg.team,nEnemy,JJ[msg.team.primary].range,true)&&inrange(E,nEnemy,JJ[primary].range,true)){
instaing = true;
meleesyncing = true;
hold = primary;
aim[0] = getDir(E,nEnemy)
ee.send("z",primary,true)
ee.send("K",1)
Hg(7,18)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client")
setTimeout(() => {
meleesyncing = false;
instaing = false;
},111);
}
}
if(z?.msg == "status"&&gE("melee sync")?.checked){
let msg = z
let team = bi(msg.team.sid)
if(msg.team.sid!=R.sid&&team!=null&& nEnemy&&msg.team.pr==1&&!msg.busy&&!instaing&&R.pr ==1 &&(dist(msg.team.np.real,nEnemy.np.real,"player")<=R.weapons[msg?.team?.primary]?.range&&dist(R.np.real,nEnemy.np.real,"player")<=R.weapons[primary].range||dist(msg.team,nEnemy.np,"player")<=R.weapons[msg?.team?.primary]?.range&&dist(R,nEnemy,"player")<=R.weapons[primary].range)){
instaing = true;
hold = primary;
aim[0] = getDir(R,nEnemy)
ee.send("K",1)
ee.send("z",primary,true)
Hg(7,18)
ee.send("z",primary,true)
visAim = true;
ee.send("D",getDir(R,nEnemy))
setTimeout(() => {
instaing = false;
},111);
}
}
if(z?.chatting){
if(z.chatting.val == E.sid)ee.send("6", z.msg)
}
if(z?.chat){
let player = findPlayerSID(z.id.sid)
if(z.server==location.href){
if((player== null||player?.sid!=E.sid)&&z.pm){
teamMessage = {message:`PM: ${z.chat}`,id:z.id.sid,time:3000}
}
if(player == null||!player?.visible||z.chatter){
let pm = z.chatter? " (PM)": ''
addChatLog(`${z.id.name}[${z.id.sid}]${pm}: `,z.chat,z.color,z.pm);
}
} else{
const match = /server=(.+)/.exec(z.server);
const link = z.server.includes("sandbox")? `s-${match && match[1]}` : match && match[1];
addChatLog(`${z.id.name}[${z.id.sid}] ${link}: `,z.chat,z.color);
}
}
if(z?.melee){
if(z.melee.sid == E.sid){
instaing = true;
hold = primary;
aim[0] = getDir(E,nEnemy)
ee.send("z",primary,true)
ee.send("K",1)
Hg(7,18)
ee.send("z",z.melee,true)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client")
setTimeout(() => {
instaing = false;
},111);
}
}
if(z?.message!=undefined&&(!findPlayerSID(z.id)?.visible||findPlayerSID(z.id)==null)){
teamMessage = z;
}
/*if(z?.msg == "melee sync"&&gE("melee sync")?.checked){
let msg = z
let team = bi(msg.team.sid);
let enemy = bi(msg.enemy.sid)
console.log(msg)
if(enemy!=null){
instaing = true;
hold = primary;
aim[0] = getDir(R,enemy)
ee.send("K",1)
Hg(7,18)
ee.send("z",primary,true)
visAim = true;
ee.send("D",getDir(R,enemy))
setTimeout(() => {
instaing = false;
},111);
}
}*/
/* if(z?.msg == "yez"&&!instaing&&R.pr == 1){
let msg = z
console.log(z.time);
let enemy = bi(msg.enemy.sid)
let team = bi(msg.team.sid)
if(enemy == null||!enemy.visible){enemy = msg.enemy};
setTimeout(() => {
instaing = true;
hold = primary;
Hg(6,21)
ee.send("z",primary,true)
visAim = true;
aim[0] = getDir(R,enemy)
ee.send("D",getDir(R,enemy))
},z.time);
setTimeout(() => {
instaing = false;
},z.time + 111);
} */
if(z?.msg == "pinger" && z?.server === location.href){
displayer = 10000;
}
// comment for now.
if(z?.msg == "removeBuild" && z?.server === location.href) {
if(z?.sender != E.sid) {
//console.log(z?.removeSid);
spectator.builds = spectator.builds.filter(obj => {
return obj.sid !== z.removeSid;
});
}
}
if(z?.msg == "sendBuildData") {
if(z?.sender != E.sid && !(((z?.sendX - E?.x) ** 2 + (z?.sendY - E?.y) ** 2) <= 1500 ** 2)) { // Get sender sid
let { sid, x, y, dir, scale, resource, item, active, owner} = z?.data;
//if(!et.find(e => e.sid == sid) || !renderObjects.find(e => e.sid == sid) || !nearObjects.find(e => e.sid == sid)) {
ue.add(sid, x, y, dir, scale, resource, item, active, owner >= 0 ? {
sid: owner
} : null, false, true, false, false, false)
//}
//console.log(x, y, dir, scale, resource, item, active, sid);
}
}
if(z?.msg == "sendWiggleData") {
if(z?.sender != E.sid && !(((z?.sendX - E?.x) ** 2 + (z?.sendY - E?.y) ** 2) <= 1500 ** 2)) { // Get sender sid
//console.log(z);
let realBuild = findSpectatorBuild(z?.build);
realBuild && (realBuild.xWiggle += T.gatherWiggle * cos(z?.wiggleDir),
realBuild.yWiggle += T.gatherWiggle * sin(z?.wiggleDir));
}
}
if(z?.msg == "spectate") {
if(z?.sender != E?.sid) {
if(z?.playerToSpec == E?.sid) {
specID = z.playerToSpec;
addChatLog(`You are being spectated by ${findPlayerSID(z?.sender)?.name} [${z?.sender}]`,'', '#2b0640',false,true);
} else if(z?.playerToSpec === undefined) {
addChatLog(`You are no longer being spectated`,'', '#2b0640',false,true);
specID = undefined;
}
/*spectator.player = z.player;
spectator.players = z.players;
spectator.builds = z.builds;*/
//console.log(z);
}
}
if(z?.msg == "spectateData" && z?.sender != E.sid && z?.server === location.href) {
spectator.player = z?.player;
spectator.testPlayers = z?.players;
//console.log("test");
const elementsNotInEt = z?.builds.filter(spectatorBuild =>
!et.some(ztItem => ztItem.sid === spectatorBuild.sid)
);
//console.log("elements", elementsNotInEt);
for (let i = 0; i < elementsNotInEt.length; i++) {
let build = elementsNotInEt[i];
//console.log("test", build);
if (!spectator?.builds.some(existingBuild => existingBuild.sid === build.sid)) {
ue.add(
build.sid,
build.x,
build.y,
build.dir,
build.scale,
build.type,
R.list[build.id],
build.active,
build?.owner?.sid >= 0 ? { sid: build?.owner?.sid } : null,
false,
true,
false,
false,
false
);
}
}
const playersNotAdded = z?.players.filter(spectatorPlayers => !J.some(ztItem => ztItem.sid === spectatorPlayers.sid));
for (let i = 0; i < playersNotAdded.length; i++) {
let player = playersNotAdded[i];
let data = [player.id, player.sid, player.name, player.x, player.y, player.dir, player.health, 100, 35, 0/*player.skinColor*/];
/*this.dir = k[5],
this.health = k[6],
this.maxHealth = k[7],
this.scale = k[8],
this.skinColor = k[9],*/
//console.log("test", player);
const existingPlayer = spectator?.players.find(player1 => player1.sid === player.sid);
if (!existingPlayer) {
const XDD = new _c(spectator.id, spectator.sid, T, C, po, ue, z?.players/*spectator.players*/, ye, R, Xt, Gt);
spectator.players.push(XDD);
console.log("XDD", XDD);
console.log("spec", spectator.players);
XDD.spawn(false /*t*/ ? xi : null);
XDD.visible = false;//true//false; // true
XDD.x2 = undefined;
XDD.y2 = undefined;
XDD.setData(data, XDD, false, true);
} else {
console.log(spectator.players.length);
for(let d = 0; d < spectator.players.length; d++) {
let p = spectator.players[d];
if(p.sid == player.sid) {
p = { ...player };
console.log("player updated", p.sid);
} else if(z?.player.sid == player.sid) {
z.player = { ...player }
}
}
}
/*if (!spectator?.players.some(existingPlayer => existingPlayer.sid === player.sid)) {
let XDD = player;//findSpectatorPlayer(player.sid);
console.log("XDD", XDD);
XDD||(XDD = new _c(spectator.id, spectator.sid,T,C,po,ue,spectator.players,ye,R,Xt,Gt),spectator.players.push(XDD))
console.log("spec", spectator.players);
XDD.spawn(false/*t ? xi : null)
XDD.visible = !1
XDD.x2 = void 0
XDD.y2 = void 0
XDD.setData(data, XDD, false, true)
}*/
}
}
if(z?.msg == "ping"&&z?.server === location.href) {
z.player.timing = z?.time
if(z.player.sid==E.sid) return;
let ez = teamDisplay.find(e => e.sid==z.player.sid)
if(!ez){
teamDisplay.push(z.player)
} else{
teamDisplay.forEach((e,index,array) => {
if(e.sid==z.player.sid){
array[index] = z.player
}
})
}
}
if(z?.msg == "pz"&&!instaing&&E.sr == 1 && qSync.checked&&z?.server === location.href){
let msg = z
let enemy = findPlayerSID(msg.enemy.sid)
let team = findPlayerSID(msg.team.sid)
if(enemy == null||!enemy.visible){enemy = msg.enemy};
shootSync2()
/*Qsync = true;
instaing = true;
hold = secondary;
Hg(53,11)
ee.send("z",secondary,true)
visAim = true;
aim[0] = getDir(R,enemy)
ee.send("D",getDir(R,enemy))
setTimeout(() => {
instaing = false;
Qsync = false;
},111);*/
}
//processBlobData(parsedData);
} catch (error) {
//console.error("Error parsing JSON:", error);
}
};
}
reader.readAsText(event.data);
// console.log(Date.now()-event.data);
}
socketer.onopen = function() {
serverconnected = true
console.log('connected')
socketer.send(JSONStringify({AMOWNER:false}))
// socketer.send(JSONStringify({serverS:location.href}))
// socketer.send(Date.now());
//socketer.send(websocket.url.split("&")[0] + "&token=" + encodeURIComponent(grecaptcha.execute(("6LevKusUAAAAAAFknhlV8sPtXAk5Z5dGP5T2FYIZ"), { action : 'homepage' })));
}
socketer.onclose = function(e){
serverconnected = false;
// socketer.send('disconnected');
//console.log('disconnected',e);
connectToWS();
sendID = false;
}
socketer.onerror = function(e){
}
}catch(error){console.log('error',error)}
}
//snow 377-344
//max 384 min: 344
function BOT(tTime, bTime, pTime, fp,fp2) {
if(!oneTickToggle) {
boostOT = false
oneTick = false;
return
}
if(!nEnemy || instaing || !oneTickToggle|| inTrap||!secondary||!amAlive) {
oneTick = false;
return;
}
//CPH6(R, nEnemy, 3, 2.0, getDir(R, nEnemy)) reference
if(dist(E,nEnemy)<=700 && E.pr === 1 && E.sr === 1 && E.tr === 1) {
boostOT = true;
oneTick = true;
const projectionDistance = 395;
const angle = getDir(nEnemy, E);
let coords = {x:nEnemy.x2 + cos(angle) * projectionDistance, y: nEnemy.y2 + sin(angle) * projectionDistance}
let roundD = dist(E,nEnemy)
let coordDist = dist(E,coords)
if(coordDist<=25) {
Hg(40,0)
} else if(coordDist<=60){
Hg(22,0)
} else if(coordDist<=110){
Hg(22,11)
} else{
fastHats()
}
if(CPH6(E, nEnemy, 3, 2.0, getDir(E, nEnemy)) >= 1 && E.movSpd <=0 && nEnemy.movSpd <=0 && CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy))!==CPH6(E, nEnemy, 3, 2.0, getDir(E, nEnemy)) && dist(E,nEnemy) <= 412 && dist(E,nEnemy) >= 378) {
let dir = getDir(E,nEnemy)
hold = secondary
ee.send("z",secondary,true)
place(boostType,dir+toRad(40))
place(boostType,dir-toRad(40))
boostOT = true;
Hg(53,0);
bTime = (CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy)) - CPH6(E, nEnemy, 3, 2.0, getDir(E, nEnemy))) * 111;
pTime = CPH6(E, nEnemy, 1, 1.5, getDir(E, nEnemy)) * 111;
fp = bTime + 80
fp2 = bTime + E.delta
ee.send("D",dir, "client")
visAim = true
/*move shoot shit wait shit needs to be here
*/
setTimeout(() => {
fastHats()
oneTick = false
instaing = true;
aim[0] = dir
hold = secondary
ee.send("D",dir, "client")
// ee.send("D",dir, "client")
ee.send("z",secondary,true)
ee.send("F", 1, dir);
ee.send("F", 0, dir)
ee.send("9", dir, "client")
},bTime)
/* wait shit
await nextTick();
*/
setTimeout(() => {
hold = primary
Hg(7,19)
visAim = true;
aim[0] = dir
ee.send("D",dir)
ee.send("z",primary,true)
// ee.send("z",primary,true)
// ee.send("z",primary,true)
ee.send("F", 1, dir);
ee.send("F", 0, dir)
},fp)
setTimeout(() => {
hold = primary
Hg(7,19)
visAim = true;
aim[0] = dir
ee.send("D",dir, "client")
ee.send("z",primary,true)
// ee.send("z",primary,true)
// ee.send("z",primary,true)
ee.send("F", 1, dir);
ee.send("F", 0, dir)
},fp2)
setTimeout(() => {
ee.send("9", dir, "client")
hold = primary
Hg(7,19)
visAim = true;
aim[0] = dir
ee.send("D",dir, "client")
ee.send("z",primary,true)
// ee.send("z",primary,true)
// ee.send("z",primary,true)
ee.send("F", 1, dir);
ee.send("F", 0, dir)
},pTime)
/*turn off wait shit
await nextTick()
*/
setTimeout(() => {
oneTickToggle = false
instaing = false;
oneTick = false;
boostOT = false;
visAim = false;
},450)
} else if(!(dist(E,nEnemy)>=378&&dist(E,nEnemy)<=412)){
ee.send("9",getDir(E,coords), "client");
} else{
ee.send("9",null, "client")
}
}
}
async function boostOneTick() {
if(!nEnemy || instaing || !oneTickToggle || E.tr !== 1 || E.pr !== 1 || E.sr !== 1 || inTrap||!secondary||secondary===10||secondary===14||!amAlive) {
oneTick = false;
return;
}
if(nEnemy.bleed === undefined){
Hn.showText(E.x2, E.y2, 25, .35, 1500, 'poison the Nigga',"#fff")
oneTickToggle = false
return
}
//move logic
if(dist(E,nEnemy)<=600) {
boostOT = true;
oneTick = true;
const projectionDistance = bMin;
const angle = getDir(nEnemy, E);
let coords = {x:nEnemy.x2 + cos(angle) * projectionDistance, y: nEnemy.y2 + sin(angle) * projectionDistance}
let roundD = dist(E,nEnemy)
let coordDist = dist(E,coords)
if(coordDist<=15) {
if(E.buildIndex!=1)ee.send("z",foodType);
Hg(40,0)
hold = foodType
} else if(coordDist<=50){
Hg(22,0)
hold = secondary;
ee.send("z",secondary,true);
} else if(coordDist<=120){
Hg(6,0)
hold = primary;
ee.send("z",primary,true);
} else{
bh()
hold = primary;
ee.send("z",primary,true)
}
if(roundD>=bMin && roundD<=bMax && E.movSpd <=5 && nEnemy.movSpd <=5&&nEnemy.bleed === 8) {
let dir = getDir(E,nEnemy)
Hg(53,11);
ee.send("D",dir, "client")
visAim = true
oneTick = false
boostOT = true;
instaing = true;
aim[0] = dir
hold = secondary
ee.send("z",secondary,true)
// ee.send("9", getDir(R,nEnemy))
if(R.list[utilityType].name == "platform"){
place(utilityType,dir+toRad(90))
place(utilityType,dir+toRad(180))
place(utilityType,dir-toRad(90))
}
ee.send("9", dir, "client")
place(boostType,dir)
await nextTick();
dir = getDir(E,nEnemy)
ee.send("9", dir, "client")
hold = primary
Hg(7,19)
visAim = true;
aim[0] = dir
ee.send("D",dir, "client")
ee.send("z",primary,true)
await nextTick()
oneTickToggle = false
instaing = false;
oneTick = false;
boostOT = false;
visAim = false;
} else if(!(roundD>=bMin&&roundD<=bMax)){
ee.send("9",getDir(E,coords), "client");
} else{
ee.send("9",null, "client")
}
}
}
/*async function bowOneTick() {
if(!nEnemy || primary !=5 || instaing || !oneTickToggle || E.tr !=1 || E.pr!=1 || !nEnemy?.inTrap || inTrap || nEnemy.skinIndex == 22) {
oneTick = false;
return
}
if(nEnemy && dist(E,nEnemy)<=330 && oneTickToggle && E.tr == 1 && E.pr == 1 && nEnemy?.inTrap && !inTrap && !instaing && nEnemy.skinIndex !== 22) {
oneTick = true;
const projectionDistance = 212;
const angle = getDir(nEnemy,E)
let coords = {x:nEnemy.x2 + Math.cos(angle) * projectionDistance, y: nEnemy.y2 + Math.sin(angle) * projectionDistance}
let distance = dist(E,nEnemy);
if(dist(E,coords)<=30){
Hg(6,0)
}
if(!(distance>=210&&distance<=240)&& !instaing){
ee.send("9",getDir(E,coords));
} else{
ee.send("9",null)
}
}
if(nEnemy.skinIndex != 22 &&!instaing&&dist(E,nEnemy)>=210&& E.tr === 1 && E.pr == 1 &&nEnemy&&nreload(nEnemy) == 1&& nEnemy.weaponR!=1 && nEnemy?.inTrap && dist(E,nEnemy)<=250&&gE('onetick bypass')?.checked && !inTrap) {
instaing = true;
oneTick = false
ee.send("9", getDir(E,nEnemy))
ee.send("D",getDir(nEnemy,E))
visAim = true
aim[0] = getDir(nEnemy,E)
hold = secondary
ee.send("z",secondary,true)
Hg(53,11)
await delay(111);
hold = primary
ee.send("z",primary,true)
aim[0] = getDir(E,nEnemy)
ee.send("D",getDir(E,nEnemy))
ee.send("9", getDir(E,nEnemy))
Hg(7,18);
await delay(111);
instaing = false;
hold = null
ee.send("9", null)
}
}*/
async function shootSync3(e, g) {
if (E.sr !== 1 || !nEnemy || !syncTeam || syncTeam.sr !== 1 || maxTime3() > 0 || nEnemy.skinIndex == 6) return;
if(E.sr === 1 && syncTeam.sr === 1 && !instaing && nEnemy && nEnemy.skinIndex !== 6) {
Hg(1,0);
instaing = true;
aim[0] = getDir(E, nEnemy);
visAim = true;
ee.send("D", getDir(E, nEnemy), "client");
ee.send("z", secondary, true);
hold = secondary;
await nextTick();
await nextTick();
instaing = false;
}
}
async function doInsta(e){
if(!e||oneTickToggle&&primary==5)return;
if(!nEnemy) return;
if(E.secondary != 13 && ((primary==4||primary==5)&&secondary==10)&&nEnemy.skinIndex!=6&& nEnemy&&!instaing&&(dist(E.np.accel,nEnemy.np.real,"player")<=R.weapons[secondary].range||dist(E,nEnemy,"player")<=R.weapons[secondary].range)&&E.pr==1&&E.sr==1&&amAlive&&shieldBypass(E,nEnemy)){
instaToggle = false;
// console.log("reverse insta");
instaing = true;
Hg(53,21)
aim[0] = getDir(E,nEnemy)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client");
ee.send("z",secondary,true)
hold = secondary
// console.log(nEnemy.np.real.type);
await nextTick();
if(nEnemy){
hold = primary
ee.send("z",primary,true)
aim[0] = getDir(E,nEnemy);
ee.send("D",getDir(E,nEnemy), "client");
Hg(7,18);
} else {
instaing =false
return
}
await nextTick();
instaing = false;
}
if(E.secondary != 13 &&!((primary==4||primary==5)&&secondary==10)&& nEnemy&&!instaing&&(dist(E.np.accel,nEnemy.np.real,"player")<=R.weapons[primary].range||dist(E,nEnemy,"player")<=R.weapons[primary].range)&&E.pr==1&&E.sr==1&&amAlive&&shieldBypass(E,nEnemy)){
instaToggle = false;
console.log(dist(E.np.accel,nEnemy.np.real,"player"))
// console.log("regular insta");
instaing = true;
Hg(7,18)
aim[0] = getDir(E,nEnemy)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client");
ee.send("z",primary,true)
hold = primary
// console.log(nEnemy.np.real.type);
await nextTick();
if(nEnemy){
hold = secondary
ee.send("z",secondary,true)
aim[0] = getDir(E,nEnemy);
ee.send("D",getDir(E,nEnemy), "client");
Hg(53,21);
} else {
instaing =false
return
}
await nextTick();
instaing = false;
}
if(E.secondary == 13 && nEnemy&&!instaing&&(dist(E.np.accel,nEnemy.np.real,"player")<=R.weapons[primary].range||dist(E,nEnemy,"player")<=R.weapons[primary].range)&&E.pr==1&&E.sr==1&&amAlive&&shieldBypass(E,nEnemy)){
instaToggle = false;
/// console.log("reverse insta");
instaing = true;
// console.log(nEnemy.np.real.type);
hold = secondary
ee.send("z",secondary,true)
aim[0] = getDir(E,nEnemy);
ee.send("D",getDir(E,nEnemy), "client");
Hg(53,21);
await nextTick();
if(nEnemy){
Hg(7,18)
aim[0] = getDir(E,nEnemy)
visAim = true;
ee.send("D",getDir(E,nEnemy), "client");
ee.send("z",primary,true)
hold = primary
} else {
instaing =false
return
}
await nextTick();
instaing = false;
}
}
let healTick = false
R.a = R.list.concat(R.weapons);
We.style.display = "none";
var anglesGenerated = [];
var updatedPos = {x:null,y:null}
function enemyPlacement(enemy, item, gAng, xd = PI / 50) {
const interval = xd;
const potentialAngles = { onPlayer: [], possible: [], placeRange: null };
const i = R.list[item];
const baseScale = 35 + i.scale + (i.placeOffset || 0);
for (let offset = gAng; offset <= gAng + PI2; offset += interval) {
const angle = offset;
const tmpS = baseScale;
const cosAngle = cos(angle);
const sinAngle = sin(angle);
const tmpX = enemy.x2 + tmpS * cosAngle;
const tmpY = enemy.y2 + tmpS * sinAngle;
const obj = { x: tmpX, y: tmpY, scale: i.scale, angle: angle, placeRange: tmpS, overlap: [], preplacer: [], sids: [] };
const canPlace = ue.checkItemLocation3(tmpX, tmpY, i.scale, 0.6, i.id, false, true, obj);
if (dist({ x: tmpX, y: tmpY }, E) <= i.scale + 35) {
if (canPlace) {
potentialAngles.onPlayer.unshift(obj);
}
}
if (canPlace) {
potentialAngles.possible.unshift(obj);
}
}
return potentialAngles;
}
/*function enemyPlacement(enemy,item, gAng, xd = Math.PI / 50) { // originally 30
const givenAngle = gAng;
const interval = xd;
const potentialAngles = {onPlayer:[],possible:[],placeRange:null}// {onPlayer:[],norm:[]};
// let ang = getDir(enemy,E)
for (let offset = gAng; offset <= gAng + (Math.PI * 2); offset += interval) {
const angle = offset;
let i = R.list[item];
let tmpS = (35 + i.scale + (i.placeOffset || 0));
let tmpX = enemy.x2 + (tmpS * Math.cos(angle));
let tmpY = enemy.y2 + (tmpS * Math.sin(angle));
let obj = {x:tmpX,y:tmpY, scale: i.scale, angle:angle, placeRange:tmpS,overlap:[],preplacer:[],sids:[]}
potentialAngles.placeRange = tmpS
let canPlace = ue.checkItemLocation3(tmpX, tmpY, i.scale, 0.6, i.id, false, true, obj)
if(dist({x:tmpX,y:tmpY},E) <= i.scale + 35){
if (canPlace)
potentialAngles.onPlayer.unshift(obj)
}
}
if(canPlace){
potentialAngles.possible.unshift(obj)
}
}
if(potentialAngles) return potentialAngles;
return false;
}*/
// placements happen after kb position is solidified basically ur coordinates after getting knocked back from melee hit and the projection of that with ur placement
function findAvailableAngles(item, thisAng, vel, xd = PI / 75){ // originally 60
if(!item) return [];
// const givenAngle = gAng;
const interval = xd;
const potentialAngles = []// {onPlayer:[],norm:[]};
let x = vel ? E.np.real.x : E.x2
let y = vel ? E.np.real.y : E.y2
for (let offset = thisAng; offset <= thisAng + PI2; offset += interval) {
const angle = offset;
let used = usedAngles.findIndex(x => dAng(angle, x.angle) <= 0.45);
let i = R.list[item];
let tmpS = (35 + i.scale + (i.placeOffset || 0));
let tmpX = x + (tmpS * cos(angle));
let tmpY = y + (tmpS * sin(angle));
let obj = {x: tmpX, y: tmpY, id: i.id, scale: i.scale, angle: angle, offset: tmpS, item: i, collide: [], points: 0, origin: [], name: i.name, overlap: [], preplacer:[],sids:[],intercepts:[],knockback:[], used: used}
let canPlace = packets <= 90 ? ue.checkItemLocation3(tmpX, tmpY, i.scale, 0.6, i.id, false, true, obj) : ue.checkItemLocation(tmpX, tmpY, i.scale, 0.6, i.id, false, true)
if(used !== -1){
if(!canPlace) usedAngles.splice(used, 1);
// continue;
}
if(canPlace)potentialAngles.push(obj);
}
//showAngles = potentialAngles;
return potentialAngles;
}
function findAvailableAnglesR(item, thisAng, vel, xd = PI / 75){ // originally 60
if(!item) return [];
// const givenAngle = gAng;
const interval = xd;
const potentialAngles = []// {onPlayer:[],norm:[]};
let x = vel ? E.np.real.x : E.x2
let y = vel ? E.np.real.y : E.y2
for (let offset = thisAng; offset <= thisAng + PI2; offset += interval) {
const angle = offset;
let used = usedAngles.findIndex(x => dAng(angle, x.angle) <= 0.45);
let i = R.list[item];
let tmpS = (35 + i.scale + (i.placeOffset || 0));
let tmpX = x + (tmpS * cos(angle));
let tmpY = y + (tmpS * sin(angle));
let obj = {x: tmpX, y: tmpY, id: i.id, scale: i.scale, angle: angle, offset: tmpS, item: i, collide: [], points: 0, origin: [], name: i.name, overlap: [], preplacer:[],sids:[],intercepts:[],knockback:[], used: used}
let canPlace = ue.checkItemLocation3(tmpX, tmpY, i.scale, 0.6, i.id, false, true, obj);
if(canPlace) potentialAngles.push(obj);
}
//showAngles = potentialAngles;
return potentialAngles;
}
function findAvailableAnglesOld(item, thisAng, vel, xd = PI / 75){ // originally 60
if(item == undefined || item == null || !item) return [];
// const givenAngle = gAng;
const interval = xd;
const potentialAngles = []// {onPlayer:[],norm:[]};
let x = vel ? E.np.real.x : E.x2
let y = vel ? E.np.real.y : E.y2
for (let offset = thisAng; offset <= thisAng + PI2; offset += interval) {
const angle = offset;
let used = usedAngles.findIndex(x => dAng(angle, x.angle) <= 0.45);
let i = R.list[item];
let tmpS = (35 + i.scale + (i.placeOffset || 0));
let tmpX = x + (tmpS * cos(angle));
let tmpY = y + (tmpS * sin(angle));
let obj = {x: tmpX, y: tmpY, id: i.id, scale: i.scale, angle: angle, offset: tmpS, item: i, collide: [], points: 0, origin: [], name: i.name, overlap: [], preplacer:[],sids:[],intercepts:[],knockback:[], used: used}
let canPlace = packets <= 90 ? ue.checkItemLocation3(tmpX, tmpY, i.scale, 0.6, i.id, false, true, obj) : ue.checkItemLocation(tmpX, tmpY, i.scale, 0.6, i.id, false, true)
if(used !== -1){
if(!canPlace) usedAngles.splice(used, 1);
// continue;
}
if(canPlace)potentialAngles.push(obj);
}
//showAngles = potentialAngles;
return potentialAngles;
}
var showAngles = []
function knockIntoP(spike,objs,enemy){
let obj = {building: null, closest: Infinity, bounce: false, dmg: 0, spikeCount: 0, trapCount: 0, total: 0, newPos: {...enemy}}
objs = objs.filter(x => !clan(x.owner?.sid) || x.y >= 12000 && x.type === 1)
for(let m = 0; m < spike.length; m++) {
let dir = Math.atan2(enemy.y2 - spike[m].y, enemy.x2 - spike[m].x); //getDir(spike,enemy)
for(let i = 0; i < objs.length; i++){
//console.log(spike, objs[i]);
let distance = fastHypot(enemy.np.real.x-objs[i].x, enemy.np.real.y - objs[i].y)//dist2(enemy,objs[i])
let closestPoint = calcPoint(enemy.np.real.x, enemy.np.real.y, dir, min(distance, 170));
obj.newPos.affected = enemy.sid;
obj.newPos.NEWX = closestPoint.x;
obj.newPos.NEWY = closestPoint.y;
obj.originDir = dir;
obj.newPos.dstSpd = distance;
obj.newPos.static = true;
obj.newPos.expire = 3;
// fastHypot(player.x2-a.x,player.y2-a.y)
// original: 47.5 - change to 46 or 45.5 for "better" accuracy
if(fastHypot(closestPoint.x-objs[i].x, closestPoint.y-objs[i].y) <= (objs[i].name == "pit trap" ? 45.5 : objs[i].realScale + 35) && distance < obj.closest){
obj.closest = distance
obj.building = objs[i]
if(distance <= 150 && distance >= 50 && (objs[i].group?.name == "spikes" || objs[i].type === 1) && dAng(dir, atan2(objs[i].y - spike.y, objs[i].x - spike.x)) <= .17){
obj.bounce = true;
} else {
obj.bounce = false;
}
return obj;
}
}
}
return obj;
// dAng() <= .19 + 45 distance too
}
function knockInto(spike,objs,enemy){
let obj = {building: null, closest: Infinity, bounce: false, dmg: 0, spikeCount: 0, trapCount: 0, total: 0, newPos: {...enemy}}
let dir = getDir(spike,enemy)
objs = objs.filter(x => (clan(x.owner?.sid) || !enemy.team && x?.owner?.sid != enemy.sid)|| x.y >= 12000 && x.type === 1)
for(let i = 0; i < objs.length; i++){
let distance = fastHypot(enemy.np.real.x-objs[i].x, enemy.np.real.y - objs[i].y)//dist2(enemy,objs[i])
let closestPoint = calcPoint(enemy.np.real.x, enemy.np.real.y, dir, min(distance, 170));
obj.newPos.affected = enemy.sid;
obj.newPos.NEWX = closestPoint.x;
obj.newPos.NEWY = closestPoint.y;
obj.originDir = dir;
obj.newPos.dstSpd = distance;
obj.newPos.static = true;
obj.newPos.expire = 3;
// fastHypot(player.x2-a.x,player.y2-a.y)
if(fastHypot(closestPoint.x-objs[i].x, closestPoint.y-objs[i].y) <= (objs[i].name == "pit trap" ? 47.5 : objs[i].realScale + 35) && distance < obj.closest){
obj.closest = distance
obj.building = objs[i]
if(distance <= 150 && distance >= 50 && (objs[i].group?.name == "spikes" || objs[i].type === 1) && dAng(dir,getDir(spike,objs[i])) <= .17){
obj.bounce = true;
} else {
obj.bounce = false
}
}
}
return obj;
// dAng() <= .19 + 45 distance too
}
// this is using lines as borders with spikes meant for infinite knockback simulations
function findIntersectionPoints(line, circle) {
let intersections = [];
let dx = line[1].x - line[0].x;
let dy = line[1].y - line[0].y;
let dr = sqrt(dx * dx + dy * dy);
let D = line[0].x * line[1].y - line[1].x * line[0].y;
let discriminant = circle.scale * circle.scale * dr * dr - D * D;
if (discriminant >= 0) {
let sign = dy < 0 ? -1 : 1;
let x1 = (D * dy + sign * dx * sqrt(discriminant)) / (dr * dr);
let x2 = (D * dy - sign * dx * sqrt(discriminant)) / (dr * dr);
let y1 = (-D * dx + abs(dy) * sqrt(discriminant)) / (dr * dr);
let y2 = (-D * dx - abs(dy) * sqrt(discriminant)) / (dr * dr);
intersections.push({ x: x1, y: y1 }, { x: x2, y: y2 });
}
return intersections;
}
// this shows me what part of line intercepts the circle
function findIntersectionParts(line, circle) {
let intersections = findIntersectionPoints(line, circle);
let intersectionParts = [];
intersections.forEach((intersection) => {
let t = (intersection.x - line[0].x) / (line[1].x - line[0].x);
if (t >= 0 && t <= 1) {
intersectionParts.push({ x: intersection.x, y: intersection.y });
}
});
return intersectionParts;
}
function createBorderLines(buildings) {
let lines = [];
// makes lines for circle borders
buildings.forEach((building) => {
let { x, y, scale } = building;
let circumference = PI2 * scale;
let numSegments = Math.floor(circumference / (2 * scale)); // this the number of line segments
for (let i = 0; i < numSegments; i++) {
let angle1 = (i / numSegments) * PI2;
let angle2 = ((i + 1) / numSegments) * PI2;
let x1 = x + scale * cos(angle1);
let y1 = y + scale * sin(angle1);
let x2 = x + scale * cos(angle2);
let y2 = y + scale * sin(angle2);
lines.push([{ x: x1, y: y1 }, { x: x2, y: y2 }]);
}
});
return lines;
}
//check if the point is surrounded by buildings
function isPointSurroundedByBuildings(point, buildings) {
let borderLines = createBorderLines(buildings);
return borderLines.every((line) => {
let intersectionParts = findIntersectionParts(line, point);
return intersectionParts.length === 0;
});
}
/*
manually grading points to every angle for all enemies
can get more specific but beware of performance costs
avoid multi calculation of the same thing
performance costs = u get outplaced
*/
let placeDist = 350, sOffset = 50, trapDst = 50;//47;
// originally 235 placeDist
function fHypot(x, y) {
return sqrt(x * x + y * y);
}
/*
manually grading points to every angle for all enemies
can get more specific but beware of performance costs
avoid multi calculation of the same thing
performance costs = u get outplaced
*/
function gradeAngles(spike, trap, newEnemies, time) {
let bestSpike, bestTrap;
let spikeNtrap = nearObjects.filter(x => (x.name == "pit trap" || x.group?.name == "spikes" || x.type === 1 && x.y >= 12000) && x.distance <= 450);
let overlapDists = {};
let spikeOffset = R.list[spikeType].scale - 50;
for(let i = 0; i < newEnemies.length; i++) { //for(let i = newEnemies.length, enemy; i--, (enemy = newEnemies[i]);) {
let enemy = newEnemies[i];
for(let t = 0; t < trap.length; t++) { //for(let t = trap.length; t--;) {
let angleAbuse = true;
for(let len = 0; len < enemy.placePot.possible.length; len++){
let obj = enemy.placePot.possible[len];
overlapDists[trap[t].angle + enemy.name + enemy.sid + obj.angle] = dist2(trap[t], obj);
if(overlapDists[trap[t].angle + enemy.name + enemy.sid + obj.angle] <= trap[t].scale + obj.scale) {
trap[t].placePriority = true;
angleAbuse = false;
break;
}
}
if(trap[t].preplacer.includes(true) && trap[t].placePriority){
trap[t].preplace = true;
trap[t].points += 1;
}
if(!trap[t].preplace && trap[t].used !== -1){
trap.splice(t, 1);
continue;
};
let plyrDist = dist2(trap[t], enemy);
if(plyrDist <= 235 && !enemy.inTrap || keys.c) trap[t].points += 1;
if(plyrDist <= 20.4) { // stops from placing
trap[i].points += 1;
}
if(plyrDist <= 47){ // maybe use 50
trap[t].retrap = true;
trap[t].collide.push(enemy.sid);
trap[t].points += 1;
if(trap[t].preplace && enemy.inTrap) {
let obj1 = spikeNtrap.filter(spk => (spk?.group?.name === "spikes" && (clan(spk.owner.sid) || !enemy.team && spk?.owner?.sid != enemy.sid)|| spk.y >= 12000 && spk.type === 1) && fastHypot(spk.x-trap[t].x,spk.y-trap[t].y) <= 50 + (spk.type == 1 ? spk.scale * 0.55 : spk.scale) + 24 && !trap[t].sids.includes(spk.sid));
// maybe uncomment this again, lets find out later
//trap[t].points += 1; // 1.5
if(obj1.length) {
trap[t].points += (obj1.length + 1);
} else {
let enemyToTrap = atan2(enemy.inTrap.y - enemy.y2, enemy.inTrap.x - enemy.x2);
let enemyCanHitTrapWhileHittingPlayer = C.getAngleDist(getDir(enemy, enemyToTrap), enemy.d2) <= gatherAng && C.getAngleDist(getDir(E, enemy), getDir(enemy, enemyToTrap)) <= gatherAng;
if(!enemyCanHitTrapWhileHittingPlayer) {
trap[t].points += 2;
} else {
trap[t].points += 1;
}
}
}
}
let obj = spikeNtrap.filter(spk => (spk?.group?.name === "spikes" && (clan(spk.owner.sid) || !enemy.team && spk?.owner?.sid != enemy.sid) || spk.y >= 12000 && spk.type === 1) && fastHypot(spk.x-trap[t].x,spk.y-trap[t].y) <= 50 + (spk.type == 1 ? spk.scale * 0.55 : spk.scale) + 24 && !trap[t].sids.includes(spk.sid))
if(obj.length) { // trap auto push potential
trap[t].points += (1 + obj.length);
trap[t].canPush = true;
}
/* if(!angleAbuse){ // too performance inefficient to use may revisit later
let points = trap[i].intercepts.length * .25
trap[i].points += points
trap[i].origin.push({amount:points,from:'blocks angle',player:x})
}*/
if(plyrDist <= enemy.placePot.placeRange) {
if(angleAbuse) { // angle abuse
trap[t].points += 1;
} else { // blocks angle
trap[t].points += .5;
}
}
if(!bestTrap || bestTrap.points <= trap[t].points) bestTrap = trap[t];
}
for(let s = 0; s < spike.length; s++) { //for(let s = spike.length; s--;){
spike[s].bounce = false;
if(isInPath(spike[s])) continue;
let plyrDist = dist2(spike[s], enemy);
let angleAbuse = true;
for(let len = 0; len < enemy.placePot.possible.length; len++){
let obj = enemy.placePot.possible[len];
if(overlapDists[spike[s].angle + enemy.name + enemy.sid + obj.angle] + spikeOffset <= spike[s].scale + obj.scale){
spike[s].placePriority = true;
angleAbuse = false;
break;
}
}
if(spike[s].preplacer.includes(true) && spike[s].placePriority) {
spike[s].preplace = true;
spike[s].points += 1;
}
if(!spike[s].preplace && spike[s].used !== -1){
spike.splice(s, 1);
continue;
};
let trapDist = enemy.inTrap ? dist2(spike[s], enemy.inTrap) : Infinity;
if(plyrDist <= 35 + spike[s].scale) {
//if(spike[i].collide.length >=1) spike[i].origin.push({amount:1,from:`collides with ${x.name}[${x.sid}]`,player:x})
spike[s].collide.push(enemy.sid)
if(!enemy.inTrap || spike[s].preplace) {
let bouncer = knockInto(spike[s], spikeNtrap, enemy);
if(bouncer.building) {
spike[s].into = bouncer;
if(bouncer.building.name == "pit trap" && !(spike[s].preplace && enemy.inTrap && spike[s].sids.includes(enemy.inTrap.sid))){
spike[s].points += 2.5;
//spike[i].origin.push({amount:1.5,from:'spike knocks into trap',player:x})
} else if(bouncer.bounce){
spike[s].bounce = true;
spike[s].points += 5;
//spike[i].origin.push({amount:2,from:'knocks between spike infinitely test',player:x})
} else if(bouncer.building.name !== "pit trap"){
spike[s].points += 3;
//spike[i].origin.push({amount:2,from:'knocks into spike',player:x})
} else {
spike[s].into = false
}
}
}
if(enemy.inTrap && !spike[s].sids.includes(enemy.inTrap.sid)) { // spike collides with player while in trap
spike[s].points += 2;
spike[s].spikeTrap = true;
spike[s].canPush = true;
}
}
if(enemy.inTrap && !spike[s].sids.includes(enemy.inTrap.sid) && trapDist <= 50 + spike[s].scale + 21) { // possible autopush spike
spike[s].canPush = true;
spike[s].points += 1;
}
if(enemy.inTrap && plyrDist <= 250 && (dAng(spike[s].angle, enemy.inTrap.angToMe) >= 1.5 || moveDirection === null || moveDirection === undefined)) { // spike surrounds trapped player
spike[s].points += 2;
}
if(angleAbuse && plyrDist <= enemy.placePot.placeRange) { // angle abuse
spike[s].points += 1;
}
if(!bestSpike || bestSpike.points <= spike[s].points) bestSpike = spike[s];
}
overlapDists = {};
}
return {
spikes: spike,
traps: trap,
bestSpike: bestSpike,
bestTrap: bestTrap
}
}
function gradeCombinations(buildings){ // maybe add later
buildings = buildings.filter(x => x.points >=1).sort((a, b) => b.points - a.points);
const result = [];
function gradeCurrent(combination) {
/* for(let i = 0; i < combination.length; i++){
}*/
return combination.reduce((sum, { points }) => sum + points, 0);
}
function generateCombinations(current, remaining, start) {
if (current.length > 0 && current.length <= 4) {
const combinationObject = {
points: gradeCurrent(current),
buildings: [...current],
};
result.push(combinationObject);
if(result.length >= 3000) return result;
}
for (let i = start; i < remaining.length; i++) {
if(!current.some(item => dist2(item, remaining[i]) <= item.scale + remaining[i].scale)) {
current.push(remaining[i]);
generateCombinations(current, remaining.slice(i + 1), i + 1);
current.pop();
}
}
}
generateCombinations([], buildings, 0);
return result;
}
function checkPlacement(obj, priority, ppAmt, timer, canPlace){
//console.log(obj, priority, ppAmt, timer, canPlace);
if(obj.preplace && obj.placePriority && ppAmt < 2 && packets <= 60){
setTimeout(() => {
place(obj.item.id,obj.angle);
prioLoc.push(obj);
}, placeDelay - pingavg)
ue.add(tick, obj.x, obj.y, obj.angle, obj.scale, null, R.list[obj.item.id], !0, {sid: E.sid}, 0, 0, 1, 1, 1,0) // comment for tests
return true;
} else if(obj.placePriority && ppAmt < 3 && packets <= 60){
placers(obj.item.id,obj.angle)
prioLoc.push(obj);
ue.add(tick, obj.x, obj.y, obj.angle, obj.scale, null, R.list[obj.item.id], !0, {sid: E.sid}, 0, 0, 1, 1, 0, 0)
return true;
}
canPlace = ue.checkItemLocation(obj.x, obj.y, obj.scale, .6, obj.item.id, false, priority)
if(canPlace){
placers(obj.item.id,obj.angle)
ue.add(tick, obj.x, obj.y, obj.angle, obj.scale, null, R.list[obj.item.id], !0, {sid: E.sid}, 0, 0, 1, 1, 0, 1)
return true;
}
return false;
}
function placers(id, ang){
ee.send("z", id, null);
ee.send("F", 1, ang);
ee.send("z", hold ? hold : E.weaponIndex, true);
}
function autoplacers(trap, spike) {
if(!aPlacer.checked||!nEnemy||!amAlive||R.list[E.items[4]]?.name != "pit trap"||!E.items[4]||autobreakBuild) return;
let timer = Date.now();
let preplaceAmt = 0;
let possibleSpikes = findAvailableAngles(spikeType, 0, 0, PI / placeAccuracy.value)
let possibleTraps = findAvailableAngles(boostType, 0, 0, PI / placeAccuracy.value)
let placer = gradeAngles(possibleSpikes, possibleTraps, nearEnemies, timer)
usedAngles = usedAngles.filter(x => tick-x.tick <= 6 && dist(E,x) <= x.offset + 20);
trap = placer.bestTrap;
spike = placer.bestSpike;
placer.spikes.sort((a, b) => b.points - a.points);
placer.traps.sort((a, b) => b.points - a.points);
// sort spikes and traps by highest points
if(!placer.spikes.length && !placer.traps.length) return;
function fullplace(e, all = placer.spikes.concat(placer.traps)){
// all = all.sort((a, b) => b.points - a.points);
all.filter(x => x.points > 0);
if(packets >= 85) return;
if(!spike&&!trap&&!keys.c) return;
all = all.sort((a, b) => {
if (b.points === a.points && a.name !== b.name) {
// If points are the same and names are different, prioritize pit trap
return a.name === 'pit trap' ? -1 : 1;
}
return b.points - a.points;
});
for(let i = 0; i < all.length; i++) { // check for any intersections lol
if(!e.some(item => dist2(item, all[i]) <= item.scale + all[i].scale)){
e.push(all[i])
};
if(e.length === 4) break;
}
for(let i = 0; i < e.length; i++) {
if(!e[i].did) { // !.did only for the bestSpike and bestTrap placements
if(e[i].preplace && e[i].placePriority && packets <= 60) preplaceAmt++;
checkPlacement(e[i], packets <= 60 ? e[i].placePriority : 0, preplaceAmt, timer)
usedAngles.push({...e[i], tick: tick});
}
}
//ee.send("z", hold ? hold : E.weaponIndex, true)
}
let placing = [];
if(spike && spike.points>0 && (!trap?.canPush || (!trap?.retrap || !spike.into))) {
if(spike.into) {
createSpikeKB(spike.into.newPos)
}
if(spike.placePriority) {
if(spike.preplace){
preplaceAmt++
setTimeout(() => {
place(spikeType, spike.angle)
usedAngles.push({...spike, tick: tick});
prioLoc.push(spike);
}, placeDelay - pingavg);
} else {
placers(spikeType, spike.angle)
usedAngles.push({...spike, tick: tick});
prioLoc.push(spike);
};
spike.did = true;
placing.push(spike);
ue.add(tick, spike.x, spike.y, spike.angle, spike.scale, null, R.list[spikeType], !0, {sid: E.sid}, false, true, true, spike.preplace)
} else {
checkPlacement(spike, 0)
usedAngles.push({...spike, tick: tick});
spike.did = true;
placing.push(spike);
}
}
if(trap && trap.points > 0 && !(spike && spike.points>0 && dist(trap,spike) <= trap.scale+spike.scale && !isInPath(spike))|| (trap?.canPush || trap?.retrap && !spike.into)) {
if(trap.placePriority) {
if(trap.preplace) {
preplaceAmt++
setTimeout(() => {
place(boostType, trap.angle)
usedAngles.push({...trap, tick: tick});
prioLoc.push(trap);
}, placeDelay - pingavg);
} else {
placers(boostType, trap.angle)
usedAngles.push({...trap, tick: tick});
prioLoc.push(trap);
};
trap.did = true;
placing.push(trap);
ue.add(tick, trap.x, trap.y, trap.angle, trap.scale, null, R.list[boostType], !0, {sid: E.sid}, false, true, true, trap.preplace);
} else {
checkPlacement(trap, 0)
usedAngles.push({...trap, tick: tick});
trap.did = true;
placing.push(trap);
}
}
fullplace(placing);
if(placeDurations.length>=6) placeDurations.pop()
placeDurations.unshift(Date.now()-time)
}
let logStack = [];
const stackTimeout = 5000;
function logAndStack(message) {
const existingLog = logStack.find(item => item.message === message);
if (existingLog) {
existingLog.count++;
} else {
logStack.push({ message: message, count: 1 });
}
logStack.forEach(log => {
addChatLog(`${log.message} (${log.count})`, '', '#5c0620', false, true);
});
setTimeout(() => {
logStack = logStack.filter(log => log.count > 1);
}, stackTimeout);
}
async function stealAnimal(e,dir){
if(instaing||!amAlive) return;
e = ye.filter((t)=> t.health<R.weapons[primary].dmg*(bH.includes(7)?1.5:1)*Variants[E.primaryVar]&&t.visible)
e = e.sort((a,b) => b.killScore - a.killScore)[0]
if(e &&dist(E,e)-1.8*e.scale<=R.weapons[primary].range&&E.pr == 1){
console.log(e)
instaing = true;
ee.send("K",1)
aim[0] = getDir(E,e)
ee.send("z", primary, true);
Hg(7,18)
ee.send("D",getDir(E,e), "client")
await nextTick()
instaing = false;
}
}
function shieldBypass(e,t,dir){
if(t.weaponIndex!=11) return true;
dir = getDir(e,t)
return C.getAngleDist(dir + PI, t.dir) > PI / 3
}
async function bowInsta(){
paths = [];
if(!(distance>=670&&distance<=700)){
ee.send("9",getDir(E,coords), "client");
} else{
ee.send("9",null, "client")
}
if(E.age < 9) Hn.showText(E.x2, E.y2, 20, .18, 300, "age up first", "#fff");
if((distance>=670&&distance<=700)&& E.movSpd <= 5 && nEnemy.movSpd <= 5&&utilityType!=undefined&&E.age>=9){
console.log(distance, "bow insta distance")
if(R.list[utilityType].name == "platform")place(utilityType,getDir(E,nEnemy));
await nextTick();
Hg(53, 0);
hold = secondary
instaing =true;
bowInstaing = false;
ee.send("z",secondary,true)
aim[0] = getDir(E,nEnemy)
ee.send("D",getDir(E,nEnemy), "client")
console.log(distance)
await nextTick()
Hg(38,0)
hold = secondary
aim[0] = getDir(E,nEnemy)
// ee.send("D",getDir(R,nEnemy))
ee.send("H",12)
await nextTick()
hold = secondary
aim[0] = getDir(E,nEnemy)
ee.send("H",15)
// ee.send("D",getDir(R,nEnemy))
await nextTick()
// Hg(38, 0);
hold = null
instaing =false;
bowInstaing = false;
visAim = false
};
}
function multiCalcVel(_,ticks,ang,set,posArr = [],type,player,v){
// console.log(ticks, 'did calc');
player = {..._}
if(_.sid==E.sid && ang!==0 &&!ang){ ang = moveDirection} else if(inTrap&&_.sid==E.sid){ ang = undefined} else if(!ang&&ang!==0){ang = _.movDir}
v = calcVel(player,ang)
player.xVel = v.xVel
player.yVel = v.yVel
player.x2 = v.real.x
player.y2 = v.real.y
posArr.push(v)
if(ticks-1<=0) {
return posArr;
} else {
return multiCalcVel(player,ticks-1,ang,player,posArr);
}
}
function calcVel(_,ang,set,docalc,time = 111){
// if(!time) time =111;
//if(!isNaN(ang)){
if(!docalc){
if(_.sid == E.sid && ang !== 0 && !ang) {
ang = moveDirection
} else if (inTrap && _.sid == E.sid) {
ang = undefined
} else if (!ang&&ang!==0) {
ang = _.movDir
}
}
// }
let cosX = cos(ang)//_.sid == R.sid ?Math.cos(ang!=undefined&&ang!==undefined?ang:!inTrap?moveDirection:undefined) :Math.cos(_.movDir);
let sinY = sin(ang)//_.sid == R.sid?Math.sin(ang!=undefined&&ang!==undefined?ang:!inTrap?moveDirection:undefined) :Math.sin(_.movDir);
let sqrtDis = sqrt(cosX * cosX + sinY * sinY);
sqrtDis!=0 && (cosX /= sqrtDis,sinY /= sqrtDis)
if(!set) set = _;
let mult = speedMult(set);
_.speedXD = 0;
_.speedYD = 0;
_.predY = 0;
_.predX = 0;
cosX && (_.speedXD += cosX * .0016 * mult * time)
sinY && (_.speedYD += sinY * .0016 * mult * time)
var y0 = C.getDistance(0, 0, _.speedXD * time, _.speedYD * time), k0 = min(4, max(1, round(y0 / 40))), v0 = 1 / k0
// U = Math.min(4, Math.max(1, Math.round(O / 40)))
// console.log(v0)
// console.log(_.speedXD,_.speedYD)
_.speedXD && (_.predX += _.speedXD * time)
_.speedYD && (_.predY += _.speedYD * time)
// console.log(v0)
let velXD = _.xVel*pow(.993,time),
velYD = _.yVel*pow(.993,time),
velX = velXD+_.predX,
velY = velYD+_.predY,
accel = {x:_.x2+velX,y:_.y2+velY,type:'accel'},
decel = {x:_.x2+velXD,y:_.y2+velYD,type:'decel'},
fullDecel = fulldecel(velX,velY,{x:_.x2+velX,y:_.y2+velY}),
current = {x:_.x2,y:_.y2,type:"current"},
nextVel = {x:velX,y:velY,type:'nextVel'},
real = accel,
vel = round(sqrt(velX * velX + velY * velY)),
spd = mult,
// realxVel = Math.abs(Math.round(Math.sqrt(velX * velX))),
// realyVel = Math.abs(Math.round(Math.sqrt(velY * velY)))
boostxVel, boostyVel;
//console.log(velX,velY)
// console.log(E.xVel,E.yVel,velX,velY)
boostxVel = time * 1.5 * cos(ang);
boostyVel = time * 1.5 * sin(ang);
let boostCoords = { x: _.x2 + boostxVel, y: _.y2 + boostyVel };
if(ltt[_.sid]?.np!=undefined&&_.sid!=E.sid)real = dist(_,ltt[_.sid]?.np?.accel)>dist(_,ltt[_.sid]?.np?.decel)&&dAng(_.movDir,_.pmovDir)<=.3 ?decel:accel;
if(_.sid==E.sid){
if(moveDirection == undefined||moveDirection == null){
real = decel;
} else{
real = accel;
}
}
function fulldecel(e,t,coords,e2,t2){
if(isNaN(e)||isNaN(t))return;
try{
e2 = e*decayRate;
t2 = t*decayRate;
if(e!=e2){ e = e2
coords.x+=e
}
if(t!=t2){ t = t2
coords.y+=t
}
if(e==e2&& t==t2){
return {x:coords.x,y:coords.y,type:'full decel'}
} else{
// console.log(e,t,coords)
return fulldecel(e,t,coords)
}
} catch(e){}
}
let result = {accel:accel,decel:decel,boostCoords:boostCoords,boostVel:{x:boostxVel,y:boostyVel},nextVel:nextVel,real:real,current:current,fullDecel:fullDecel,xVel:velX, spd: mult, yVel:velY,vel:vel}
return result
}
function place(id,ang,wep) {//||!R.canBuild(R.list[id])&&id!=foodType
if(id==null||id==undefined||id==foodType&&E.food<R.list[foodType].req[1]&&!sandbox||!E.canBuild(R.list[id])&&id!=foodType||!amAlive||id==foodType && E.skinIndex==45) return;
!wep&&hold? wep = hold:wep = E.weaponIndex
ee.send("z",id,null)
ee.send("F",1,ang)
// ee.send("d",0)
ee.send("z",wep,(wep==wep||wep==secondary)?true:null)
//id != foodType && addVisual(id, ang); // op XD // remove this for no visual (fix later)
}
function healPlacer(id,ang,wep) {//||!R.canBuild(R.list[id])&&id!=foodType
if(id==null||id==undefined||id==foodType&&E.food<R.list[foodType].req[1]&&!sandbox||!E.canBuild(R.list[id])&&id!=foodType||!amAlive||id==foodType && E.skinIndex==45) return;
!wep && hold ? wep = hold : wep = E.weaponIndex;
ee.send("z", id);
ee.send("F", 1);
ee.send("z",wep,(wep==wep||wep==secondary)?true:null);
//id != foodType && addVisual(id, ang); // op XD // remove this for no visual (fix later)
}
function heal(e=E.health, t = [20, 40, 30]){
for(var n = e; n < 100; n += t[E.items[0]]) healPlacer(E.items[0], true);
}
function addVisual(millType, t) {
let n = R.list[millType];
let i = (35 + n.scale + (n.placeOffset || 0));
let x = E.x2 + cos(t) * i
let y = E.y2 + sin(t) * i
console.log("PLS");
ue.add(tick, x, y, C.fixTo(atan2(y - E.y2, x - E.x2) || 0, 2), n.scale, null, R.list[n.id], !0,{sid: E.sid},false, false, true,true)
}
function place2(id, wep) {//||!R.canBuild(R.list[id])&&id!=foodType
if(id==null||id==undefined||id==foodType&&E.food<R.list[foodType].req[1]&&!sandbox||!E.canBuild(R.list[id])&&id!=foodType||!amAlive||id==foodType && E.skinIndex==45) return;
!wep&&hold? wep = hold:wep = E.weaponIndex
ee.send("z",id)
ee.send("F",1)
ee.send("z",wep,(wep==wep||wep==secondary)?true:null)
}
function Qheal(e = 100-E?.dmgpot?.hp, t = [20, 40, 30]){
for(var n = e; n < 100; n += t[E.items[0]])place2(E.items[0], true)
}
function getOrdinalNumber(number) {
const suffixes = ["th", "st", "nd", "rd"];
const lastDigit = number % 10;
const suffix = suffixes[number % 100 > 10 && number % 100 < 20 ? 0 : (lastDigit < 1 || lastDigit > 3) ? 0 : lastDigit];
return number + suffix;
}
function ageCheck(_){
let test = 0;
let ez = _.loadout;
if(ez?.spawnpad ||R.weapons[_?.secondary]?.age==9||ez?.spike?.age==9) return 9;
ez.utility &&(test = 7);
test<R.weapons[_?.secondary]?.age&&(test = R.weapons[_?.secondary]?.age);
test<R.weapons[_?.primary]?.age &&(test = R.weapons[_?.primary]?.age);
test<ez?.spike?.age &&(test = ez.spike.age);
test<ez?.food?.age &&(test = ez.food.age);
test<ez?.windmill?.age && (test = ez.windmill.age);
test<ez?.wall?.age && (test = ez.wall.age);
_?.weaponIndex == 0 &&(test = 1);
// console.log(R.list)
if(_?.primary==0&&test>1) _.primary = undefined;
return test;
}
const defaultSpeed = timeBetweenTick / 2;
function speedMult(_){
var i = (((_.buildIndex < 0) + 1) / 2) * (R.weapons[_.weaponIndex]?.spdMult || 1) * (_.skinIndex && Xt.find(s => s.id == _.skinIndex)?.spdMult || 1)
* (_.tailIndex && Gt.find(r => r.id == _.tailIndex)?.spdMult || 1)
* (_.y2 <= T.snowBiomeTop ? _.skinIndex && Xt.find(p => p.id == _.skinIndex)?.coldM ? 1 : .75 : 1) * 1/*_.slowMult*/;
!_.zIndex && _.y2 >= T.mapScale / 2 - T.riverWidth / 2 && _.y2 <= T.mapScale / 2 + T.riverWidth / 2 &&
(_.skinIndex && Xt.find(s => s.id == _.skinIndex).watrImm ? (i *= 0.75) : (i *= 0.33));
return i;
}
function findID(tmpObj, tmp) {
return tmpObj.find((THIS) => THIS.id == tmp);
}
function speedMultTest(_, backup) {
_ = {
buildIndex: _?.buildIndex ?? backup?.buildIndex ?? -1,
weaponIndex: _?.weaponIndex ?? backup?.weaponIndex ?? null,
skinIndex: _?.skinIndex ?? backup?.skinIndex ?? null,
tailIndex: _?.tailIndex ?? backup?.tailIndex ?? null,
y2: _?.y2 ?? backup?.y2 ?? 0,
zIndex: _?.zIndex ?? backup?.zIndex ?? false
};
//console.log(_);
let i = (((_.buildIndex < 0) + 1) / 2) *
(R.weapons[_.weaponIndex]?.spdMult || 1) *
(_.skinIndex && Xt.find(s => s.id == _.skinIndex)?.spdMult || 1) *
(_.tailIndex && Gt.find(r => r.id == _.tailIndex)?.spdMult || 1) *
(_.y2 <= T.snowBiomeTop ? (_.skinIndex && Xt.find(p => p.id == _.skinIndex)?.coldM ? 1 : 0.75) : 1) *
1; // Adjust as needed, _.slowMult is commented out
if (!_.zIndex && _.y2 >= T.mapScale / 2 - T.riverWidth / 2 && _.y2 <= T.mapScale / 2 + T.riverWidth / 2) {
const watrImmMult = (_.skinIndex && Xt.find(s => s.id == _.skinIndex)?.watrImm) ? 0.75 : 0.33;
i *= watrImmMult;
}
// Add defaultSpeed calculation if needed
return defaultSpeed * i;
}
function loadoutSort(e,t){
let ez=0;
let obj = R.list[t]
if(obj.group.name == 'mill'){
e.windmill = obj
}
if(obj.group.name == 'spikes'){
e.spike = obj
}
if(obj.name == "boost pad"){
e.trap = false;
// console.log(e+" has", R.list[t].name)
}
if(obj.age == 7){
e.utility = obj;
// console.log(e+" has", R.list[t].name)
}
if(obj.group.name == 'walls'){
e.wall = obj
// console.log(e+" has", R.list[t].name)
}
if(obj.group.name == 'food'){
e.food = obj
// console.log(e+" has", R.list[t].name)
}
if(obj.name == "spawn pad"){
e.spawnpad = true;
}
}
function findTurret(e,t){
let turretFind = et.find((b)=>b.name=='turret'&&b.x==e&&b.y==t)
if(turretFind){
turretFind.time =2200;
turretFind.NOW=false;
turretFind.shot = Date.now();
return turretFind
}
return false
}
function turretTimer(){
for(let i=0;i<et.length;i++){
let turreter = et[i]
if(turreter.name == 'turret' && turreter?.time) turreter.time -= E.delta;
if(turreter.name == 'turret'&& turreter?.time<=0 )turreter.time = 2200;
}
}
function nextTick(){
return new Promise(r => {
managePromises[managePromises.length] = r
});
}
function elem(){
if(document.activeElement.id ==="") return true
return false
}
function dist2(a,b){
return C.getDistance(a.x2 || a.x, a.y2 || a.y, b.x2 || b.x, b.y2 || b.y)//Math.sqrt(Math.pow((b.y2||b.y) - (a.y2||a.y), 2) + Math.pow((b.x2||b.x) - (a.x2||a.x), 2));
}
function dist(a, b, bool) {
const distance = bool === "player" ? -1.8 * 35 : bool === "object" ? -b?.scale : 0;
return C.getDistance(a.x2 || a.x, a.y2 || a.y, b.x2 || b.x, b.y2 || b.y) + distance
}
// veltick (I added)
let velTickActive = false;
function handleVelTick() {
if (!document.getElementById("VelTick")?.checked || !nEnemy || !E.alive) return;
if (!E.skins[53]) return;
let isAutoSpacingOn = isAutoSpacingActive;
let ping = window.pingTime || 0;
let minRange = (ping > 140) ? 230 : (ping > 110) ? 210 : (ping > 85) ? 190 : 170;
let maxRange = 245;
let distToEnemy = dist(E, nEnemy);
let isVulnerable = nEnemy.skinIndex != 6 && nEnemy.skinIndex != 22;
if (!velTickActive) {
if (isAutoSpacingOn && isVulnerable && distToEnemy >= 160 && distToEnemy <= 270) {
if (distToEnemy > maxRange) {
ee.send("9", getDir(E, nEnemy));
return;
} else if (distToEnemy < minRange) {
ee.send("9", getDir(nEnemy, E));
return;
}
}
if (distToEnemy >= minRange &&
distToEnemy <= maxRange &&
!inTrap &&
E.pr == 1 &&
E.tr == 1 &&
primary == 5 &&
isVulnerable) {
velTickActive = true;
ee.send("9", undefined);
performVelTickCombo();
}
}
}
function performVelTickCombo() {
visAim = true;
aim[0] = getDir(E, nEnemy);
let moveTail = E.tails[19] ? 19 : (E.tails[11] ? 11 : 0);
Hg(53, moveTail);
ee.send("z", primary, true);
setTimeout(() => {
if (!nEnemy || !E.alive || dist(E, nEnemy) > 300) {
velTickActive = false;
visAim = false;
aim[0] = null;
return;
}
let enemyDir = getDir(E, nEnemy);
ee.send("9", enemyDir);
ee.send("9", enemyDir);
ee.send("D", enemyDir);
let attackTail = E.tails[19] ? 19 : 0;
Hg(7, attackTail);
ee.send("K", 1);
setTimeout(() => {
if (velTickActive) Hg(7, attackTail);
ee.send("z", primary, true);
// ee.send("K", 1);
// if lagging (dont need)
ee.send("K", 1);
velTickActive = false;
visAim = false;
aim[0] = null;
}, timeBetweenTick);
}, timeBetweenTick);
}
document.addEventListener('keyup', function(e) {
if (e.key.toLowerCase() === "u") {
isAutoSpacingActive = false;
let statusText = "Auto Spacing: Off";
if (typeof Hn !== "undefined" && E) {
Hn.showText(E.x2, E.y2 - 10, 50, 0.2, 500, statusText, "#fff");
}
}
});