HaxKiller (unpatched)

no desrcription because someone reported it

  1. // ==UserScript==
  2. // @name HaxKiller (unpatched)
  3. // @match *://*.moomoo.io/*
  4. // @version 1400
  5. // @author HaxBountyHunter
  6. // @description no desrcription because someone reported it
  7. // @icon https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTW__q_hiNTduWCXL2JdSKgqbI-ZhdOegRusQ&s
  8. // @match *://moomoo.io/*
  9. // @match *://sandbox.moomoo.io/*
  10. // @match *://dev.moomoo.io/*
  11. // @grant none
  12. // @namespace none
  13. // ==/UserScript==
  14. // Moo Moo
  15. document.getElementById("mainMenu").style.backgroundImage = "url('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTW__q_hiNTduWCXL2JdSKgqbI-ZhdOegRusQ&s')";
  16. document.getElementById("mainMenu").style.backgroundRepeat = "repeat";
  17. document.getElementById("mainMenu").style.backgroundSize = "contain";
  18. window.reloadedColor = "#880808";
  19. window.middleReloadedColor = "#880808";
  20. window.notReloadedColor = "#880808";
  21. document.getElementById("loadingText").innerText="";
  22. document.getElementById("loadingText").style.color = "#880808";
  23. document.getElementById("loadingText").style.color = "linear-gradient(red,yellow)";
  24. document.getElementById("loadingText").style.textShadow = "#880808 -2px -2px 10px, purple 0px -5px 1px, purple 0px -5px 10px";
  25. var gameNameElement = document.getElementById("gameName");
  26. gameNameElement.style.backgroundImage = "linear-gradient(to right, red, yellow)";
  27. gameNameElement.style.WebkitBackgroundClip = "text";
  28. gameNameElement.style.color = "transparent";
  29. gameNameElement.style.textShadow = "0 0 2px #880808, 0 0 5px red";
  30. gameNameElement.style.webkitTextFillColor = "transparent";
  31. gameNameElement.style.webkitTextStroke = "1px black";
  32. gameNameElement.style.animation = "popIn 1.5s ease-out";
  33.  
  34. (function() {
  35. const scriptSrc = "index-6b10514b.js";
  36. const scriptTags = document.querySelectorAll(`script[src*="${scriptSrc}"]`);
  37. if (scriptTags.length > 0) {
  38. scriptTags[0].remove();
  39. }
  40. })();
  41.  
  42. document.addEventListener("keydown", function(event) {
  43. if (event.keyCode === 192) {
  44. const chatHolder = document.getElementById("gameUI");
  45. if (chatHolder) {
  46. const currentDisplay = chatHolder.style.display;
  47. chatHolder.style.display = currentDisplay === "none" ? "block" : "none";
  48. }
  49. }
  50. });
  51.  
  52. function getEl(id) {
  53. return document.getElementById(id);
  54. }
  55.  
  56. function loadScript(url, callback) {
  57. let script = document.createElement("script");
  58. script.src = url;
  59. script.onload = () => {
  60. console.log(`Successfully loaded script: ${url}`);
  61. if (callback) callback();
  62. };
  63. script.onerror = (error) => {
  64. console.error(`Failed to load script: ${url}`, error);
  65. };
  66. document.body.appendChild(script);
  67. }
  68.  
  69. const msgpackUrl = "https://rawgit.com/kawanet/msgpack-lite/master/dist/msgpack.min.js";
  70. const customScriptUrl = null;
  71.  
  72. loadScript(msgpackUrl, () => {
  73. loadScript(customScriptUrl);
  74. });
  75.  
  76. window.oncontextmenu = function() {
  77. return false;
  78. };
  79.  
  80. let config = window.config;
  81. let recording;
  82.  
  83. config.clientSendRate = 9;
  84. config.serverUpdateRate = 9;
  85.  
  86. config.deathFadeout = 0;
  87.  
  88. config.playerCapacity = 50;
  89. window.config.maxPlayers = 50;
  90.  
  91. config.isSandbox = window.location.hostname == "sandbox.moomoo.io";
  92.  
  93. config.skinColors = ["#bf8f54", "#4c4c4c", "#896c4b",
  94. "#fadadc", "#ececec", "#c37373", "#000000", "#ecaff7", "#738cc3",
  95. "#8bc373", "#91b2db"
  96. ];
  97.  
  98. config.weaponVariants = [{
  99. id: 0,
  100. src: "",
  101. xp: 0,
  102. val: 1,
  103. }, {
  104. id: 1,
  105. src: "_g",
  106. xp: 3000,
  107. val: 1.1,
  108. }, {
  109. id: 2,
  110. src: "_d",
  111. xp: 7000,
  112. val: 1.18,
  113. }, {
  114. id: 3,
  115. src: "_r",
  116. poison: true,
  117. xp: 12000,
  118. val: 1.18,
  119. }, {
  120. id: 4,
  121. src: "_e",
  122. poison: true,
  123. heal: true,
  124. xp: 24000,
  125. val: 1.18,
  126. }];
  127.  
  128. config.anotherVisual = true;
  129. config.useWebGl = false;
  130. config.resetRender = true;
  131.  
  132. function waitTime(timeout) {
  133. return new Promise((done) => {
  134. setTimeout(() => {
  135. done();
  136. }, timeout);
  137. });
  138. }
  139.  
  140. let canStore;
  141. if (typeof(Storage) !== "undefined") {
  142. canStore = true;
  143. }
  144.  
  145. function saveVal(name, val) {
  146. if (canStore)
  147. localStorage.setItem(name, val);
  148. }
  149.  
  150. function deleteVal(name) {
  151. if (canStore)
  152. localStorage.removeItem(name);
  153. }
  154.  
  155. function getSavedVal(name) {
  156. if (canStore)
  157. return localStorage.getItem(name);
  158. return null;
  159. }
  160.  
  161. let gC = function(a, b) {
  162. try {
  163. let res = JSON.parse(getSavedVal(a));
  164. if (typeof res === "object") {
  165. return b;
  166. } else {
  167. return res;
  168. }
  169. } catch (e) {
  170. return b;
  171. }
  172. };
  173.  
  174. function setConfigs() {
  175. return {
  176. killChat: true,
  177. autoBuy: true,
  178. autoBuyEquip: true,
  179. autoPush: true,
  180. revTick: true,
  181. spikeTick: true,
  182. predictTick: true,
  183. autoPlace: true,
  184. autoReplace: true,
  185. antiTrap: true,
  186. slowOT: false,
  187. attackDir: false,
  188. showDir: true,
  189. autoRespawn: false
  190. };
  191. }
  192.  
  193. let configs = setConfigs();
  194.  
  195. window.removeConfigs = function() {
  196. for (let cF in configs) {
  197. deleteVal(cF, configs[cF]);
  198. }
  199. };
  200.  
  201. for (let cF in configs) {
  202. configs[cF] = gC(cF, configs[cF]);
  203. }
  204.  
  205. window.changeMenu = function() {};
  206. window.debug = function() {};
  207. window.wasdMode = function() {};
  208.  
  209. window.startGrind = function() {};
  210.  
  211. window.resBuild = function() {};
  212. window.toggleVisual = function() {};
  213.  
  214. window.prepareUI = function() {};
  215. window.leave = function() {};
  216.  
  217. class HtmlAction {
  218. constructor(element) {
  219. this.element = element;
  220. };
  221. add(code) {
  222. if (!this.element) return undefined;
  223. this.element.innerHTML += code;
  224. };
  225. newLine(amount) {
  226. let result = `<br>`;
  227. if (amount > 0) {
  228. result = ``;
  229. for (let i = 0; i < amount; i++) {
  230. result += `<br>`;
  231. }
  232. }
  233. this.add(result);
  234. };
  235. checkBox(setting) {
  236. let newCheck = `<input type = "checkbox"`;
  237. setting.id && (newCheck += ` id = ${setting.id}`);
  238. setting.style && (newCheck += ` style = ${setting.style.replaceAll(" ", "")}`);
  239. setting.class && (newCheck += ` class = ${setting.class}`);
  240. setting.checked && (newCheck += ` checked`);
  241. setting.onclick && (newCheck += ` onclick = ${setting.onclick}`);
  242. newCheck += `>`;
  243. this.add(newCheck);
  244. };
  245. text(setting) {
  246. let newText = `<input type = "text"`;
  247. setting.id && (newText += ` id = ${setting.id}`);
  248. setting.style && (newText += ` style = ${setting.style.replaceAll(" ", "")}`);
  249. setting.class && (newText += ` class = ${setting.class}`);
  250. setting.size && (newText += ` size = ${setting.size}`);
  251. setting.maxLength && (newText += ` maxLength = ${setting.maxLength}`);
  252. setting.value && (newText += ` value = ${setting.value}`);
  253. setting.placeHolder && (newText += ` placeHolder = ${setting.placeHolder.replaceAll(" ", "&nbsp;")}`);
  254. newText += `>`;
  255. this.add(newText);
  256. };
  257. select(setting) {
  258. let newSelect = `<select`;
  259. setting.id && (newSelect += ` id = ${setting.id}`);
  260. setting.style && (newSelect += ` style = ${setting.style.replaceAll(" ", "")}`);
  261. setting.class && (newSelect += ` class = ${setting.class}`);
  262. newSelect += `>`;
  263. for (let options in setting.option) {
  264. newSelect += `<option value = ${setting.option[options].id}`
  265. setting.option[options].selected && (newSelect += ` selected`);
  266. newSelect += `>${options}</option>`;
  267. }
  268. newSelect += `</select>`;
  269. this.add(newSelect);
  270. };
  271. button(setting) {
  272. let newButton = `<button`;
  273. setting.id && (newButton += ` id = ${setting.id}`);
  274. setting.style && (newButton += ` style = ${setting.style.replaceAll(" ", "")}`);
  275. setting.class && (newButton += ` class = ${setting.class}`);
  276. setting.onclick && (newButton += ` onclick = ${setting.onclick}`);
  277. newButton += `>`;
  278. setting.innerHTML && (newButton += setting.innerHTML);
  279. newButton += `</button>`;
  280. this.add(newButton);
  281. };
  282. selectMenu(setting) {
  283. let newSelect = `<select`;
  284. if (!setting.id) {
  285. alert("please put id skid");
  286. return;
  287. }
  288. window[setting.id + "Func"] = function() {};
  289. setting.id && (newSelect += ` id = ${setting.id}`);
  290. setting.style && (newSelect += ` style = ${setting.style.replaceAll(" ", "")}`);
  291. setting.class && (newSelect += ` class = ${setting.class}`);
  292. newSelect += ` onchange = window.${setting.id + "Func"}()`;
  293. newSelect += `>`;
  294. let last;
  295. let i = 0;
  296. for (let options in setting.menu) {
  297. newSelect += `<option value = ${"option_" + options} id = ${"O_" + options}`;
  298. setting.menu[options] && (newSelect += ` checked`);
  299. newSelect += ` style = "color: ${setting.menu[options] ? "#880808" : "#880808"}; background: ${setting.menu[options] ? "#880808" : "#880808"};">${options}</option>`;
  300. i++;
  301. }
  302. newSelect += `</select>`;
  303.  
  304. this.add(newSelect);
  305.  
  306. i = 0;
  307. for (let options in setting.menu) {
  308. window[options + "Func"] = function() {
  309. setting.menu[options] = getEl("check_" + options).checked ? true : false;
  310. saveVal(options, setting.menu[options]);
  311. getEl("O_" + options).style.color = setting.menu[options] ? "#880808" : "#880808";
  312. getEl("O_" + options).style.background = setting.menu[options] ? "#880808" : "#880808";
  313. };
  314. this.checkBox({
  315. id: "check_" + options,
  316. style: `display: ${i == 0 ? "inline-block" : "none"};`,
  317. class: "checkB",
  318. onclick: `window.${options + "Func"}()`,
  319. checked: setting.menu[options]
  320. });
  321. i++;
  322. }
  323.  
  324. last = "check_" + getEl(setting.id).value.split("_")[1];
  325. window[setting.id + "Func"] = function() {
  326. getEl(last).style.display = "none";
  327. last = "check_" + getEl(setting.id).value.split("_")[1];
  328. getEl(last).style.display = "inline-block";
  329. };
  330. };
  331. };
  332. class Html {
  333. constructor() {
  334. this.element = null;
  335. this.action = null;
  336. this.divElement = null;
  337. this.startDiv = function(setting, func) {
  338.  
  339. let newDiv = document.createElement("div");
  340. setting.id && (newDiv.id = setting.id);
  341. setting.style && (newDiv.style = setting.style);
  342. setting.class && (newDiv.className = setting.class);
  343. this.element.appendChild(newDiv);
  344. this.divElement = newDiv;
  345.  
  346. let addRes = new HtmlAction(newDiv);
  347. typeof func == "function" && func(addRes);
  348.  
  349. };
  350. this.addDiv = function(setting, func) {
  351.  
  352. let newDiv = document.createElement("div");
  353. setting.id && (newDiv.id = setting.id);
  354. setting.style && (newDiv.style = setting.style);
  355. setting.class && (newDiv.className = setting.class);
  356. setting.appendID && getEl(setting.appendID).appendChild(newDiv);
  357. this.divElement = newDiv;
  358.  
  359. let addRes = new HtmlAction(newDiv);
  360. typeof func == "function" && func(addRes);
  361.  
  362. };
  363. };
  364. set(id) {
  365. this.element = getEl(id);
  366. this.action = new HtmlAction(this.element);
  367. };
  368. resetHTML(text) {
  369. if (text) {
  370. this.element.innerHTML = ``;
  371. } else {
  372. this.element.innerHTML = ``;
  373. }
  374. };
  375. setStyle(style) {
  376. this.element.style = style;
  377. };
  378. setCSS(style) {
  379. this.action.add(`<style>` + style + `</style>`);
  380. };
  381. };
  382.  
  383.  
  384.  
  385. let HTML = new Html();
  386.  
  387. let menuDiv = document.createElement("div");
  388. menuDiv.id = "menuDiv";
  389. document.body.appendChild(menuDiv);
  390. HTML.set("menuDiv");
  391. HTML.setStyle(`
  392. position: absolute;
  393. display: none;
  394. left: 20px;
  395. top: 135px;
  396. `);
  397. HTML.resetHTML();
  398. HTML.setCSS(`
  399. body {
  400. margin: 0;
  401. padding: 0;
  402. overflow: hidden;
  403. color: red;
  404. font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  405. }
  406.  
  407. .menuClass {
  408. color: #fff;
  409. font-size: 22px;
  410. text-align: left;
  411. padding: 20px;
  412. width: 300px;
  413. background-color: rgba(0, 0, 0, 0.25);
  414. border-radius: 4px;
  415. border: 3px solid cyan;
  416. position: fixed;
  417. top: 50%;
  418. left: 50%;
  419. transform: translate(-50%, -50%);
  420. }
  421.  
  422. .menuC {
  423. display: none;
  424. font-size: 14px;
  425. max-height: 200px;
  426. overflow-y: auto;
  427. }
  428.  
  429. .menuB {
  430. text-align: center;
  431. background-color: rgba(0, 0, 0, 0.55);
  432. color: #000;
  433. border: none;
  434. border-radius: 4px;
  435. padding: 4px 4px;
  436. cursor: pointer;
  437. transition: 0.3s ease;
  438. }
  439.  
  440. .menuB:hover {
  441. background-color: red;
  442. color: #000;
  443. }
  444.  
  445. .menuB:active {
  446. transform: translateY(1px);
  447. }
  448.  
  449. .checkB {
  450. cursor: pointer;
  451. }
  452.  
  453. .Cselect {
  454. background-color: #880808;
  455. color: #fff;
  456. border: 3px solid red;
  457. border-radius: 66px;
  458. padding: 2px;
  459. }
  460.  
  461. #menuChanger {
  462. position: absolute;
  463. right: 20px;
  464. top: 20px;
  465. background-color: rgba(0, 0, 0, 0.55);
  466. border-radius: 100%;
  467. width: 35px;
  468. height: 35px;
  469. color: red;
  470. border: none;
  471. cursor: pointer;
  472. transition: 0.3s ease;
  473. }
  474.  
  475. #menuChanger:hover {
  476. background-color: red;
  477. color: #880808;
  478. }
  479. `);
  480.  
  481. HTML.startDiv({
  482. id: "menuHeadLine",
  483. class: "menuClass"
  484. }, (html) => {
  485. html.add(`HaxBountyHunter Ai`);
  486. html.button({
  487. id: "menuChanger",
  488. class: "material-icons",
  489. innerHTML: `sync`,
  490. onclick: "window.changeMenu()"
  491. });
  492. HTML.addDiv({
  493. id: "menuButtons",
  494. style: "display: block; overflow-y: visible;",
  495. class: "menuC",
  496. appendID: "menuHeadLine"
  497. }, (html) => {
  498. html.button({
  499. class: "menuB",
  500. innerHTML: "Debug",
  501. onclick: "window.debug()"
  502. });
  503. });
  504. HTML.addDiv({
  505. id: "menuMain",
  506. style: "display: block",
  507. class: "menuC",
  508. appendID: "menuHeadLine"
  509. }, (html) => {
  510. html.button({
  511. class: "menuB",
  512. innerHTML: "Dagger Optimisation",
  513. onclick: "window.wasdMode()"
  514. });
  515. html.newLine();
  516. html.add(`Auto-Grinder: `);
  517. html.checkBox({
  518. id: "weaponGrind",
  519. class: "checkB",
  520. onclick: "window.startGrind()"
  521. });
  522. html.newLine(2);
  523. HTML.addDiv({
  524. style: "font-size: 30px; color: #880808;",
  525. appendID: "menuMain"
  526. }, (html) => {
  527. html.add(`_______________`);
  528. });
  529. html.add(`Anti-Push:`);
  530. html.checkBox({
  531. id: "antipush",
  532. class: "checkB",
  533. checked: true
  534. });
  535. html.newLine();
  536. html.add(`Auto-Health:`);
  537. html.checkBox({
  538. id: "healingBeta",
  539. class: "checkB",
  540. checked: true
  541. });
  542. html.newLine();
  543. });
  544. HTML.addDiv({
  545. id: "menuConfig",
  546. class: "menuC",
  547. appendID: "menuHeadLine"
  548. }, (html) => {
  549. html.add(`AutoPlacer Placement Tick: `);
  550. html.text({
  551. id: "autoPlaceTick",
  552. class: "customText",
  553. value: "1",
  554. size: "2em",
  555. maxLength: "2"
  556. });
  557. html.newLine();
  558. html.add(`Configs: `);
  559. html.selectMenu({
  560. id: "configsChanger",
  561. class: "Cselect",
  562. menu: configs
  563. });
  564. html.newLine();
  565. html.add(`InstaKill Type: `);
  566. html.select({
  567. id: "instaType",
  568. class: "Cselect",
  569. option: {
  570. OneShot: {
  571. id: "oneShot",
  572. selected: true
  573. },
  574. Spammer: {
  575. id: "spammer"
  576. }
  577. }
  578. });
  579. html.newLine();
  580. html.add(`AntiBull Type: `);
  581. html.select({
  582. id: "antiBullType",
  583. class: "Cselect",
  584. option: {
  585. "Disable AntiBull": {
  586. id: "noab",
  587. selected: true
  588. },
  589. "When Reloaded": {
  590. id: "abreload",
  591. },
  592. "Primary Reloaded": {
  593. id: "abalway"
  594. }
  595. }
  596. });
  597. html.newLine();
  598. html.add(`Backup Nobull Insta: `);
  599. html.checkBox({
  600. id: "backupNobull",
  601. class: "checkB",
  602. checked: true
  603. });
  604. html.newLine();
  605. html.add(`Turret Gear Combat Assistance: `);
  606. html.checkBox({
  607. id: "turretCombat",
  608. class: "checkB",
  609. checked: true
  610. });
  611. html.newLine();
  612. html.add(`Safe AntiSpikeTick: `);
  613. html.checkBox({
  614. id: "safeAntiSpikeTick",
  615. class: "checkB",
  616. checked: true
  617. });
  618. html.newLine();
  619. });
  620. HTML.addDiv({
  621. id: "menuOther",
  622. class: "menuC",
  623. appendID: "menuHeadLine"
  624. }, (html) => {
  625. html.newLine();
  626. html.button({
  627. class: "menuB",
  628. innerHTML: "Reset Break Objects",
  629. onclick: "window.resBuild()"
  630. });
  631. html.newLine();
  632. html.add(`Break Objects Range: `);
  633. html.text({
  634. id: "breakRange",
  635. class: "customText",
  636. value: "700",
  637. size: "3em",
  638. maxLength: "4"
  639. });
  640. html.newLine();
  641. html.add(`Predict Movement Type: `);
  642. html.select({
  643. id: "predictType",
  644. class: "Cselect",
  645. option: {
  646. "Disable Render": {
  647. id: "disableRender",
  648. selected: true
  649. },
  650. "X/Y and 2": {
  651. id: "pre2",
  652. },
  653. "X/Y and 3": {
  654. id: "pre3"
  655. }
  656. }
  657. });
  658. html.newLine();
  659. html.add(`Render Placers: `);
  660. html.checkBox({
  661. id: "placeVis",
  662. class: "checkB",
  663. });
  664. });
  665. });
  666.  
  667. let menuIndex = 0;
  668. let menus = ["menuMain", "menuConfig", "menuOther"];
  669. window.changeMenu = function() {
  670. getEl(menus[menuIndex % menus.length]).style.display = "none";
  671. menuIndex++;
  672. getEl(menus[menuIndex % menus.length]).style.display = "block";
  673. };
  674.  
  675. let openMenu = false;
  676.  
  677. let WS = undefined;
  678. let socketID = undefined;
  679.  
  680. let useWasd = false;
  681. let secPacket = 0;
  682. let secMax = 120;
  683. let secTime = 1000;
  684. let firstSend = {
  685. sec: false
  686. };
  687. let game = {
  688. tick: 0,
  689. tickQueue: [],
  690. tickBase: function(set, tick) {
  691. if (this.tickQueue[this.tick + tick]) {
  692. this.tickQueue[this.tick + tick].push(set);
  693. } else {
  694. this.tickQueue[this.tick + tick] = [set];
  695. }
  696. },
  697. tickRate: (1000 / config.serverUpdateRate),
  698. tickSpeed: 0,
  699. lastTick: performance.now()
  700. };
  701. let modConsole = [];
  702.  
  703. let dontSend = false;
  704. let fpsTimer = {
  705. last: 0,
  706. time: 0,
  707. ltime: 0
  708. }
  709. let lastMoveDir = undefined;
  710. let lastsp = ["cc", 1, "__proto__"];
  711.  
  712. WebSocket.prototype.nsend = WebSocket.prototype.send;
  713. WebSocket.prototype.send = function(message) {
  714. if (!WS) {
  715. WS = this;
  716. WS.addEventListener("message", function(msg) {
  717. getMessage(msg);
  718. });
  719. WS.addEventListener("close", (event) => {
  720. if (event.code == 4001) {
  721. window.location.reload();
  722. }
  723. });
  724. }
  725. if (WS == this) {
  726. dontSend = false;
  727.  
  728. let data = new Uint8Array(message);
  729. let parsed = window.msgpack.decode(data);
  730. let type = parsed[0];
  731. data = parsed[1];
  732.  
  733. if (type == "6") {
  734.  
  735. if (data[0]) {
  736. let profanity = ["cunt", "whore", "fuck", "shit", "faggot", "nigger", "nigga", "dick", "vagina", "minge", "cock", "rape", "cum", "sex", "tits", "penis", "clit", "pussy", "meatcurtain", "jizz", "prune", "douche", "wanker", "damn", "bitch", "dick", "fag", "bastard", ];
  737. let tmpString;
  738. profanity.forEach((profany) => {
  739. if (data[0].indexOf(profany) > -1) {
  740. tmpString = "";
  741. for (let i = 0; i < profany.length; ++i) {
  742. if (i == 1) {
  743. tmpString += String.fromCharCode(0);
  744. }
  745. tmpString += profany[i];
  746. }
  747. let re = new RegExp(profany, "g");
  748. data[0] = data[0].replace(re, tmpString);
  749. }
  750. });
  751.  
  752. data[0] = data[0].slice(0, 30);
  753. }
  754.  
  755. } else if (type == "L") {
  756. data[0] = data[0] + (String.fromCharCode(0).repeat(7));
  757. data[0] = data[0].slice(0, 7);
  758. } else if (type == "M") {
  759. data[0].name = data[0].name == "" ? "unknown" : "" + data[0].name;
  760. data[0].moofoll = true;
  761. data[0].skin = data[0].skin == 10 ? "__proto__" : data[0].skin;
  762. lastsp = [data[0].name, data[0].moofoll, data[0].skin];
  763. } else if (type == "D") {
  764. if ((my.lastDir == data[0]) || [null, undefined].includes(data[0])) {
  765. dontSend = true;
  766. } else {
  767. my.lastDir = data[0];
  768. }
  769. } else if (type == "d") {
  770. if (!data[2]) {
  771. dontSend = true;
  772. } else {
  773. if (![null, undefined].includes(data[1])) {
  774. my.lastDir = data[1];
  775. }
  776. }
  777. } else if (type == "K") {
  778. if (!data[1]) {
  779. dontSend = true;
  780. }
  781. } else if (type == "S") {
  782. instaC.wait = !instaC.wait;
  783. dontSend = true;
  784. } else if (type == "f") {
  785. if (data[1]) {
  786. if (player.moveDir == data[0]) {
  787. dontSend = true;
  788. }
  789. player.moveDir = data[0];
  790. } else {
  791. dontSend = true;
  792. }
  793. }
  794. if (!dontSend) {
  795. let binary = window.msgpack.encode([type, data]);
  796. this.nsend(binary);
  797.  
  798. if (!firstSend.sec) {
  799. firstSend.sec = true;
  800. setTimeout(() => {
  801. firstSend.sec = false;
  802. secPacket = 0;
  803. }, secTime);
  804. }
  805.  
  806. secPacket++;
  807. }
  808. } else {
  809. this.nsend(message);
  810. }
  811. }
  812.  
  813. function packet(type) {
  814. let data = Array.prototype.slice.call(arguments, 1);
  815. let binary = window.msgpack.encode([type, data]);
  816. WS.send(binary);
  817. }
  818.  
  819. function origPacket(type) {
  820. let data = Array.prototype.slice.call(arguments, 1);
  821. let binary = window.msgpack.encode([type, data]);
  822. WS.nsend(binary);
  823. }
  824.  
  825. window.leave = function() {
  826. origPacket("kys", {
  827. "frvr is so bad": true,
  828. "sidney is too good": true,
  829. "dev are too weak": true,
  830. });
  831. };
  832.  
  833. let io = {
  834. send: packet
  835. };
  836.  
  837. function getMessage(message) {
  838. let data = new Uint8Array(message.data);
  839. let parsed = window.msgpack.decode(data);
  840. let type = parsed[0];
  841. data = parsed[1];
  842. let events = {
  843. A: setInitData,
  844. C: setupGame,
  845. D: addPlayer,
  846. E: removePlayer,
  847. a: updatePlayers,
  848. G: updateLeaderboard,
  849. H: loadGameObject,
  850. I: loadAI,
  851. J: animateAI,
  852. K: gatherAnimation,
  853. L: wiggleGameObject,
  854. M: shootTurret,
  855. N: updatePlayerValue,
  856. O: updateHealth,
  857. P: killPlayer,
  858. Q: killObject,
  859. R: killObjects,
  860. S: updateItemCounts,
  861. T: updateAge,
  862. U: updateUpgrades,
  863. V: updateItems,
  864. X: addProjectile,
  865. 3: setPlayerTeam,
  866. 4: setAlliancePlayers,
  867. 5: updateStoreItems,
  868. 6: receiveChat,
  869. 7: updateMinimap,
  870. 8: showText,
  871. 9: pingMap,
  872. 0: pingSocketResponse,
  873. };
  874. if (type == "io-init") {
  875. socketID = data[0];
  876. } else {
  877. if (events[type]) {
  878. events[type].apply(undefined, data);
  879. }
  880. }
  881. }
  882.  
  883. Math.lerpAngle = function(value1, value2, amount) {
  884. let difference = Math.abs(value2 - value1);
  885. if (difference > Math.PI) {
  886. if (value1 > value2) {
  887. value2 += Math.PI * 2;
  888. } else {
  889. value1 += Math.PI * 2;
  890. }
  891. }
  892. let value = value2 + ((value1 - value2) * amount);
  893. if (value >= 0 && value <= Math.PI * 2) return value;
  894. return value % (Math.PI * 2);
  895. };
  896.  
  897. CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
  898. if (w < 2 * r) r = w / 2;
  899. if (h < 2 * r) r = h / 2;
  900. if (r < 0)
  901. r = 0;
  902. this.beginPath();
  903. this.moveTo(x + r, y);
  904. this.arcTo(x + w, y, x + w, y + h, r);
  905. this.arcTo(x + w, y + h, x, y + h, r);
  906. this.arcTo(x, y + h, x, y, r);
  907. this.arcTo(x, y, x + w, y, r);
  908. this.closePath();
  909. return this;
  910. };
  911.  
  912. function resetMoveDir() {
  913. keys = {};
  914. io.send("e");
  915. }
  916.  
  917. let allChats = [];
  918. let ticks = {
  919. tick: 0,
  920. delay: 0,
  921. time: [],
  922. manage: [],
  923. };
  924. let ais = [];
  925. let players = [];
  926. let alliances = [];
  927. let alliancePlayers = [];
  928. let gameObjects = [];
  929. let liztobj = [];
  930. let projectiles = [];
  931. let deadPlayers = [];
  932.  
  933. let breakObjects = [];
  934.  
  935. let player;
  936. let playerSID;
  937. let tmpObj;
  938.  
  939. let enemy = [];
  940. let nears = [];
  941. let near = [];
  942.  
  943. let my = {
  944. reloaded: false,
  945. waitHit: 0,
  946. autoAim: false,
  947. revAim: false,
  948. ageInsta: true,
  949. reSync: false,
  950. bullTick: 0,
  951. anti0Tick: 0,
  952. antiSync: false,
  953. safePrimary: function(tmpObj) {
  954. return [0, 8].includes(tmpObj.primaryIndex);
  955. },
  956. safeSecondary: function(tmpObj) {
  957. return [10, 11, 14].includes(tmpObj.secondaryIndex);
  958. },
  959. lastDir: 0,
  960. autoPush: false,
  961. pushData: {}
  962. }
  963.  
  964. function findID(tmpObj, tmp) {
  965. return tmpObj.find((THIS) => THIS.id == tmp);
  966. }
  967.  
  968. function findSID(tmpObj, tmp) {
  969. return tmpObj.find((THIS) => THIS.sid == tmp);
  970. }
  971.  
  972. function findPlayerByID(id) {
  973. return findID(players, id);
  974. }
  975.  
  976. function findPlayerBySID(sid) {
  977. return findSID(players, sid);
  978. }
  979.  
  980. function findAIBySID(sid) {
  981. return findSID(ais, sid);
  982. }
  983.  
  984. function findObjectBySid(sid) {
  985. return findSID(gameObjects, sid);
  986. }
  987.  
  988. function findProjectileBySid(sid) {
  989. return findSID(gameObjects, sid);
  990. }
  991.  
  992. let adCard = getEl("adCard");
  993. adCard.remove();
  994. let promoImageHolder = getEl("promoImgHolder");
  995. promoImageHolder.remove();
  996.  
  997. let chatButton = getEl("chatButton");
  998. chatButton.remove();
  999. let gameCanvas = getEl("gameCanvas");
  1000. let mainContext = gameCanvas.getContext("2d");
  1001. let mapDisplay = getEl("mapDisplay");
  1002. let mapContext = mapDisplay.getContext("2d");
  1003. mapDisplay.width = 300;
  1004. mapDisplay.height = 300;
  1005. let storeMenu = getEl("storeMenu");
  1006. let storeHolder = getEl("storeHolder");
  1007. let upgradeHolder = getEl("upgradeHolder");
  1008. let upgradeCounter = getEl("upgradeCounter");
  1009. let chatBox = getEl("chatBox");
  1010. chatBox.autocomplete = "off";
  1011. chatBox.style.textAlign = "center";
  1012. chatBox.style.width = "18em";
  1013. let chatHolder = getEl("chatHolder");
  1014. let actionBar = getEl("actionBar");
  1015. let leaderboardData = getEl("leaderboardData");
  1016. let itemInfoHolder = getEl("itemInfoHolder");
  1017. let menuCardHolder = getEl("menuCardHolder");
  1018. let mainMenu = getEl("mainMenu");
  1019. let diedText = getEl("diedText");
  1020. let screenWidth;
  1021. let screenHeight;
  1022. let maxScreenWidth = config.maxScreenWidth;
  1023. let maxScreenHeight = config.maxScreenHeight;
  1024. let pixelDensity = 1;
  1025. let delta;
  1026. let now;
  1027. let lastUpdate = performance.now();
  1028. let camX;
  1029. let camY;
  1030. let tmpDir;
  1031. let mouseX = 0;
  1032. let mouseY = 0;
  1033. let allianceMenu = getEl("allianceMenu");
  1034. let waterMult = 1;
  1035. let waterPlus = 0;
  1036. let outlineColor = "#880808";
  1037. let darkOutlineColor = "#880808";
  1038. let outlineWidth = 5.5;
  1039.  
  1040. let firstSetup = true;
  1041. let keys = {};
  1042. let moveKeys = {
  1043. 87: [0, -1],
  1044. 38: [0, -1],
  1045. 83: [0, 1],
  1046. 40: [0, 1],
  1047. 65: [-1, 0],
  1048. 37: [-1, 0],
  1049. 68: [1, 0],
  1050. 39: [1, 0],
  1051. };
  1052.  
  1053. let attackState = 0;
  1054. let inGame = false;
  1055.  
  1056. let macro = {};
  1057. let mills = {
  1058. place: 0,
  1059. placeSpawnPads: 0
  1060. };
  1061. let lastDir;
  1062.  
  1063. let lastLeaderboardData = [];
  1064.  
  1065. let inWindow = true;
  1066. window.onblur = function() {
  1067. inWindow = false;
  1068. };
  1069. window.onfocus = function() {
  1070. inWindow = true;
  1071. };
  1072. let ms = {
  1073. avg: 0,
  1074. max: 0,
  1075. min: 0,
  1076. delay: 0
  1077. }
  1078. function pingSocketResponse() {
  1079. let pingTime = window.pingTime;
  1080. const pingDisplay = document.getElementById("pingDisplay")
  1081. pingDisplay.innerText = "";
  1082. if (pingTime > ms.max || isNaN(ms.max)) {
  1083. ms.max = pingTime;
  1084. }
  1085. if (pingTime < ms.min || isNaN(ms.min)) {
  1086. ms.min = pingTime;
  1087. }
  1088. }
  1089.  
  1090. let placeVisible = [];
  1091.  
  1092.  
  1093. class Utils {
  1094. constructor() {
  1095.  
  1096. let mathABS = Math.abs,
  1097. mathCOS = Math.cos,
  1098. mathSIN = Math.sin,
  1099. mathPOW = Math.pow,
  1100. mathSQRT = Math.sqrt,
  1101. mathATAN2 = Math.atan2,
  1102. mathPI = Math.PI;
  1103.  
  1104. let _this = this;
  1105.  
  1106. this.round = function(n, v) {
  1107. return Math.round(n * v) / v;
  1108. };
  1109. this.toRad = function(angle) {
  1110. return angle * (mathPI / 180);
  1111. };
  1112. this.toAng = function(radian) {
  1113. return radian / (mathPI / 180);
  1114. };
  1115. this.randInt = function(min, max) {
  1116. return Math.floor(Math.random() * (max - min + 1)) + min;
  1117. };
  1118. this.randFloat = function(min, max) {
  1119. return Math.random() * (max - min + 1) + min;
  1120. };
  1121. this.lerp = function(value1, value2, amount) {
  1122. return value1 + (value2 - value1) * amount;
  1123. };
  1124. this.decel = function(val, cel) {
  1125. if (val > 0)
  1126. val = Math.max(0, val - cel);
  1127. else if (val < 0)
  1128. val = Math.min(0, val + cel);
  1129. return val;
  1130. };
  1131. this.getDistance = function(x1, y1, x2, y2) {
  1132. return mathSQRT((x2 -= x1) * x2 + (y2 -= y1) * y2);
  1133. };
  1134. this.getDist = function(tmp1, tmp2, type1, type2) {
  1135. let tmpXY1 = {
  1136. x: type1 == 0 ? tmp1.x : type1 == 1 ? tmp1.x1 : type1 == 2 ? tmp1.x2 : type1 == 3 && tmp1.x3,
  1137. y: type1 == 0 ? tmp1.y : type1 == 1 ? tmp1.y1 : type1 == 2 ? tmp1.y2 : type1 == 3 && tmp1.y3,
  1138. };
  1139. let tmpXY2 = {
  1140. x: type2 == 0 ? tmp2.x : type2 == 1 ? tmp2.x1 : type2 == 2 ? tmp2.x2 : type2 == 3 && tmp2.x3,
  1141. y: type2 == 0 ? tmp2.y : type2 == 1 ? tmp2.y1 : type2 == 2 ? tmp2.y2 : type2 == 3 && tmp2.y3,
  1142. };
  1143. return mathSQRT((tmpXY2.x -= tmpXY1.x) * tmpXY2.x + (tmpXY2.y -= tmpXY1.y) * tmpXY2.y);
  1144. };
  1145. this.getDirection = function(x1, y1, x2, y2) {
  1146. return mathATAN2(y1 - y2, x1 - x2);
  1147. };
  1148. this.getDirect = function(tmp1, tmp2, type1, type2) {
  1149. let tmpXY1 = {
  1150. x: type1 == 0 ? tmp1.x : type1 == 1 ? tmp1.x1 : type1 == 2 ? tmp1.x2 : type1 == 3 && tmp1.x3,
  1151. y: type1 == 0 ? tmp1.y : type1 == 1 ? tmp1.y1 : type1 == 2 ? tmp1.y2 : type1 == 3 && tmp1.y3,
  1152. };
  1153. let tmpXY2 = {
  1154. x: type2 == 0 ? tmp2.x : type2 == 1 ? tmp2.x1 : type2 == 2 ? tmp2.x2 : type2 == 3 && tmp2.x3,
  1155. y: type2 == 0 ? tmp2.y : type2 == 1 ? tmp2.y1 : type2 == 2 ? tmp2.y2 : type2 == 3 && tmp2.y3,
  1156. };
  1157. return mathATAN2(tmpXY1.y - tmpXY2.y, tmpXY1.x - tmpXY2.x);
  1158. };
  1159. this.getAngleDist = function(a, b) {
  1160. let p = mathABS(b - a) % (mathPI * 2);
  1161. return (p > mathPI ? (mathPI * 2) - p : p);
  1162. };
  1163. this.isNumber = function(n) {
  1164. return (typeof n == "number" && !isNaN(n) && isFinite(n));
  1165. };
  1166. this.isString = function(s) {
  1167. return (s && typeof s == "string");
  1168. };
  1169. this.kFormat = function(num) {
  1170. return num > 999 ? (num / 1000).toFixed(1) + "k" : num;
  1171. };
  1172. this.sFormat = function(num) {
  1173. let fixs = [{
  1174. num: 1e3,
  1175. string: "k"
  1176. },
  1177. {
  1178. num: 1e6,
  1179. string: "m"
  1180. },
  1181. {
  1182. num: 1e9,
  1183. string: "b"
  1184. },
  1185. {
  1186. num: 1e12,
  1187. string: "q"
  1188. }
  1189. ].reverse();
  1190. let sp = fixs.find(v => num >= v.num);
  1191. if (!sp) return num;
  1192. return (num / sp.num).toFixed(1) + sp.string;
  1193. };
  1194. this.capitalizeFirst = function(string) {
  1195. return string.charAt(0).toUpperCase() + string.slice(1);
  1196. };
  1197. this.fixTo = function(n, v) {
  1198. return parseFloat(n.toFixed(v));
  1199. };
  1200. this.sortByPoints = function(a, b) {
  1201. return parseFloat(b.points) - parseFloat(a.points);
  1202. };
  1203. this.lineInRect = function(recX, recY, recX2, recY2, x1, y1, x2, y2) {
  1204. let minX = x1;
  1205. let maxX = x2;
  1206. if (x1 > x2) {
  1207. minX = x2;
  1208. maxX = x1;
  1209. }
  1210. if (maxX > recX2)
  1211. maxX = recX2;
  1212. if (minX < recX)
  1213. minX = recX;
  1214. if (minX > maxX)
  1215. return false;
  1216. let minY = y1;
  1217. let maxY = y2;
  1218. let dx = x2 - x1;
  1219. if (Math.abs(dx) > 0.0000001) {
  1220. let a = (y2 - y1) / dx;
  1221. let b = y1 - a * x1;
  1222. minY = a * minX + b;
  1223. maxY = a * maxX + b;
  1224. }
  1225. if (minY > maxY) {
  1226. let tmp = maxY;
  1227. maxY = minY;
  1228. minY = tmp;
  1229. }
  1230. if (maxY > recY2)
  1231. maxY = recY2;
  1232. if (minY < recY)
  1233. minY = recY;
  1234. if (minY > maxY)
  1235. return false;
  1236. return true;
  1237. };
  1238. this.containsPoint = function(element, x, y) {
  1239. let bounds = element.getBoundingClientRect();
  1240. let left = bounds.left + window.scrollX;
  1241. let top = bounds.top + window.scrollY;
  1242. let width = bounds.width;
  1243. let height = bounds.height;
  1244.  
  1245. let insideHorizontal = x > left && x < left + width;
  1246. let insideVertical = y > top && y < top + height;
  1247. return insideHorizontal && insideVertical;
  1248. };
  1249. this.mousifyTouchEvent = function(event) {
  1250. let touch = event.changedTouches[0];
  1251. event.screenX = touch.screenX;
  1252. event.screenY = touch.screenY;
  1253. event.clientX = touch.clientX;
  1254. event.clientY = touch.clientY;
  1255. event.pageX = touch.pageX;
  1256. event.pageY = touch.pageY;
  1257. };
  1258. this.hookTouchEvents = function(element, skipPrevent) {
  1259. let preventDefault = !skipPrevent;
  1260. let isHovering = false;
  1261. let passive = false;
  1262. element.addEventListener("touchstart", this.checkTrusted(touchStart), passive);
  1263. element.addEventListener("touchmove", this.checkTrusted(touchMove), passive);
  1264. element.addEventListener("touchend", this.checkTrusted(touchEnd), passive);
  1265. element.addEventListener("touchcancel", this.checkTrusted(touchEnd), passive);
  1266. element.addEventListener("touchleave", this.checkTrusted(touchEnd), passive);
  1267.  
  1268. function touchStart(e) {
  1269. _this.mousifyTouchEvent(e);
  1270. window.setUsingTouch(true);
  1271. if (preventDefault) {
  1272. e.preventDefault();
  1273. e.stopPropagation();
  1274. }
  1275. if (element.onmouseover)
  1276. element.onmouseover(e);
  1277. isHovering = true;
  1278. }
  1279.  
  1280. function touchMove(e) {
  1281. _this.mousifyTouchEvent(e);
  1282. window.setUsingTouch(true);
  1283. if (preventDefault) {
  1284. e.preventDefault();
  1285. e.stopPropagation();
  1286. }
  1287. if (_this.containsPoint(element, e.pageX, e.pageY)) {
  1288. if (!isHovering) {
  1289. if (element.onmouseover)
  1290. element.onmouseover(e);
  1291. isHovering = true;
  1292. }
  1293. } else {
  1294. if (isHovering) {
  1295. if (element.onmouseout)
  1296. element.onmouseout(e);
  1297. isHovering = false;
  1298. }
  1299. }
  1300. }
  1301.  
  1302. function touchEnd(e) {
  1303. _this.mousifyTouchEvent(e);
  1304. window.setUsingTouch(true);
  1305. if (preventDefault) {
  1306. e.preventDefault();
  1307. e.stopPropagation();
  1308. }
  1309. if (isHovering) {
  1310. if (element.onclick)
  1311. element.onclick(e);
  1312. if (element.onmouseout)
  1313. element.onmouseout(e);
  1314. isHovering = false;
  1315. }
  1316. }
  1317. };
  1318. this.removeAllChildren = function(element) {
  1319. while (element.hasChildNodes()) {
  1320. element.removeChild(element.lastChild);
  1321. }
  1322. };
  1323. this.generateElement = function(config) {
  1324. let element = document.createElement(config.tag || "div");
  1325.  
  1326. function bind(configValue, elementValue) {
  1327. if (config[configValue])
  1328. element[elementValue] = config[configValue];
  1329. }
  1330. bind("text", "textContent");
  1331. bind("html", "innerHTML");
  1332. bind("class", "className");
  1333. for (let key in config) {
  1334. switch (key) {
  1335. case "tag":
  1336. case "text":
  1337. case "html":
  1338. case "class":
  1339. case "style":
  1340. case "hookTouch":
  1341. case "parent":
  1342. case "children":
  1343. continue;
  1344. default:
  1345. break;
  1346. }
  1347. element[key] = config[key];
  1348. }
  1349. if (element.onclick)
  1350. element.onclick = this.checkTrusted(element.onclick);
  1351. if (element.onmouseover)
  1352. element.onmouseover = this.checkTrusted(element.onmouseover);
  1353. if (element.onmouseout)
  1354. element.onmouseout = this.checkTrusted(element.onmouseout);
  1355. if (config.style) {
  1356. element.style.cssText = config.style;
  1357. }
  1358. if (config.hookTouch) {
  1359. this.hookTouchEvents(element);
  1360. }
  1361. if (config.parent) {
  1362. config.parent.appendChild(element);
  1363. }
  1364. if (config.children) {
  1365. for (let i = 0; i < config.children.length; i++) {
  1366. element.appendChild(config.children[i]);
  1367. }
  1368. }
  1369. return element;
  1370. };
  1371. this.checkTrusted = function(callback) {
  1372. return function(ev) {
  1373. if (ev && ev instanceof Event && (ev && typeof ev.isTrusted == "boolean" ? ev.isTrusted : true)) {
  1374. callback(ev);
  1375. }
  1376. };
  1377. };
  1378. this.randomString = function(length) {
  1379. let text = "";
  1380. let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  1381. for (let i = 0; i < length; i++) {
  1382. text += possible.charAt(Math.floor(Math.random() * possible.length));
  1383. }
  1384. return text;
  1385. };
  1386. this.countInArray = function(array, val) {
  1387. let count = 0;
  1388. for (let i = 0; i < array.length; i++) {
  1389. if (array[i] === val) count++;
  1390. }
  1391. return count;
  1392. };
  1393. this.hexToRgb = function(hex) {
  1394. return hex.slice(1).match(/.{1,2}/g).map(g => parseInt(g, 16));
  1395. };
  1396. this.getRgb = function(r, g, b) {
  1397. return [r / 255, g / 255, b / 255].join(", ");
  1398. };
  1399. }
  1400. };
  1401. class Animtext {
  1402. constructor() {
  1403. this.init = function (x, y, scale, speed, life, text, color) {
  1404. this.x = x;
  1405. this.y = y;
  1406. this.color = color;
  1407. this.scale = scale;
  1408. this.startScale = this.scale;
  1409. this.maxScale = scale * 1.5;
  1410. this.scaleSpeed = 0.7;
  1411. this.speed = speed;
  1412. this.life = life;
  1413. this.text = text;
  1414. this.acc = 1;
  1415. this.alpha = 0;
  1416. this.maxLife = life;
  1417. this.ranX = UTILS.randFloat(-1, 1);
  1418. };
  1419.  
  1420. this.update = function (delta) {
  1421. if (this.life > 0) {
  1422. this.life -= delta;
  1423. this.y -= this.speed * delta;
  1424. if (this.life <= 200) {
  1425. if (this.alpha > 0) {
  1426. this.alpha = Math.max(0, this.alpha - (delta / 300));
  1427. }
  1428. } else {
  1429. if (this.alpha < 1) {
  1430. this.alpha = Math.min(1, this.alpha + (delta / 100));
  1431. }
  1432. }
  1433. if (this.life <= 0) {
  1434. this.life = 0;
  1435. }
  1436. }
  1437. };
  1438.  
  1439. this.render = function (ctxt, xOff, yOff, value) {
  1440. ctxt.lineWidth = 5;
  1441. ctxt.fillStyle = this.color;
  1442. ctxt.strokeStyle = "#fff";
  1443. ctxt.font = this.scale + "px 'Comic Sans MS', cursive";
  1444. ctxt.textAlign = "center";
  1445. ctxt.textBaseline = "middle";
  1446.  
  1447. ctxt.globalAlpha = this.alpha;
  1448.  
  1449. ctxt.strokeText(this.text, this.x - xOff, this.y - yOff);
  1450. ctxt.fillText(this.text, this.x - xOff, this.y - yOff);
  1451.  
  1452. ctxt.globalAlpha = 1;
  1453. };
  1454. }
  1455. }
  1456. class Textmanager {
  1457. constructor() {
  1458. this.texts = [];
  1459. this.stack = [];
  1460.  
  1461. this.update = function(delta, ctxt, xOff, yOff) {
  1462. ctxt.textBaseline = "middle";
  1463. ctxt.textAlign = "center";
  1464. for (let i = 0; i < this.texts.length; ++i) {
  1465. if (this.texts[i].life) {
  1466. this.texts[i].update(delta);
  1467. this.texts[i].render(ctxt, xOff, yOff);
  1468. }
  1469. }
  1470. };
  1471.  
  1472. this.showText = function(x, y, scale, speed, life, text, color) {
  1473. let tmpText;
  1474. for (let i = 0; i < this.texts.length; ++i) {
  1475. if (!this.texts[i].life) {
  1476. tmpText = this.texts[i];
  1477. break;
  1478. }
  1479. }
  1480. if (!tmpText) {
  1481. tmpText = new Animtext();
  1482. this.texts.push(tmpText);
  1483. }
  1484. tmpText.init(x, y, scale, speed, life, text, color);
  1485. };
  1486. }
  1487. }
  1488.  
  1489. class GameObject {
  1490. constructor(sid) {
  1491. this.sid = sid;
  1492.  
  1493. this.init = function(x, y, dir, scale, type, data, owner) {
  1494. data = data || {};
  1495. this.sentTo = {};
  1496. this.gridLocations = [];
  1497. this.active = true;
  1498. this.render = true;
  1499. this.doUpdate = data.doUpdate;
  1500. this.x = x;
  1501. this.y = y;
  1502. this.dir = dir;
  1503. this.lastDir = dir;
  1504. this.xWiggle = 0;
  1505. this.yWiggle = 0;
  1506. this.visScale = scale;
  1507. this.scale = scale;
  1508. this.type = type;
  1509. this.id = data.id;
  1510. this.owner = owner;
  1511. this.name = data.name;
  1512. this.isItem = (this.id != undefined);
  1513. this.group = data.group;
  1514. this.maxHealth = data.health;
  1515. this.health = this.maxHealth;
  1516. this.layer = 2;
  1517. if (this.group != undefined) {
  1518. this.layer = this.group.layer;
  1519. } else if (this.type == 0) {
  1520. this.layer = 3;
  1521. } else if (this.type == 2) {
  1522. this.layer = 0;
  1523. } else if (this.type == 4) {
  1524. this.layer = -1;
  1525. }
  1526. this.colDiv = data.colDiv || 1;
  1527. this.blocker = data.blocker;
  1528. this.ignoreCollision = data.ignoreCollision;
  1529. this.dontGather = data.dontGather;
  1530. this.hideFromEnemy = data.hideFromEnemy;
  1531. this.friction = data.friction;
  1532. this.projDmg = data.projDmg;
  1533. this.dmg = data.dmg;
  1534. this.pDmg = data.pDmg;
  1535. this.pps = data.pps;
  1536. this.zIndex = data.zIndex || 0;
  1537. this.turnSpeed = data.turnSpeed;
  1538. this.req = data.req;
  1539. this.trap = data.trap;
  1540. this.healCol = data.healCol;
  1541. this.teleport = data.teleport;
  1542. this.boostSpeed = data.boostSpeed;
  1543. this.projectile = data.projectile;
  1544. this.shootRange = data.shootRange;
  1545. this.shootRate = data.shootRate;
  1546. this.shootCount = this.shootRate;
  1547. this.spawnPoint = data.spawnPoint;
  1548. this.onNear = 0;
  1549. this.breakObj = false;
  1550. this.alpha = data.alpha || 1;
  1551. this.maxAlpha = data.alpha || 1;
  1552. this.damaged = 0;
  1553. };
  1554.  
  1555. this.changeHealth = function(amount, doer) {
  1556. this.health += amount;
  1557. return (this.health <= 0);
  1558. };
  1559.  
  1560. this.getScale = function(sM, ig) {
  1561. sM = sM || 1;
  1562. return this.scale * ((this.isItem || this.type == 2 || this.type == 3 || this.type == 4) ?
  1563. 1 : (0.6 * sM)) * (ig ? 1 : this.colDiv);
  1564. };
  1565.  
  1566. this.visibleToPlayer = function(player) {
  1567. return !(this.hideFromEnemy) || (this.owner && (this.owner == player ||
  1568. (this.owner.team && player.team == this.owner.team)));
  1569. };
  1570.  
  1571. this.update = function(delta) {
  1572. if (this.active) {
  1573. if (this.xWiggle) {
  1574. this.xWiggle *= Math.pow(0.99, delta);
  1575. }
  1576. if (this.yWiggle) {
  1577. this.yWiggle *= Math.pow(0.99, delta);
  1578. }
  1579. let d2 = UTILS.getAngleDist(this.lastDir, this.dir);
  1580. if (d2 > 0.01) {
  1581. this.dir += d2 / 5;
  1582. } else {
  1583. this.dir = this.lastDir;
  1584. }
  1585. } else {
  1586. if (this.alive) {
  1587. this.alpha -= delta / (200 / this.maxAlpha);
  1588. this.visScale += delta / (this.scale / 2.5);
  1589. if (this.alpha <= 0) {
  1590. this.alpha = 0;
  1591. this.alive = false;
  1592. }
  1593. }
  1594. }
  1595. };
  1596.  
  1597. this.isTeamObject = function(tmpObj) {
  1598. return this.owner == null ? true : (this.owner && tmpObj.sid == this.owner.sid || tmpObj.findAllianceBySid(this.owner.sid));
  1599. };
  1600. }
  1601. }
  1602. class Items {
  1603. constructor() {
  1604. this.groups = [{
  1605. id: 0,
  1606. name: "food",
  1607. layer: 0
  1608. }, {
  1609. id: 1,
  1610. name: "walls",
  1611. place: true,
  1612. limit: 30,
  1613. layer: 0
  1614. }, {
  1615. id: 2,
  1616. name: "spikes",
  1617. place: true,
  1618. limit: 15,
  1619. layer: 0
  1620. }, {
  1621. id: 3,
  1622. name: "mill",
  1623. place: true,
  1624. limit: 7,
  1625. layer: 1
  1626. }, {
  1627. id: 4,
  1628. name: "mine",
  1629. place: true,
  1630. limit: 1,
  1631. layer: 0
  1632. }, {
  1633. id: 5,
  1634. name: "trap",
  1635. place: true,
  1636. limit: 6,
  1637. layer: -1
  1638. }, {
  1639. id: 6,
  1640. name: "booster",
  1641. place: true,
  1642. limit: 12,
  1643. layer: -1
  1644. }, {
  1645. id: 7,
  1646. name: "turret",
  1647. place: true,
  1648. limit: 2,
  1649. layer: 1
  1650. }, {
  1651. id: 8,
  1652. name: "watchtower",
  1653. place: true,
  1654. limit: 12,
  1655. layer: 1
  1656. }, {
  1657. id: 9,
  1658. name: "buff",
  1659. place: true,
  1660. limit: 4,
  1661. layer: -1
  1662. }, {
  1663. id: 10,
  1664. name: "spawn",
  1665. place: true,
  1666. limit: 1,
  1667. layer: -1
  1668. }, {
  1669. id: 11,
  1670. name: "sapling",
  1671. place: true,
  1672. limit: 2,
  1673. layer: 0
  1674. }, {
  1675. id: 12,
  1676. name: "blocker",
  1677. place: true,
  1678. limit: 3,
  1679. layer: -1
  1680. }, {
  1681. id: 13,
  1682. name: "teleporter",
  1683. place: true,
  1684. limit: 2,
  1685. layer: -1
  1686. }];
  1687.  
  1688. this.projectiles = [{
  1689. indx: 0,
  1690. layer: 0,
  1691. src: "arrow_1",
  1692. dmg: 25,
  1693. speed: 1.6,
  1694. scale: 103,
  1695. range: 1000
  1696. }, {
  1697. indx: 1,
  1698. layer: 1,
  1699. dmg: 25,
  1700. scale: 20
  1701. }, {
  1702. indx: 0,
  1703. layer: 0,
  1704. src: "arrow_1",
  1705. dmg: 35,
  1706. speed: 2.5,
  1707. scale: 103,
  1708. range: 1200
  1709. }, {
  1710. indx: 0,
  1711. layer: 0,
  1712. src: "arrow_1",
  1713. dmg: 30,
  1714. speed: 2,
  1715. scale: 103,
  1716. range: 1200
  1717. }, {
  1718. indx: 1,
  1719. layer: 1,
  1720. dmg: 16,
  1721. scale: 20
  1722. }, {
  1723. indx: 0,
  1724. layer: 0,
  1725. src: "bullet_1",
  1726. dmg: 50,
  1727. speed: 3.6,
  1728. scale: 160,
  1729. range: 1400
  1730. }];
  1731.  
  1732. this.weapons = [{
  1733. id: 0,
  1734. type: 0,
  1735. name: "tool hammer",
  1736. desc: "tool for gathering all resources",
  1737. src: "hammer_1",
  1738. length: 140,
  1739. width: 140,
  1740. xOff: -3,
  1741. yOff: 18,
  1742. dmg: 25,
  1743. range: 65,
  1744. gather: 1,
  1745. speed: 300
  1746. }, {
  1747. id: 1,
  1748. type: 0,
  1749. age: 2,
  1750. name: "hand axe",
  1751. desc: "gathers resources at a higher rate",
  1752. src: "axe_1",
  1753. length: 140,
  1754. width: 140,
  1755. xOff: 3,
  1756. yOff: 24,
  1757. dmg: 30,
  1758. spdMult: 1,
  1759. range: 70,
  1760. gather: 2,
  1761. speed: 400
  1762. }, {
  1763. id: 2,
  1764. type: 0,
  1765. age: 8,
  1766. pre: 1,
  1767. name: "great axe",
  1768. desc: "deal more damage and gather more resources",
  1769. src: "great_axe_1",
  1770. length: 140,
  1771. width: 140,
  1772. xOff: -8,
  1773. yOff: 25,
  1774. dmg: 35,
  1775. spdMult: 1,
  1776. range: 75,
  1777. gather: 4,
  1778. speed: 400
  1779. }, {
  1780. id: 3,
  1781. type: 0,
  1782. age: 2,
  1783. name: "short sword",
  1784. desc: "increased attack power but slower move speed",
  1785. src: "sword_1",
  1786. iPad: 1.3,
  1787. length: 130,
  1788. width: 210,
  1789. xOff: -8,
  1790. yOff: 46,
  1791. dmg: 35,
  1792. spdMult: 0.85,
  1793. range: 110,
  1794. gather: 1,
  1795. speed: 300
  1796. }, {
  1797. id: 4,
  1798. type: 0,
  1799. age: 8,
  1800. pre: 3,
  1801. name: "katana",
  1802. desc: "greater range and damage",
  1803. src: "samurai_1",
  1804. iPad: 1.3,
  1805. length: 130,
  1806. width: 210,
  1807. xOff: -8,
  1808. yOff: 59,
  1809. dmg: 40,
  1810. spdMult: 0.8,
  1811. range: 118,
  1812. gather: 1,
  1813. speed: 300
  1814. }, {
  1815. id: 5,
  1816. type: 0,
  1817. age: 2,
  1818. name: "polearm",
  1819. desc: "long range melee weapon",
  1820. src: "spear_1",
  1821. iPad: 1.3,
  1822. length: 130,
  1823. width: 210,
  1824. xOff: -8,
  1825. yOff: 53,
  1826. dmg: 45,
  1827. knock: 0.2,
  1828. spdMult: 0.82,
  1829. range: 142,
  1830. gather: 1,
  1831. speed: 700
  1832. }, {
  1833. id: 6,
  1834. type: 0,
  1835. age: 2,
  1836. name: "bat",
  1837. desc: "fast long range melee weapon",
  1838. src: "bat_1",
  1839. iPad: 1.3,
  1840. length: 110,
  1841. width: 180,
  1842. xOff: -8,
  1843. yOff: 53,
  1844. dmg: 20,
  1845. knock: 0.7,
  1846. range: 110,
  1847. gather: 1,
  1848. speed: 300
  1849. }, {
  1850. id: 7,
  1851. type: 0,
  1852. age: 2,
  1853. name: "daggers",
  1854. desc: "really fast short range weapon",
  1855. src: "dagger_1",
  1856. iPad: 0.8,
  1857. length: 110,
  1858. width: 110,
  1859. xOff: 18,
  1860. yOff: 0,
  1861. dmg: 20,
  1862. knock: 0.1,
  1863. range: 65,
  1864. gather: 1,
  1865. hitSlow: 0.1,
  1866. spdMult: 1.13,
  1867. speed: 100
  1868. }, {
  1869. id: 8,
  1870. type: 0,
  1871. age: 2,
  1872. name: "stick",
  1873. desc: "great for gathering but very weak",
  1874. src: "stick_1",
  1875. length: 140,
  1876. width: 140,
  1877. xOff: 3,
  1878. yOff: 24,
  1879. dmg: 1,
  1880. spdMult: 1,
  1881. range: 70,
  1882. gather: 7,
  1883. speed: 400
  1884. }, {
  1885. id: 9,
  1886. type: 1,
  1887. age: 6,
  1888. name: "hunting bow",
  1889. desc: "bow used for ranged combat and hunting",
  1890. src: "bow_1",
  1891. req: ["wood", 4],
  1892. length: 120,
  1893. width: 120,
  1894. xOff: -6,
  1895. yOff: 0,
  1896. Pdmg: 25,
  1897. projectile: 0,
  1898. spdMult: 0.75,
  1899. speed: 600
  1900. }, {
  1901. id: 10,
  1902. type: 1,
  1903. age: 6,
  1904. name: "great hammer",
  1905. desc: "hammer used for destroying structures",
  1906. src: "great_hammer_1",
  1907. length: 140,
  1908. width: 140,
  1909. xOff: -9,
  1910. yOff: 25,
  1911. dmg: 10,
  1912. Pdmg: 10,
  1913. spdMult: 0.88,
  1914. range: 75,
  1915. sDmg: 7.5,
  1916. gather: 1,
  1917. speed: 400
  1918. }, {
  1919. id: 11,
  1920. type: 1,
  1921. age: 6,
  1922. name: "wooden shield",
  1923. desc: "blocks projectiles and reduces melee damage",
  1924. src: "shield_1",
  1925. length: 120,
  1926. width: 120,
  1927. shield: 0.2,
  1928. xOff: 6,
  1929. yOff: 0,
  1930. Pdmg: 0,
  1931. spdMult: 0.7
  1932. }, {
  1933. id: 12,
  1934. type: 1,
  1935. age: 8,
  1936. pre: 9,
  1937. name: "crossbow",
  1938. desc: "deals more damage and has greater range",
  1939. src: "crossbow_1",
  1940. req: ["wood", 5],
  1941. aboveHand: true,
  1942. armS: 0.75,
  1943. length: 120,
  1944. width: 120,
  1945. xOff: -4,
  1946. yOff: 0,
  1947. Pdmg: 35,
  1948. projectile: 2,
  1949. spdMult: 0.7,
  1950. speed: 700
  1951. }, {
  1952. id: 13,
  1953. type: 1,
  1954. age: 9,
  1955. pre: 12,
  1956. name: "repeater crossbow",
  1957. desc: "high firerate crossbow with reduced damage",
  1958. src: "crossbow_2",
  1959. req: ["wood", 10],
  1960. aboveHand: true,
  1961. armS: 0.75,
  1962. length: 120,
  1963. width: 120,
  1964. xOff: -4,
  1965. yOff: 0,
  1966. Pdmg: 30,
  1967. projectile: 3,
  1968. spdMult: 0.7,
  1969. speed: 230
  1970. }, {
  1971. id: 14,
  1972. type: 1,
  1973. age: 6,
  1974. name: "mc grabby",
  1975. desc: "steals resources from enemies",
  1976. src: "grab_1",
  1977. length: 130,
  1978. width: 210,
  1979. xOff: -8,
  1980. yOff: 53,
  1981. dmg: 0,
  1982. Pdmg: 0,
  1983. steal: 250,
  1984. knock: 0.2,
  1985. spdMult: 1.05,
  1986. range: 125,
  1987. gather: 0,
  1988. speed: 700
  1989. }, {
  1990. id: 15,
  1991. type: 1,
  1992. age: 9,
  1993. pre: 12,
  1994. name: "musket",
  1995. desc: "slow firerate but high damage and range",
  1996. src: "musket_1",
  1997. req: ["stone", 10],
  1998. aboveHand: true,
  1999. rec: 0.35,
  2000. armS: 0.6,
  2001. hndS: 0.3,
  2002. hndD: 1.6,
  2003. length: 205,
  2004. width: 205,
  2005. xOff: 25,
  2006. yOff: 0,
  2007. Pdmg: 50,
  2008. projectile: 5,
  2009. hideProjectile: true,
  2010. spdMult: 0.6,
  2011. speed: 1500
  2012. }];
  2013.  
  2014. this.list = [{
  2015. group: this.groups[0],
  2016. name: "apple",
  2017. desc: "restores 20 health when consumed",
  2018. req: ["food", 10],
  2019. consume: function(doer) {
  2020. return doer.changeHealth(20, doer);
  2021. },
  2022. scale: 22,
  2023. holdOffset: 15,
  2024. healing: 20,
  2025. itemID: 0,
  2026. itemAID: 16,
  2027. }, {
  2028. age: 3,
  2029. group: this.groups[0],
  2030. name: "cookie",
  2031. desc: "restores 40 health when consumed",
  2032. req: ["food", 15],
  2033. consume: function(doer) {
  2034. return doer.changeHealth(40, doer);
  2035. },
  2036. scale: 27,
  2037. holdOffset: 15,
  2038. healing: 40,
  2039. itemID: 1,
  2040. itemAID: 17,
  2041. }, {
  2042. age: 7,
  2043. group: this.groups[0],
  2044. name: "cheese",
  2045. desc: "restores 30 health and another 50 over 5 seconds",
  2046. req: ["food", 25],
  2047. consume: function(doer) {
  2048. if (doer.changeHealth(30, doer) || doer.health < 100) {
  2049. doer.dmgOverTime.dmg = -10;
  2050. doer.dmgOverTime.doer = doer;
  2051. doer.dmgOverTime.time = 5;
  2052. return true;
  2053. }
  2054. return false;
  2055. },
  2056. scale: 27,
  2057. holdOffset: 15,
  2058. healing: 30,
  2059. itemID: 2,
  2060. itemAID: 18,
  2061. }, {
  2062. group: this.groups[1],
  2063. name: "wood wall",
  2064. desc: "provides protection for your village",
  2065. req: ["wood", 10],
  2066. projDmg: true,
  2067. health: 380,
  2068. scale: 50,
  2069. holdOffset: 20,
  2070. placeOffset: -5,
  2071. itemID: 3,
  2072. itemAID: 19,
  2073. }, {
  2074. age: 3,
  2075. group: this.groups[1],
  2076. name: "stone wall",
  2077. desc: "provides improved protection for your village",
  2078. req: ["stone", 25],
  2079. health: 900,
  2080. scale: 50,
  2081. holdOffset: 20,
  2082. placeOffset: -5,
  2083. itemID: 4,
  2084. itemAID: 20,
  2085. }, {
  2086. age: 7,
  2087. group: this.groups[1],
  2088. name: "castle wall",
  2089. desc: "provides powerful protection for your village",
  2090. req: ["stone", 35],
  2091. health: 1500,
  2092. scale: 52,
  2093. holdOffset: 20,
  2094. placeOffset: -5,
  2095. itemID: 5,
  2096. itemAID: 21,
  2097. }, {
  2098. group: this.groups[2],
  2099. name: "spikes",
  2100. desc: "damages enemies when they touch them",
  2101. req: ["wood", 20, "stone", 5],
  2102. health: 400,
  2103. dmg: 20,
  2104. scale: 49,
  2105. spritePadding: -23,
  2106. holdOffset: 8,
  2107. placeOffset: -5,
  2108. itemID: 6,
  2109. itemAID: 22,
  2110. shadow: {
  2111. offsetX: 5,
  2112. offsetY: 5,
  2113. color: "rgba()"
  2114. }
  2115.  
  2116. }, {
  2117. age: 5,
  2118. group: this.groups[2],
  2119. name: "greater spikes",
  2120. desc: "damages enemies when they touch them",
  2121. req: ["wood", 30, "stone", 10],
  2122. health: 500,
  2123. dmg: 35,
  2124. scale: 52,
  2125. spritePadding: -23,
  2126. holdOffset: 8,
  2127. placeOffset: -5,
  2128. itemID: 7,
  2129. itemAID: 23,
  2130. }, {
  2131. age: 9,
  2132. group: this.groups[2],
  2133. name: "poison spikes",
  2134. desc: "poisons enemies when they touch them",
  2135. req: ["wood", 35, "stone", 15],
  2136. health: 600,
  2137. dmg: 30,
  2138. pDmg: 5,
  2139. scale: 52,
  2140. spritePadding: -23,
  2141. holdOffset: 8,
  2142. placeOffset: -5,
  2143. itemID: 8,
  2144. itemAID: 24,
  2145. }, {
  2146. age: 9,
  2147. group: this.groups[2],
  2148. name: "spinning spikes",
  2149. desc: "damages enemies when they touch them",
  2150. req: ["wood", 30, "stone", 20],
  2151. health: 500,
  2152. dmg: 45,
  2153. turnSpeed: 0.003,
  2154. scale: 52,
  2155. spritePadding: -23,
  2156. holdOffset: 8,
  2157. placeOffset: -5,
  2158. itemID: 9,
  2159. itemAID: 25,
  2160. }, {
  2161. group: this.groups[3],
  2162. name: "windmill",
  2163. desc: "generates gold over time",
  2164. req: ["wood", 50, "stone", 10],
  2165. health: 400,
  2166. pps: 1,
  2167. turnSpeed: 0.0016,
  2168. spritePadding: 25,
  2169. iconLineMult: 12,
  2170. scale: 45,
  2171. holdOffset: 20,
  2172. placeOffset: 5,
  2173. itemID: 10,
  2174. itemAID: 26,
  2175. }, {
  2176. age: 5,
  2177. group: this.groups[3],
  2178. name: "faster windmill",
  2179. desc: "generates more gold over time",
  2180. req: ["wood", 60, "stone", 20],
  2181. health: 500,
  2182. pps: 1.5,
  2183. turnSpeed: 0.0025,
  2184. spritePadding: 25,
  2185. iconLineMult: 12,
  2186. scale: 47,
  2187. holdOffset: 20,
  2188. placeOffset: 5,
  2189. itemID: 11,
  2190. itemAID: 27,
  2191. }, {
  2192. age: 8,
  2193. group: this.groups[3],
  2194. name: "power mill",
  2195. desc: "generates more gold over time",
  2196. req: ["wood", 100, "stone", 50],
  2197. health: 800,
  2198. pps: 2,
  2199. turnSpeed: 0.005,
  2200. spritePadding: 25,
  2201. iconLineMult: 12,
  2202. scale: 47,
  2203. holdOffset: 20,
  2204. placeOffset: 5,
  2205. itemID: 12,
  2206. itemAID: 28,
  2207. }, {
  2208. age: 5,
  2209. group: this.groups[4],
  2210. type: 2,
  2211. name: "mine",
  2212. desc: "allows you to mine stone",
  2213. req: ["wood", 20, "stone", 100],
  2214. iconLineMult: 12,
  2215. scale: 65,
  2216. holdOffset: 20,
  2217. placeOffset: 0,
  2218. itemID: 13,
  2219. itemAID: 29,
  2220. }, {
  2221. age: 5,
  2222. group: this.groups[11],
  2223. type: 0,
  2224. name: "sapling",
  2225. desc: "allows you to farm wood",
  2226. req: ["wood", 150],
  2227. iconLineMult: 12,
  2228. colDiv: 0.5,
  2229. scale: 110,
  2230. holdOffset: 50,
  2231. placeOffset: -15,
  2232. itemID: 14,
  2233. itemAID: 30,
  2234. }, {
  2235. age: 4,
  2236. group: this.groups[5],
  2237. name: "pit trap",
  2238. desc: "pit that traps enemies if they walk over it",
  2239. req: ["wood", 30, "stone", 30],
  2240. trap: true,
  2241. ignoreCollision: true,
  2242. hideFromEnemy: true,
  2243. health: 500,
  2244. colDiv: 0.2,
  2245. scale: 50,
  2246. holdOffset: 20,
  2247. placeOffset: -5,
  2248. alpha: 0.6,
  2249. itemID: 15,
  2250. itemAID: 31,
  2251. }, {
  2252. age: 4,
  2253. group: this.groups[6],
  2254. name: "boost pad",
  2255. desc: "provides boost when stepped on",
  2256. req: ["stone", 20, "wood", 5],
  2257. ignoreCollision: true,
  2258. boostSpeed: 1.5,
  2259. health: 150,
  2260. colDiv: 0.7,
  2261. scale: 45,
  2262. holdOffset: 20,
  2263. placeOffset: -5,
  2264. itemID: 16,
  2265. itemAID: 32,
  2266. }, {
  2267. age: 7,
  2268. group: this.groups[7],
  2269. doUpdate: true,
  2270. name: "turret",
  2271. desc: "defensive structure that shoots at enemies",
  2272. req: ["wood", 200, "stone", 150],
  2273. health: 800,
  2274. projectile: 1,
  2275. shootRange: 700,
  2276. shootRate: 2200,
  2277. scale: 43,
  2278. holdOffset: 20,
  2279. placeOffset: -5,
  2280. itemID: 17,
  2281. itemAID: 33,
  2282. }, {
  2283. age: 7,
  2284. group: this.groups[8],
  2285. name: "platform",
  2286. desc: "platform to shoot over walls and cross over water",
  2287. req: ["wood", 20],
  2288. ignoreCollision: true,
  2289. zIndex: 1,
  2290. health: 300,
  2291. scale: 43,
  2292. holdOffset: 20,
  2293. placeOffset: -5,
  2294. itemID: 18,
  2295. itemAID: 34,
  2296. }, {
  2297. age: 7,
  2298. group: this.groups[9],
  2299. name: "healing pad",
  2300. desc: "standing on it will slowly heal you",
  2301. req: ["wood", 30, "food", 10],
  2302. ignoreCollision: true,
  2303. healCol: 15,
  2304. health: 400,
  2305. colDiv: 0.7,
  2306. scale: 45,
  2307. holdOffset: 20,
  2308. placeOffset: -5,
  2309. itemID: 19,
  2310. itemAID: 35,
  2311. }, {
  2312. age: 9,
  2313. group: this.groups[10],
  2314. name: "spawn pad",
  2315. desc: "you will spawn here when you die but it will dissapear",
  2316. req: ["wood", 100, "stone", 100],
  2317. health: 400,
  2318. ignoreCollision: true,
  2319. spawnPoint: true,
  2320. scale: 45,
  2321. holdOffset: 20,
  2322. placeOffset: -5,
  2323. itemID: 20,
  2324. itemAID: 36,
  2325. }, {
  2326. age: 7,
  2327. group: this.groups[12],
  2328. name: "blocker",
  2329. desc: "blocks building in radius",
  2330. req: ["wood", 30, "stone", 25],
  2331. ignoreCollision: true,
  2332. blocker: 300,
  2333. health: 400,
  2334. colDiv: 0.7,
  2335. scale: 45,
  2336. holdOffset: 20,
  2337. placeOffset: -5,
  2338. itemID: 21,
  2339. itemAID: 37,
  2340. }, {
  2341. age: 7,
  2342. group: this.groups[13],
  2343. name: "teleporter",
  2344. desc: "teleports you to a random point on the map",
  2345. req: ["wood", 60, "stone", 60],
  2346. ignoreCollision: true,
  2347. teleport: true,
  2348. health: 200,
  2349. colDiv: 0.7,
  2350. scale: 45,
  2351. holdOffset: 20,
  2352. placeOffset: -5,
  2353. itemID: 22,
  2354. itemAID: 38
  2355. }];
  2356.  
  2357. this.checkItem = {
  2358. index: function(id, myItems) {
  2359. return [0, 1, 2].includes(id) ? 0 : [3, 4, 5].includes(id) ? 1 : [6, 7, 8, 9].includes(id) ? 2 : [10, 11, 12].includes(id) ? 3 : [13, 14].includes(id) ? 5 : [15, 16].includes(id) ? 4 : [17, 18, 19, 21, 22].includes(id) ? [13, 14].includes(myItems) ? 6 :
  2360. 5 :
  2361. id == 20 ? [13, 14].includes(myItems) ? 7 :
  2362. 6 :
  2363. undefined;
  2364. }
  2365. }
  2366.  
  2367. for (let i = 0; i < this.list.length; ++i) {
  2368. this.list[i].id = i;
  2369. if (this.list[i].pre) this.list[i].pre = i - this.list[i].pre;
  2370. }
  2371.  
  2372. if (typeof window !== "undefined") {
  2373. function shuffle(a) {
  2374. for (let i = a.length - 1; i > 0; i--) {
  2375. const j = Math.floor(Math.random() * (i + 1));
  2376. [a[i], a[j]] = [a[j], a[i]];
  2377. }
  2378. return a;
  2379. }
  2380. }
  2381. }
  2382. }
  2383. class Objectmanager {
  2384. constructor(GameObject, liztobj, UTILS, config, players, server) {
  2385. let mathFloor = Math.floor,
  2386. mathABS = Math.abs,
  2387. mathCOS = Math.cos,
  2388. mathSIN = Math.sin,
  2389. mathPOW = Math.pow,
  2390. mathSQRT = Math.sqrt;
  2391.  
  2392. this.ignoreAdd = false;
  2393. this.hitObj = [];
  2394.  
  2395. this.disableObj = function(obj) {
  2396. obj.active = false;
  2397. };
  2398.  
  2399. let tmpObj;
  2400. this.add = function(sid, x, y, dir, s, type, data, setSID, owner) {
  2401. tmpObj = findObjectBySid(sid);
  2402. if (!tmpObj) {
  2403. tmpObj = gameObjects.find((tmp) => !tmp.active);
  2404. if (!tmpObj) {
  2405. tmpObj = new GameObject(sid);
  2406. gameObjects.push(tmpObj);
  2407. }
  2408. }
  2409. if (setSID) {
  2410. tmpObj.sid = sid;
  2411. }
  2412. tmpObj.init(x, y, dir, s, type, data, owner);
  2413. };
  2414.  
  2415. this.disableBySid = function(sid) {
  2416. let find = findObjectBySid(sid);
  2417. if (find) {
  2418. this.disableObj(find);
  2419. }
  2420. };
  2421.  
  2422. this.removeAllItems = function(sid, server) {
  2423. gameObjects.filter((tmp) => tmp.active && tmp.owner && tmp.owner.sid == sid).forEach((tmp) => this.disableObj(tmp));
  2424. };
  2425.  
  2426. this.checkItemLocation = function(x, y, s, sM, indx, ignoreWater, placer) {
  2427. let cantPlace = liztobj.find((tmp) => tmp.active && UTILS.getDistance(x, y, tmp.x, tmp.y) < s + (tmp.blocker ? tmp.blocker : tmp.getScale(sM, tmp.isItem)));
  2428. if (cantPlace) return false;
  2429. if (!ignoreWater && indx != 18 && y >= config.mapScale / 2 - config.riverWidth / 2 && y <= config.mapScale / 2 + config.riverWidth / 2) return false;
  2430. return true;
  2431. };
  2432.  
  2433. }
  2434. }
  2435. class Projectile {
  2436. constructor(players, ais, objectManager, items, config, UTILS, server) {
  2437.  
  2438. this.init = function(indx, x, y, dir, spd, dmg, rng, scl, owner) {
  2439. this.active = true;
  2440. this.tickActive = true;
  2441. this.indx = indx;
  2442. this.x = x;
  2443. this.y = y;
  2444. this.x2 = x;
  2445. this.y2 = y;
  2446. this.dir = dir;
  2447. this.skipMov = true;
  2448. this.speed = spd;
  2449. this.dmg = dmg;
  2450. this.scale = scl;
  2451. this.range = rng;
  2452. this.r2 = rng;
  2453. this.owner = owner;
  2454. };
  2455.  
  2456. this.update = function(delta) {
  2457. if (this.active) {
  2458. let tmpSpeed = this.speed * delta;
  2459. if (!this.skipMov) {
  2460. this.x += tmpSpeed * Math.cos(this.dir);
  2461. this.y += tmpSpeed * Math.sin(this.dir);
  2462. this.range -= tmpSpeed;
  2463. if (this.range <= 0) {
  2464. this.x += this.range * Math.cos(this.dir);
  2465. this.y += this.range * Math.sin(this.dir);
  2466. tmpSpeed = 1;
  2467. this.range = 0;
  2468. this.active = false;
  2469. }
  2470. } else {
  2471. this.skipMov = false;
  2472. }
  2473. }
  2474. };
  2475. this.tickUpdate = function(delta) {
  2476. if (this.tickActive) {
  2477. let tmpSpeed = this.speed * delta;
  2478. if (!this.skipMov) {
  2479. this.x2 += tmpSpeed * Math.cos(this.dir);
  2480. this.y2 += tmpSpeed * Math.sin(this.dir);
  2481. this.r2 -= tmpSpeed;
  2482. if (this.r2 <= 0) {
  2483. this.x2 += this.r2 * Math.cos(this.dir);
  2484. this.y2 += this.r2 * Math.sin(this.dir);
  2485. tmpSpeed = 1;
  2486. this.r2 = 0;
  2487. this.tickActive = false;
  2488. }
  2489. } else {
  2490. this.skipMov = false;
  2491. }
  2492. }
  2493. };
  2494. }
  2495. };
  2496. class Store {
  2497. constructor() {
  2498. this.hats = [{
  2499. id: 45,
  2500. name: "Shame!",
  2501. dontSell: true,
  2502. price: 0,
  2503. scale: 120,
  2504. desc: "hacks are for winners"
  2505. }, {
  2506. id: 51,
  2507. name: "Moo Cap",
  2508. price: 0,
  2509. scale: 120,
  2510. desc: "coolest mooer around"
  2511. }, {
  2512. id: 50,
  2513. name: "Apple Cap",
  2514. price: 0,
  2515. scale: 120,
  2516. desc: "apple farms remembers"
  2517. }, {
  2518. id: 28,
  2519. name: "Moo Head",
  2520. price: 0,
  2521. scale: 120,
  2522. desc: "no effect"
  2523. }, {
  2524. id: 29,
  2525. name: "Pig Head",
  2526. price: 0,
  2527. scale: 120,
  2528. desc: "no effect"
  2529. }, {
  2530. id: 30,
  2531. name: "Fluff Head",
  2532. price: 0,
  2533. scale: 120,
  2534. desc: "no effect"
  2535. }, {
  2536. id: 36,
  2537. name: "Pandou Head",
  2538. price: 0,
  2539. scale: 120,
  2540. desc: "no effect"
  2541. }, {
  2542. id: 37,
  2543. name: "Bear Head",
  2544. price: 0,
  2545. scale: 120,
  2546. desc: "no effect"
  2547. }, {
  2548. id: 38,
  2549. name: "Monkey Head",
  2550. price: 0,
  2551. scale: 120,
  2552. desc: "no effect"
  2553. }, {
  2554. id: 44,
  2555. name: "Polar Head",
  2556. price: 0,
  2557. scale: 120,
  2558. desc: "no effect"
  2559. }, {
  2560. id: 35,
  2561. name: "Fez Hat",
  2562. price: 0,
  2563. scale: 120,
  2564. desc: "no effect"
  2565. }, {
  2566. id: 42,
  2567. name: "Enigma Hat",
  2568. price: 0,
  2569. scale: 120,
  2570. desc: "join the enigma army"
  2571. }, {
  2572. id: 43,
  2573. name: "Blitz Hat",
  2574. price: 0,
  2575. scale: 120,
  2576. desc: "hey everybody i'm blitz"
  2577. }, {
  2578. id: 49,
  2579. name: "Bob XIII Hat",
  2580. price: 0,
  2581. scale: 120,
  2582. desc: "like and subscribe"
  2583. }, {
  2584. id: 57,
  2585. name: "Pumpkin",
  2586. price: 50,
  2587. scale: 120,
  2588. desc: "Spooooky"
  2589. }, {
  2590. id: 8,
  2591. name: "Bummle Hat",
  2592. price: 100,
  2593. scale: 120,
  2594. desc: "no effect"
  2595. }, {
  2596. id: 2,
  2597. name: "Straw Hat",
  2598. price: 500,
  2599. scale: 120,
  2600. desc: "no effect"
  2601. }, {
  2602. id: 15,
  2603. name: "Winter Cap",
  2604. price: 600,
  2605. scale: 120,
  2606. desc: "allows you to move at normal speed in snow",
  2607. coldM: 1
  2608. }, {
  2609. id: 5,
  2610. name: "Cowboy Hat",
  2611. price: 1000,
  2612. scale: 120,
  2613. desc: "no effect"
  2614. }, {
  2615. id: 4,
  2616. name: "Ranger Hat",
  2617. price: 2000,
  2618. scale: 120,
  2619. desc: "no effect"
  2620. }, {
  2621. id: 18,
  2622. name: "Explorer Hat",
  2623. price: 2000,
  2624. scale: 120,
  2625. desc: "no effect"
  2626. }, {
  2627. id: 31,
  2628. name: "Flipper Hat",
  2629. price: 2500,
  2630. scale: 120,
  2631. desc: "have more control while in water",
  2632. watrImm: true
  2633. }, {
  2634. id: 1,
  2635. name: "Marksman Cap",
  2636. price: 3000,
  2637. scale: 120,
  2638. desc: "increases arrow speed and range",
  2639. aMlt: 1.3
  2640. }, {
  2641. id: 10,
  2642. name: "Bush Gear",
  2643. price: 3000,
  2644. scale: 160,
  2645. desc: "allows you to disguise yourself as a bush"
  2646. }, {
  2647. id: 48,
  2648. name: "Halo",
  2649. price: 3000,
  2650. scale: 120,
  2651. desc: "no effect"
  2652. }, {
  2653. id: 6,
  2654. name: "Soldier Helmet",
  2655. price: 4000,
  2656. scale: 120,
  2657. desc: "reduces damage taken but slows movement",
  2658. spdMult: 0.94,
  2659. dmgMult: 0.75
  2660. }, {
  2661. id: 23,
  2662. name: "Anti Venom Gear",
  2663. price: 4000,
  2664. scale: 120,
  2665. desc: "makes you immune to poison",
  2666. poisonRes: 1
  2667. }, {
  2668. id: 13,
  2669. name: "Medic Gear",
  2670. price: 5000,
  2671. scale: 110,
  2672. desc: "slowly regenerates health over time",
  2673. healthRegen: 3
  2674. }, {
  2675. id: 9,
  2676. name: "Miners Helmet",
  2677. price: 5000,
  2678. scale: 120,
  2679. desc: "earn 1 extra gold per resource",
  2680. extraGold: 1
  2681. }, {
  2682. id: 32,
  2683. name: "Musketeer Hat",
  2684. price: 5000,
  2685. scale: 120,
  2686. desc: "reduces cost of projectiles",
  2687. projCost: 0.5
  2688. }, {
  2689. id: 7,
  2690. name: "Bull Helmet",
  2691. price: 6000,
  2692. scale: 120,
  2693. desc: "increases damage done but drains health",
  2694. healthRegen: -5,
  2695. dmgMultO: 1.5,
  2696. spdMult: 0.96
  2697. }, {
  2698. id: 22,
  2699. name: "Emp Helmet",
  2700. price: 6000,
  2701. scale: 120,
  2702. desc: "turrets won't attack but you move slower",
  2703. antiTurret: 1,
  2704. spdMult: 0.7
  2705. }, {
  2706. id: 12,
  2707. name: "Booster Hat",
  2708. price: 6000,
  2709. scale: 120,
  2710. desc: "increases your movement speed",
  2711. spdMult: 1.16
  2712. }, {
  2713. id: 26,
  2714. name: "Barbarian Armor",
  2715. price: 8000,
  2716. scale: 120,
  2717. desc: "knocks back enemies that attack you",
  2718. dmgK: 0.6
  2719. }, {
  2720. id: 21,
  2721. name: "Plague Mask",
  2722. price: 10000,
  2723. scale: 120,
  2724. desc: "melee attacks deal poison damage",
  2725. poisonDmg: 5,
  2726. poisonTime: 6
  2727. }, {
  2728. id: 46,
  2729. name: "Bull Mask",
  2730. price: 10000,
  2731. scale: 120,
  2732. desc: "bulls won't target you unless you attack them",
  2733. bullRepel: 1
  2734. }, {
  2735. id: 14,
  2736. name: "Windmill Hat",
  2737. topSprite: true,
  2738. price: 10000,
  2739. scale: 120,
  2740. desc: "generates points while worn",
  2741. pps: 1.5
  2742. }, {
  2743. id: 11,
  2744. name: "Spike Gear",
  2745. topSprite: true,
  2746. price: 10000,
  2747. scale: 120,
  2748. desc: "deal damage to players that damage you",
  2749. dmg: 0.45
  2750. }, {
  2751. id: 53,
  2752. name: "Turret Gear",
  2753. topSprite: true,
  2754. price: 10000,
  2755. scale: 120,
  2756. desc: "you become a walking turret",
  2757. turret: {
  2758. proj: 1,
  2759. range: 700,
  2760. rate: 2500
  2761. },
  2762. spdMult: 0.7
  2763. }, {
  2764. id: 20,
  2765. name: "Samurai Armor",
  2766. price: 12000,
  2767. scale: 120,
  2768. desc: "increased attack speed and fire rate",
  2769. atkSpd: 0.78
  2770. }, {
  2771. id: 58,
  2772. name: "Dark Knight",
  2773. price: 12000,
  2774. scale: 120,
  2775. desc: "restores health when you deal damage",
  2776. healD: 0.4
  2777. }, {
  2778. id: 27,
  2779. name: "Scavenger Gear",
  2780. price: 15000,
  2781. scale: 120,
  2782. desc: "earn double points for each kill",
  2783. kScrM: 2
  2784. }, {
  2785. id: 40,
  2786. name: "Tank Gear",
  2787. price: 15000,
  2788. scale: 120,
  2789. desc: "increased damage to buildings but slower movement",
  2790. spdMult: 0.3,
  2791. bDmg: 3.3
  2792. }, {
  2793. id: 52,
  2794. name: "Thief Gear",
  2795. price: 15000,
  2796. scale: 120,
  2797. desc: "steal half of a players gold when you kill them",
  2798. goldSteal: 0.5
  2799. }, {
  2800. id: 55,
  2801. name: "Bloodthirster",
  2802. price: 20000,
  2803. scale: 120,
  2804. desc: "Restore Health when dealing damage. And increased damage",
  2805. healD: 0.25,
  2806. dmgMultO: 1.2,
  2807. }, {
  2808. id: 56,
  2809. name: "Assassin Gear",
  2810. price: 20000,
  2811. scale: 120,
  2812. desc: "Go invisible when not moving. Can't eat. Increased speed",
  2813. noEat: true,
  2814. spdMult: 1.1,
  2815. invisTimer: 1000
  2816. }];
  2817.  
  2818. this.accessories = [{
  2819. id: 12,
  2820. name: "Snowball",
  2821. price: 1000,
  2822. scale: 105,
  2823. xOff: 18,
  2824. desc: "no effect"
  2825. }, {
  2826. id: 9,
  2827. name: "Tree Cape",
  2828. price: 1000,
  2829. scale: 90,
  2830. desc: "no effect"
  2831. }, {
  2832. id: 10,
  2833. name: "Stone Cape",
  2834. price: 1000,
  2835. scale: 90,
  2836. desc: "no effect"
  2837. }, {
  2838. id: 3,
  2839. name: "Cookie Cape",
  2840. price: 1500,
  2841. scale: 90,
  2842. desc: "no effect"
  2843. }, {
  2844. id: 8,
  2845. name: "Cow Cape",
  2846. price: 2000,
  2847. scale: 90,
  2848. desc: "no effect"
  2849. }, {
  2850. id: 11,
  2851. name: "Monkey Tail",
  2852. price: 2000,
  2853. scale: 97,
  2854. xOff: 25,
  2855. desc: "Super speed but reduced damage",
  2856. spdMult: 1.35,
  2857. dmgMultO: 0.2
  2858. }, {
  2859. id: 17,
  2860. name: "Apple Basket",
  2861. price: 3000,
  2862. scale: 80,
  2863. xOff: 12,
  2864. desc: "slowly regenerates health over time",
  2865. healthRegen: 1
  2866. }, {
  2867. id: 6,
  2868. name: "Winter Cape",
  2869. price: 3000,
  2870. scale: 90,
  2871. desc: "no effect"
  2872. }, {
  2873. id: 4,
  2874. name: "Skull Cape",
  2875. price: 4000,
  2876. scale: 90,
  2877. desc: "no effect"
  2878. }, {
  2879. id: 5,
  2880. name: "Dash Cape",
  2881. price: 5000,
  2882. scale: 90,
  2883. desc: "no effect"
  2884. }, {
  2885. id: 2,
  2886. name: "Dragon Cape",
  2887. price: 6000,
  2888. scale: 90,
  2889. desc: "no effect"
  2890. }, {
  2891. id: 1,
  2892. name: "Super Cape",
  2893. price: 8000,
  2894. scale: 90,
  2895. desc: "no effect"
  2896. }, {
  2897. id: 7,
  2898. name: "Troll Cape",
  2899. price: 8000,
  2900. scale: 90,
  2901. desc: "no effect"
  2902. }, {
  2903. id: 14,
  2904. name: "Thorns",
  2905. price: 10000,
  2906. scale: 115,
  2907. xOff: 20,
  2908. desc: "no effect"
  2909. }, {
  2910. id: 15,
  2911. name: "Blockades",
  2912. price: 10000,
  2913. scale: 95,
  2914. xOff: 15,
  2915. desc: "no effect"
  2916. }, {
  2917. id: 20,
  2918. name: "Devils Tail",
  2919. price: 10000,
  2920. scale: 95,
  2921. xOff: 20,
  2922. desc: "no effect"
  2923. }, {
  2924. id: 16,
  2925. name: "Sawblade",
  2926. price: 12000,
  2927. scale: 90,
  2928. spin: true,
  2929. xOff: 0,
  2930. desc: "deal damage to players that damage you",
  2931. dmg: 0.15
  2932. }, {
  2933. id: 13,
  2934. name: "Angel Wings",
  2935. price: 15000,
  2936. scale: 138,
  2937. xOff: 22,
  2938. desc: "slowly regenerates health over time",
  2939. healthRegen: 3
  2940. }, {
  2941. id: 19,
  2942. name: "Shadow Wings",
  2943. price: 15000,
  2944. scale: 138,
  2945. xOff: 22,
  2946. desc: "increased movement speed",
  2947. spdMult: 1.1
  2948. }, {
  2949. id: 18,
  2950. name: "Blood Wings",
  2951. price: 20000,
  2952. scale: 178,
  2953. xOff: 26,
  2954. desc: "restores health when you deal damage",
  2955. healD: 0.2
  2956. }, {
  2957. id: 21,
  2958. name: "Corrupt X Wings",
  2959. price: 20000,
  2960. scale: 178,
  2961. xOff: 26,
  2962. desc: "deal damage to players that damage you",
  2963. dmg: 0.25
  2964. }];
  2965. }
  2966. };
  2967. class ProjectileManager {
  2968. constructor(Projectile, projectiles, players, ais, objectManager, items, config, UTILS, server) {
  2969. this.addProjectile = function(x, y, dir, range, speed, indx, owner, ignoreObj, layer, inWindow) {
  2970. let tmpData = items.projectiles[indx];
  2971. let tmpProj;
  2972. for (let i = 0; i < projectiles.length; ++i) {
  2973. if (!projectiles[i].active) {
  2974. tmpProj = projectiles[i];
  2975. break;
  2976. }
  2977. }
  2978. if (!tmpProj) {
  2979. tmpProj = new Projectile(players, ais, objectManager, items, config, UTILS, server);
  2980. tmpProj.sid = projectiles.length;
  2981. projectiles.push(tmpProj);
  2982. }
  2983. tmpProj.init(indx, x, y, dir, speed, tmpData.dmg, range, tmpData.scale, owner);
  2984. tmpProj.ignoreObj = ignoreObj;
  2985. tmpProj.layer = layer || tmpData.layer;
  2986. tmpProj.inWindow = inWindow;
  2987. tmpProj.src = tmpData.src;
  2988. return tmpProj;
  2989. };
  2990. }
  2991. };
  2992. class AiManager {
  2993.  
  2994. constructor(ais, AI, players, items, objectManager, config, UTILS, scoreCallback, server) {
  2995.  
  2996. this.aiTypes = [{
  2997. id: 0,
  2998. src: "cow_1",
  2999. killScore: 150,
  3000. health: 500,
  3001. weightM: 0.8,
  3002. speed: 0.00095,
  3003. turnSpeed: 0.001,
  3004. scale: 72,
  3005. drop: ["food", 50]
  3006. }, {
  3007. id: 1,
  3008. src: "pig_1",
  3009. killScore: 200,
  3010. health: 800,
  3011. weightM: 0.6,
  3012. speed: 0.00085,
  3013. turnSpeed: 0.001,
  3014. scale: 72,
  3015. drop: ["food", 80]
  3016. }, {
  3017. id: 2,
  3018. name: "Bull",
  3019. src: "bull_2",
  3020. hostile: true,
  3021. dmg: 20,
  3022. killScore: 1000,
  3023. health: 1800,
  3024. weightM: 0.5,
  3025. speed: 0.00094,
  3026. turnSpeed: 0.00074,
  3027. scale: 78,
  3028. viewRange: 800,
  3029. chargePlayer: true,
  3030. drop: ["food", 100]
  3031. }, {
  3032. id: 3,
  3033. name: "Bully",
  3034. src: "bull_1",
  3035. hostile: true,
  3036. dmg: 20,
  3037. killScore: 2000,
  3038. health: 2800,
  3039. weightM: 0.45,
  3040. speed: 0.001,
  3041. turnSpeed: 0.0008,
  3042. scale: 90,
  3043. viewRange: 900,
  3044. chargePlayer: true,
  3045. drop: ["food", 400]
  3046. }, {
  3047. id: 4,
  3048. name: "Wolf",
  3049. src: "wolf_1",
  3050. hostile: true,
  3051. dmg: 8,
  3052. killScore: 500,
  3053. health: 300,
  3054. weightM: 0.45,
  3055. speed: 0.001,
  3056. turnSpeed: 0.002,
  3057. scale: 84,
  3058. viewRange: 800,
  3059. chargePlayer: true,
  3060. drop: ["food", 200]
  3061. }, {
  3062. id: 5,
  3063. name: "Quack",
  3064. src: "chicken_1",
  3065. dmg: 8,
  3066. killScore: 2000,
  3067. noTrap: true,
  3068. health: 300,
  3069. weightM: 0.2,
  3070. speed: 0.0018,
  3071. turnSpeed: 0.006,
  3072. scale: 70,
  3073. drop: ["food", 100]
  3074. }, {
  3075. id: 6,
  3076. name: "MOOSTAFA",
  3077. nameScale: 50,
  3078. src: "enemy",
  3079. hostile: true,
  3080. dontRun: true,
  3081. fixedSpawn: true,
  3082. spawnDelay: 60000,
  3083. noTrap: true,
  3084. colDmg: 100,
  3085. dmg: 40,
  3086. killScore: 8000,
  3087. health: 18000,
  3088. weightM: 0.4,
  3089. speed: 0.0007,
  3090. turnSpeed: 0.01,
  3091. scale: 80,
  3092. spriteMlt: 1.8,
  3093. leapForce: 0.9,
  3094. viewRange: 1000,
  3095. hitRange: 210,
  3096. hitDelay: 1000,
  3097. chargePlayer: true,
  3098. drop: ["food", 100]
  3099. }, {
  3100. id: 7,
  3101. name: "Treasure",
  3102. hostile: true,
  3103. nameScale: 35,
  3104. src: "crate_1",
  3105. fixedSpawn: true,
  3106. spawnDelay: 120000,
  3107. colDmg: 200,
  3108. killScore: 5000,
  3109. health: 20000,
  3110. weightM: 0.1,
  3111. speed: 0.0,
  3112. turnSpeed: 0.0,
  3113. scale: 70,
  3114. spriteMlt: 1.0
  3115. }, {
  3116. id: 8,
  3117. name: "MOOFIE",
  3118. src: "wolf_2",
  3119. hostile: true,
  3120. fixedSpawn: true,
  3121. dontRun: true,
  3122. hitScare: 4,
  3123. spawnDelay: 30000,
  3124. noTrap: true,
  3125. nameScale: 35,
  3126. dmg: 10,
  3127. colDmg: 100,
  3128. killScore: 3000,
  3129. health: 7000,
  3130. weightM: 0.45,
  3131. speed: 0.0015,
  3132. turnSpeed: 0.002,
  3133. scale: 90,
  3134. viewRange: 800,
  3135. chargePlayer: true,
  3136. drop: ["food", 1000]
  3137. }, {
  3138. id: 9,
  3139. name: "💀MOOFIE",
  3140. src: "wolf_2",
  3141. hostile: !0,
  3142. fixedSpawn: !0,
  3143. dontRun: !0,
  3144. hitScare: 50,
  3145. spawnDelay: 6e4,
  3146. noTrap: !0,
  3147. nameScale: 35,
  3148. dmg: 12,
  3149. colDmg: 100,
  3150. killScore: 3e3,
  3151. health: 9e3,
  3152. weightM: .45,
  3153. speed: .0015,
  3154. turnSpeed: .0025,
  3155. scale: 94,
  3156. viewRange: 1440,
  3157. chargePlayer: !0,
  3158. drop: ["food", 3e3],
  3159. minSpawnRange: .85,
  3160. maxSpawnRange: .9
  3161. }, {
  3162. id: 10,
  3163. name: "💀Wolf",
  3164. src: "wolf_1",
  3165. hostile: !0,
  3166. fixedSpawn: !0,
  3167. dontRun: !0,
  3168. hitScare: 50,
  3169. spawnDelay: 3e4,
  3170. dmg: 10,
  3171. killScore: 700,
  3172. health: 500,
  3173. weightM: .45,
  3174. speed: .00115,
  3175. turnSpeed: .0025,
  3176. scale: 88,
  3177. viewRange: 1440,
  3178. chargePlayer: !0,
  3179. drop: ["food", 400],
  3180. minSpawnRange: .85,
  3181. maxSpawnRange: .9
  3182. }, {
  3183. id: 11,
  3184. name: "💀Bully",
  3185. src: "bull_1",
  3186. hostile: !0,
  3187. fixedSpawn: !0,
  3188. dontRun: !0,
  3189. hitScare: 50,
  3190. dmg: 20,
  3191. killScore: 5e3,
  3192. health: 5e3,
  3193. spawnDelay: 1e5,
  3194. weightM: .45,
  3195. speed: .00115,
  3196. turnSpeed: .0025,
  3197. scale: 94,
  3198. viewRange: 1440,
  3199. chargePlayer: !0,
  3200. drop: ["food", 800],
  3201. minSpawnRange: .85,
  3202. maxSpawnRange: .9
  3203. }];
  3204.  
  3205. this.spawn = function(x, y, dir, index) {
  3206. let tmpObj = ais.find((tmp) => !tmp.active);
  3207. if (!tmpObj) {
  3208. tmpObj = new AI(ais.length, objectManager, players, items, UTILS, config, scoreCallback, server);
  3209. ais.push(tmpObj);
  3210. }
  3211. tmpObj.init(x, y, dir, index, this.aiTypes[index]);
  3212. return tmpObj;
  3213. };
  3214. }
  3215.  
  3216. };
  3217.  
  3218. class AI {
  3219. constructor(sid, objectManager, players, items, UTILS, config, scoreCallback, server) {
  3220. this.sid = sid;
  3221. this.isAI = true;
  3222. this.nameIndex = UTILS.randInt(0, config.cowNames.length - 1);
  3223.  
  3224. this.init = function(x, y, dir, index, data) {
  3225. this.x = x;
  3226. this.y = y;
  3227. this.startX = data.fixedSpawn ? x : null;
  3228. this.startY = data.fixedSpawn ? y : null;
  3229. this.xVel = 0;
  3230. this.yVel = 0;
  3231. this.zIndex = 0;
  3232. this.dir = dir;
  3233. this.dirPlus = 0;
  3234. this.showName = 'aaa';
  3235. this.index = index;
  3236. this.src = data.src;
  3237. if (data.name) this.name = data.name;
  3238. this.weightM = data.weightM;
  3239. this.speed = data.speed;
  3240. this.killScore = data.killScore;
  3241. this.turnSpeed = data.turnSpeed;
  3242. this.scale = data.scale;
  3243. this.maxHealth = data.health;
  3244. this.leapForce = data.leapForce;
  3245. this.health = this.maxHealth;
  3246. this.chargePlayer = data.chargePlayer;
  3247. this.viewRange = data.viewRange;
  3248. this.drop = data.drop;
  3249. this.dmg = data.dmg;
  3250. this.hostile = data.hostile;
  3251. this.dontRun = data.dontRun;
  3252. this.hitRange = data.hitRange;
  3253. this.hitDelay = data.hitDelay;
  3254. this.hitScare = data.hitScare;
  3255. this.spriteMlt = data.spriteMlt;
  3256. this.nameScale = data.nameScale;
  3257. this.colDmg = data.colDmg;
  3258. this.noTrap = data.noTrap;
  3259. this.spawnDelay = data.spawnDelay;
  3260. this.hitWait = 0;
  3261. this.waitCount = 1000;
  3262. this.moveCount = 0;
  3263. this.targetDir = 0;
  3264. this.active = true;
  3265. this.alive = true;
  3266. this.runFrom = null;
  3267. this.chargeTarget = null;
  3268. this.dmgOverTime = {};
  3269. };
  3270.  
  3271. let tmpRatio = 0;
  3272. let animIndex = 0;
  3273. this.animate = function(delta) {
  3274. if (this.animTime > 0) {
  3275. this.animTime -= delta;
  3276. if (this.animTime <= 0) {
  3277. this.animTime = 0;
  3278. this.dirPlus = 0;
  3279. tmpRatio = 0;
  3280. animIndex = 0;
  3281. } else {
  3282. if (animIndex == 0) {
  3283. tmpRatio += delta / (this.animSpeed * config.hitReturnRatio);
  3284. this.dirPlus = UTILS.lerp(0, this.targetAngle, Math.min(1, tmpRatio));
  3285. if (tmpRatio >= 1) {
  3286. tmpRatio = 1;
  3287. animIndex = 1;
  3288. }
  3289. } else {
  3290. tmpRatio -= delta / (this.animSpeed * (1 - config.hitReturnRatio));
  3291. this.dirPlus = UTILS.lerp(0, this.targetAngle, Math.max(0, tmpRatio));
  3292. }
  3293. }
  3294. }
  3295. };
  3296.  
  3297. this.startAnim = function() {
  3298. this.animTime = this.animSpeed = 600;
  3299. this.targetAngle = Math.PI * 0.8;
  3300. tmpRatio = 0;
  3301. animIndex = 0;
  3302. };
  3303.  
  3304. };
  3305.  
  3306. };
  3307. class addCh {
  3308. constructor(x, y, chat, tmpObj) {
  3309. this.x = x;
  3310. this.y = y;
  3311. this.alpha = 0;
  3312. this.active = true;
  3313. this.alive = false;
  3314. this.chat = chat;
  3315. this.owner = tmpObj;
  3316. };
  3317. };
  3318. class DeadPlayer {
  3319. constructor(x, y, dir, buildIndex, weaponIndex, weaponVariant, skinColor, scale, name) {
  3320. this.x = x;
  3321. this.y = y;
  3322. this.lastDir = dir;
  3323. this.dir = dir + Math.PI;
  3324. this.buildIndex = buildIndex;
  3325. this.weaponIndex = weaponIndex;
  3326. this.weaponVariant = weaponVariant;
  3327. this.skinColor = skinColor;
  3328. this.scale = scale;
  3329. this.visScale = 0;
  3330. this.name = name;
  3331. this.alpha = 1;
  3332. this.active = true;
  3333. this.animate = function(delta) {
  3334. let d2 = UTILS.getAngleDist(this.lastDir, this.dir);
  3335. if (d2 > 0.01) {
  3336. this.dir += d2 / 20;
  3337. } else {
  3338. this.dir = this.lastDir;
  3339. }
  3340. if (this.visScale < this.scale) {
  3341. this.visScale += delta / (this.scale / 2);
  3342. if (this.visScale >= this.scale) {
  3343. this.visScale = this.scale;
  3344. }
  3345. }
  3346. this.alpha -= delta / 30000;
  3347. if (this.alpha <= 0) {
  3348. this.alpha = 0;
  3349. this.active = false;
  3350. }
  3351. }
  3352. }
  3353. };
  3354. class Player {
  3355. constructor(id, sid, config, UTILS, projectileManager, objectManager, players, ais, items, hats, accessories, server, scoreCallback, iconCallback) {
  3356. this.id = id;
  3357. this.sid = sid;
  3358. this.tmpScore = 0;
  3359. this.team = null;
  3360. this.latestSkin = 0;
  3361. this.oldSkinIndex = 0;
  3362. this.skinIndex = 0;
  3363. this.latestTail = 0;
  3364. this.oldTailIndex = 0;
  3365. this.tailIndex = 0;
  3366. this.hitTime = 0;
  3367. this.lastHit = 0;
  3368. this.showName = 'NOOO';
  3369. this.tails = {};
  3370.  
  3371. for (let i = 0; i < accessories.length; ++i) {
  3372. if (accessories[i].price <= 0)
  3373. this.tails[accessories[i].id] = 1;
  3374. }
  3375. this.skins = {};
  3376. for (let i = 0; i < hats.length; ++i) {
  3377. if (hats[i].price <= 0)
  3378. this.skins[hats[i].id] = 1;
  3379. }
  3380.  
  3381. this.points = 0;
  3382. this.dt = 0;
  3383. this.hidden = false;
  3384. this.itemCounts = {};
  3385. this.isPlayer = true;
  3386. this.pps = 0;
  3387. this.moveDir = undefined;
  3388. this.skinRot = 0;
  3389. this.lastPing = 0;
  3390. this.iconIndex = 0;
  3391. this.skinColor = 0;
  3392. this.dist2 = 0;
  3393. this.aim2 = 0;
  3394. this.maxSpeed = 1;
  3395. this.chat = {
  3396. message: null,
  3397. count: 0
  3398. };
  3399. this.backupNobull = true;
  3400. this.spawn = function(moofoll) {
  3401. this.attacked = false;
  3402. this.timeDamaged = 0;
  3403. this.timeHealed = 0;
  3404. this.pinge = 0;
  3405. this.millPlace = 'NOOO';
  3406. this.lastshamecount = 0;
  3407. this.death = false;
  3408. this.spinDir = 0;
  3409. this.sync = false;
  3410. this.antiBull = 0;
  3411. this.bullTimer = 0;
  3412. this.poisonTimer = 0;
  3413. this.active = true;
  3414. this.alive = true;
  3415. this.lockMove = false;
  3416. this.lockDir = false;
  3417. this.minimapCounter = 0;
  3418. this.chatCountdown = 0;
  3419. this.shameCount = 0;
  3420. this.shameTimer = 0;
  3421. this.sentTo = {};
  3422. this.gathering = 0;
  3423. this.gatherIndex = 0;
  3424. this.shooting = {};
  3425. this.shootIndex = 9;
  3426. this.autoGather = 0;
  3427. this.animTime = 0;
  3428. this.animSpeed = 0;
  3429. this.mouseState = 0;
  3430. this.buildIndex = -1;
  3431. this.weaponIndex = 0;
  3432. this.weaponCode = 0;
  3433. this.weaponVariant = 0;
  3434. this.primaryIndex = undefined;
  3435. this.secondaryIndex = undefined;
  3436. this.dmgOverTime = {};
  3437. this.noMovTimer = 0;
  3438. this.maxXP = 300;
  3439. this.XP = 0;
  3440. this.age = 1;
  3441. this.kills = 0;
  3442. this.upgrAge = 2;
  3443. this.upgradePoints = 0;
  3444. this.x = 0;
  3445. this.y = 0;
  3446. this.oldXY = {
  3447. x: 0,
  3448. y: 0
  3449. };
  3450. this.zIndex = 0;
  3451. this.xVel = 0;
  3452. this.yVel = 0;
  3453. this.slowMult = 1;
  3454. this.dir = 0;
  3455. this.dirPlus = 0;
  3456. this.targetDir = 0;
  3457. this.targetAngle = 0;
  3458. this.maxHealth = 100;
  3459. this.health = this.maxHealth;
  3460. this.oldHealth = this.maxHealth;
  3461. this.damaged = 0;
  3462. this.scale = config.playerScale;
  3463. this.speed = config.playerSpeed;
  3464. this.resetMoveDir();
  3465. this.resetResources(moofoll);
  3466. this.items = [0, 3, 6, 10];
  3467. this.weapons = [0];
  3468. this.shootCount = 0;
  3469. this.weaponXP = [];
  3470. this.reloads = {
  3471. 0: 0,
  3472. 1: 0,
  3473. 2: 0,
  3474. 3: 0,
  3475. 4: 0,
  3476. 5: 0,
  3477. 6: 0,
  3478. 7: 0,
  3479. 8: 0,
  3480. 9: 0,
  3481. 10: 0,
  3482. 11: 0,
  3483. 12: 0,
  3484. 13: 0,
  3485. 14: 0,
  3486. 15: 0,
  3487. 53: 0,
  3488. };
  3489. this.bowThreat = {
  3490. 9: 0,
  3491. 12: 0,
  3492. 13: 0,
  3493. 15: 0,
  3494. };
  3495. this.damageThreat = 0;
  3496. this.inTrap = false;
  3497. this.canEmpAnti = false;
  3498. this.empAnti = false;
  3499. this.soldierAnti = false;
  3500. this.poisonTick = 0;
  3501. this.bullTick = 0;
  3502. this.setPoisonTick = false;
  3503. this.setBullTick = false;
  3504. this.antiTimer = 2;
  3505. };
  3506.  
  3507. this.resetMoveDir = function() {
  3508. this.moveDir = undefined;
  3509. };
  3510.  
  3511. this.resetResources = function(moofoll) {
  3512. for (let i = 0; i < config.resourceTypes.length; ++i) {
  3513. this[config.resourceTypes[i]] = moofoll ? 100 : 0;
  3514. }
  3515. };
  3516.  
  3517. this.getItemType = function(id) {
  3518. let findindx = this.items.findIndex((ids) => ids == id);
  3519. if (findindx != -1) {
  3520. return findindx;
  3521. } else {
  3522. return items.checkItem.index(id, this.items);
  3523. }
  3524. };
  3525.  
  3526. this.setData = function(data) {
  3527. this.id = data[0];
  3528. this.sid = data[1];
  3529. this.name = data[2];
  3530. this.x = data[3];
  3531. this.y = data[4];
  3532. this.dir = data[5];
  3533. this.health = data[6];
  3534. this.maxHealth = data[7];
  3535. this.scale = data[8];
  3536. this.skinColor = data[9];
  3537. };
  3538.  
  3539. this.updateTimer = function() {
  3540.  
  3541. this.bullTimer -= 1;
  3542. if (this.bullTimer <= 0) {
  3543. this.setBullTick = false;
  3544. this.bullTick = game.tick - 1;
  3545. this.bullTimer = config.serverUpdateRate;
  3546. }
  3547. this.poisonTimer -= 1;
  3548. if (this.poisonTimer <= 0) {
  3549. this.setPoisonTick = false;
  3550. this.poisonTick = game.tick - 1;
  3551. this.poisonTimer = config.serverUpdateRate;
  3552. }
  3553.  
  3554. };
  3555. this.update = function(delta) {
  3556. if (this.active) {
  3557.  
  3558. let gear = {
  3559. skin: findID(hats, this.skinIndex),
  3560. tail: findID(accessories, this.tailIndex)
  3561. }
  3562. let spdMult = ((this.buildIndex >= 0) ? 0.5 : 1) * (items.weapons[this.weaponIndex].spdMult || 1) * (gear.skin ? (gear.skin.spdMult || 1) : 1) * (gear.tail ? (gear.tail.spdMult || 1) : 1) * (this.y <= config.snowBiomeTop ? ((gear.skin && gear.skin.coldM) ? 1 : config.snowSpeed) : 1) * this.slowMult;
  3563. this.maxSpeed = spdMult;
  3564.  
  3565. }
  3566. };
  3567.  
  3568. let tmpRatio = 0;
  3569. let animIndex = 0;
  3570. let crazyFactor = 3;
  3571. let waveAmplitude = Math.PI / -16;
  3572. this.animate = function(delta) {
  3573. if (this.animTime > 0) {
  3574. this.animTime -= delta;
  3575. if (this.animTime <= 0) {
  3576. this.animTime = 0;
  3577. this.dirPlus = 0;
  3578. tmpRatio = 0;
  3579. animIndex = 0;
  3580. } else {
  3581. if (animIndex == 0) {
  3582. tmpRatio += delta / (this.animSpeed * config.hitReturnRatio);
  3583. let progress = Math.min(1, tmpRatio);
  3584. this.dirPlus = UTILS.lerp(0, this.targetAngle, easeInOutSine(progress)) + waveAmplitude * Math.sin(progress * crazyFactor * Math.PI);
  3585. if (progress >= 1) {
  3586. tmpRatio = 1;
  3587. animIndex = 1;
  3588. }
  3589. } else {
  3590. tmpRatio -= delta / (this.animSpeed * (1 - config.hitReturnRatio));
  3591. let progress = Math.max(0, tmpRatio);
  3592. this.dirPlus = UTILS.lerp(0, this.targetAngle, easeInOutSine(progress)) + waveAmplitude * Math.cos(progress * crazyFactor * Math.PI);
  3593. }
  3594. }
  3595. }
  3596. };
  3597.  
  3598. this.startAnim = function(didHit, index) {
  3599. this.animTime = this.animSpeed = items.weapons[index].speed * 1.8;
  3600. this.targetAngle = (didHit ? -config.hitAngle : -Math.PI);
  3601. tmpRatio = 0;
  3602. animIndex = 0;
  3603. };
  3604.  
  3605. this.canSee = function(other) {
  3606. if (!other) return false;
  3607. let dx = Math.abs(other.x - this.x) - other.scale;
  3608. let dy = Math.abs(other.y - this.y) - other.scale;
  3609. return dx <= (config.maxScreenWidth / 2) * 1.3 && dy <= (config.maxScreenHeight / 2) * 1.3;
  3610. };
  3611.  
  3612. this.judgeShame = function() {
  3613. this.lastshamecount = this.shameCount;
  3614. if (this.oldHealth < this.health) {
  3615. if (this.hitTime) {
  3616. let timeSinceHit = game.tick - this.hitTime;
  3617. this.lastHit = game.tick;
  3618. this.hitTime = 0;
  3619. if (timeSinceHit < 2) {
  3620. this.shameCount++;
  3621. } else {
  3622. this.shameCount = Math.max(0, this.shameCount - 2);
  3623. }
  3624. }
  3625. } else if (this.oldHealth > this.health) {
  3626. this.hitTime = game.tick;
  3627. }
  3628. };
  3629. this.addShameTimer = function() {
  3630. this.shameCount = 0;
  3631. this.shameTimer = 30;
  3632. let interval = setInterval(() => {
  3633. this.shameTimer--;
  3634. if (this.shameTimer <= 0) {
  3635. clearInterval(interval);
  3636. }
  3637. }, 1000);
  3638. };
  3639.  
  3640. this.isTeam = function(tmpObj) {
  3641. return (this == tmpObj || (this.team && this.team == tmpObj.team));
  3642. };
  3643.  
  3644. this.findAllianceBySid = function(sid) {
  3645. return this.team ? alliancePlayers.find((THIS) => THIS === sid) : null;
  3646. };
  3647. this.checkCanInsta = function(nobull) {
  3648. let totally = 0;
  3649. if (this.alive && inGame) {
  3650. let primary = {
  3651. weapon: this.weapons[0],
  3652. variant: this.primaryVariant,
  3653. dmg: this.weapons[0] == undefined ? 0 : items.weapons[this.weapons[0]].dmg,
  3654. };
  3655. let secondary = {
  3656. weapon: this.weapons[1],
  3657. variant: this.secondaryVariant,
  3658. dmg: this.weapons[1] == undefined ? 0 : items.weapons[this.weapons[1]].Pdmg,
  3659. };
  3660. let bull = this.skins[7] && !nobull ? 1.5 : 1;
  3661. let pV = primary.variant != undefined ? config.weaponVariants[primary.variant].val : 1;
  3662. if (primary.weapon != undefined && this.reloads[primary.weapon] == 0) {
  3663. totally += primary.dmg * pV * bull;
  3664. }
  3665. if (secondary.weapon != undefined && this.reloads[secondary.weapon] == 0) {
  3666. totally += secondary.dmg;
  3667. }
  3668. if (this.skins[53] && this.reloads[53] <= (player.weapons[1] == 10 ? 0 : game.tickRate) && near.skinIndex != 22) {
  3669. totally += 25;
  3670. }
  3671. totally *= near.skinIndex == 6 ? 0.75 : 1;
  3672. return totally;
  3673. }
  3674. return 0;
  3675. };
  3676.  
  3677. this.manageReload = function() {
  3678. if (this.shooting[53]) {
  3679. this.shooting[53] = 0;
  3680. this.reloads[53] = (2500 - game.tickRate);
  3681. } else {
  3682. if (this.reloads[53] > 0) {
  3683. this.reloads[53] = Math.max(0, this.reloads[53] - game.tickRate);
  3684. }
  3685. }
  3686.  
  3687. if (this.reloads[this.weaponIndex] <= 1000/9) {
  3688. let index = this.weaponIndex;
  3689. let nearObja = liztobj.filter((e) => (e.active || e.alive) && e.health < e.maxHealth && e.group !== undefined && UTILS.getDist(e, player, 0, 2) <= (items.weapons[player.weaponIndex].range + e.scale));
  3690. for(let i = 0; i < nearObja.length; i++) {
  3691. let aaa = nearObja[i];
  3692.  
  3693. let val = items.weapons[index].dmg * (config.weaponVariants[tmpObj[(index < 9 ? "prima" : "seconda") + "ryVariant"]].val) * (items.weapons[index].sDmg || 1) * 3.3;
  3694. let valaa = items.weapons[index].dmg * (config.weaponVariants[tmpObj[(index < 9 ? "prima" : "seconda") + "ryVariant"]].val) * (items.weapons[index].sDmg || 1);
  3695. if(aaa.health - (valaa) <= 0 && near.length) {
  3696. place(near.dist2<((near.scale * 1.8) + 50)?4:2, caf(aaa, player) + Math.PI);
  3697. }
  3698. }
  3699. }
  3700.  
  3701. if (this.gathering || this.shooting[1]) {
  3702. if (this.gathering) {
  3703. this.gathering = 0;
  3704. this.reloads[this.gatherIndex] = (items.weapons[this.gatherIndex].speed * (this.skinIndex == 20 ? 0.78 : 1));
  3705. this.attacked = true;
  3706. }
  3707. if (this.shooting[1]) {
  3708. this.shooting[1] = 0;
  3709. this.reloads[this.shootIndex] = (items.weapons[this.shootIndex].speed * (this.skinIndex == 20 ? 0.78 : 1));
  3710. this.attacked = true;
  3711. }
  3712. } else {
  3713. this.attacked = false;
  3714. if (this.buildIndex < 0) {
  3715. if (this.reloads[this.weaponIndex] > 0) {
  3716. this.reloads[this.weaponIndex] = Math.max(0, this.reloads[this.weaponIndex] - 110);
  3717. if (this == player) {
  3718. if (getEl("weaponGrind").checked) {
  3719. for (let i = 0; i < Math.PI * 2; i += Math.PI / 2) {
  3720. checkPlace(player.getItemType(22), i);
  3721. }
  3722. }
  3723. }
  3724. if (this.reloads[this.primaryIndex] == 0 && this.reloads[this.weaponIndex] == 0) {
  3725. this.antiBull++;
  3726. game.tickBase(() => {
  3727. this.antiBull = 0;
  3728. }, 1);
  3729. }
  3730. }
  3731. }
  3732. }
  3733. };
  3734.  
  3735. this.addDamageThreat = function(tmpObj) {
  3736. let primary = {
  3737. weapon: this.primaryIndex,
  3738. variant: this.primaryVariant
  3739. };
  3740. primary.dmg = primary.weapon == undefined ? 45 : items.weapons[primary.weapon].dmg;
  3741. let secondary = {
  3742. weapon: this.secondaryIndex,
  3743. variant: this.secondaryVariant
  3744. };
  3745. secondary.dmg = secondary.weapon == undefined ? 75 : items.weapons[secondary.weapon].Pdmg;
  3746. let bull = 1.5;
  3747. let pV = primary.variant != undefined ? config.weaponVariants[primary.variant].val : 1.18;
  3748. let sV = secondary.variant != undefined ? [9, 12, 13, 15].includes(secondary.weapon) ? 1 : config.weaponVariants[secondary.variant].val : 1.18;
  3749. if (primary.weapon == undefined ? true : this.reloads[primary.weapon] == 0) {
  3750. this.damageThreat += primary.dmg * pV * bull;
  3751. }
  3752. if (secondary.weapon == undefined ? true : this.reloads[secondary.weapon] == 0) {
  3753. this.damageThreat += secondary.dmg * sV;
  3754. }
  3755. if (this.reloads[53] <= game.tickRate) {
  3756. this.damageThreat += 25;
  3757. }
  3758. this.damageThreat *= tmpObj.skinIndex == 6 ? 0.75 : 1;
  3759. if (!this.isTeam(tmpObj)) {
  3760. if (this.dist2 <= 300) {
  3761. tmpObj.damageThreat += this.damageThreat;
  3762. }
  3763. }
  3764. };
  3765.  
  3766. }
  3767. };
  3768.  
  3769. // Sine easing functions for smooth transitions
  3770. function easeInOutSine(x) {
  3771. return -(Math.cos(Math.PI * x) - 1) / 2;
  3772. }
  3773.  
  3774. function sendUpgrade(index) {
  3775. player.reloads[index] = 0;
  3776. packet("H", index);
  3777. }
  3778.  
  3779. function storeEquip(id, index) {
  3780. packet("c", 0, id, index);
  3781. }
  3782.  
  3783. function storeBuy(id, index) {
  3784. packet("c", 1, id, index);
  3785. }
  3786.  
  3787. function buyEquip(id, index) {
  3788. let nID = player.skins[6] ? 6 : 0;
  3789. if (player.alive && inGame) {
  3790. if (index == 0) {
  3791. if (player.skins[id]) {
  3792. if (player.latestSkin != id) {
  3793. packet("c", 0, id, 0);
  3794. }
  3795. } else {
  3796. if (configs.autoBuyEquip) {
  3797. let find = findID(hats, id);
  3798. if (find) {
  3799. if (player.points >= find.price) {
  3800. packet("c", 1, id, 0);
  3801. packet("c", 0, id, 0);
  3802. } else {
  3803. if (player.latestSkin != nID) {
  3804. packet("c", 0, nID, 0);
  3805. }
  3806. }
  3807. } else {
  3808. if (player.latestSkin != nID) {
  3809. packet("c", 0, nID, 0);
  3810. }
  3811. }
  3812. } else {
  3813. if (player.latestSkin != nID) {
  3814. packet("c", 0, nID, 0);
  3815. }
  3816. }
  3817. }
  3818. } else if (index == 1) {
  3819. if (useWasd && (id != 11 && id != 0)) {
  3820. if (player.latestTail != 0) {
  3821. packet("c", 0, 0, 1);
  3822. }
  3823. return;
  3824. }
  3825. if (player.tails[id]) {
  3826. if (player.latestTail != id) {
  3827. packet("c", 0, id, 1);
  3828. }
  3829. } else {
  3830. if (configs.autoBuyEquip) {
  3831. let find = findID(accessories, id);
  3832. if (find) {
  3833. if (player.points >= find.price) {
  3834. packet("c", 1, id, 1);
  3835. packet("c", 0, id, 1);
  3836. } else {
  3837. if (player.latestTail != 0) {
  3838. packet("c", 0, 0, 1);
  3839. }
  3840. }
  3841. } else {
  3842. if (player.latestTail != 0) {
  3843. packet("c", 0, 0, 1);
  3844. }
  3845. }
  3846. } else {
  3847. if (player.latestTail != 0) {
  3848. packet("c", 0, 0, 1);
  3849. }
  3850. }
  3851. }
  3852. }
  3853. }
  3854. }
  3855.  
  3856. function selectToBuild(index, wpn) {
  3857. packet("z", index, wpn);
  3858. }
  3859.  
  3860. function selectWeapon(index, isPlace) {
  3861. if (!isPlace) {
  3862. player.weaponCode = index;
  3863. }
  3864. packet("z", index, 1);
  3865. }
  3866.  
  3867. function sendAutoGather() {
  3868. packet("K", 1, 1);
  3869. }
  3870.  
  3871. function sendAtck(id, angle) {
  3872. packet("F", id, angle, 1);
  3873. }
  3874.  
  3875. function place(itemId, angle, shouldRemove) {
  3876. try {
  3877. if (itemId === undefined) return;
  3878.  
  3879. const item = items.list[player.items[itemId]];
  3880. const tmpScale = player.scale + item.scale + (item.placeOffset || 0);
  3881. const tmpX = player.x2 + tmpScale * Math.cos(angle);
  3882. const tmpY = player.y2 + tmpScale * Math.sin(angle);
  3883.  
  3884. const canPlaceItem = player.alive && inGame && (player.itemCounts[item.group.id] === undefined || (config.isSandbox ? true : player.itemCounts[item.group.id] < (item.group.limit ? item.group.limit : 99)));
  3885.  
  3886. if (canPlaceItem) {
  3887. selectToBuild(player.items[itemId]);
  3888. sendAtck(1, angle);
  3889. selectWeapon(player.weaponCode, 1);
  3890.  
  3891. if (shouldRemove && document.getElementById("placeVis").checked) {
  3892. placeVisible.push({
  3893. x: tmpX,
  3894. y: tmpY,
  3895. name: item.name,
  3896. scale: item.scale,
  3897. dir: angle
  3898. });
  3899.  
  3900. game.tickBase(() => {
  3901. placeVisible.shift();
  3902. }, 1);
  3903. }
  3904. }
  3905. } catch (error) {
  3906. console.error("Error while placing item:", error);
  3907. }
  3908. }
  3909.  
  3910. function checkPlace(itemId, angle) {
  3911. try {
  3912. if (itemId === undefined) return;
  3913.  
  3914. const item = items.list[player.items[itemId]];
  3915. const tmpScale = player.scale + item.scale + (item.placeOffset || 0);
  3916. const tmpX = player.x2 + tmpScale * Math.cos(angle);
  3917. const tmpY = player.y2 + tmpScale * Math.sin(angle);
  3918.  
  3919. if (objectManager.checkItemLocation(tmpX, tmpY, item.scale, 0.6, item.id, false, player)) {
  3920. place(itemId, angle, true);
  3921. }
  3922. } catch (error) {
  3923. console.error("Error while checking place:", error);
  3924. }
  3925. }
  3926.  
  3927. function soldierMult() {
  3928. return player.latestSkin == 6 ? 0.75 : 1;
  3929. }
  3930.  
  3931. function healthBased() {
  3932. if (player.health === 100) {
  3933. return 0;
  3934. }
  3935.  
  3936. if (player.skinIndex !== 45 && player.skinIndex !== 56) {
  3937. const currentItem = items.list[player.items[0]];
  3938. if (currentItem && currentItem.healing) {
  3939. const remainingHealth = 100 - player.health;
  3940. const itemsNeeded = Math.ceil(remainingHealth / currentItem.healing);
  3941. return itemsNeeded;
  3942. } else {
  3943. console.error("Item data missing or invalid for player's current item.");
  3944. return -1;
  3945. }
  3946. }
  3947. return 0;
  3948. }
  3949.  
  3950. function getAttacker(damaged) {
  3951. let attackers = enemy.filter(tmp => {
  3952. let rule = {
  3953. three: tmp.attacked
  3954. }
  3955. return rule.three;
  3956. });
  3957. return attackers;
  3958. }
  3959.  
  3960. function healer() {
  3961. for (let i = 0; i < healthBased(); i++) {
  3962. place(0, getAttackDir());
  3963. }
  3964. }
  3965. function healer33() {
  3966. for (let i = 0; i < healthBased(); i++) {
  3967. place(0, getAttackDir());
  3968. }
  3969. }
  3970. function healer1() {
  3971. place(0, getAttackDir());
  3972. return Math.ceil((100 - player.health) / items.list[player.items[0]].healing);
  3973. }
  3974.  
  3975. function noshameheal() {
  3976. place(0, getAttackDir());
  3977. if (player.shameCount >= 5) {
  3978. place(0, getAttackDir());
  3979. healer33();
  3980. } else {
  3981. if (player.skinIndex != 6 && player.skinIndex != 22) {
  3982. healer33();
  3983. buyEquip(6, 0);
  3984. } else {
  3985. const neededHealing = Math.ceil((100 - player.health) / items.list[player.items[0]].healing);
  3986. healer33();
  3987. return neededHealing;
  3988. }
  3989. }
  3990. }
  3991.  
  3992. function antiSyncHealing() {
  3993. if (my.antiSync) return;
  3994. my.antiSync = true;
  3995. const healAnti = setInterval(() => {
  3996. const shameCount = player.shameCount;
  3997. const attackDirection = getAttackDir();
  3998. if (shameCount < 5) {
  3999. place(0, attackDirection);
  4000. } else {
  4001. clearInterval(healAnti);
  4002. my.antiSync = false;
  4003. }
  4004. }, 75);
  4005. setTimeout(() => {
  4006. clearInterval(healAnti);
  4007. my.antiSync = false;
  4008. }, game.tickRate);
  4009. }
  4010.  
  4011.  
  4012. function biomeGear(mover, returns) {
  4013. const riverMinY = config.mapScale / 2 - config.riverWidth / 2;
  4014. const riverMaxY = config.mapScale / 2 + config.riverWidth / 2;
  4015.  
  4016. if (player.y2 >= riverMinY && player.y2 <= riverMaxY) {
  4017. if (returns) return 31;
  4018. buyEquip(31, 0);
  4019. if (returns) return 0;
  4020. }
  4021.  
  4022. if (player.y2 <= config.snowBiomeTop) {
  4023. if (returns) return (enemy && near.dist2 <= 300) ? 6 : 15;
  4024. buyEquip(15, 0);
  4025. if (returns) return 0;
  4026. }
  4027.  
  4028. const defaultEquip = (enemy && near.dist2 <= 300) ? 6 : 12;
  4029. if (returns) return defaultEquip;
  4030. buyEquip(defaultEquip, 0);
  4031.  
  4032. if (returns) return 0;
  4033. }
  4034.  
  4035. class Traps {
  4036. constructor(UTILS, items) {
  4037. this.dist = 0;
  4038. this.aim = 0;
  4039. this.inTrap = false;
  4040. this.replaced = false;
  4041. this.antiTrapped = false;
  4042. this.info = {};
  4043. this.trappling = false;
  4044. this.spikeplacer = false;
  4045. this.spikePlaced = false;
  4046. this.spikSync = false;
  4047.  
  4048. this.notFast = function() {
  4049. return player.weapons[1] === 10 && ((this.info.health > items.weapons[player.weapons[0]].dmg) || player.weapons[0] === 5);
  4050. };
  4051.  
  4052. this.testCanPlace = function(id, first = -(Math.PI / 2), repeat = Math.PI / 2, plus = Math.PI / 18, radian, replacer, yaboi) {
  4053. try {
  4054. let item = items.list[player.items[id]];
  4055. let tmpS = player.scale + item.scale + (item.placeOffset || 0);
  4056. let counts = { attempts: 0, placed: 0 };
  4057. let tmpObjects = [];
  4058.  
  4059. liztobj.forEach(p => {
  4060. tmpObjects.push({
  4061. x: p.x,
  4062. y: p.y,
  4063. active: p.active,
  4064. blocker: p.blocker,
  4065. scale: p.scale,
  4066. isItem: p.isItem,
  4067. type: p.type,
  4068. colDiv: p.colDiv,
  4069. getScale: function(sM = 1, ig) {
  4070. return this.scale * ((this.isItem || [2, 3, 4].includes(this.type)) ? 1 : (0.6 * sM)) * (ig ? 1 : this.colDiv);
  4071. }
  4072. });
  4073. });
  4074.  
  4075. for (let i = first; i < repeat; i += plus) {
  4076. counts.attempts++;
  4077. let relAim = radian + i;
  4078. let tmpX = player.x2 + tmpS * Math.cos(relAim);
  4079. let tmpY = player.y2 + tmpS * Math.sin(relAim);
  4080. let cantPlace = tmpObjects.find(tmp => tmp.active && UTILS.getDistance(tmpX, tmpY, tmp.x, tmp.y) < item.scale + (tmp.blocker ? tmp.blocker : tmp.getScale(0.6, tmp.isItem)));
  4081. if (cantPlace) continue;
  4082. if (item.id !== 18 && tmpY >= config.mapScale / 2 - config.riverWidth / 2 && tmpY <= config.mapScale / 2 + config.riverWidth / 2) continue;
  4083.  
  4084. if (!replacer && yaboi) {
  4085. if (yaboi.inTrap) {
  4086. if (UTILS.getAngleDist(near.aim2 + Math.PI, relAim + Math.PI) <= Math.PI * 1.3) {
  4087. place(2, relAim, 1);
  4088. } else {
  4089. player.items[4] === 15 && place(4, relAim, 1);
  4090. }
  4091. } else {
  4092. if (UTILS.getAngleDist(near.aim2, relAim) <= config.gatherAngle / 2.6) {
  4093. place(2, relAim, 1);
  4094. } else {
  4095. player.items[4] === 15 && place(4, relAim, 1);
  4096. }
  4097. }
  4098. } else {
  4099. place(id, relAim, 1);
  4100. }
  4101.  
  4102. tmpObjects.push({
  4103. x: tmpX,
  4104. y: tmpY,
  4105. active: true,
  4106. blocker: item.blocker,
  4107. scale: item.scale,
  4108. isItem: true,
  4109. type: null,
  4110. colDiv: item.colDiv,
  4111. getScale: function() {
  4112. return this.scale;
  4113. }
  4114. });
  4115.  
  4116. if (UTILS.getAngleDist(near.aim2, relAim) <= 1) {
  4117. counts.placed++;
  4118. }
  4119. }
  4120.  
  4121. if (counts.placed > 0 && replacer && item.dmg) {
  4122. if (near.dist2 <= items.weapons[player.weapons[0]].range + player.scale * 1.8 && configs.spikeTick) {
  4123. instaC.canSpikeTick = true;
  4124. }
  4125. }
  4126. } catch (err) {
  4127. console.error("Error in testCanPlace: ", err);
  4128. }
  4129. };
  4130.  
  4131. this.checkSpikeTick = function() {
  4132. try {
  4133. if (![3, 4, 5].includes(near.primaryIndex)) return false;
  4134. if ((getEl("safeAntiSpikeTick").checked || my.autoPush) ? false : near.primaryIndex === undefined ? true : near.reloads[near.primaryIndex] > game.tickRate) return false;
  4135.  
  4136. if (near.dist2 <= items.weapons[near.primaryIndex || 5].range + near.scale * 1.8) {
  4137. let item = items.list[9];
  4138. let tmpS = near.scale + item.scale + (item.placeOffset || 0);
  4139. let danger = 0;
  4140. let counts = { attempts: 0, block: `unblocked` };
  4141.  
  4142. for (let i = -1; i <= 1; i += 1 / 10) {
  4143. counts.attempts++;
  4144. let relAim = UTILS.getDirect(player, near, 2, 2) + i;
  4145. let tmpX = near.x2 + tmpS * Math.cos(relAim);
  4146. let tmpY = near.y2 + tmpS * Math.sin(relAim);
  4147. let cantPlace = liztobj.find(tmp => tmp.active && UTILS.getDistance(tmpX, tmpY, tmp.x, tmp.y) < item.scale + (tmp.blocker ? tmp.blocker : tmp.getScale(0.6, tmp.isItem)));
  4148. if (cantPlace) continue;
  4149. if (tmpY >= config.mapScale / 2 - config.riverWidth / 2 && tmpY <= config.mapScale / 2 + config.riverWidth / 2) continue;
  4150. danger++;
  4151. counts.block = `blocked`;
  4152. break;
  4153. }
  4154. if (danger) {
  4155. my.anti0Tick = 1;
  4156. return true;
  4157. }
  4158. }
  4159. } catch (err) {
  4160. console.error("Error in checkSpikeTick: ", err);
  4161. }
  4162. return false;
  4163. };
  4164.  
  4165. this.protect = function(aim) {
  4166. if (!configs.antiTrap) return;
  4167. if (player.items[4]) {
  4168. this.testCanPlace(4, -(Math.PI / 2), Math.PI / 2, Math.PI / 18, aim + Math.PI);
  4169. this.antiTrapped = true;
  4170. }
  4171. };
  4172.  
  4173. this.autoPlace = function() {
  4174. if (enemy.length && configs.autoPlace && !instaC.ticking) {
  4175. let nearTrap = gameObjects.find(obj => obj.trap && obj.active && obj.isTeamObject(player) && UTILS.getDist(obj, near, 0, 2) <= near.scale + obj.getScale() + 5);
  4176. let nearDistance = UTILS.getDist(player, near, 0, 2);
  4177.  
  4178. if (nearTrap && nearDistance <= 375) {
  4179. let safePlacement = nearDistance <= 200;
  4180. if (safePlacement) {
  4181. this.testCanPlace(4, 0, Math.PI * 2, Math.PI / 24, near.aim2, 0, { inTrap: true });
  4182. } else if (player.items[4] === 15) {
  4183. this.testCanPlace(4, 0, Math.PI * 2, Math.PI / 24, near.aim2);
  4184. }
  4185. } else if (nearDistance <= 400 && player.items[4] === 15) {
  4186. this.testCanPlace(4, 0, Math.PI * 2, Math.PI / 24, near.aim2);
  4187. }
  4188. }
  4189. };
  4190.  
  4191. this.replacer = function(findObj) {
  4192. if (!findObj || !configs.autoReplace || !inGame || this.antiTrapped) return;
  4193.  
  4194. game.tickBase(() => {
  4195. let objAim = UTILS.getDirect(findObj, player, 0, 2);
  4196. let objDst = UTILS.getDist(findObj, player, 0, 2);
  4197.  
  4198. if (getEl("weaponGrind").checked && objDst <= items.weapons[player.weaponIndex].range + player.scale) return;
  4199.  
  4200. if (objDst <= 250 && near.dist2 <= 250) {
  4201. let danger = this.checkSpikeTick();
  4202. if (!danger && near.dist3 <= items.weapons[near.primaryIndex || 5].range + near.scale * 1.8) {
  4203. for (let i = 0; i < 24; i++) {
  4204. let angle = (Math.PI * 2) * i / 24;
  4205. this.testCanPlace(2, angle, angle + Math.PI / 24, Math.PI / 24, objAim, 1);
  4206. this.testCanPlace(2, Math.PI / 2, Math.PI / 2, Math.PI / 2, near, objAim, 1);
  4207. }
  4208. } else if (player.items[4] === 15) {
  4209. this.testCanPlace(4, 0, Math.PI * 2, Math.PI / 24, objAim, 1);
  4210. }
  4211.  
  4212. this.replaced = true;
  4213. } else if (!this.spikePlaced && near.dist2 <= 250) {
  4214. for (let i = 0; i < 24; i++) {
  4215. let angle = (Math.PI * 2) * i / 24;
  4216. this.testCanPlace(2, angle, angle + Math.PI / 24, Math.PI / 24, objAim, 1);
  4217. }
  4218. this.spikePlaced = true;
  4219. }
  4220. }, 1);
  4221. };
  4222. }
  4223. }
  4224.  
  4225. class Instakill {
  4226. constructor() {
  4227. this.wait = false;
  4228. this.can = false;
  4229. this.isTrue = false;
  4230. this.nobull = false;
  4231. this.ticking = false;
  4232. this.canSpikeTick = false;
  4233. this.startTick = false;
  4234. this.readyTick = false;
  4235. this.canCounter = false;
  4236. this.revTick = false;
  4237. this.syncHit = false;
  4238.  
  4239. this.changeType = function(type) {
  4240. this.wait = false;
  4241. this.isTrue = true;
  4242. my.autoAim = true;
  4243. near.backupNobull = false;
  4244.  
  4245. const actions = {
  4246. "rev": () => this.revInstakill(),
  4247. "nobull": () => this.noBullInstakill(),
  4248. "normal": () => this.normalInstakill(),
  4249. "default": () => {
  4250. setTimeout(() => {
  4251. this.isTrue = false;
  4252. my.autoAim = false;
  4253. }, 50);
  4254. }
  4255. };
  4256.  
  4257. (actions[type] || actions.default)();
  4258. };
  4259.  
  4260. this.revInstakill = function() {
  4261. healer1();
  4262. selectWeapon(player.weapons[1]);
  4263. buyEquip(53, 0);
  4264. sendAutoGather();
  4265. setTimeout(() => {
  4266. selectWeapon(player.weapons[0]);
  4267. buyEquip(7, 0);
  4268. setTimeout(() => {
  4269. sendAutoGather();
  4270. this.isTrue = false;
  4271. my.autoAim = false;
  4272. }, 225);
  4273. }, 100);
  4274. };
  4275.  
  4276. this.noBullInstakill = function() {
  4277. selectWeapon(player.weapons[0]);
  4278. healer1();
  4279. buyEquip(7, 0);
  4280. buyEquip(21, 1);
  4281. sendAutoGather();
  4282. setTimeout(() => {
  4283. selectWeapon(player.weapons[1]);
  4284. buyEquip(player.reloads[53] == 0 ? 53 : 6, 0);
  4285. setTimeout(() => {
  4286. sendAutoGather();
  4287. this.isTrue = false;
  4288. my.autoAim = false;
  4289. }, 255);
  4290. }, 105);
  4291. };
  4292.  
  4293. this.normalInstakill = function() {
  4294. selectWeapon(player.weapons[0]);
  4295. healer1();
  4296. buyEquip(7, 0);
  4297. buyEquip(21, 1);
  4298. sendAutoGather();
  4299. setTimeout(() => {
  4300. selectWeapon(player.weapons[1]);
  4301. buyEquip(player.reloads[53] == 0 ? 53 : 6, 0);
  4302. setTimeout(() => {
  4303. sendAutoGather();
  4304. this.isTrue = false;
  4305. my.autoAim = false;
  4306. }, 255);
  4307. }, 100);
  4308. };
  4309.  
  4310. this.spikeTickType = function() {
  4311. this.isTrue = true;
  4312. my.autoAim = true;
  4313. selectWeapon(player.weapons[0]);
  4314. buyEquip(7, 0);
  4315. sendAutoGather();
  4316. game.tickBase(() => {
  4317. buyEquip(53, 0);
  4318. selectWeapon(player.weapons[0]);
  4319. buyEquip(53, 0);
  4320. game.tickBase(() => {
  4321. sendAutoGather();
  4322. this.isTrue = false;
  4323. my.autoAim = false;
  4324. buyEquip(6, 0);
  4325. buyEquip(21, 1);
  4326. }, 3);
  4327. }, 1);
  4328. };
  4329.  
  4330. this.counterType = function() {
  4331. this.isTrue = true;
  4332. my.autoAim = true;
  4333. my.revAim = true;
  4334. if (!recording) {
  4335. sendChat("SUPER T R A S H counter instakill");
  4336. }
  4337. selectWeapon(player.weapons[1]);
  4338. buyEquip(53, 0);
  4339. buyEquip(19, 1);
  4340. sendAutoGather();
  4341. packet("9", near.aim2, 1);
  4342. game.tickBase(() => {
  4343. my.revAim = false;
  4344. selectWeapon(player.weapons[0]);
  4345. buyEquip(7, 0);
  4346. buyEquip(19, 1);
  4347. packet("9", near.aim2, 1);
  4348. game.tickBase(() => {
  4349. sendAutoGather();
  4350. this.isTrue = false;
  4351. my.autoAim = false;
  4352. packet("9", undefined, 1);
  4353. }, 1);
  4354. }, 1);
  4355. };
  4356.  
  4357. this.antiCounterType = function() {
  4358. my.autoAim = true;
  4359. this.isTrue = true;
  4360. selectWeapon(player.weapons[0]);
  4361. buyEquip(6, 0);
  4362. buyEquip(21, 1);
  4363. io.send("D", near.aim2);
  4364. sendAutoGather();
  4365. game.tickBase(() => {
  4366. buyEquip(player.reloads[53] == 0 ? player.skins[53] ? 53 : 6 : 6, 0);
  4367. buyEquip(21, 1);
  4368. game.tickBase(() => {
  4369. sendAutoGather();
  4370. this.isTrue = false;
  4371. my.autoAim = false;
  4372. }, 1);
  4373. }, 1);
  4374. };
  4375.  
  4376. this.rangeType = function(type) {
  4377. this.isTrue = true;
  4378. my.autoAim = true;
  4379. if (type === "ageInsta") {
  4380. this.ageInstaKill();
  4381. } else {
  4382. this.rangeInstaKill();
  4383. }
  4384. };
  4385.  
  4386. this.ageInstaKill = function() {
  4387. my.ageInsta = false;
  4388. if (player.items[5] === 18) {
  4389. place(5, near.aim2);
  4390. }
  4391. packet("9", undefined, 1);
  4392. buyEquip(22, 0);
  4393. buyEquip(21, 1);
  4394. game.tickBase(() => {
  4395. selectWeapon(player.weapons[1]);
  4396. buyEquip(53, 0);
  4397. buyEquip(21, 1);
  4398. sendAutoGather();
  4399. game.tickBase(() => {
  4400. sendUpgrade(12);
  4401. selectWeapon(player.weapons[1]);
  4402. buyEquip(53, 0);
  4403. buyEquip(21, 1);
  4404. game.tickBase(() => {
  4405. sendUpgrade(15);
  4406. selectWeapon(player.weapons[1]);
  4407. buyEquip(53, 0);
  4408. buyEquip(21, 1);
  4409. game.tickBase(() => {
  4410. sendAutoGather();
  4411. this.isTrue = false;
  4412. my.autoAim = false;
  4413. }, 1);
  4414. }, 1);
  4415. }, 1);
  4416. }, 1);
  4417. };
  4418.  
  4419. this.rangeInstaKill = function() {
  4420. selectWeapon(player.weapons[1]);
  4421. if (player.reloads[53] == 0 && near.dist2 <= 700 && near.skinIndex != 22) {
  4422. buyEquip(53, 0);
  4423. } else {
  4424. buyEquip(20, 0);
  4425. }
  4426. buyEquip(11, 1);
  4427. sendAutoGather();
  4428. game.tickBase(() => {
  4429. sendAutoGather();
  4430. this.isTrue = false;
  4431. my.autoAim = false;
  4432. }, 1);
  4433. };
  4434.  
  4435. this.oneTickType = function() {
  4436. io.send("7113213.29154");
  4437. this.isTrue = true;
  4438. my.autoAim = true;
  4439. selectWeapon(player.weapons[1]);
  4440. buyEquip(53, 0);
  4441. buyEquip(19, 1);
  4442. packet("9", near.aim2, 1);
  4443. if (player.weapons[1] == 15) {
  4444. my.revAim = true;
  4445. sendAutoGather();
  4446. }
  4447. game.tickBase(() => {
  4448. my.revAim = false;
  4449. selectWeapon(player.weapons[0]);
  4450. buyEquip(7, 0);
  4451. buyEquip(19, 1);
  4452. packet("9", near.aim2, 1);
  4453. if (player.weapons[1] != 15) {
  4454. sendAutoGather();
  4455. }
  4456. game.tickBase(() => {
  4457. sendAutoGather();
  4458. this.isTrue = false;
  4459. my.autoAim = false;
  4460. packet("9", undefined, 1);
  4461. }, 1);
  4462. }, 1);
  4463. };
  4464.  
  4465. this.threeOneTickType = function() {
  4466. io.send("Tick2");
  4467. this.isTrue = true;
  4468. my.autoAim = true;
  4469. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4470. biomeGear();
  4471. buyEquip(19, 1);
  4472. packet("9", near.aim2, 1);
  4473. game.tickBase(() => {
  4474. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4475. buyEquip(53, 0);
  4476. buyEquip(19, 1);
  4477. packet("9", near.aim2, 1);
  4478. game.tickBase(() => {
  4479. selectWeapon(player.weapons[0]);
  4480. buyEquip(7, 0);
  4481. buyEquip(19, 1);
  4482. sendAutoGather();
  4483. packet("9", near.aim2, 1);
  4484. game.tickBase(() => {
  4485. sendAutoGather();
  4486. this.isTrue = false;
  4487. my.autoAim = false;
  4488. packet("9", undefined, 1);
  4489. }, 1);
  4490. }, 1);
  4491. }, 1);
  4492. };
  4493.  
  4494. this.kmTickType = function() {
  4495. this.isTrue = true;
  4496. my.autoAim = true;
  4497. my.revAim = true;
  4498. selectWeapon(player.weapons[1]);
  4499. buyEquip(53, 0);
  4500. buyEquip(19, 1);
  4501. sendAutoGather();
  4502. packet("9", near.aim2, 1);
  4503. game.tickBase(() => {
  4504. my.revAim = false;
  4505. selectWeapon(player.weapons[0]);
  4506. buyEquip(7, 0);
  4507. buyEquip(19, 1);
  4508. packet("9", near.aim2, 1);
  4509. game.tickBase(() => {
  4510. sendAutoGather();
  4511. this.isTrue = false;
  4512. my.autoAim = false;
  4513. packet("9", undefined, 1);
  4514. }, 1);
  4515. }, 1);
  4516. };
  4517.  
  4518. this.boostTickType = function() {
  4519. this.isTrue = true;
  4520. my.autoAim = true;
  4521. biomeGear();
  4522. buyEquip(19, 1);
  4523. packet("9", near.aim2, 1);
  4524. game.tickBase(() => {
  4525. if (player.weapons[1] == 15) {
  4526. my.revAim = true;
  4527. }
  4528. selectWeapon(player.weapons[[9, 12, 13, 15].includes(player.weapons[1]) ? 1 : 0]);
  4529. buyEquip(53, 0);
  4530. buyEquip(19, 1);
  4531. if ([9, 12, 13, 15].includes(player.weapons[1])) {
  4532. sendAutoGather();
  4533. }
  4534. packet("9", near.aim2, 1);
  4535. place(4, near.aim2);
  4536. game.tickBase(() => {
  4537. my.revAim = false;
  4538. selectWeapon(player.weapons[0]);
  4539. buyEquip(7, 0);
  4540. buyEquip(19, 1);
  4541. if (![9, 12, 13, 15].includes(player.weapons[1])) {
  4542. sendAutoGather();
  4543. }
  4544. packet("9", near.aim2, 1);
  4545. game.tickBase(() => {
  4546. sendAutoGather();
  4547. this.isTrue = false;
  4548. my.autoAim = false;
  4549. packet("9", undefined, 1);
  4550. }, 1);
  4551. }, 1);
  4552. }, 1);
  4553. };
  4554.  
  4555. this.gotoGoal = function(goto, OT) {
  4556. let slowDists = (weeeee) => weeeee * config.playerScale;
  4557. let goal = {
  4558. a: goto - OT,
  4559. b: goto + OT,
  4560. c: goto - slowDists(1),
  4561. d: goto + slowDists(1),
  4562. e: goto - slowDists(2),
  4563. f: goto + slowDists(2),
  4564. g: goto - slowDists(4),
  4565. h: goto + slowDists(4)
  4566. };
  4567. let bQ = (wwww, awwww) => {
  4568. if (player.y2 >= config.mapScale / 2 - config.riverWidth / 2 && player.y2 <= config.mapScale / 2 + config.riverWidth / 2 && awwww == 0) {
  4569. buyEquip(31, 0);
  4570. } else {
  4571. buyEquip(wwww, awwww);
  4572. }
  4573. };
  4574.  
  4575. if (enemy.length) {
  4576. let dst = near.dist2;
  4577. this.ticking = true;
  4578. if (dst >= goal.a && dst <= goal.b) {
  4579. bQ(22, 0);
  4580. bQ(11, 1);
  4581. if (player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0] || player.buildIndex > -1) {
  4582. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4583. }
  4584. return {
  4585. dir: undefined,
  4586. action: 1
  4587. };
  4588. } else {
  4589. if (dst < goal.a) {
  4590. if (dst >= goal.g) {
  4591. if (dst >= goal.e) {
  4592. if (dst >= goal.c) {
  4593. bQ(40, 0);
  4594. bQ(10, 1);
  4595. if (configs.none) {
  4596. player.buildIndex != player.items[1] && selectToBuild(player.items[1]);
  4597. } else {
  4598. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4599. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4600. }
  4601. }
  4602. } else {
  4603. bQ(22, 0);
  4604. bQ(19, 1);
  4605. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4606. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4607. }
  4608. }
  4609. } else {
  4610. bQ(6, 0);
  4611. bQ(12, 1);
  4612. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4613. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4614. }
  4615. }
  4616. } else {
  4617. biomeGear();
  4618. bQ(11, 1);
  4619. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4620. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4621. }
  4622. }
  4623. return {
  4624. dir: near.aim2 + Math.PI,
  4625. action: 0
  4626. };
  4627. } else if (dst > goal.b) {
  4628. if (dst <= goal.h) {
  4629. if (dst <= goal.f) {
  4630. if (dst <= goal.d) {
  4631. bQ(40, 0);
  4632. bQ(9, 1);
  4633. if (configs.none) {
  4634. player.buildIndex != player.items[1] && selectToBuild(player.items[1]);
  4635. } else {
  4636. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4637. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4638. }
  4639. }
  4640. } else {
  4641. bQ(22, 0);
  4642. bQ(19, 1);
  4643. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4644. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4645. }
  4646. }
  4647. } else {
  4648. bQ(6, 0);
  4649. bQ(12, 1);
  4650. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4651. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4652. }
  4653. }
  4654. } else {
  4655. biomeGear();
  4656. bQ(11, 1);
  4657. if ((player.weaponIndex != player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]) || player.buildIndex > -1) {
  4658. selectWeapon(player.weapons[[10, 14].includes(player.weapons[1]) ? 1 : 0]);
  4659. }
  4660. }
  4661. return {
  4662. dir: near.aim2,
  4663. action: 0
  4664. };
  4665. }
  4666. return {
  4667. dir: undefined,
  4668. action: 0
  4669. };
  4670. }
  4671. } else {
  4672. this.ticking = false;
  4673. return {
  4674. dir: undefined,
  4675. action: 0
  4676. };
  4677. }
  4678. };
  4679.  
  4680. this.bowMovement = function() {
  4681. let moveMent = this.gotoGoal(685, 3);
  4682. if (moveMent.action) {
  4683. if (player.reloads[53] == 0 && !this.isTrue) {
  4684. this.rangeType("ageInsta");
  4685. } else {
  4686. packet("9", moveMent.dir, 1);
  4687. }
  4688. } else {
  4689. packet("9", moveMent.dir, 1);
  4690. }
  4691. };
  4692.  
  4693. this.tickMovement = function() {
  4694. let moveMent = this.gotoGoal(238, 3);
  4695. if (moveMent.action) {
  4696. if (player.reloads[53] == 0 && !this.isTrue) {
  4697. this.boostTickType();
  4698. } else {
  4699. packet("9", moveMent.dir, 1);
  4700. }
  4701. } else {
  4702. packet("9", moveMent.dir, 1);
  4703. }
  4704. };
  4705.  
  4706. this.kmTickMovement = function() {
  4707. let moveMent = this.gotoGoal(240, 3);
  4708. if (moveMent.action) {
  4709. if (near.skinIndex != 22 && player.reloads[53] == 0 && !this.isTrue && ((game.tick - near.poisonTick) % config.serverUpdateRate == 8)) {
  4710. this.kmTickType();
  4711. } else {
  4712. packet("9", moveMent.dir, 1);
  4713. }
  4714. } else {
  4715. packet("9", moveMent.dir, 1);
  4716. }
  4717. };
  4718.  
  4719. this.boostTickMovement = function() {
  4720. let dist = player.weapons[1] == 9 ? 365 : player.weapons[1] == 12 ? 380 : player.weapons[1] == 13 ? 365 : player.weapons[1] == 15 ? 365 : 370;
  4721. let moveMent = this.gotoGoal(372, 3);
  4722. if (moveMent.action) {
  4723. if (player.reloads[53] == 0 && !this.isTrue) {
  4724. this.boostTickType();
  4725. } else {
  4726. packet("9", moveMent.dir, 1);
  4727. }
  4728. } else {
  4729. packet("9", moveMent.dir, 1);
  4730. }
  4731. };
  4732.  
  4733. this.perfCheck = function(pl, nr) {
  4734. if (nr.weaponIndex == 11 && UTILS.getAngleDist(nr.aim2 + Math.PI, nr.d2) <= config.shieldAngle) return false;
  4735. if (![9, 12, 13, 15].includes(player.weapons[1])) return true;
  4736. let pjs = {
  4737. x: nr.x2 + (65 * Math.cos(nr.aim2 + Math.PI)),
  4738. y: nr.y2 + (65 * Math.sin(nr.aim2 + Math.PI))
  4739. };
  4740. if (UTILS.lineInRect(pl.x2 - pl.scale, pl.y2 - pl.scale, pl.x2 + pl.scale, pl.y2 + pl.scale, pjs.x, pjs.y, pjs.x, pjs.y)) {
  4741. return true;
  4742. }
  4743. let finds = ais.filter(tmp => tmp.visible).find((tmp) => {
  4744. if (UTILS.lineInRect(tmp.x2 - tmp.scale, tmp.y2 - tmp.scale, tmp.x2 + tmp.scale, tmp.y2 + tmp.scale, pjs.x, pjs.y, pjs.x, pjs.y)) {
  4745. return true;
  4746. }
  4747. });
  4748. if (finds) return false;
  4749. finds = liztobj.filter(tmp => tmp.active).find((tmp) => {
  4750. let tmpScale = tmp.getScale();
  4751. if (!tmp.ignoreCollision && UTILS.lineInRect(tmp.x - tmpScale, tmp.y - tmpScale, tmp.x + tmpScale, tmp.y + tmpScale, pjs.x, pjs.y, pjs.x, pjs.y)) {
  4752. return true;
  4753. }
  4754. });
  4755. if (finds) return false;
  4756. return true;
  4757. };
  4758. }
  4759. }
  4760.  
  4761. class Autobuy {
  4762. constructor(buyHat, buyAcc) {
  4763. this.hat = function() {
  4764. buyHat.forEach((id) => {
  4765. let find = findID(hats, id);
  4766. if (find && !player.skins[id] && player.points >= find.price) packet("c", 1, id, 0);
  4767. });
  4768. };
  4769. this.acc = function() {
  4770. buyAcc.forEach((id) => {
  4771. let find = findID(accessories, id);
  4772. if (find && !player.tails[id] && player.points >= find.price) packet("c", 1, id, 1);
  4773. });
  4774. };
  4775. }
  4776. };
  4777.  
  4778.  
  4779. class Autoupgrade {
  4780. constructor() {
  4781. this.sb = function(upg) {
  4782. upg(3);
  4783. upg(17);
  4784. upg(31);
  4785. upg(23);
  4786. upg(9);
  4787. upg(38);
  4788. };
  4789. this.kh = function(upg) {
  4790. upg(3);
  4791. upg(17);
  4792. upg(31);
  4793. upg(23);
  4794. upg(10);
  4795. upg(38);
  4796. upg(4);
  4797. upg(25);
  4798. };
  4799. this.pb = function(upg) {
  4800. upg(5);
  4801. upg(17);
  4802. upg(32);
  4803. upg(23);
  4804. upg(9);
  4805. upg(38);
  4806. };
  4807. this.ph = function(upg) {
  4808. upg(5);
  4809. upg(17);
  4810. upg(32);
  4811. upg(23);
  4812. upg(10);
  4813. upg(38);
  4814. upg(28);
  4815. upg(25);
  4816. };
  4817. this.db = function(upg) {
  4818. upg(7);
  4819. upg(17);
  4820. upg(31);
  4821. upg(23);
  4822. upg(9);
  4823. upg(34);
  4824. };
  4825. this.km = function(upg) {
  4826. upg(7);
  4827. upg(17);
  4828. upg(31);
  4829. upg(23);
  4830. upg(10);
  4831. upg(38);
  4832. upg(4);
  4833. upg(15);
  4834. };
  4835. };
  4836. };
  4837.  
  4838. class Damages {
  4839. constructor(items) {
  4840. this.calcDmg = function(dmg, val) {
  4841. return dmg * val;
  4842. };
  4843. this.getAllDamage = function(dmg) {
  4844. return [this.calcDmg(dmg, 0.75), dmg, this.calcDmg(dmg, 1.125), this.calcDmg(dmg, 1.5)];
  4845. };
  4846. this.weapons = [];
  4847. for (let i = 0; i < items.weapons.length; i++) {
  4848. let wp = items.weapons[i];
  4849. let name = wp.name.split(" ").length <= 1 ? wp.name : (wp.name.split(" ")[0] + "_" + wp.name.split(" ")[1]);
  4850. this.weapons.push(this.getAllDamage(i > 8 ? wp.Pdmg : wp.dmg));
  4851. this[name] = this.weapons[i];
  4852. }
  4853. }
  4854. }
  4855.  
  4856. let tmpList = [];
  4857. let UTILS = new Utils();
  4858. let items = new Items();
  4859. let objectManager = new Objectmanager(GameObject, gameObjects, UTILS, config);
  4860. let store = new Store();
  4861. let hats = store.hats;
  4862. let accessories = store.accessories;
  4863. let projectileManager = new ProjectileManager(Projectile, projectiles, players, ais, objectManager, items, config, UTILS);
  4864. let aiManager = new AiManager(ais, AI, players, items, null, config, UTILS);
  4865. let textManager = new Textmanager();
  4866.  
  4867. let traps = new Traps(UTILS, items);
  4868. let instaC = new Instakill();
  4869. let autoBuy = new Autobuy([40, 6, 7, 22, 53, 15, 31], [11, 21, 18, 13]);
  4870. let autoUpgrade = new Autoupgrade();
  4871.  
  4872. let lastDeath;
  4873. let minimapData;
  4874. let mapMarker = {};
  4875. let mapPings = [];
  4876. let tmpPing;
  4877.  
  4878. let antiinsta = true;
  4879. let antiinsta1 = false;
  4880.  
  4881. function sendChat(message) {
  4882. packet("6", message.slice(0, 30));
  4883. }
  4884.  
  4885. let runAtNextTick = [];
  4886.  
  4887. function checkProjectileHolder(x, y, dir, range, speed, indx, layer, sid) {
  4888. let weaponIndx = indx == 0 ? 9 : indx == 2 ? 12 : indx == 3 ? 13 : indx == 5 && 15;
  4889. let projOffset = config.playerScale * 2;
  4890. let projXY = {
  4891. x: indx == 1 ? x : x - projOffset * Math.cos(dir),
  4892. y: indx == 1 ? y : y - projOffset * Math.sin(dir),
  4893. };
  4894. let nearPlayer = players.filter((e) => e.visible && UTILS.getDist(projXY, e, 0, 2) <= e.scale).sort(function(a, b) {
  4895. return UTILS.getDist(projXY, a, 0, 2) - UTILS.getDist(projXY, b, 0, 2);
  4896. })[0];
  4897. if (nearPlayer) {
  4898. if (indx == 1) {
  4899. nearPlayer.shooting[53] = 1;
  4900. } else {
  4901. nearPlayer.shootIndex = weaponIndx;
  4902. nearPlayer.shooting[1] = 1;
  4903. antiProj(nearPlayer, dir, range, speed, indx, weaponIndx);
  4904. }
  4905. }
  4906. }
  4907. let projectileCount = 0;
  4908.  
  4909. function antiProj(tmpObj, dir, range, speed, index, weaponIndex) {
  4910. if (!tmpObj.isTeam(player)) {
  4911. tmpDir = UTILS.getDirect(player, tmpObj, 2, 2);
  4912. if (UTILS.getAngleDist(tmpDir, dir) <= 0.2) {
  4913. tmpObj.bowThreat[weaponIndex]++;
  4914. if (index == 5) {
  4915. projectileCount++;
  4916. }
  4917. setTimeout(() => {
  4918. tmpObj.bowThreat[weaponIndex]--;
  4919. if (index == 5) {
  4920. projectileCount--;
  4921. }
  4922. }, range / speed);
  4923. if (tmpObj.bowThreat[9] >= 1 && (tmpObj.bowThreat[12] >= 1 || tmpObj.bowThreat[15] >= 1)) {
  4924. place(1, tmpObj.aim2);
  4925. my.anti0Tick = 4;
  4926. if (!recording) {
  4927. sendChat("Bow Instas For Fags");
  4928. }
  4929. if (!my.antiSync) {
  4930. antiSyncHealing(4);
  4931. }
  4932. } else {
  4933. if (projectileCount >= 2) {
  4934. place(1, tmpObj.aim2);
  4935. healer();
  4936. if (!recording) {
  4937. sendChat("Sync = gay");
  4938. }
  4939. buyEquip(22, 0);
  4940. buyEquip(13, 1);
  4941. my.anti0Tick = 4;
  4942. if (!my.antiSync) {
  4943. antiSyncHealing(4);
  4944. }
  4945. } else {
  4946. if (projectileCount === 1) {
  4947. buyEquip(6, 0);
  4948. buyEquip(13, 1);
  4949. } else {
  4950. if (projectileCount >= 2) {
  4951. return Math.ceil((100 - player.health) / items.list[player.items[0]].healing);
  4952. healer();
  4953. buyEquip(6, 0);
  4954. }
  4955. }
  4956. }
  4957. }
  4958. }
  4959. }
  4960. }
  4961.  
  4962. function showItemInfo(item, isWeapon, isStoreItem) {
  4963. if (player && item) {
  4964. UTILS.removeAllChildren(itemInfoHolder);
  4965. itemInfoHolder.classList.add("visible");
  4966. UTILS.generateElement({
  4967. id: "itemInfoName",
  4968. text: UTILS.capitalizeFirst(item.name),
  4969. parent: itemInfoHolder
  4970. });
  4971. UTILS.generateElement({
  4972. id: "itemInfoDesc",
  4973. text: item.desc,
  4974. parent: itemInfoHolder
  4975. });
  4976. if (isStoreItem) {
  4977.  
  4978. } else if (isWeapon) {
  4979. UTILS.generateElement({
  4980. class: "itemInfoReq",
  4981. text: !item.type ? "primary" : "secondary",
  4982. parent: itemInfoHolder
  4983. });
  4984. } else {
  4985. for (let i = 0; i < item.req.length; i += 2) {
  4986. UTILS.generateElement({
  4987. class: "itemInfoReq",
  4988. html: item.req[i] + "<span class='itemInfoReqVal'> x" + item.req[i + 1] + "</span>",
  4989. parent: itemInfoHolder
  4990. });
  4991. }
  4992. if (item.group.limit) {
  4993. UTILS.generateElement({
  4994. class: "itemInfoLmt",
  4995. text: (player.itemCounts[item.group.id] || 0) + "/" + (config.isSandbox ? 99 : item.group.limit),
  4996. parent: itemInfoHolder
  4997. });
  4998. }
  4999. }
  5000. } else {
  5001. itemInfoHolder.classList.remove("visible");
  5002. }
  5003. }
  5004.  
  5005. window.addEventListener("resize", UTILS.checkTrusted(resize));
  5006.  
  5007. function resize() {
  5008. screenWidth = window.innerWidth;
  5009. screenHeight = window.innerHeight;
  5010. let scaleFillNative = Math.max(screenWidth / maxScreenWidth, screenHeight / maxScreenHeight) * pixelDensity;
  5011. gameCanvas.width = screenWidth * pixelDensity;
  5012. gameCanvas.height = screenHeight * pixelDensity;
  5013. gameCanvas.style.width = screenWidth + "px";
  5014. gameCanvas.style.height = screenHeight + "px";
  5015. mainContext.setTransform(
  5016. scaleFillNative, 0,
  5017. 0, scaleFillNative,
  5018. (screenWidth * pixelDensity - (maxScreenWidth * scaleFillNative)) / 2,
  5019. (screenHeight * pixelDensity - (maxScreenHeight * scaleFillNative)) / 2
  5020. );
  5021. }
  5022. resize();
  5023.  
  5024. var usingTouch;
  5025. const mals = document.getElementById('touch-controls-fullscreen');
  5026. mals.style.display = 'block';
  5027. mals.addEventListener("mousemove", gameInput, false);
  5028.  
  5029. function gameInput(e) {
  5030. mouseX = e.clientX;
  5031. mouseY = e.clientY;
  5032. }
  5033. let clicks = {
  5034. left: false,
  5035. middle: false,
  5036. right: false,
  5037. };
  5038. mals.addEventListener("mousedown", mouseDown, false);
  5039.  
  5040. function mouseDown(e) {
  5041. if (attackState != 1) {
  5042. attackState = 1;
  5043. if (e.button == 0) {
  5044. clicks.left = true;
  5045. } else if (e.button == 1) {
  5046. clicks.middle = true;
  5047. } else if (e.button == 2) {
  5048. clicks.right = true;
  5049. }
  5050. }
  5051. }
  5052. mals.addEventListener("mouseup", UTILS.checkTrusted(mouseUp));
  5053.  
  5054. function mouseUp(e) {
  5055. if (attackState != 0) {
  5056. attackState = 0;
  5057. if (e.button == 0) {
  5058. clicks.left = false;
  5059. } else if (e.button == 1) {
  5060. clicks.middle = false;
  5061. } else if (e.button == 2) {
  5062. clicks.right = false;
  5063. }
  5064. }
  5065. }
  5066. mals.addEventListener("wheel", wheel, false);
  5067.  
  5068. function wheel(e) {
  5069. if(player.shameCount > 1) {
  5070. buyEquip(7, 0);
  5071. } else {
  5072. buyEquip(6, 0);
  5073. }
  5074. }
  5075.  
  5076.  
  5077. function getMoveDir() {
  5078. let dx = 0;
  5079. let dy = 0;
  5080. for (let key in moveKeys) {
  5081. let tmpDir = moveKeys[key];
  5082. dx += !!keys[key] * tmpDir[0];
  5083. dy += !!keys[key] * tmpDir[1];
  5084. }
  5085. return dx == 0 && dy == 0 ? undefined : Math.atan2(dy, dx);
  5086. }
  5087.  
  5088. function getSafeDir() {
  5089. if (!player) {
  5090. return 0;
  5091. }
  5092. if (!player.lockDir) {
  5093. lastDir = Math.atan2(mouseY - (screenHeight / 2), mouseX - (screenWidth / 2));
  5094. }
  5095. return lastDir || 0;
  5096. }
  5097.  
  5098. let plusDir = 0;
  5099. let lastSpin = Date.now();
  5100.  
  5101. function getAttackDir() {
  5102. const now = Date.now();
  5103.  
  5104. if (player && now - lastSpin >= 235 && !(clicks.right || clicks.left)) {
  5105. plusDir += Math.random() * (Math.PI * 2);
  5106. lastSpin = now;
  5107. }
  5108.  
  5109. if (!player) {
  5110. return "0";
  5111. }
  5112.  
  5113. const primaryWeapon = player.weapons[0];
  5114. const secondaryWeapon = player.weapons[1];
  5115. const primaryReload = player.reloads[primaryWeapon];
  5116. const secondaryReload = player.reloads[secondaryWeapon];
  5117. const primaryInRange = near.dist2 <= items.weapons[primaryWeapon].range + near.scale * 1.8;
  5118.  
  5119. function getBestTargetDirection() {
  5120. if (enemy.length) {
  5121. return near.aim2;
  5122. }
  5123. return getSafeDir();
  5124. }
  5125.  
  5126. if (my.autoAim || (clicks.left || (useWasd && primaryInRange && !traps.inTrap)) && primaryReload === 0) {
  5127. lastDir = getBestTargetDirection();
  5128. } else if (clicks.right && (secondaryWeapon === 10 ? secondaryReload : primaryReload) === 0) {
  5129. lastDir = getSafeDir();
  5130. } else if (traps.inTrap) {
  5131. lastDir = traps.aim;
  5132. } else if (!player.lockDir) {
  5133. if (!autos.stopspin || !useWasd) {
  5134. lastDir = getSafeDir();
  5135. }
  5136. }
  5137.  
  5138. lastDir = smoothTransition(lastDir);
  5139.  
  5140. return lastDir;
  5141. }
  5142.  
  5143. function smoothTransition(targetDir) {
  5144. const smoothingFactor = 0.1;
  5145. return (1 - smoothingFactor) * lastDir + smoothingFactor * targetDir;
  5146. }
  5147.  
  5148. function getVisualDir() {
  5149. if (!player) {
  5150. return 0;
  5151. }
  5152. lastDir = getSafeDir();
  5153. return lastDir || 0;
  5154. }
  5155.  
  5156. function keysActive() {
  5157. return (allianceMenu.style.display != "block" &&
  5158. chatHolder.style.display != "block");
  5159. }
  5160.  
  5161. function keyDown(event) {
  5162. let keyNum = event.which || event.keyCode || 0;
  5163. if (player && player.alive && keysActive()) {
  5164. if (!keys[keyNum]) {
  5165. keys[keyNum] = 1;
  5166. macro[event.key] = 1;
  5167. if (keyNum == 27) {
  5168. openMenu = !openMenu;
  5169. $("#menuDiv").toggle();
  5170. } else if (keyNum == 109) {
  5171. recording = !recording;
  5172. console.log(recording);
  5173. } else if (keyNum == 69) {
  5174. sendAutoGather();
  5175. } else if (keyNum == 67) {
  5176. updateMapMarker();
  5177. } else if (player.weapons[keyNum - 49] != undefined) {
  5178. player.weaponCode = player.weapons[keyNum - 49];
  5179. } else if (moveKeys[keyNum]) {
  5180. sendMoveDir();
  5181. } else if (event.key == "m") {
  5182. mills.placeSpawnPads = !mills.placeSpawnPads;
  5183. } else if (event.key == "z") {
  5184. mills.place = !mills.place;
  5185. } else if (event.key == "²") {
  5186. io.send("6", "HaxBountyHunter AI")
  5187. } else if (event.key == "Z") {
  5188. typeof window.debug == "function" && window.debug();
  5189. } else if (keyNum == 32) {
  5190. packet("F", 1, getSafeDir(), 1);
  5191. packet("F", 0, getSafeDir(), 1);
  5192. }
  5193. }
  5194. }
  5195. }
  5196.  
  5197. addEventListener("keydown", UTILS.checkTrusted(keyDown));
  5198.  
  5199. function keyUp(event) {
  5200. if (player && player.alive) {
  5201. let keyNum = event.which || event.keyCode || 0;
  5202. if (keysActive()) {
  5203. if (keys[keyNum]) {
  5204. keys[keyNum] = 0;
  5205. macro[event.key] = 0;
  5206. if (moveKeys[keyNum]) {
  5207. sendMoveDir();
  5208. } else if (event.key == ",") {
  5209. player.sync = false;
  5210. }
  5211. }
  5212. }
  5213. }
  5214. }
  5215.  
  5216.  
  5217. window.addEventListener("keyup", UTILS.checkTrusted(keyUp));
  5218.  
  5219. function sendMoveDir() {
  5220. if(found) {
  5221. packet("9", undefined, 1);
  5222. } else {
  5223. let newMoveDir = getMoveDir();
  5224. if (lastMoveDir == undefined || newMoveDir == undefined || Math.abs(newMoveDir - lastMoveDir) > 0.3) {
  5225. if (!my.autoPush && !found) {
  5226. packet("9", newMoveDir, 1);
  5227. }
  5228. lastMoveDir = newMoveDir;
  5229. }
  5230. }
  5231. }
  5232.  
  5233. function bindEvents() {}
  5234. bindEvents();
  5235.  
  5236. let isItemSetted = [];
  5237.  
  5238. function updateItemCountDisplay(index = undefined) {
  5239. for (let i = 3; i < items.list.length; ++i) {
  5240. let id = items.list[i].group.id;
  5241. let tmpI = items.weapons.length + i;
  5242. if (!isItemSetted[tmpI]) {
  5243. isItemSetted[tmpI] = document.createElement("div");
  5244. isItemSetted[tmpI].id = "itemCount" + tmpI;
  5245. getEl("actionBarItem" + tmpI).appendChild(isItemSetted[tmpI]);
  5246. isItemSetted[tmpI].style = `
  5247. display: block;
  5248. position: absolute;
  5249. padding-left: 5px;
  5250. font-size: 2em;
  5251. color: #880808;
  5252. `;
  5253. isItemSetted[tmpI].innerHTML = player.itemCounts[id] || 0;
  5254. } else {
  5255. if (index == id) isItemSetted[tmpI].innerHTML = player.itemCounts[index] || 0;
  5256. }
  5257. }
  5258. }
  5259.  
  5260. var retrappable = false;
  5261. function autoPush() {
  5262. retrappable = true;
  5263. let nearTrap = gameObjects.filter(tmp => tmp.trap && tmp.active && tmp.isTeamObject(player) && UTILS.getDist(tmp, near, 0, 2) <= (near.scale + tmp.getScale() + 5)).sort(function(a, b) {
  5264. return UTILS.getDist(a, near, 0, 2) - UTILS.getDist(b, near, 0, 2);
  5265. })[0];
  5266. if (nearTrap) {
  5267. let spike = gameObjects.filter(tmp => tmp.dmg && tmp.active && tmp.isTeamObject(player) && UTILS.getDist(tmp, nearTrap, 0, 0) <= (near.scale + nearTrap.scale + tmp.scale)).sort(function(a, b) {
  5268. return UTILS.getDist(a, near, 0, 2) - UTILS.getDist(b, near, 0, 2);
  5269. })[0];
  5270. if (spike) {
  5271. let pos = {
  5272. x: spike.x + (250 * Math.cos(UTILS.getDirect(near, spike, 2, 0))),
  5273. y: spike.y + (250 * Math.sin(UTILS.getDirect(near, spike, 2, 0))),
  5274. x2: spike.x + ((UTILS.getDist(near, spike, 2, 0) + player.scale) * Math.cos(UTILS.getDirect(near, spike, 2, 0))),
  5275. y2: spike.y + ((UTILS.getDist(near, spike, 2, 0) + player.scale) * Math.sin(UTILS.getDirect(near, spike, 2, 0)))
  5276. };
  5277. let finds = gameObjects.filter(tmp => tmp.active).find((tmp) => {
  5278. let tmpScale = tmp.getScale();
  5279. if (!tmp.ignoreCollision && UTILS.lineInRect(tmp.x - tmpScale, tmp.y - tmpScale, tmp.x + tmpScale, tmp.y + tmpScale, player.x2, player.y2, pos.x2, pos.y2)) {
  5280. return true;
  5281. }
  5282. });
  5283. if (finds) {
  5284. if (my.autoPush) {
  5285. my.autoPush = false;
  5286. packet("9", lastMoveDir || undefined, 1);
  5287. }
  5288. } else {
  5289. my.autoPush = true;
  5290. my.pushData = {
  5291. x: spike.x,
  5292. y: spike.y,
  5293. x2: pos.x2,
  5294. y2: pos.y2
  5295. };
  5296. let scale = (player.scale / 10);
  5297. if (UTILS.lineInRect(player.x2 - scale, player.y2 - scale, player.x2 + scale, player.y2 + scale, near.x2, near.y2, pos.x, pos.y)) {
  5298. packet("9", near.aim2, 1);
  5299. } else {
  5300. packet("9", UTILS.getDirect(pos, player, 2, 2), 1);
  5301. }
  5302. }
  5303. } else {
  5304. if (my.autoPush) {
  5305. my.autoPush = false;
  5306. packet("9", lastMoveDir || undefined, 1);
  5307. }
  5308. }
  5309. } else {
  5310. if (my.autoPush) {
  5311. my.autoPush = false;
  5312. packet("9", lastMoveDir || undefined, 1);
  5313. }
  5314. }
  5315. }
  5316.  
  5317. function addDeadPlayer(tmpObj) {
  5318. deadPlayers.push(new DeadPlayer(tmpObj.x, tmpObj.y, tmpObj.dir, tmpObj.buildIndex, tmpObj.weaponIndex, tmpObj.weaponVariant, tmpObj.skinColor, tmpObj.scale, tmpObj.name));
  5319. }
  5320.  
  5321.  
  5322. function setInitData(data) {
  5323. alliances = data.teams;
  5324. }
  5325.  
  5326. function setupGame(yourSID) {
  5327. keys = {};
  5328. macro = {};
  5329. playerSID = yourSID;
  5330. attackState = 0;
  5331. inGame = true;
  5332. musicToggle()
  5333. packet("F", 0, getAttackDir(), 1);
  5334. my.ageInsta = true;
  5335. if (firstSetup) {
  5336. firstSetup = false;
  5337. gameObjects.length = 0;
  5338. liztobj.length = 0;
  5339. }
  5340. }
  5341.  
  5342. let originalName = null;
  5343.  
  5344. function addPlayer(data, isYou) {
  5345. let tmpPlayer = findPlayerByID(data[0]);
  5346. if (!tmpPlayer) {
  5347. tmpPlayer = new Player(data[0], data[1], config, UTILS, projectileManager,
  5348. objectManager, players, ais, items, hats, accessories);
  5349. players.push(tmpPlayer);
  5350. }
  5351. tmpPlayer.spawn(isYou ? true : null);
  5352. tmpPlayer.visible = false;
  5353. tmpPlayer.oldPos = {
  5354. x2: undefined,
  5355. y2: undefined
  5356. };
  5357. tmpPlayer.x2 = undefined;
  5358. tmpPlayer.y2 = undefined;
  5359. tmpPlayer.x3 = undefined;
  5360. tmpPlayer.y3 = undefined;
  5361. tmpPlayer.setData(data);
  5362. if (isYou) {
  5363. if (!player) {
  5364. window.prepareUI(tmpPlayer);
  5365. }
  5366. player = tmpPlayer;
  5367. camX = player.x;
  5368. camY = player.y;
  5369. originalName = player.name;
  5370. my.lastDir = 0;
  5371. updateItems();
  5372. updateAge();
  5373. updateItemCountDisplay();
  5374. if (player.skins[7]) {
  5375. my.reSync = true;
  5376. }
  5377. }
  5378. }
  5379.  
  5380. function removePlayer(id) {
  5381. for (let i = 0; i < players.length; i++) {
  5382. if (players[i].id == id) {
  5383. players.splice(i, 1);
  5384. break;
  5385. }
  5386. }
  5387. }
  5388.  
  5389. function updateHealth(sid, value) {
  5390. let tmpObj = findPlayerBySID(sid);
  5391. if (tmpObj) {
  5392. tmpObj.oldHealth = tmpObj.health;
  5393. tmpObj.health = value;
  5394. tmpObj.judgeShame();
  5395.  
  5396. if (tmpObj.oldHealth > tmpObj.health) {
  5397. tmpObj.timeDamaged = Date.now();
  5398. tmpObj.damaged = tmpObj.oldHealth - tmpObj.health;
  5399. let damaged = tmpObj.damaged;
  5400.  
  5401. if (tmpObj.health <= 0 && !tmpObj.death) {
  5402. tmpObj.death = true;
  5403. addDeadPlayer(tmpObj);
  5404. }
  5405.  
  5406. if (tmpObj === player) {
  5407. handlePlayerDamage(tmpObj, damaged);
  5408. } else {
  5409. handleNonPlayerDamage(tmpObj);
  5410. }
  5411. }
  5412. }
  5413. }
  5414.  
  5415. function handlePlayerDamage(player, damaged) {
  5416. let bullTicked = false;
  5417. let autoheal = false;
  5418. let antiinsta = true, antiinsta1 = true, antiinsta4 = true;
  5419.  
  5420. if(player.shameCount > 1) {
  5421. buyEquip(7, 0);
  5422. buyEquip(13, 1);
  5423. } else {
  5424. if(player.lastshamecount != 1 || player.lastshamecount != 2 || player.lastshamecount != 3 || player.lastshamecount != 4 || player.lastshamecount != 5 || player.lastshamecount != 6 || player.lastshamecount == 0) {
  5425. buyEquip(6, 0);
  5426. }
  5427. }
  5428.  
  5429. if (inGame) {
  5430. let attackers = getAttacker(damaged);
  5431. let gearDmgs = [0.25, 0.45].map((val) => val * items.weapons[player.weapons[0]].dmg);
  5432. let includeSpikeDmgs = near.length ? !bullTicked && (gearDmgs.includes(damaged) && near[0].skinIndex == 11 && near[0].tailIndex == 21) : false;
  5433. let healTimeout = 140 - window.ping;
  5434.  
  5435. if (damaged >= 0 && damaged <= 66 && player.shameCount === 4 && player.primaryIndex !== "4") {
  5436. autoheal = true;
  5437. antiinsta = false;
  5438. antiinsta1 = false;
  5439. antiinsta4 = false;
  5440. } else {
  5441. if (player.shameCount !== 4) {
  5442. autoheal = false;
  5443. antiinsta = true;
  5444. antiinsta4 = true;
  5445. }
  5446. }
  5447.  
  5448. if (damaged <= 66 && player.shameCount === 3 && player.primaryIndex !== "4") {
  5449. antiinsta = false;
  5450. } else {
  5451. if (player.shameCount !== 3) {
  5452. antiinsta = true;
  5453. }
  5454. }
  5455.  
  5456. if (damaged <= 66 && player.shameCount === 4 && player.primaryIndex !== "4") {
  5457. antiinsta1 = true;
  5458. } else {
  5459. if (player.shameCount !== 4) {
  5460. antiinsta1 = false;
  5461. }
  5462. }
  5463.  
  5464. if (damaged >= 0 && damaged <= 90 && player.shameCount === 2) {
  5465. antiinsta4 = false;
  5466. } else {
  5467. if (player.shameCount !== 3) {
  5468. antiinsta4 = true;
  5469. }
  5470. }
  5471.  
  5472. if (damaged >= 0 && damaged <= 90 && !antiinsta) {
  5473. if (player.shameCount === 3) {
  5474. antiinsta1 = true;
  5475. } else {
  5476. antiinsta1 = false;
  5477. }
  5478. }
  5479.  
  5480. if (damaged <= 66 && player.skinIndex != 6 && enemy.weaponIndex === 4) {
  5481. game.tickBase(() => {
  5482. healer1();
  5483. }, 2);
  5484. }
  5485.  
  5486. if (damaged >= (includeSpikeDmgs ? 8 : 20) && player.damageThreat >= 20 && antiinsta4 && (game.tick - player.antiTimer) > 1) {
  5487. if (player.reloads[53] == 0 && player.reloads[player.weapons[1]] == 0) {
  5488. player.canEmpAnti = true;
  5489. } else {
  5490. player.soldierAnti = true;
  5491. }
  5492. player.antiTimer = game.tick;
  5493. let shame = player.weapons[0] == 4 ? 2 : 5;
  5494. if (player.shameCount < shame) {
  5495. healer();
  5496. } else {
  5497. game.tickBase(() => {
  5498. healer();
  5499. }, 2);
  5500. }
  5501. if (damaged >= (includeSpikeDmgs ? 8 : 20) && player.damageThreat >= 20 && autoheal) {
  5502. setTimeout(() => {
  5503. healer();
  5504. }, 120);
  5505. }
  5506. } else {
  5507. game.tickBase(() => {
  5508. healer();
  5509. }, 2);
  5510. }
  5511.  
  5512. if (damaged >= 20 && player.skinIndex == 11 && player.shameCount <= 3) {
  5513. instaC.canCounter = true;
  5514. }
  5515. }
  5516. }
  5517.  
  5518. function handleNonPlayerDamage(tmpObj) {
  5519. if (!tmpObj.setPoisonTick && (tmpObj.damaged == 5 || (tmpObj.latestTail == 13 && tmpObj.damaged == 2))) {
  5520. tmpObj.setPoisonTick = true;
  5521. }
  5522. }
  5523.  
  5524. function killPlayer(sid) {
  5525. inGame = false;
  5526. lastDeath = {
  5527. x: player.x,
  5528. y: player.y,
  5529. };
  5530. musicToggle();
  5531. }
  5532.  
  5533. function updateItemCounts(index, value) {
  5534. if (player) {
  5535. player.itemCounts[index] = value;
  5536. updateItemCountDisplay(index);
  5537. }
  5538. }
  5539.  
  5540. function updateAge(xp, mxp, age) {
  5541. if (xp != undefined) {
  5542. player.XP = xp;
  5543. }
  5544. if (mxp != undefined) {
  5545. player.maxXP = mxp;
  5546. }
  5547. if (age != undefined) {
  5548. player.age = age;
  5549. }
  5550. }
  5551.  
  5552. function updateUpgrades(points, age) {
  5553. player.upgradePoints = points;
  5554. player.upgrAge = age;
  5555. if (points > 0) {
  5556. tmpList.length = 0;
  5557. UTILS.removeAllChildren(upgradeHolder);
  5558. for (let i = 0; i < items.weapons.length; ++i) {
  5559. if (items.weapons[i].age == age && (items.weapons[i].pre == undefined || player.weapons.indexOf(items.weapons[i].pre) >= 0)) {
  5560. let e = UTILS.generateElement({
  5561. id: "upgradeItem" + i,
  5562. class: "actionBarItem",
  5563. onmouseout: function() {
  5564. showItemInfo();
  5565. },
  5566. parent: upgradeHolder
  5567. });
  5568. e.style.backgroundImage = getEl("actionBarItem" + i).style.backgroundImage;
  5569. tmpList.push(i);
  5570. }
  5571. }
  5572. for (let i = 0; i < items.list.length; ++i) {
  5573. if (items.list[i].age == age && (items.list[i].pre == undefined || player.items.indexOf(items.list[i].pre) >= 0)) {
  5574. let tmpI = (items.weapons.length + i);
  5575. let e = UTILS.generateElement({
  5576. id: "upgradeItem" + tmpI,
  5577. class: "actionBarItem",
  5578. onmouseout: function() {
  5579. showItemInfo();
  5580. },
  5581. parent: upgradeHolder
  5582. });
  5583. e.style.backgroundImage = getEl("actionBarItem" + tmpI).style.backgroundImage;
  5584. tmpList.push(tmpI);
  5585. }
  5586. }
  5587. for (let i = 0; i < tmpList.length; i++) {
  5588. (function(i) {
  5589. let tmpItem = getEl('upgradeItem' + i);
  5590. tmpItem.onmouseover = function() {
  5591. if (items.weapons[i]) {
  5592. showItemInfo(items.weapons[i], true);
  5593. } else {
  5594. showItemInfo(items.list[i - items.weapons.length]);
  5595. }
  5596. };
  5597. tmpItem.onclick = UTILS.checkTrusted(function() {
  5598. packet("H", i);
  5599. });
  5600. UTILS.hookTouchEvents(tmpItem);
  5601. })(tmpList[i]);
  5602. }
  5603. if (tmpList.length) {
  5604. upgradeHolder.style.display = "block";
  5605. upgradeCounter.style.display = "block";
  5606. upgradeCounter.innerHTML = "SELECT ITEMS (" + points + ")";
  5607. } else {
  5608. upgradeHolder.style.display = "none";
  5609. upgradeCounter.style.display = "none";
  5610. showItemInfo();
  5611. }
  5612. } else {
  5613. upgradeHolder.style.display = "none";
  5614. upgradeCounter.style.display = "none";
  5615. showItemInfo();
  5616. }
  5617. }
  5618.  
  5619. const killObject = (sid) => {
  5620. const findObj = findObjectBySid(sid);
  5621. objectManager.disableBySid(sid);
  5622.  
  5623. if (!player) return;
  5624.  
  5625. const index = breakObjects.findIndex(obj => obj.sid === sid);
  5626. if (index !== -1) {
  5627. breakObjects.splice(index, 1);
  5628. }
  5629.  
  5630. traps.replacer(findObj);
  5631. };
  5632.  
  5633. function killObjects(sid) {
  5634. if (player) objectManager.removeAllItems(sid);
  5635. }
  5636.  
  5637. function setTickout(doo, timeout) {
  5638. if (!ticks.manage[ticks.tick + timeout]) {
  5639. ticks.manage[ticks.tick + timeout] = [doo];
  5640. } else {
  5641. ticks.manage[ticks.tick + timeout].push(doo);
  5642. }
  5643. }
  5644.  
  5645. function caf(e, t) {
  5646. try {
  5647. return Math.atan2((t.y2 || t.y) - (e.y2 || e.y), (t.x2 || t.x) - (e.x2 || e.x));
  5648. } catch (e) {
  5649. return 0;
  5650. }
  5651. }
  5652.  
  5653. let found = false;
  5654. let autoQ = false;
  5655.  
  5656. let autos = {
  5657. insta: {
  5658. todo: false,
  5659. wait: false,
  5660. count: 4,
  5661. shame: 5
  5662. },
  5663. bull: false,
  5664. antibull: 0,
  5665. reloaded: false,
  5666. stopspin: true
  5667. }
  5668.  
  5669. const inGameAudio = new Audio("https://cdn.discordapp.com/attachments/1254124674158297131/1254162245781553162/Mesmerizer.MP3?ex=667b201c&is=6679ce9c&hm=61133eb8e6729d6e288168f0f26676122f722daada7adf114f94b1ef72cb2501&");
  5670. const outGameAudio = new Audio("https://cdn.discordapp.com/attachments/1254124674158297131/1254157684811235420/-_Nostalgic_Arrange.mp3?ex=667a731d&is=6679219d&hm=0c248a31c01dc5a56da543529d2356e5ca133e30e29faccddafb2d539bfbaf9e&");
  5671. inGameAudio.loop = true;
  5672. outGameAudio.loop = true;
  5673. outGameAudio.autoplay = true;
  5674.  
  5675. function fadeOut(audio, callback) {
  5676. let volume = audio.volume;
  5677. const fadeInterval = setInterval(() => {
  5678. if (volume >= 0.4) {
  5679. volume -= 0.02;
  5680. audio.volume = Math.max(volume, 0).toFixed(1);
  5681. } else {
  5682. clearInterval(fadeInterval);
  5683. audio.pause();
  5684. audio.volume = 0.4;
  5685. if (callback) callback();
  5686. }
  5687. }, 30);
  5688. }
  5689.  
  5690. function fadeIn(audio) {
  5691. let volume = 0;
  5692. audio.volume = volume;
  5693. audio.play();
  5694. const fadeInterval = setInterval(() => {
  5695. if (volume <= 0.4) {
  5696. volume += 0.02;
  5697. audio.volume = Math.min(volume, 1).toFixed(1);
  5698. } else {
  5699. clearInterval(fadeInterval);
  5700. audio.volume = 0.4;
  5701. }
  5702. }, 30);
  5703. }
  5704.  
  5705. function musicToggle() {
  5706. if (inGame) {
  5707. fadeOut(outGameAudio, () => fadeIn(inGameAudio));
  5708. } else {
  5709. fadeOut(inGameAudio, () => fadeIn(outGameAudio));
  5710. }
  5711. }
  5712.  
  5713. function updatePlayers(data) {
  5714. const shameCounts = [1, 2, 3, 4, 5, 6];
  5715. if (player.shameCount > 1) {
  5716. buyEquip(7, 0);
  5717. buyEquip(13, 1);
  5718. } else {
  5719. if (!shameCounts.includes(player.lastshamecount) || player.lastshamecount === 0) {
  5720. buyEquip(6, 0);
  5721. }
  5722. }
  5723. player.lastshamecount = player.shameCount;
  5724. function getAngleDifference(angle1, angle2) {
  5725. angle1 = angle1 % (2 * Math.PI);
  5726. angle2 = angle2 % (2 * Math.PI);
  5727. let diff = Math.abs(angle1 - angle2);
  5728. if (diff > Math.PI) {
  5729. diff = (2 * Math.PI) - diff;
  5730. }
  5731. return diff;
  5732. }
  5733. game.tick++;
  5734. enemy = [];
  5735. nears = [];
  5736. near = [];
  5737. game.tickSpeed = performance.now() - game.lastTick;
  5738. game.lastTick = performance.now();
  5739. players.forEach((tmp) => {
  5740. tmp.forcePos = !tmp.visible;
  5741. tmp.visible = false;
  5742. if((tmp.timeHealed - tmp.timeDamaged)>0 && tmp.lastshamecount<tmp.shameCount) {
  5743. tmp.pinge = (tmp.timeHealed - tmp.timeDamaged);
  5744. }
  5745. });
  5746. for (let i = 0; i < data.length;) {
  5747. tmpObj = findPlayerBySID(data[i]);
  5748. if (tmpObj) {
  5749. tmpObj.t1 = (tmpObj.t2 === undefined) ? game.lastTick : tmpObj.t2;
  5750. tmpObj.t2 = game.lastTick;
  5751. tmpObj.oldPos.x2 = tmpObj.x2;
  5752. tmpObj.oldPos.y2 = tmpObj.y2;
  5753. tmpObj.x1 = tmpObj.x;
  5754. tmpObj.y1 = tmpObj.y;
  5755. tmpObj.x2 = data[i + 1];
  5756. tmpObj.y2 = data[i + 2];
  5757. tmpObj.x3 = tmpObj.x2 + (tmpObj.x2 - tmpObj.oldPos.x2);
  5758. tmpObj.y3 = tmpObj.y2 + (tmpObj.y2 - tmpObj.oldPos.y2);
  5759. tmpObj.d1 = (tmpObj.d2 === undefined) ? data[i + 3] : tmpObj.d2;
  5760. tmpObj.d2 = data[i + 3];
  5761. tmpObj.dt = 0;
  5762. tmpObj.buildIndex = data[i + 4];
  5763. tmpObj.weaponIndex = data[i + 5];
  5764. tmpObj.weaponVariant = data[i + 6];
  5765. tmpObj.team = data[i + 7];
  5766. tmpObj.isLeader = data[i + 8];
  5767. tmpObj.oldSkinIndex = tmpObj.skinIndex;
  5768. tmpObj.oldTailIndex = tmpObj.tailIndex;
  5769. tmpObj.skinIndex = data[i + 9];
  5770. tmpObj.tailIndex = data[i + 10];
  5771. tmpObj.iconIndex = data[i + 11];
  5772. tmpObj.zIndex = data[i + 12];
  5773. tmpObj.visible = true;
  5774. tmpObj.update(game.tickSpeed);
  5775. tmpObj.dist2 = UTILS.getDist(tmpObj, player, 2, 2);
  5776. tmpObj.aim2 = UTILS.getDirect(tmpObj, player, 2, 2);
  5777. tmpObj.dist3 = UTILS.getDist(tmpObj, player, 3, 3);
  5778. tmpObj.aim3 = UTILS.getDirect(tmpObj, player, 3, 3);
  5779. tmpObj.damageThreat = 0;
  5780. if (tmpObj.skinIndex == 45 && tmpObj.shameTimer <= 0) {
  5781. tmpObj.addShameTimer();
  5782. }
  5783. if (tmpObj.oldSkinIndex == 45 && tmpObj.skinIndex != 45) {
  5784. tmpObj.shameTimer = 0;
  5785. tmpObj.shameCount = 0;
  5786. if (tmpObj == player) {
  5787. healer();
  5788. }
  5789. }
  5790.  
  5791. if (player.shameCount < 4 && near.dist3 <= 300 && near.reloads[near.primaryIndex] <= game.tickRate * (window.pingTime >= 130 ? 2 : 1)) {
  5792. autoQ = true;
  5793. healer();
  5794. } else {
  5795. if (autoQ) {
  5796. healer();
  5797. }
  5798. autoQ = false;
  5799. }
  5800.  
  5801.  
  5802. if (tmpObj == player) {
  5803. if (liztobj.length) {
  5804. liztobj.forEach((tmp) => {
  5805. tmp.onNear = false;
  5806. if (tmp.active) {
  5807. if (!tmp.onNear && UTILS.getDist(tmp, tmpObj, 0, 2) <= tmp.scale + items.weapons[tmpObj.weapons[0]].range) {
  5808. tmp.onNear = true;
  5809. }
  5810. if (tmp.isItem && tmp.owner) {
  5811. if (!tmp.pps && tmpObj.sid == tmp.owner.sid && UTILS.getDist(tmp, tmpObj, 0, 2) > (parseInt(getEl("breakRange").value) || 0) && !tmp.breakObj && ![13, 14, 20].includes(tmp.id)) {
  5812. tmp.breakObj = true;
  5813. breakObjects.push({
  5814. x: tmp.x,
  5815. y: tmp.y,
  5816. sid: tmp.sid
  5817. });
  5818. }
  5819. }
  5820. }
  5821. });
  5822. let nearTrap = liztobj.filter(e => e.trap && e.active && UTILS.getDist(e, tmpObj, 0, 2) <= (tmpObj.scale + e.getScale() + 25) && !e.isTeamObject(tmpObj)).sort(function(a, b) {
  5823. return UTILS.getDist(a, tmpObj, 0, 2) - UTILS.getDist(b, tmpObj, 0, 2);
  5824. })[0];
  5825. if (nearTrap) {
  5826. let spike = gameObjects.filter(obj => obj.dmg && cdf(tmpObj, obj) <= tmpObj.scale + nearTrap.scale/2 && !obj.isTeamObject(tmpObj) && obj.active)[0]
  5827. traps.dist = UTILS.getDist(nearTrap, tmpObj, 0, 2);
  5828. traps.aim = UTILS.getDirect(spike ? spike : nearTrap, tmpObj, 0, 2);
  5829. traps.protect(caf(nearTrap, tmpObj) - Math.PI);
  5830. traps.inTrap = true;
  5831. traps.info = nearTrap;
  5832. } else {
  5833. traps.inTrap = false;
  5834. traps.info = {};
  5835. }
  5836. } else {
  5837. traps.inTrap = false;
  5838. }
  5839. }
  5840. if (tmpObj.weaponIndex < 9) {
  5841. tmpObj.primaryIndex = tmpObj.weaponIndex;
  5842. tmpObj.primaryVariant = tmpObj.weaponVariant;
  5843. } else if (tmpObj.weaponIndex > 8) {
  5844. tmpObj.secondaryIndex = tmpObj.weaponIndex;
  5845. tmpObj.secondaryVariant = tmpObj.weaponVariant;
  5846. }
  5847. }
  5848. i += 13;
  5849. }
  5850. if (textManager.stack.length) {
  5851. let stacks = [];
  5852. let notstacks = [];
  5853. let num = 0;
  5854. let num2 = 0;
  5855. let pos = {
  5856. x: null,
  5857. y: null
  5858. };
  5859. let pos2 = {
  5860. x: null,
  5861. y: null
  5862. }
  5863. textManager.stack.forEach((text) => {
  5864. if (text.value >= 0) {
  5865. if (num == 0) pos = {
  5866. x: text.x,
  5867. y: text.y
  5868. };
  5869. num += Math.abs(text.value);
  5870. } else {
  5871. if (num2 == 0) pos2 = {
  5872. x: text.x,
  5873. y: text.y
  5874. };
  5875. num2 += Math.abs(text.value);
  5876. }
  5877. });
  5878. if (num2 > 0) {
  5879. textManager.showText(pos2.x, pos2.y, Math.max(45, Math.min(50, num2)), 0.18, 500, num2, "#8ecc51");
  5880. }
  5881. if (num > 0) {
  5882. textManager.showText(pos.x, pos.y, Math.max(45, Math.min(50, num)), 0.18, 500, num, "#fff");
  5883. }
  5884. textManager.stack = [];
  5885. }
  5886. if (runAtNextTick.length) {
  5887. runAtNextTick.forEach((tmp) => {
  5888. checkProjectileHolder(...tmp);
  5889. });
  5890. runAtNextTick = [];
  5891. }
  5892. for (let i = 0; i < data.length;) {
  5893. tmpObj = findPlayerBySID(data[i]);
  5894. if (tmpObj) {
  5895. if (!tmpObj.isTeam(player)) {
  5896. enemy.push(tmpObj);
  5897. if (tmpObj.dist2 <= items.weapons[tmpObj.primaryIndex == undefined ? 5 : tmpObj.primaryIndex].range + (player.scale * 2)) {
  5898. nears.push(tmpObj);
  5899. }
  5900. }
  5901. tmpObj.manageReload();
  5902. if (tmpObj != player) {
  5903. tmpObj.addDamageThreat(player);
  5904. }
  5905. }
  5906. i += 13;
  5907. }
  5908. if (player && player.alive) {
  5909. if (enemy.length) {
  5910. near = enemy.sort(function(tmp1, tmp2) {
  5911. return tmp1.dist2 - tmp2.dist2;
  5912. })[0];
  5913. }
  5914. if (game.tickQueue[game.tick]) {
  5915. game.tickQueue[game.tick].forEach((action) => {
  5916. action();
  5917. });
  5918. game.tickQueue[game.tick] = null;
  5919. }
  5920. players.forEach((tmp) => {
  5921. if (!tmp.visible && player != tmp) {
  5922. tmp.reloads = {
  5923. 0: 0,
  5924. 1: 0,
  5925. 2: 0,
  5926. 3: 0,
  5927. 4: 0,
  5928. 5: 0,
  5929. 6: 0,
  5930. 7: 0,
  5931. 8: 0,
  5932. 9: 0,
  5933. 10: 0,
  5934. 11: 0,
  5935. 12: 0,
  5936. 13: 0,
  5937. 14: 0,
  5938. 15: 0,
  5939. 53: 0,
  5940. };
  5941. }
  5942. if (tmp.setBullTick) {
  5943. tmp.bullTimer = 0;
  5944. }
  5945. if (tmp.setPoisonTick) {
  5946. tmp.poisonTimer = 0;
  5947. }
  5948. tmp.updateTimer();
  5949. });
  5950. if (inGame) {
  5951. if (enemy.length) {
  5952. if (player.canEmpAnti) {
  5953. player.canEmpAnti = false;
  5954. if (near.dist2 <= 300 && !my.safePrimary(near) && !my.safeSecondary(near)) {
  5955. if (near.reloads[53] == 0) {
  5956. player.empAnti = true;
  5957. player.soldierAnti = false;
  5958. } else {
  5959. player.empAnti = false;
  5960. player.soldierAnti = true;
  5961. }
  5962. }
  5963. }
  5964. let prehit = liztobj.filter(tmp => tmp.dmg && tmp.active && tmp.isTeamObject(player) && UTILS.getDist(tmp, near, 0, 3) <= (tmp.scale + near.scale)).sort(function(a, b) {
  5965. return UTILS.getDist(a, near, 0, 2) - UTILS.getDist(b, near, 0, 2);
  5966. })[0];
  5967. if (prehit) {
  5968. if (near.dist3 <= items.weapons[player.weapons[0]].range + player.scale * 1.8 && configs.predictTick) {
  5969. instaC.canSpikeTick = true;
  5970. instaC.syncHit = true;
  5971. if (configs.revTick && player.weapons[1] == 15 && player.reloads[53] == 0 && instaC.perfCheck(player, near)) {
  5972. instaC.revTick = true;
  5973. }
  5974. }
  5975. }
  5976. let antiSpikeTick = liztobj.filter(tmp => tmp.dmg && tmp.active && !tmp.isTeamObject(player) && UTILS.getDist(tmp, player, 0, 3) < (tmp.scale + player.scale)).sort(function(a, b) {
  5977. return UTILS.getDist(a, player, 0, 2) - UTILS.getDist(b, player, 0, 2);
  5978. })[0];
  5979. if (antiSpikeTick && !traps.inTrap) {
  5980. if (near.dist3 <= items.weapons[5].range + near.scale * 1.8) {
  5981. my.anti0Tick = 1;
  5982. }
  5983. }
  5984. }
  5985. if ((useWasd ? true : ((player.checkCanInsta(true) >= 100 ? player.checkCanInsta(true) : player.checkCanInsta(false)) >= (player.weapons[1] == 10 ? 95 : 100))) && near.dist2 <= items.weapons[player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]].range + near.scale * 1.8 && (instaC.wait || (useWasd && Math.floor(Math.random() * 5) == 0)) && !instaC.isTrue && !my.waitHit && player.reloads[player.weapons[0]] == 0 && player.reloads[player.weapons[1]] == 0 && (useWasd ? true : getEl("instaType").value == "oneShot" ? (player.reloads[53] <= (player.weapons[1] == 10 ? 0 : game.tickRate)) : true) && instaC.perfCheck(player, near)) {
  5986. if (player.checkCanInsta(true) >= 100) {
  5987. instaC.nobull = useWasd ? false : instaC.canSpikeTick ? false : true;
  5988. } else {
  5989. instaC.nobull = false;
  5990. }
  5991. instaC.can = true;
  5992. } else {
  5993. instaC.can = false;
  5994. }
  5995. macro.q && place(0, getAttackDir());
  5996. macro.f && place(4, getSafeDir());
  5997. macro.v && place(2, getSafeDir());
  5998. macro.y && place(5, getSafeDir());
  5999. macro.h && place(player.getItemType(22), getSafeDir());
  6000. macro.n && place(3, getSafeDir());
  6001. if (game.tick % 1 == 0) {
  6002. if (mills.place) {
  6003. let plcAng = 7.7;
  6004. for (let i = -plcAng; i <= plcAng; i += plcAng) {
  6005. checkPlace(3, UTILS.getDirect(player.oldPos, player, 2, 2) + i);
  6006. }
  6007. } else {
  6008. if (mills.placeSpawnPads) {
  6009. for (let i = 0; i < Math.PI * 2; i += Math.PI / 2) {
  6010. checkPlace(player.getItemType(20), UTILS.getDirect(player.oldPos, player, 2, 2) + i);
  6011. }
  6012. }
  6013. }
  6014. }
  6015. if (instaC.can) {
  6016. instaC.changeType(player.weapons[1] == 10 ? "rev" : "normal");
  6017. }
  6018. if (instaC.canCounter) {
  6019. instaC.canCounter = false;
  6020. if (player.reloads[player.weapons[0]] == 0 && !instaC.isTrue) {
  6021. instaC.counterType();
  6022. if (!recording) {
  6023. sendChat("SUPER T R A S H counter insta");
  6024. }
  6025. }
  6026. }
  6027. if (instaC.canSpikeTick) {
  6028. instaC.canSpikeTick = false;
  6029. if (instaC.revTick) {
  6030. instaC.revTick = false;
  6031. if ([1, 2, 3, 4, 5, 6].includes(player.weapons[0]) && player.reloads[player.weapons[1]] == 0 && !instaC.isTrue) {
  6032. instaC.changeType("rev");
  6033. }
  6034. } else {
  6035. if ([1, 2, 3, 4, 5, 6].includes(player.weapons[0]) && player.reloads[player.weapons[0]] == 0 && !instaC.isTrue) {
  6036. instaC.spikeTickType();
  6037. if (instaC.syncHit) {
  6038. }
  6039. }
  6040. }
  6041. }
  6042. if (!clicks.middle && (clicks.left || clicks.right) && !instaC.isTrue) {
  6043. if ((player.weaponIndex != (clicks.right && player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0])) || player.buildIndex > -1) {
  6044. selectWeapon(clicks.right && player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]);
  6045. }
  6046. if (player.reloads[clicks.right && player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]] == 0 && !my.waitHit) {
  6047. sendAutoGather();
  6048. my.waitHit = 1;
  6049. game.tickBase(() => {
  6050. sendAutoGather();
  6051. my.waitHit = 0;
  6052. }, 1);
  6053. }
  6054. }
  6055. if (useWasd && !clicks.left && !clicks.right && !instaC.isTrue && near.dist2 <= (items.weapons[player.weapons[0]].range + near.scale * 1.8) && !traps.inTrap) {
  6056. if ((player.weaponIndex != player.weapons[0]) || player.buildIndex > -1) {
  6057. selectWeapon(player.weapons[0]);
  6058. }
  6059. if (player.reloads[player.weapons[0]] == 0 && !my.waitHit) {
  6060. sendAutoGather();
  6061. my.waitHit = 1;
  6062. game.tickBase(() => {
  6063. sendAutoGather();
  6064. my.waitHit = 0;
  6065. }, 1);
  6066. }
  6067. }
  6068. if (traps.inTrap) {
  6069. if (!clicks.left && !clicks.right && !instaC.isTrue) {
  6070. if (player.weaponIndex != (traps.notFast() ? player.weapons[1] : player.weapons[0]) || player.buildIndex > -1) {
  6071. selectWeapon(traps.notFast() ? player.weapons[1] : player.weapons[0]);
  6072. }
  6073. if (player.reloads[traps.notFast() ? player.weapons[1] : player.weapons[0]] == 0 && !my.waitHit) {
  6074. sendAutoGather();
  6075. my.waitHit = 1;
  6076. game.tickBase(() => {
  6077. sendAutoGather();
  6078. my.waitHit = 0;
  6079. }, 1);
  6080. }
  6081. }
  6082. }
  6083. if (clicks.middle && !traps.inTrap) {
  6084. if (!instaC.isTrue && player.reloads[player.weapons[1]] == 0) {
  6085. if (my.ageInsta && player.weapons[0] != 4 && player.weapons[1] == 9 && player.age >= 9 && enemy.length) {
  6086. instaC.bowMovement();
  6087. } else {
  6088. instaC.rangeType();
  6089. }
  6090. }
  6091. }
  6092. if (macro.t && !traps.inTrap) {
  6093. if (!instaC.isTrue && player.reloads[player.weapons[0]] == 0 && (player.weapons[1] == 15 ? (player.reloads[player.weapons[1]] == 0) : true) && (player.weapons[0] == 5 || (player.weapons[0] == 4 && player.weapons[1] == 15))) {
  6094. instaC[(player.weapons[0] == 4 && player.weapons[1] == 15) ? "kmTickMovement" : "tickMovement"]();
  6095. }
  6096. }
  6097. if (macro["."] && !traps.inTrap) {
  6098. if (!instaC.isTrue && player.reloads[player.weapons[0]] == 0 && ([9, 12, 13, 15].includes(player.weapons[1]) ? (player.reloads[player.weapons[1]] == 0) : true)) {
  6099. instaC.boostTickMovement();
  6100. }
  6101. }
  6102. if (player.weapons[1] && !clicks.left && !clicks.right && !traps.inTrap && !instaC.isTrue && !(useWasd && near.dist2 <= items.weapons[player.weapons[0]].range + near.scale * 1.8)) {
  6103. if (player.reloads[player.weapons[0]] == 0 && player.reloads[player.weapons[1]] == 0) {
  6104. if (!my.reloaded) {
  6105. my.reloaded = true;
  6106. let fastSpeed = items.weapons[player.weapons[0]].spdMult < items.weapons[player.weapons[1]].spdMult ? 1 : 0;
  6107. if (player.weaponIndex != player.weapons[fastSpeed] || player.buildIndex > -1) {
  6108. selectWeapon(player.weapons[fastSpeed]);
  6109. }
  6110. }
  6111. } else {
  6112. my.reloaded = false;
  6113. if(useWasd) {
  6114. autos.stopspin = false;
  6115. }
  6116. if (player.reloads[player.weapons[0]] > 0) {
  6117. if (player.weaponIndex != player.weapons[0] || player.buildIndex > -1) {
  6118. selectWeapon(player.weapons[0]);
  6119. }
  6120. } else if (player.reloads[player.weapons[0]] == 0 && player.reloads[player.weapons[1]] > 0) {
  6121. if (player.weaponIndex != player.weapons[1] || player.buildIndex > -1) {
  6122. selectWeapon(player.weapons[1]);
  6123. }
  6124. if(useWasd) {
  6125. if (!autos.stopspin) {
  6126. setTimeout(()=>{
  6127. autos.stopspin = true;
  6128. }, 750);
  6129. }
  6130. }
  6131. }
  6132. }
  6133. }
  6134. if (!instaC.isTrue && !traps.inTrap && !traps.replaced) {
  6135. traps.autoPlace();
  6136. }
  6137. if (!macro.q && !macro.f && !macro.v && !macro.h && !macro.n) {
  6138. packet("D", getAttackDir());
  6139. }
  6140. let hatChanger = function () {
  6141. if (clicks.left || clicks.right) {
  6142. if (clicks.left) {
  6143. buyEquip(player.reloads[player.weapons[0]] == 0 ? getEl("weaponGrind").checked ? 40 : 7 : player.empAnti ? 22 : 6, 0);
  6144. } else if (clicks.right) {
  6145. buyEquip(player.reloads[clicks.right && player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]] == 0 ? 40 : player.empAnti ? 22 : 6, 0);
  6146. }
  6147. } else {
  6148.  
  6149.  
  6150. if (clicks.left || clicks.right) {
  6151. if (
  6152. ((player.shameCount > 0 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) &&
  6153. ((near && near.dist2 > 120) || !near)
  6154. ) {
  6155. } else {
  6156. if (clicks.left) {
  6157. buyEquip(
  6158. player.reloads[player.weapons[0]] == 0
  6159. ? getEl('weaponGrind').checked
  6160. ? 40
  6161. : 7
  6162. : player.empAnti
  6163. ? 22
  6164. : player.soldierAnti
  6165. ? 6
  6166. : getEl('antiBullType').value == 'abreload' && near.antiBull > 0
  6167. ? 11
  6168. : near.dist2 <= 300
  6169. ? getEl('antiBullType').value == 'abalway' && near.reloads[near.primaryIndex] == 0
  6170. ? 11
  6171. : 6
  6172. : biomeGear(1, 1),
  6173. 0
  6174. );
  6175. } else if (clicks.right) {
  6176. buyEquip(
  6177. player.reloads[clicks.right && player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]] == 0
  6178. ? 40
  6179. : player.empAnti
  6180. ? 22
  6181. : player.soldierAnti
  6182. ? 6
  6183. : getEl('antiBullType').value == 'abreload' && near.antiBull > 0
  6184. ? 11
  6185. : near.dist2 <= 300
  6186. ? getEl('antiBullType').value == 'abalway' && near.reloads[near.primaryIndex] == 0
  6187. ? 11
  6188. : 6
  6189. : biomeGear(1, 1),
  6190. 0
  6191. );
  6192. }
  6193. }
  6194. } else if (traps.inTrap) {
  6195. if (traps.info.health <= items.weapons[player.weaponIndex].dmg ? false : player.reloads[player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]] == 0) {
  6196. buyEquip(40, 0);
  6197. buyEquip(21, 1);
  6198. } else {
  6199. if (
  6200. ((player.shameCount > 0 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) &&
  6201. ((near && near.dist2 > 140) || !near)
  6202. ) {
  6203. }
  6204. }
  6205. } else {
  6206. if (
  6207. ((player.shameCount > 0 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) &&
  6208. ((near && near.dist2 > 140) || !near)
  6209. ) {
  6210. } else {
  6211. if (near.dist2 <= 300) {
  6212. buyEquip(
  6213. getEl('antiBullType').value == 'abreload' && near.antiBull > 0
  6214. ? 11
  6215. : getEl('antiBullType').value == 'abalway' && near.reloads[near.primaryIndex] == 0
  6216. ? 11
  6217. : 6,
  6218. 0
  6219. );
  6220. } else {
  6221. biomeGear(1);
  6222. }
  6223. }
  6224. }
  6225. }
  6226. };
  6227.  
  6228. let accChanger = function() {
  6229. if (instaC.can && player.checkCanInsta(true) >= 100) {
  6230. buyEquip(18, 1);
  6231. } else if (clicks.left) {
  6232. setTimeout(() => {
  6233. buyEquip(21, 1);
  6234. }, 50);
  6235. } else if (clicks.right) {
  6236. setTimeout(() => {
  6237. buyEquip(18, 1);
  6238. }, 50);
  6239. } else if (near.dist2 <= 240) {
  6240. buyEquip(21, 1);
  6241. } else {
  6242. traps.inTrap ? buyEquip(21, 1) : buyEquip(11, 1);
  6243. }
  6244. };
  6245.  
  6246. let wasdGears = function() {
  6247. if (my.anti0Tick > 0) {
  6248. buyEquip(6, 0);
  6249. } else {
  6250. if (clicks.left || clicks.right) {
  6251. if ((player.shameCount > 4320 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) {
  6252. buyEquip(7, 0);
  6253. } else {
  6254. if (clicks.left) {
  6255. buyEquip(player.reloads[player.weapons[0]] == 0 ? getEl("weaponGrind").checked ? 40 : 7 : player.empAnti ? 22 : 6, 0);
  6256. } else if (clicks.right) {
  6257. buyEquip(player.reloads[clicks.right && player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]] == 0 ? 40 : player.empAnti ? 22 : 6, 0);
  6258. }
  6259. }
  6260. } else if (near.dist2 <= items.weapons[player.weapons[0]].range + near.scale * 1.8 && !traps.inTrap) {
  6261. if ((player.shameCount > 4320 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) {
  6262. buyEquip(7, 0);
  6263. } else {
  6264. buyEquip(player.reloads[player.weapons[0]] == 0 ? 7 : player.empAnti ? 22 : 6, 0);
  6265. }
  6266. } else if (traps.inTrap) {
  6267. if (traps.info.health <= items.weapons[player.weaponIndex].dmg ? false : (player.reloads[player.weapons[1] == 10 ? player.weapons[1] : player.weapons[0]] == 0)) {
  6268. buyEquip(40, 0);
  6269. } else {
  6270. if ((player.shameCount > 4320 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) {
  6271. buyEquip(7, 0);
  6272. } else {
  6273. buyEquip(player.empAnti ? 22 : 6, 0);
  6274. }
  6275. }
  6276. } else {
  6277. if (player.empAnti) {
  6278. buyEquip(22, 0);
  6279. } else {
  6280. if ((player.shameCount > 4320 && (game.tick - player.bullTick) % config.serverUpdateRate === 0 && player.skinIndex != 45) || my.reSync) {
  6281. buyEquip(7, 0);
  6282. } else {
  6283. buyEquip(6, 0);
  6284. }
  6285. }
  6286. }
  6287. }
  6288. if (clicks.left || clicks.right) {
  6289. if (clicks.left) {
  6290. buyEquip(0, 1);
  6291. } else if (clicks.right) {
  6292. buyEquip(11, 1);
  6293. }
  6294. } else if (near.dist2 <= items.weapons[player.weapons[0]].range + near.scale * 1.8 && !traps.inTrap) {
  6295. buyEquip(0, 1);
  6296. } else if (traps.inTrap) {
  6297. buyEquip(0, 1);
  6298. } else {
  6299. buyEquip(11, 1);
  6300. }
  6301. }
  6302. if (storeMenu.style.display != "block" && !instaC.isTrue && !instaC.ticking) {
  6303. if (useWasd) {
  6304. wasdGears();
  6305. } else {
  6306. hatChanger();
  6307. accChanger();
  6308. }
  6309. }
  6310. if (configs.autoPush && enemy.length && !traps.inTrap && !instaC.ticking) {
  6311. autoPush();
  6312. } else {
  6313. if (my.autoPush) {
  6314. my.autoPush = false;
  6315. packet("9", lastMoveDir || undefined, 1);
  6316. }
  6317. }
  6318. if (instaC.ticking) {
  6319. instaC.ticking = false;
  6320. }
  6321. if (instaC.syncHit) {
  6322. instaC.syncHit = false;
  6323. }
  6324. if (player.empAnti) {
  6325. player.empAnti = false;
  6326. }
  6327. if (player.soldierAnti) {
  6328. player.soldierAnti = false;
  6329. }
  6330. if (my.anti0Tick > 0) {
  6331. my.anti0Tick--;
  6332. }
  6333. if (traps.replaced) {
  6334. traps.replaced = false;
  6335. }
  6336. if (traps.antiTrapped) {
  6337. traps.antiTrapped = false;
  6338. }
  6339.  
  6340. const getPotentialDamage = (build, user) => {
  6341. const weapIndex = user.weapons[1] === 10 && !player.reloads[user.weapons[1]] ? 1 : 0;
  6342. const weap = user.weapons[weapIndex];
  6343. if (player.reloads[weap]) return 0;
  6344. const weapon = items.weapons[weap];
  6345. const inDist = cdf(build, user) <= build.getScale() + weapon.range;
  6346. return (user.visible && inDist) ? weapon.dmg * (weapon.sDmg || 1) * 3.3 : 0;
  6347. };
  6348.  
  6349. const AutoReplace = () => {
  6350. const replaceable = [];
  6351. const playerX = player.x;
  6352. const playerY = player.y;
  6353. const gameObjectCount = gameObjects.length;
  6354.  
  6355. for (let i = 0; i < gameObjectCount; i++) {
  6356. const build = gameObjects[i];
  6357. if (build.isItem && build.active && build.health > 0) {
  6358. const item = items.list[build.id];
  6359. const posDist = 35 + item.scale + (item.placeOffset || 0);
  6360. const inDistance = cdf(build, player) <= posDist * 2;
  6361. if (inDistance) {
  6362. let canDeal = 0;
  6363. const playersCount = players.length;
  6364. for (let j = 0; j < playersCount; j++) {
  6365. canDeal += getPotentialDamage(build, players[j]);
  6366. }
  6367. if (build.health <= canDeal) {
  6368. replaceable.push(build);
  6369. }
  6370. }
  6371. }
  6372. }
  6373.  
  6374. const findPlacementAngle = (player, itemId, build) => {
  6375. if (!build) return null;
  6376. const MAX_ANGLE = 2 * Math.PI;
  6377. const ANGLE_STEP = Math.PI / 360;
  6378. const item = items.list[player.items[itemId]];
  6379. let buildingAngle = Math.atan2(build.y - player.y, build.x - player.x);
  6380. let tmpS = player.scale + (item.scale || 1) + (item.placeOffset || 0);
  6381.  
  6382. for (let offset = 0; offset < MAX_ANGLE; offset += ANGLE_STEP) {
  6383. let angles = [(buildingAngle + offset) % MAX_ANGLE, (buildingAngle - offset + MAX_ANGLE) % MAX_ANGLE];
  6384. for (let angle of angles) {
  6385. return angle;
  6386. }
  6387. }
  6388. return null;
  6389. };
  6390.  
  6391. const replace = (() => {
  6392. let nearTrap = liztobj.filter(tmp => tmp.trap && tmp.active && tmp.isTeamObject(player) && cdf(tmp, player) <= tmp.getScale() + 5);
  6393. let spike = gameObjects.find(tmp => tmp.dmg && tmp.active && tmp.isTeamObject(player) && cdf(tmp, player) < 87 && !nearTrap.length);
  6394. const buildId = spike ? 4 : 2;
  6395.  
  6396. replaceable.forEach(build => {
  6397. let angle = findPlacementAngle(player, buildId, build);
  6398. if (angle !== null) {
  6399. place(buildId, angle);
  6400. }
  6401. });
  6402. });
  6403.  
  6404. if (near && near.dist3 <= 360) {
  6405. replace();
  6406. }
  6407. replace;
  6408. }
  6409. }
  6410. }
  6411. }
  6412. for(var i1 = 0; i1 < liztobj.length; i1++) {
  6413. if (liztobj[i1].active && liztobj[i1].health > 0 && UTILS.getDist(liztobj[i1], player, 0, 2) < 150 && getEl("antipush").checked) {
  6414.  
  6415. if(liztobj[i1].name.includes("spike") && liztobj[i1]){
  6416. if(liztobj[i1].owner.sid != player.sid && clicks.left == false && tmpObj.reloads[tmpObj.secondaryIndex] == 0){
  6417. selectWeapon(player.weapons[1])
  6418. buyEquip(40, 0);
  6419. packet("D", UTILS.getDirect(liztobj[i1], player, 0, 2))
  6420. setTickout( () => {
  6421. buyEquip(6, 0)
  6422. }, 1);
  6423. }
  6424. }
  6425. }
  6426. }
  6427. function ez(context, x, y) {
  6428. context.fillStyle = "rgba(0, 255, 255, 0.2)";
  6429. context.beginPath();
  6430. context.arc(x, y, 55, 0, Math.PI * 2);
  6431. context.fill();
  6432. context.closePath();
  6433. context.globalAlpha = 1;
  6434. }
  6435.  
  6436. function updateLeaderboard(data) {
  6437. lastLeaderboardData = data;
  6438. return;
  6439. UTILS.removeAllChildren(leaderboardData);
  6440. let tmpC = 1;
  6441. for (let i = 0; i < data.length; i += 3) {
  6442. (function(i) {
  6443. UTILS.generateElement({
  6444. class: "leaderHolder",
  6445. parent: leaderboardData,
  6446. children: [
  6447. UTILS.generateElement({
  6448. class: "leaderboardItem",
  6449. style: "color:" + ((data[i] == playerSID) ? "#880808" : "rgba(255,255,255,0.6)"),
  6450. text: tmpC + ". " + (data[i + 1] != "" ? data[i + 1] : "Hax-")
  6451. }),
  6452. UTILS.generateElement({
  6453. class: "leaderScore",
  6454. text: UTILS.sFormat(data[i + 2]) || "0"
  6455. })
  6456. ]
  6457. });
  6458. })(i);
  6459. tmpC++;
  6460. }
  6461. }
  6462.  
  6463. function loadGameObject(data) {
  6464. for (let i = 0; i < data.length;) {
  6465. objectManager.add(data[i], data[i + 1], data[i + 2], data[i + 3], data[i + 4],
  6466. data[i + 5], items.list[data[i + 6]], true, (data[i + 7] >= 0 ? {
  6467. sid: data[i + 7]
  6468. } : null));
  6469. i += 8;
  6470. }
  6471. }
  6472.  
  6473. function loadAI(data) {
  6474. for (let i = 0; i < ais.length; ++i) {
  6475. ais[i].forcePos = !ais[i].visible;
  6476. ais[i].visible = false;
  6477. }
  6478. if (data) {
  6479. let tmpTime = performance.now();
  6480. for (let i = 0; i < data.length;) {
  6481. tmpObj = findAIBySID(data[i]);
  6482. if (tmpObj) {
  6483. tmpObj.index = data[i + 1];
  6484. tmpObj.t1 = (tmpObj.t2 === undefined) ? tmpTime : tmpObj.t2;
  6485. tmpObj.t2 = tmpTime;
  6486. tmpObj.x1 = tmpObj.x;
  6487. tmpObj.y1 = tmpObj.y;
  6488. tmpObj.x2 = data[i + 2];
  6489. tmpObj.y2 = data[i + 3];
  6490. tmpObj.d1 = (tmpObj.d2 === undefined) ? data[i + 4] : tmpObj.d2;
  6491. tmpObj.d2 = data[i + 4];
  6492. tmpObj.health = data[i + 5];
  6493. tmpObj.dt = 0;
  6494. tmpObj.visible = true;
  6495. } else {
  6496. tmpObj = aiManager.spawn(data[i + 2], data[i + 3], data[i + 4], data[i + 1]);
  6497. tmpObj.x2 = tmpObj.x;
  6498. tmpObj.y2 = tmpObj.y;
  6499. tmpObj.d2 = tmpObj.dir;
  6500. tmpObj.health = data[i + 5];
  6501. if (!aiManager.aiTypes[data[i + 1]].name)
  6502. tmpObj.name = config.cowNames[data[i + 6]];
  6503. tmpObj.forcePos = true;
  6504. tmpObj.sid = data[i];
  6505. tmpObj.visible = true;
  6506. }
  6507. i += 7;
  6508. }
  6509. }
  6510. }
  6511.  
  6512. function animateAI(sid) {
  6513. tmpObj = findAIBySID(sid);
  6514. if (tmpObj) tmpObj.startAnim();
  6515. }
  6516.  
  6517. function gatherAnimation(sid, didHit, index) {
  6518. tmpObj = findPlayerBySID(sid);
  6519. if (tmpObj) {
  6520. tmpObj.startAnim(didHit, index);
  6521. tmpObj.gatherIndex = index;
  6522. tmpObj.gathering = 1;
  6523. if (didHit) {
  6524. let tmpObjects = objectManager.hitObj;
  6525. objectManager.hitObj = [];
  6526. game.tickBase(() => {
  6527. tmpObj = findPlayerBySID(sid);
  6528. let val = items.weapons[index].dmg * (config.weaponVariants[tmpObj[(index < 9 ? "prima" : "seconda") + "ryVariant"]].val) * (items.weapons[index].sDmg || 1) * (tmpObj.skinIndex == 40 ? 3.3 : 1);
  6529. tmpObjects.forEach((healthy) => {
  6530. healthy.health -= val;
  6531. });
  6532. }, 1);
  6533. }
  6534. }
  6535. }
  6536. if(nears.filter(near => near.gathering).length>1) {
  6537. player.chat.message = "pSyD";
  6538. healer();
  6539. }
  6540.  
  6541. function wiggleGameObject(dir, sid) {
  6542. tmpObj = findObjectBySid(sid);
  6543. if (tmpObj) {
  6544. tmpObj.xWiggle += config.gatherWiggle * Math.cos(dir);
  6545. tmpObj.yWiggle += config.gatherWiggle * Math.sin(dir);
  6546. if (tmpObj.health) {
  6547. objectManager.hitObj.push(tmpObj);
  6548. }
  6549. }
  6550. }
  6551.  
  6552. function shootTurret(sid, dir) {
  6553. tmpObj = findObjectBySid(sid);
  6554. if (tmpObj) {
  6555. if (config.anotherVisual) {
  6556. tmpObj.lastDir = dir;
  6557. } else {
  6558. tmpObj.dir = dir;
  6559. }
  6560. tmpObj.xWiggle += config.gatherWiggle * Math.cos(dir + Math.PI);
  6561. tmpObj.yWiggle += config.gatherWiggle * Math.sin(dir + Math.PI);
  6562. }
  6563. }
  6564.  
  6565. function updatePlayerValue(index, value, updateView) {
  6566. if (player) {
  6567. player[index] = value;
  6568. if (index == "points") {
  6569. if (configs.autoBuy) {
  6570. autoBuy.hat();
  6571. autoBuy.acc();
  6572. }
  6573. } else if (index == "kills") {
  6574. if (configs.killChat) {
  6575. if (!recording) {
  6576. sendChat("HaxBountyHunter AI");
  6577. }
  6578. }
  6579. }
  6580. }
  6581. }
  6582.  
  6583. function updateItems(data, wpn) {
  6584. if (data) {
  6585. if (wpn) {
  6586. player.weapons = data;
  6587. player.primaryIndex = player.weapons[0];
  6588. player.secondaryIndex = player.weapons[1];
  6589. if (!instaC.isTrue) {
  6590. selectWeapon(player.weapons[0]);
  6591. }
  6592. } else {
  6593. player.items = data;
  6594. }
  6595. }
  6596.  
  6597. for (let i = 0; i < items.list.length; i++) {
  6598. let tmpI = items.weapons.length + i;
  6599. let actionBarItem = getEl("actionBarItem" + tmpI);
  6600. actionBarItem.style.display = player.items.indexOf(items.list[i].id) >= 0 ? "inline-block" : "none";
  6601. }
  6602.  
  6603. for (let i = 0; i < items.weapons.length; i++) {
  6604. let actionBarItem = getEl("actionBarItem" + i);
  6605. actionBarItem.style.display = player.weapons[items.weapons[i].type] == items.weapons[i].id ? "inline-block" : "none";
  6606. }
  6607.  
  6608. let kms = player.weapons[0] == 3 && player.weapons[1] == 15;
  6609. if (kms) {
  6610. getEl("actionBarItem3").style.display = "none";
  6611. getEl("actionBarItem4").style.display = "inline-block";
  6612. }
  6613. }
  6614.  
  6615. function addProjectile(x, y, dir, range, speed, indx, layer, sid) {
  6616. projectileManager.addProjectile(x, y, dir, range, speed, indx, null, null, layer, inWindow).sid = sid;
  6617. runAtNextTick.push(Array.prototype.slice.call(arguments));
  6618. }
  6619.  
  6620. function remProjectile(sid, range) {
  6621. for (let i = 0; i < projectiles.length; ++i) {
  6622. if (projectiles[i].sid == sid) {
  6623. projectiles[i].range = range;
  6624. let tmpObjects = objectManager.hitObj;
  6625. objectManager.hitObj = [];
  6626. game.tickBase(() => {
  6627. let val = projectiles[i].dmg;
  6628. tmpObjects.forEach((healthy) => {
  6629. if (healthy.projDmg) {
  6630. healthy.health -= val;
  6631. }
  6632. });
  6633. }, 1);
  6634. }
  6635. }
  6636. }
  6637.  
  6638. function setPlayerTeam(team, isOwner) {
  6639. if (player) {
  6640. player.team = team;
  6641. player.isOwner = isOwner;
  6642. if (team == null)
  6643. alliancePlayers = [];
  6644. }
  6645. }
  6646.  
  6647. function setAlliancePlayers(data) {
  6648. alliancePlayers = data;
  6649. }
  6650.  
  6651. function updateStoreItems(type, id, index) {
  6652. if (index) {
  6653. if (!type)
  6654. player.tails[id] = 1;
  6655. else {
  6656. player.latestTail = id;
  6657. }
  6658. } else {
  6659. if (!type)
  6660. player.skins[id] = 1,
  6661. id == 7 && (my.reSync = true);
  6662. else {
  6663. player.latestSkin = id;
  6664. }
  6665. }
  6666. }
  6667.  
  6668.  
  6669. const videoContainer = document.createElement('div');
  6670. videoContainer.id = 'video-bg';
  6671. videoContainer.style.position = 'absolute';
  6672. videoContainer.style.width = '100%';
  6673. videoContainer.style.height = '100%';
  6674. videoContainer.style.zIndex = '10';
  6675. videoContainer.style.overflow = 'hidden';
  6676. const videoElement = document.createElement('video');
  6677. videoElement.src = '';
  6678. videoElement.autoplay = true;
  6679. videoElement.loop = true;
  6680. videoElement.muted = true;
  6681. videoElement.style.width = '100%';
  6682. videoElement.style.height = '100%';
  6683. videoContainer.style.zIndex = '-1';
  6684. videoContainer.style.opacity = '0.5';
  6685. videoContainer.appendChild(videoElement);
  6686. document.querySelector('#mainMenu').appendChild(videoContainer);
  6687.  
  6688. const style = document.createElement('style');
  6689. style.textContent = `
  6690. html, body {
  6691. background-color: #880808;
  6692. overflow: hidden;
  6693. position: relative;
  6694. width: 100%;
  6695. height: 100%;
  6696. margin: 0;
  6697. padding: 0;
  6698. }
  6699.  
  6700. ::-webkit-input-placeholder {
  6701. color: #000000;
  6702. }
  6703. :-moz-placeholder {
  6704. color: #7DDA58;
  6705. opacity: 1;
  6706. }
  6707. ::-moz-placeholder {
  6708. color: #7DDA58;
  6709. opacity: 1;
  6710. }
  6711. :-ms-input-placeholder {
  6712. color: #7DDA58;
  6713. }
  6714.  
  6715. input[type=text] {
  6716. -webkit-touch-callout: text;
  6717. -webkit-user-select: text;
  6718. -khtml-user-select: text;
  6719. -moz-user-select: text;
  6720. -ms-user-select: text;
  6721. user-select: text;
  6722. }
  6723.  
  6724. .menuLink {
  6725. font-size: 20px;
  6726. }
  6727. a {
  6728. color: ;
  6729. text-decoration: none;
  6730. }
  6731. a:active {
  6732. color: ;
  6733. }
  6734. a:visited {
  6735. color: ;
  6736. }
  6737. a:hover {
  6738. color: ;
  6739. }
  6740.  
  6741. * {
  6742. font-family: 'Comic Sans MS', 'Comic Neue', cursive;
  6743. font-size: 12px;
  6744. -webkit-touch-callout: none;
  6745. -webkit-user-select: none;
  6746. -khtml-user-select: none;
  6747. -moz-user-select: none;
  6748. -ms-user-select: none;
  6749. user-select: none;
  6750. transition: background-color 0.5s;
  6751. }
  6752.  
  6753. span {
  6754. font-size: inherit;
  6755. }
  6756.  
  6757. #errorNotification {
  6758. position: absolute;
  6759. top: 20px;
  6760. left: 50%;
  6761. transform: translateX(-50%);
  6762. max-width: 500px;
  6763. z-index: 99999;
  6764. background-color: ;
  6765. border-radius: 8px;
  6766. padding: 10px;
  6767. box-shadow: 0 0 10px rgba(0,0,0,0.1);
  6768. }
  6769.  
  6770. #errorNotification .errorClose {
  6771. position: absolute;
  6772. top: 5px;
  6773. left: 5px;
  6774. }
  6775.  
  6776. #youtuberOf {
  6777. position: absolute;
  6778. top: 10px;
  6779. left: 10px;
  6780. color: #000;
  6781. font-size: 24px;
  6782. }
  6783.  
  6784. .ytLink {
  6785. color: #6EB3EF;
  6786. font-size: 24px;
  6787. text-decoration: none;
  6788. }
  6789.  
  6790. .ytLink:hover {
  6791. color: #5C96C9;
  6792. }
  6793.  
  6794. #featuredYoutube {
  6795. margin-top: 5px;
  6796. }
  6797.  
  6798. #featuredYoutube a {
  6799. color: #6EB3EF !important;
  6800. }
  6801.  
  6802. #featuredYoutube a:hover {
  6803. color: #5C96C9 !important;
  6804. }
  6805.  
  6806. #mainMenu {
  6807. background-color: rgba(8,8,8);
  6808. position: absolute;
  6809. width: 100%;
  6810. height: 100%;
  6811. z-index: 10;
  6812. }
  6813.  
  6814. #menuContainer {
  6815. width: 100%;
  6816. white-space: nowrap;
  6817. text-align: center;
  6818. position: absolute;
  6819. top: 45%;
  6820. transform: translateY(-50%);
  6821. }
  6822.  
  6823. #soundSetting {
  6824. position: absolute;
  6825. top: 10px;
  6826. right: 10px;
  6827. }
  6828.  
  6829.  
  6830.  
  6831. #joinPartyButton {
  6832. position: absolute;
  6833. top: 54px;
  6834. right: 20px;
  6835. cursor: pointer;
  6836. }
  6837.  
  6838. #pingDisplay {
  6839. position: absolute;
  6840. top: 20px;
  6841. left: 50%;
  6842. transform: translateX(-50%);
  6843. color: white;
  6844. }
  6845.  
  6846. #shutdownDisplay {
  6847. position: absolute;
  6848. top: 20px;
  6849. left: 50%;
  6850. transform: translateX(-50%);
  6851. color: white;
  6852. font-size: 25px;
  6853. z-index: 100;
  6854. }
  6855.  
  6856. #settingsButton {
  6857. position: absolute;
  6858. cursor: pointer;
  6859. display: none;
  6860. }
  6861.  
  6862. #followText {
  6863. position: absolute;
  6864. bottom: 40px;
  6865. left: 10px;
  6866. color: #000;
  6867. font-size: 22px;
  6868. }
  6869.  
  6870. #twitterFollow {
  6871. position: absolute;
  6872. bottom: 10px;
  6873. left: 10px;
  6874. }
  6875.  
  6876. #youtubeFollow {
  6877. position: absolute;
  6878. bottom: 10px;
  6879. left: 10px;
  6880. }
  6881.  
  6882. #linksContainer1 {
  6883. border-radius: 4px;
  6884. position: absolute;
  6885. bottom: 0px;
  6886. left: 0px;
  6887. background-color: #880808;
  6888. font-size: 20px;
  6889. padding: 8px;
  6890. border-radius: 0 4px 0 0;
  6891. }
  6892.  
  6893. #linksContainer2 {
  6894. border-radius: 4px;
  6895. position: absolute;
  6896. bottom: 0px;
  6897. right: 0px;
  6898. background-color: #880808;
  6899. text-align: right;
  6900. font-size: 20px;
  6901. padding: 8px;
  6902. border-radius: 4px 0 0 0;
  6903. }
  6904.  
  6905. #loadingText {
  6906. font-size: 45px;
  6907. color: #5DE2E7;
  6908. text-align: center;
  6909. }
  6910.  
  6911. #loadingText a {
  6912. display: block;
  6913. }
  6914.  
  6915. .menuCard, .adMenuCard {
  6916. vertical-align: top;
  6917. text-align: left;
  6918. white-space: normal;
  6919. word-wrap: break-word;
  6920. margin: 5px;
  6921. display: inline-block;
  6922. width: 300px;
  6923. padding: 18px;
  6924. background-color: #880808;
  6925. box-shadow: 0px 7px #C4C4C4;
  6926. border-radius: 10px;
  6927. overflow: hidden;
  6928. }
  6929.  
  6930. .adMenuCard {
  6931. min-width: 0;
  6932. min-height: 0;
  6933. height: initial;
  6934. width: initial;
  6935. padding: 0;
  6936. box-shadow: none;
  6937. }
  6938.  
  6939. .menuHeader {
  6940. font-size: 24px;
  6941. color: #292929;
  6942. margin-bottom: 5px;
  6943. }
  6944.  
  6945. .menuText {
  6946. font-size: 18px;
  6947. color: #A8A8A8;
  6948. margin-bottom: 10px;
  6949. }
  6950.  
  6951. #serverBrowser select {
  6952. width: 100%;
  6953. height: 24px;
  6954. }
  6955.  
  6956. #altServer {
  6957. width: 100%;
  6958. text-align: center;
  6959. margin-top: 10px;
  6960. }
  6961.  
  6962. #skinColorHolder {
  6963. width: 100%;
  6964. padding: 0px;
  6965. padding-top: 5px;
  6966. padding-bottom: 0px;
  6967. }
  6968.  
  6969. .activeSkin {
  6970. border-radius: 8px !important;
  6971. }
  6972.  
  6973. .skinColorItem {
  6974. cursor: pointer;
  6975. display: inline-block;
  6976. margin-right: 10px;
  6977. width: 30px;
  6978. height: 30px;
  6979. border-radius: 20px;
  6980. border: 3px solid #525252;
  6981. }
  6982.  
  6983. .skinColorItem:hover {
  6984. border-radius: 8px;
  6985. }
  6986.  
  6987. .settingRadio {
  6988. font-size: 18px;
  6989. color: #A8A8A8;
  6990. margin-bottom: 10px;
  6991. }
  6992.  
  6993. #gameName {
  6994. font-size: 170px;
  6995. margin-bottom: -25px;
  6996. text-shadow: 0 1px 0 #98F5F9, 0 2px 0 #98F5F9, 0 3px 0 #98F5F9, 0 4px 0 #98F5F9, 0 5px 0 #98F5F9, 0 6px 0 #98F5F9, 0 7px 0 #98F5F9, 0 8px 0 #98F5F9, 0 9px 0 #98F5F9 !important;
  6997. color: #880808;
  6998. }
  6999.  
  7000. #guideCard {
  7001. max-height: 250px;
  7002. overflow-y: scroll;
  7003. -webkit-overflow-scrolling: touch;
  7004. }
  7005.  
  7006. #guideCard #smallLinks {
  7007. display: none;
  7008. }
  7009.  
  7010. #guideCard #desktopInstructions {
  7011. display: block;
  7012. }
  7013.  
  7014. #guideCard #mobileInstructions {
  7015. display: none;
  7016. }
  7017.  
  7018. #guideCard.touch #desktopInstructions {
  7019. display: none;
  7020. }
  7021.  
  7022. #guideCard.touch #mobileInstructions {
  7023. display: block;
  7024. }
  7025.  
  7026. #promoImgHolder {
  7027. text-align: center;
  7028. }
  7029.  
  7030. #promoImg:hover {
  7031. opacity: 0.9;
  7032. }
  7033.  
  7034. #rightCardHolder {
  7035. display: inline-block;
  7036. vertical-align: top;
  7037. }
  7038.  
  7039. #downloadButtonContainer {
  7040. display: block;
  7041. text-align: center;
  7042. padding-bottom: 12px;
  7043. margin-top: 14px;
  7044. }
  7045.  
  7046. #downloadButtonContainer.cordova {
  7047. display: none;
  7048. }
  7049.  
  7050. #mobileDownloadButtonContainer {
  7051. display: none;
  7052. }
  7053.  
  7054. #mobileDownloadButtonContainer.cordova {
  7055. display: none;
  7056. }
  7057.  
  7058. .downloadBadge {
  7059. margin: 0 6px 0 6px;
  7060. }
  7061.  
  7062. .downloadBadge img {
  7063. height: 40px;
  7064. }
  7065.  
  7066. #adCard {
  7067. text-align: center;
  7068. width: 300px;
  7069. height: auto;
  7070. }
  7071.  
  7072. #nameInput {
  7073. text-align: center;
  7074. font-size: 26px;
  7075. margin-bottom: 16px;
  7076. padding: 6px;
  7077. border: none;
  7078. outline: none;
  7079. box-sizing: border-box;
  7080. color: #4A4A4A;
  7081. background-color: #880808;
  7082. width: 100%;
  7083. border-radius: 8px;
  7084. box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
  7085. }
  7086.  
  7087. .menuButton {
  7088. text-align: center;
  7089. font-size: 23px;
  7090. padding: 6px;
  7091. margin-top: 10px;
  7092. border: none;
  7093. outline: none;
  7094. cursor: pointer;
  7095. background-color: #880808;
  7096. color: white;
  7097. box-shadow: 0px 5px #98F5F9;
  7098. width: 100%;
  7099. border-radius: 8px;
  7100. }
  7101.  
  7102. .menuButton:hover {
  7103. background-color: #880808;
  7104. }
  7105.  
  7106. #leftCard {
  7107. display: inline-block;
  7108. vertical-align: top;
  7109. margin-right: 5px;
  7110. }
  7111.  
  7112. #rightCard {
  7113. display: inline-block;
  7114. vertical-align: top;
  7115. margin-left: 5px;
  7116. }
  7117.  
  7118. .card {
  7119. display: inline-block;
  7120. vertical-align: top;
  7121. }
  7122.  
  7123. #inputWrapper {
  7124. width: 100%;
  7125. text-align: center;
  7126. }
  7127.  
  7128. #playCard {
  7129. display: inline-block;
  7130. vertical-align: top;
  7131. width: 300px;
  7132. margin-left: 0px;
  7133. margin-right: 5px;
  7134. }
  7135.  
  7136. #skinsButton {
  7137. width: 50%;
  7138. margin-right: 3px;
  7139. display: inline-block;
  7140. vertical-align: top;
  7141. }
  7142.  
  7143. #shopButton {
  7144. width: 50%;
  7145. margin-left: 3px;
  7146. display: inline-block;
  7147. vertical-align: top;
  7148. }
  7149.  
  7150. #mainCard {
  7151. display: inline-block;
  7152. vertical-align: top;
  7153. margin-left: 5px;
  7154. margin-right: 5px;
  7155. width: 300px;
  7156. }
  7157.  
  7158. #nickCard {
  7159. display: inline-block;
  7160. vertical-align: top;
  7161. width: 300px;
  7162. margin-left: 5px;
  7163. margin-right: 0px;
  7164. }
  7165.  
  7166. #footerCard {
  7167. display: inline-block;
  7168. vertical-align: top;
  7169. width: 300px;
  7170. margin-left: 5px;
  7171. margin-right: 5px;
  7172. }
  7173.  
  7174. #centeredHr {
  7175. width: 40%;
  7176. }
  7177.  
  7178. #socialCard {
  7179. width: 300px;
  7180. }
  7181.  
  7182. .newsCard {
  7183. display: inline-block;
  7184. vertical-align: top;
  7185. width: 300px;
  7186. margin-left: 5px;
  7187. margin-right: 5px;
  7188. }
  7189.  
  7190. #newsCardContainer {
  7191. white-space: nowrap;
  7192. width: 100%;
  7193. overflow-y: hidden;
  7194. overflow-x: auto;
  7195. }
  7196.  
  7197. #subTitle {
  7198. font-size: 35px;
  7199. color: #000;
  7200. text-align: center;
  7201. }
  7202.  
  7203. #gameContainerWrapper {
  7204. width: 100%;
  7205. height: 100%;
  7206. position: absolute;
  7207. }
  7208.  
  7209. #gameContainer {
  7210. position: relative;
  7211. width: 100%;
  7212. height: 100%;
  7213. }
  7214.  
  7215. #mobileStuff {
  7216. position: absolute;
  7217. top: 0;
  7218. left: 0;
  7219. width: 100%;
  7220. height: 100%;
  7221. z-index: 30;
  7222. }
  7223.  
  7224. #centerButton {
  7225. position: absolute;
  7226. width: 12%;
  7227. padding-top: 12%;
  7228. bottom: 15%;
  7229. left: 50%;
  7230. transform: translateX(-50%);
  7231. z-index: 100;
  7232. border-radius: 50%;
  7233. background-color: #880808;
  7234. box-shadow: 0 5px rgba(0, 0, 0, 0.2);
  7235. }
  7236.  
  7237. #scoreHolder {
  7238. width: 100%;
  7239. text-align: center;
  7240. font-size: 45px;
  7241. }
  7242.  
  7243. #scoreText {
  7244. padding: 6px;
  7245. font-size: 20px;
  7246. color: #000;
  7247. background-color: rgba(0, 0, 0, 0.1);
  7248. border-radius: 4px;
  7249. display: inline-block;
  7250. }
  7251.  
  7252. #timeHolder {
  7253. width: 100%;
  7254. text-align: center;
  7255. font-size: 45px;
  7256. }
  7257.  
  7258. #timeText {
  7259. padding: 6px;
  7260. font-size: 20px;
  7261. color: #000;
  7262. background-color: rgba(0, 0, 0, 0.1);
  7263. border-radius: 4px;
  7264. display: inline-block;
  7265. }
  7266.  
  7267. #chatLog {
  7268. position: absolute;
  7269. top: 20px;
  7270. left: 20px;
  7271. width: 300px;
  7272. height: 100px;
  7273. overflow-y: scroll;
  7274. background-color: rgba(0, 0, 0, 0.25);
  7275. border-radius: 4px;
  7276. padding: 10px;
  7277. font-family: Arial, sans-serif;
  7278. z-index: 9999;
  7279. }
  7280.  
  7281. #chatLog::-webkit-scrollbar {
  7282. width: 10px;
  7283. }
  7284.  
  7285. #chatLog::-webkit-scrollbar-track {
  7286. background: rgba(0, 0, 0, 0.1);
  7287. border-radius: 10px;
  7288. }
  7289.  
  7290. #chatLog::-webkit-scrollbar-thumb {
  7291. background: rgba(0, 0, 0, 0.25);
  7292. border-radius: 10px;
  7293. border: 2px solid #ccc;
  7294. }
  7295.  
  7296. #chatLog::-webkit-scrollbar-thumb:hover {
  7297. background: rgba(0, 0, 0, 0.35);
  7298. }
  7299.  
  7300. #chatLog {
  7301. scrollbar-width: thin;
  7302. scrollbar-color: rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.1);
  7303. }
  7304.  
  7305. .chatMessage {
  7306. margin-bottom: 5px;
  7307. padding: 7px;
  7308. background-color: rgba(0, 0, 0, 0.25);
  7309. border-radius: 5px;
  7310. font-size: 13px;
  7311. }
  7312. `;
  7313. document.head.appendChild(style);
  7314.  
  7315. const chatLogBox = document.createElement('div');
  7316. chatLogBox.id = 'chatLog';
  7317. document.body.appendChild(chatLogBox);
  7318.  
  7319. function receiveChat(sid, message) {
  7320. let tmpPlayer = findPlayerBySID(sid);
  7321. tmpPlayer.chatMessage = message;
  7322. tmpPlayer.chatCountdown = config.chatCountdown;
  7323. const playerName = tmpPlayer.name;
  7324. const chatMessage = document.createElement('div');
  7325. chatMessage.textContent = `${playerName}: ${message}`;
  7326. chatMessage.classList.add('chatMessage');
  7327. chatLogBox.appendChild(chatMessage);
  7328. chatLogBox.scrollTop = chatLogBox.scrollHeight;
  7329. }
  7330.  
  7331. function updateMinimap(data) {
  7332. minimapData = data;
  7333. }
  7334.  
  7335. function showText(x, y, value, type) {
  7336. textManager.showText(x, y, 45, 0.1, 1000, Math.abs(value), value >= 0 ? "#FFB6C1" : "#da3e3e")
  7337. }
  7338.  
  7339. function renderLeaf(x, y, l, r, ctxt) {
  7340. let endX = x + (l * Math.cos(r));
  7341. let endY = y + (l * Math.sin(r));
  7342. let width = l * 0.4;
  7343. ctxt.moveTo(x, y);
  7344. ctxt.beginPath();
  7345. ctxt.quadraticCurveTo(((x + endX) / 2) + (width * Math.cos(r + Math.PI / 2)),
  7346. ((y + endY) / 2) + (width * Math.sin(r + Math.PI / 2)), endX, endY);
  7347. ctxt.quadraticCurveTo(((x + endX) / 2) - (width * Math.cos(r + Math.PI / 2)),
  7348. ((y + endY) / 2) - (width * Math.sin(r + Math.PI / 2)), x, y);
  7349. ctxt.closePath();
  7350. ctxt.fill();
  7351. ctxt.stroke();
  7352. }
  7353.  
  7354. function renderCircle(x, y, scale, tmpContext, dontStroke, dontFill) {
  7355. tmpContext = tmpContext || mainContext;
  7356. tmpContext.beginPath();
  7357. tmpContext.arc(x, y, scale, 0, 2 * Math.PI);
  7358. if (!dontFill) tmpContext.fill();
  7359. if (!dontStroke) tmpContext.stroke();
  7360. }
  7361.  
  7362. function renderHealthCircle(x, y, scale, tmpContext, dontStroke, dontFill) {
  7363. tmpContext = tmpContext || mainContext;
  7364. tmpContext.beginPath();
  7365. tmpContext.arc(x, y, scale, 0, 2 * Math.PI);
  7366. if (!dontFill) tmpContext.fill();
  7367. if (!dontStroke) tmpContext.stroke();
  7368. }
  7369.  
  7370. function renderStar(ctxt, spikes, outer, inner) {
  7371. let rot = Math.PI / 2 * 3;
  7372. let x, y;
  7373. let step = Math.PI / spikes;
  7374. ctxt.beginPath();
  7375. ctxt.moveTo(0, -outer);
  7376. for (let i = 0; i < spikes; i++) {
  7377. x = Math.cos(rot) * outer;
  7378. y = Math.sin(rot) * outer;
  7379. ctxt.lineTo(x, y);
  7380. rot += step;
  7381. x = Math.cos(rot) * inner;
  7382. y = Math.sin(rot) * inner;
  7383. ctxt.lineTo(x, y);
  7384. rot += step;
  7385. }
  7386. ctxt.lineTo(0, -outer);
  7387. ctxt.closePath();
  7388. }
  7389.  
  7390. function renderHealthStar(ctxt, spikes, outer, inner) {
  7391. let rot = Math.PI / 2 * 3;
  7392. let x, y;
  7393. let step = Math.PI / spikes;
  7394. ctxt.beginPath();
  7395. ctxt.moveTo(0, -outer);
  7396. for (let i = 0; i < spikes; i++) {
  7397. x = Math.cos(rot) * outer;
  7398. y = Math.sin(rot) * outer;
  7399. ctxt.lineTo(x, y);
  7400. rot += step;
  7401. x = Math.cos(rot) * inner;
  7402. y = Math.sin(rot) * inner;
  7403. ctxt.lineTo(x, y);
  7404. rot += step;
  7405. }
  7406. ctxt.lineTo(0, -outer);
  7407. ctxt.closePath();
  7408. }
  7409.  
  7410. function renderRect(x, y, w, h, ctxt, dontStroke, dontFill) {
  7411. if (!dontFill) ctxt.fillRect(x - (w / 2), y - (h / 2), w, h);
  7412. if (!dontStroke) ctxt.strokeRect(x - (w / 2), y - (h / 2), w, h);
  7413. }
  7414.  
  7415. function renderHealthRect(x, y, w, h, ctxt, dontStroke, dontFill) {
  7416. if (!dontFill) ctxt.fillRect(x - (w / 2), y - (h / 2), w, h);
  7417. if (!dontStroke) ctxt.strokeRect(x - (w / 2), y - (h / 2), w, h);
  7418. }
  7419.  
  7420. function renderRectCircle(x, y, s, sw, seg, ctxt, dontStroke, dontFill) {
  7421. ctxt.save();
  7422. ctxt.translate(x, y);
  7423. seg = Math.ceil(seg / 2);
  7424. for (let i = 0; i < seg; i++) {
  7425. renderRect(0, 0, s * 2, sw, ctxt, dontStroke, dontFill);
  7426. ctxt.rotate(Math.PI / seg);
  7427. }
  7428. ctxt.restore();
  7429. }
  7430.  
  7431. function renderBlob(ctxt, spikes, outer, inner) {
  7432. let rot = Math.PI / 2 * 3;
  7433. let x, y;
  7434. let step = Math.PI / spikes;
  7435. let tmpOuter;
  7436. ctxt.beginPath();
  7437. ctxt.moveTo(0, -inner);
  7438. for (let i = 0; i < spikes; i++) {
  7439. tmpOuter = UTILS.randInt(outer + 0.9, outer * 1.2);
  7440. ctxt.quadraticCurveTo(Math.cos(rot + step) * tmpOuter, Math.sin(rot + step) * tmpOuter,
  7441. Math.cos(rot + (step * 2)) * inner, Math.sin(rot + (step * 2)) * inner);
  7442. rot += step * 2;
  7443. }
  7444. ctxt.lineTo(0, -inner);
  7445. ctxt.closePath();
  7446. }
  7447.  
  7448. function renderTriangle(s, ctx) {
  7449. ctx = ctx || mainContext;
  7450. let h = s * (Math.sqrt(3) / 2);
  7451. ctx.beginPath();
  7452. ctx.moveTo(0, -h / 2);
  7453. ctx.lineTo(-s / 2, h / 2);
  7454. ctx.lineTo(s / 2, h / 2);
  7455. ctx.lineTo(0, -h / 2);
  7456. ctx.fill();
  7457. ctx.closePath();
  7458. }
  7459.  
  7460. function prepareMenuBackground() {
  7461.  
  7462. }
  7463.  
  7464. function renderPlayers(xOffset, yOffset, zIndex) {
  7465. mainContext.globalAlpha = 1;
  7466. mainContext.fillStyle = "#91b2db";
  7467. for (var i = 0; i < players.length; ++i) {
  7468. tmpObj = players[i];
  7469. if (tmpObj.zIndex == zIndex) {
  7470. tmpObj.animate(delta);
  7471. if (tmpObj.visible) {
  7472. tmpObj.skinRot += (0.002 * delta);
  7473. tmpDir = (tmpObj==player?getVisualDir():(tmpObj.dir || 0));
  7474. tmpObj.skinRot += (0.001 * delta);
  7475. tmpDir = (!configs.showDir && !useWasd && tmpObj == player) ? configs.attackDir ? getVisualDir() : getSafeDir() : (tmpObj.dir || 0);
  7476. mainContext.save();
  7477. mainContext.translate(tmpObj.x - xOffset, tmpObj.y - yOffset);
  7478. mainContext.rotate(tmpDir + tmpObj.dirPlus);
  7479. renderPlayer(tmpObj, mainContext);
  7480. mainContext.restore();
  7481. }
  7482. }
  7483. }
  7484. }
  7485.  
  7486.  
  7487. function renderPlayer(obj, ctxt) {
  7488. ctxt = ctxt || mainContext;
  7489. ctxt.lineWidth = outlineWidth;
  7490. ctxt.lineJoin = "miter";
  7491. let handAngle = (Math.PI / 4) * (items.weapons[obj.weaponIndex].armS || 1);
  7492. let oHandAngle = (obj.buildIndex < 0) ? (items.weapons[obj.weaponIndex].hndS || 1) : 1;
  7493. let oHandDist = (obj.buildIndex < 0) ? (items.weapons[obj.weaponIndex].hndD || 1) : 1;
  7494.  
  7495. let katanaMusket = (obj == player && obj.weapons[0] == 3 && obj.weapons[1] == 15);
  7496.  
  7497. if (obj.tailIndex > 0) {
  7498. renderTailTextureImage(obj.tailIndex, ctxt, obj);
  7499. }
  7500.  
  7501. if (obj.buildIndex < 0 && !items.weapons[obj.weaponIndex].aboveHand) {
  7502. renderTool(items.weapons[katanaMusket ? 4 : obj.weaponIndex], config.weaponVariants[obj.weaponVariant].src, obj.scale, 0, ctxt);
  7503. if (items.weapons[obj.weaponIndex].projectile != undefined && !items.weapons[obj.weaponIndex].hideProjectile) {
  7504. renderProjectile(obj.scale, 0,
  7505. items.projectiles[items.weapons[obj.weaponIndex].projectile], mainContext);
  7506. }
  7507. }
  7508.  
  7509. ctxt.fillStyle = config.skinColors[obj.skinColor];
  7510. renderCircle(obj.scale * Math.cos(handAngle), (obj.scale * Math.sin(handAngle)), 14);
  7511. renderCircle((obj.scale * oHandDist) * Math.cos(-handAngle * oHandAngle),
  7512. (obj.scale * oHandDist) * Math.sin(-handAngle * oHandAngle), 14);
  7513.  
  7514. if (obj.buildIndex < 0 && items.weapons[obj.weaponIndex].aboveHand) {
  7515. renderTool(items.weapons[obj.weaponIndex], config.weaponVariants[obj.weaponVariant].src, obj.scale, 0, ctxt);
  7516. if (items.weapons[obj.weaponIndex].projectile != undefined && !items.weapons[obj.weaponIndex].hideProjectile) {
  7517. renderProjectile(obj.scale, 0,
  7518. items.projectiles[items.weapons[obj.weaponIndex].projectile], mainContext);
  7519. }
  7520. }
  7521.  
  7522. if (obj.buildIndex >= 0) {
  7523. var tmpSprite = getItemSprite(items.list[obj.buildIndex]);
  7524. ctxt.drawImage(tmpSprite, obj.scale - items.list[obj.buildIndex].holdOffset, -tmpSprite.width / 2);
  7525. }
  7526.  
  7527. renderCircle(0, 0, obj.scale, ctxt);
  7528.  
  7529. if (obj.skinIndex > 0) {
  7530. ctxt.rotate(Math.PI / 2);
  7531. renderTextureSkin(obj.skinIndex, ctxt, null, obj);
  7532. }
  7533. }
  7534.  
  7535. var skinSprites2 = {};
  7536. var skinPointers2 = {};
  7537. function renderSkin2(index, ctxt, parentSkin, owner) {
  7538. tmpSkin = skinSprites2[index];
  7539. if (!tmpSkin) {
  7540. var tmpImage = new Image();
  7541. tmpImage.onload = function() {
  7542. this.isLoaded = true;
  7543. this.onload = null;
  7544. };
  7545. tmpImage.src = "https://moomoo.io/img/hats/hat_" + index + ".png";
  7546. skinSprites2[index] = tmpImage;
  7547. tmpSkin = tmpImage;
  7548. }
  7549. var tmpObj = parentSkin||skinPointers2[index];
  7550. if (!tmpObj) {
  7551. for (var i = 0; i < hats.length; ++i) {
  7552. if (hats[i].id == index) {
  7553. tmpObj = hats[i];
  7554. break;
  7555. }
  7556. }
  7557. skinPointers2[index] = tmpObj;
  7558. }
  7559. if (tmpSkin.isLoaded) {
  7560. ctxt.drawImage(tmpSkin, -tmpObj.scale/2, -tmpObj.scale/2, tmpObj.scale, tmpObj.scale);
  7561. }
  7562. if (!parentSkin && tmpObj.topSprite) {
  7563. ctxt.save();
  7564. ctxt.rotate(owner.skinRot);
  7565. renderSkin2(index + "_top", ctxt, tmpObj, owner);
  7566. ctxt.restore();
  7567. }
  7568. }
  7569.  
  7570. function renderTextureSkin(index, ctxt, parentSkin, owner) {
  7571. if (!(tmpSkin = skinSprites[index + (txt ? "lol" : 0)])) {
  7572. var tmpImage = new Image();
  7573. tmpImage.onload = function() {
  7574. this.isLoaded = true;
  7575. this.onload = null;
  7576. }
  7577. tmpImage.src = setSkinTextureImage(index, "hat", index);
  7578. skinSprites[index + (txt ? "lol" : 0)] = tmpImage;
  7579. tmpSkin = tmpImage;
  7580. }
  7581. var tmpObj = parentSkin||skinPointers[index];
  7582. if (!tmpObj) {
  7583. for (var i = 0; i < hats.length; ++i) {
  7584. if (hats[i].id == index) {
  7585. tmpObj = hats[i];
  7586. break;
  7587. }
  7588. }
  7589. skinPointers[index] = tmpObj;
  7590. }
  7591. if (tmpSkin.isLoaded) {
  7592. ctxt.drawImage(tmpSkin, -tmpObj.scale/2, -tmpObj.scale/2, tmpObj.scale, tmpObj.scale);
  7593. }
  7594. if (!parentSkin && tmpObj.topSprite) {
  7595. ctxt.save();
  7596. ctxt.rotate(owner.skinRot);
  7597. renderSkin(index + "_top", ctxt, tmpObj, owner);
  7598. ctxt.restore();
  7599. }
  7600. }
  7601.  
  7602. function setSkinTextureImage(id, type, id2) {
  7603. if (true) {
  7604. if(type == "acc") {
  7605. return ".././img/accessories/access_" + id + ".png";
  7606. } else if(type == "hat") {
  7607. return ".././img/hats/hat_" + id + ".png";
  7608. } else {
  7609. return ".././img/weapons/" + id + ".png";
  7610. }
  7611. }
  7612. }
  7613.  
  7614. let skinSprites = {};
  7615. let skinPointers = {};
  7616. let tmpSkin;
  7617.  
  7618. function renderSkin(index, ctxt, parentSkin, owner) {
  7619. tmpSkin = skinSprites[index];
  7620. if (!tmpSkin) {
  7621. let tmpImage = new Image();
  7622. tmpImage.onload = function() {
  7623. this.isLoaded = true;
  7624. this.onload = null;
  7625. };
  7626. tmpImage.src = "https://moomoo.io/img/hats/hat_" + index + ".png";
  7627. skinSprites[index] = tmpImage;
  7628. tmpSkin = tmpImage;
  7629. }
  7630. let tmpObj = parentSkin || skinPointers[index];
  7631. if (!tmpObj) {
  7632. for (let i = 0; i < hats.length; ++i) {
  7633. if (hats[i].id == index) {
  7634. tmpObj = hats[i];
  7635. break;
  7636. }
  7637. }
  7638. skinPointers[index] = tmpObj;
  7639. }
  7640. if (tmpSkin.isLoaded)
  7641. ctxt.drawImage(tmpSkin, -tmpObj.scale / 2, -tmpObj.scale / 2, tmpObj.scale, tmpObj.scale);
  7642. if (!parentSkin && tmpObj.topSprite) {
  7643. ctxt.save();
  7644. ctxt.rotate(owner.skinRot);
  7645. renderSkin(index + "_top", ctxt, tmpObj, owner);
  7646. ctxt.restore();
  7647. }
  7648. }
  7649.  
  7650.  
  7651. function setTailTextureImage(id, type, id2) {
  7652. if (true) {
  7653. if(type == "acc") {
  7654. return ".././img/accessories/access_" + id + ".png";
  7655. } else if(type == "hat") {
  7656. return ".././img/hats/hat_" + id + ".png";
  7657. } else {
  7658. return ".././img/weapons/" + id + ".png";
  7659. }
  7660. } else {
  7661. if(type == "acc") {
  7662. return ".././img/accessories/access_" + id + ".png";
  7663. } else if(type == "hat") {
  7664. return ".././img/hats/hat_" + id + ".png";
  7665. } else {
  7666. return ".././img/weapons/" + id + ".png";
  7667. }
  7668. }
  7669. }
  7670. function renderTailTextureImage(index, ctxt, owner) {
  7671. if (!(tmpSkin = accessSprites[index + (txt ? "lol" : 0)])) {
  7672. var tmpImage = new Image();
  7673. tmpImage.onload = function() {
  7674. this.isLoaded = true,
  7675. this.onload = null
  7676. }
  7677. ,
  7678. tmpImage.src = setTailTextureImage(index, "acc"),
  7679. accessSprites[index + (txt ? "lol" : 0)] = tmpImage,
  7680. tmpSkin = tmpImage;
  7681. }
  7682. var tmpObj = accessPointers[index];
  7683. if (!tmpObj) {
  7684. for (var i = 0; i < accessories.length; ++i) {
  7685. if (accessories[i].id == index) {
  7686. tmpObj = accessories[i];
  7687. break;
  7688. }
  7689. }
  7690. accessPointers[index] = tmpObj;
  7691. }
  7692. if (tmpSkin.isLoaded) {
  7693. ctxt.save();
  7694. ctxt.translate(-20 - (tmpObj.xOff||0), 0);
  7695. if (tmpObj.spin)
  7696. ctxt.rotate(owner.skinRot);
  7697. ctxt.drawImage(tmpSkin, -(tmpObj.scale/2), -(tmpObj.scale/2), tmpObj.scale, tmpObj.scale);
  7698. ctxt.restore();
  7699. }
  7700. }
  7701.  
  7702. let accessSprites = {};
  7703. let accessPointers = {};
  7704. var txt = true;
  7705.  
  7706. function renderTail(index, ctxt, owner) {
  7707. tmpSkin = accessSprites[index];
  7708. if (!tmpSkin) {
  7709. let tmpImage = new Image();
  7710. tmpImage.onload = function() {
  7711. this.isLoaded = true;
  7712. this.onload = null;
  7713. };
  7714. tmpImage.src = "https://moomoo.io/img/accessories/access_" + index + ".png";
  7715. accessSprites[index] = tmpImage;
  7716. tmpSkin = tmpImage;
  7717. }
  7718. let tmpObj = accessPointers[index];
  7719. if (!tmpObj) {
  7720. for (let i = 0; i < accessories.length; ++i) {
  7721. if (accessories[i].id == index) {
  7722. tmpObj = accessories[i];
  7723. break;
  7724. }
  7725. }
  7726. accessPointers[index] = tmpObj;
  7727. }
  7728. if (tmpSkin.isLoaded) {
  7729. ctxt.save();
  7730. ctxt.translate(-20 - (tmpObj.xOff || 0), 0);
  7731. if (tmpObj.spin)
  7732. ctxt.rotate(owner.skinRot);
  7733. ctxt.drawImage(tmpSkin, -(tmpObj.scale / 2), -(tmpObj.scale / 2), tmpObj.scale, tmpObj.scale);
  7734. ctxt.restore();
  7735. }
  7736. }
  7737.  
  7738. var accessSprites2 = {};
  7739. var accessPointers2 = {};
  7740. function renderTail2(index, ctxt, owner) {
  7741. tmpSkin = accessSprites2[index];
  7742. if (!tmpSkin) {
  7743. var tmpImage = new Image();
  7744. tmpImage.onload = function() {
  7745. this.isLoaded = true;
  7746. this.onload = null;
  7747. };
  7748. tmpImage.src = "https://moomoo.io/img/accessories/access_" + index + ".png";
  7749. accessSprites2[index] = tmpImage;
  7750. tmpSkin = tmpImage;
  7751. }
  7752. var tmpObj = accessPointers2[index];
  7753. if (!tmpObj) {
  7754. for (var i = 0; i < accessories.length; ++i) {
  7755. if (accessories[i].id == index) {
  7756. tmpObj = accessories[i];
  7757. break;
  7758. }
  7759. }
  7760. accessPointers2[index] = tmpObj;
  7761. }
  7762. if (tmpSkin.isLoaded) {
  7763. ctxt.save();
  7764. ctxt.translate(-20 - (tmpObj.xOff||0), 0);
  7765. if (tmpObj.spin)
  7766. ctxt.rotate(owner.skinRot);
  7767. ctxt.drawImage(tmpSkin, -(tmpObj.scale/2), -(tmpObj.scale/2), tmpObj.scale, tmpObj.scale);
  7768. ctxt.restore();
  7769. }
  7770. }
  7771.  
  7772. let toolSprites = {};
  7773. function renderTool(obj, variant, x, y, ctxt) {
  7774. let tmpSrc = obj.src + (variant || "");
  7775. let tmpSprite = toolSprites[tmpSrc];
  7776. if (!tmpSprite) {
  7777. tmpSprite = new Image();
  7778. tmpSprite.onload = function() {
  7779. this.isLoaded = true;
  7780. }
  7781. tmpSprite.src = "https://moomoo.io/img/weapons/" + tmpSrc + ".png";
  7782. toolSprites[tmpSrc] = tmpSprite;
  7783. }
  7784. if (tmpSprite.isLoaded)
  7785. ctxt.drawImage(tmpSprite, x + obj.xOff - (obj.length / 2), y + obj.yOff - (obj.width / 2), obj.length, obj.width);
  7786. }
  7787.  
  7788. function renderProjectiles(layer, xOffset, yOffset) {
  7789. for (let i = 0; i < projectiles.length; i++) {
  7790. tmpObj = projectiles[i];
  7791. if (tmpObj.active && tmpObj.layer == layer && tmpObj.inWindow) {
  7792. tmpObj.update(delta);
  7793. if (tmpObj.active && isOnScreen(tmpObj.x - xOffset, tmpObj.y - yOffset, tmpObj.scale)) {
  7794. mainContext.save();
  7795. mainContext.translate(tmpObj.x - xOffset, tmpObj.y - yOffset);
  7796. mainContext.rotate(tmpObj.dir);
  7797. renderProjectile(0, 0, tmpObj, mainContext, 1);
  7798. mainContext.restore();
  7799. }
  7800. }
  7801. };
  7802. }
  7803.  
  7804. let projectileSprites = {};
  7805.  
  7806. function renderProjectile(x, y, obj, ctxt, debug) {
  7807. if (obj.src) {
  7808. let tmpSrc = items.projectiles[obj.indx].src;
  7809. let tmpSprite = projectileSprites[tmpSrc];
  7810. if (!tmpSprite) {
  7811. tmpSprite = new Image();
  7812. tmpSprite.onload = function() {
  7813. this.isLoaded = true;
  7814. }
  7815. tmpSprite.src = "https://moomoo.io/img/weapons/" + tmpSrc + ".png";
  7816. projectileSprites[tmpSrc] = tmpSprite;
  7817. }
  7818. if (tmpSprite.isLoaded)
  7819. ctxt.drawImage(tmpSprite, x - (obj.scale / 2), y - (obj.scale / 2), obj.scale, obj.scale);
  7820. } else if (obj.indx == 1) {
  7821. ctxt.fillStyle = "#939393";
  7822. renderCircle(x, y, obj.scale, ctxt);
  7823. }
  7824. }
  7825.  
  7826. let aiSprites = {};
  7827.  
  7828. function renderAI(obj, ctxt) {
  7829. let tmpIndx = obj.index;
  7830. let tmpSprite = aiSprites[tmpIndx];
  7831. if (!tmpSprite) {
  7832. let tmpImg = new Image();
  7833. tmpImg.onload = function() {
  7834. this.isLoaded = true;
  7835. this.onload = null;
  7836. };
  7837. tmpImg.src = "https://moomoo.io/img/animals/" + obj.src + ".png";
  7838. tmpSprite = tmpImg;
  7839. aiSprites[tmpIndx] = tmpSprite;
  7840. }
  7841. if (tmpSprite.isLoaded) {
  7842. let tmpScale = obj.scale * 1.2 * (obj.spriteMlt || 1);
  7843. ctxt.drawImage(tmpSprite, -tmpScale, -tmpScale, tmpScale * 2, tmpScale * 2);
  7844. }
  7845. }
  7846.  
  7847. function renderWaterBodies(xOffset, yOffset, ctxt, padding) {
  7848.  
  7849. let tmpW = config.riverWidth + padding;
  7850. let tmpY = (config.mapScale / 2) - yOffset - (tmpW / 2);
  7851. if (tmpY < maxScreenHeight && tmpY + tmpW > 0) {
  7852. ctxt.fillRect(0, tmpY, maxScreenWidth, tmpW);
  7853. }
  7854. }
  7855.  
  7856. let gameObjectSprites = {};
  7857.  
  7858. function getResSprite(obj) {
  7859. let biomeID = (obj.y>=config.mapScale-config.snowBiomeTop)?2:((obj.y<=config.snowBiomeTop)?1:0);
  7860. let tmpIndex = (obj.type + "_" + obj.scale + "_" + biomeID);
  7861. let tmpSprite = gameObjectSprites[tmpIndex];
  7862. if (!tmpSprite) {
  7863. let tmpCanvas = document.createElement("canvas");
  7864. tmpCanvas.width = tmpCanvas.height = (obj.scale * 2.1) + outlineWidth;
  7865. let tmpContext = tmpCanvas.getContext('2d');
  7866. tmpContext.translate((tmpCanvas.width / 2), (tmpCanvas.height / 2));
  7867. tmpContext.rotate(UTILS.randFloat(0, Math.PI));
  7868. tmpContext.strokeStyle = outlineColor;
  7869. tmpContext.lineWidth = outlineWidth;
  7870. if (obj.type == 0) {
  7871. let tmpScale;
  7872. let tmpCount = 7;
  7873. tmpContext.globalAlpha = 1;
  7874. for (let i = 0; i < 2; ++i) {
  7875. tmpScale = tmpObj.scale * (!i?1:0.5);
  7876. renderStar(tmpContext, tmpCount, tmpScale, tmpScale * 0.7);
  7877. tmpContext.fillStyle = !biomeID?(!i?"#9ebf57":"#b4db62"):(!i?"#e3f1f4":"#fff");
  7878. tmpContext.fill();
  7879. if (!i) {
  7880. tmpContext.stroke();
  7881. tmpContext.globalAlpha = 1;
  7882. }
  7883. }
  7884. } else if (obj.type == 1) {
  7885. if (biomeID == 2) {
  7886. tmpContext.fillStyle = "#606060";
  7887. renderStar(tmpContext, 6, obj.scale * 0.3, obj.scale * 0.71);
  7888. tmpContext.fill();
  7889. tmpContext.stroke();
  7890. tmpContext.fillStyle = "#89a54c";
  7891. renderCircle(0, 0, obj.scale * 0.55, tmpContext);
  7892. tmpContext.fillStyle = "#a5c65b";
  7893. renderCircle(0, 0, obj.scale * 0.3, tmpContext, true);
  7894. } else {
  7895. renderBlob(tmpContext, 6, tmpObj.scale, tmpObj.scale * 0.7);
  7896. tmpContext.fillStyle = biomeID?"#e3f1f4":"#89a54c";
  7897. tmpContext.fill();
  7898. tmpContext.stroke();
  7899. tmpContext.fillStyle = biomeID?"#FFB6C1":"#FF6F61";
  7900. let tmpRange;
  7901. let berries = 4;
  7902. let rotVal = (Math.PI * 2) / berries;
  7903. for (let i = 0; i < berries; ++i) {
  7904. tmpRange = UTILS.randInt(tmpObj.scale/3.5, tmpObj.scale/2.3);
  7905. renderCircle(tmpRange * Math.cos(rotVal * i), tmpRange * Math.sin(rotVal * i),
  7906. UTILS.randInt(10, 12), tmpContext);
  7907. }
  7908. }
  7909. } else if (obj.type == 2 || obj.type == 3) {
  7910. tmpContext.fillStyle = (obj.type==2)?(biomeID==2?"#938d77":"#939393"):"#e0c655";
  7911. renderStar(tmpContext, 3, obj.scale, obj.scale);
  7912. tmpContext.fill();
  7913. tmpContext.stroke();
  7914. tmpContext.fillStyle = (obj.type==2)?(biomeID==2?"#b2ab90":"#bcbcbc"):"#ebdca3";
  7915. renderStar(tmpContext, 3, obj.scale * 0.55, obj.scale * 0.65);
  7916. tmpContext.fill();
  7917. }
  7918. tmpSprite = tmpCanvas;
  7919. gameObjectSprites[tmpIndex] = tmpSprite;
  7920. }
  7921. return tmpSprite;
  7922. }
  7923.  
  7924. let itemSprites = [];
  7925. function getItemSprite(obj, asIcon) {
  7926. let tmpSprite = itemSprites[obj.id];
  7927. if (!tmpSprite || asIcon) {
  7928. let tmpCanvas = document.createElement("canvas");
  7929. let reScale = ((!asIcon && obj.name == "windmill") ? items.list[4].scale : obj.scale);
  7930. tmpCanvas.width = tmpCanvas.height = (reScale * 2.5) + outlineWidth + (items.list[obj.id].spritePadding || 0);
  7931. if (config.useWebGl) {
  7932. let gl = tmpCanvas.getContext("webgl");
  7933. gl.clearColor(0, 0, 0, 0);
  7934. gl.clear(gl.COLOR_BUFFER_BIT);
  7935.  
  7936. let buffer = gl.createBuffer();
  7937. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  7938.  
  7939. function render(vs, fs, vertice, type) {
  7940.  
  7941. let vShader = gl.createShader(gl.VERTEX_SHADER);
  7942. gl.shaderSource(vShader, vs);
  7943. gl.compileShader(vShader);
  7944. gl.getShaderParameter(vShader, gl.COMPILE_STATUS);
  7945.  
  7946. let fShader = gl.createShader(gl.FRAGMENT_SHADER);
  7947. gl.shaderSource(fShader, fs);
  7948. gl.compileShader(fShader);
  7949. gl.getShaderParameter(fShader, gl.COMPILE_STATUS);
  7950.  
  7951. let program = gl.createProgram();
  7952. gl.attachShader(program, vShader);
  7953. gl.attachShader(program, fShader);
  7954. gl.linkProgram(program);
  7955. gl.getProgramParameter(program, gl.LINK_STATUS);
  7956. gl.useProgram(program);
  7957.  
  7958. let vertex = gl.getAttribLocation(program, "vertex");
  7959. gl.enableVertexAttribArray(vertex);
  7960. gl.vertexAttribPointer(vertex, 2, gl.FLOAT, false, 0, 0);
  7961.  
  7962. let vertices = vertice.length / 2;
  7963. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertice), gl.DYNAMIC_DRAW);
  7964. gl.drawArrays(type, 0, vertices);
  7965. }
  7966.  
  7967. function hexToRgb(hex) {
  7968. return hex.slice(1).match(/.{1,2}/g).map(g => parseInt(g, 16));
  7969. }
  7970.  
  7971. function getRgb(r, g, b) {
  7972. return [r / 255, g / 255, b / 255].join(", ");
  7973. }
  7974.  
  7975. let max = 100;
  7976. for (let i = 0; i < max; i++) {
  7977. let radian = (Math.PI * (i / (max / 2)));
  7978. render(`
  7979. precision mediump float;
  7980. attribute vec2 vertex;
  7981. void main(void) {
  7982. gl_Position = vec4(vertex, 0, 1);
  7983. }
  7984. `, `
  7985. precision mediump float;
  7986. void main(void) {
  7987. gl_FragColor = vec4(${getRgb(...hexToRgb("#fff"))}, 1);
  7988. }
  7989. `, [
  7990. 0 + (Math.cos(radian) * 0.5), 0 + (Math.sin(radian) * 0.5),
  7991. 0, 0,
  7992. ], gl.LINE_LOOP);
  7993. }
  7994. } else {
  7995. let tmpContext = tmpCanvas.getContext("2d");
  7996. tmpContext.translate((tmpCanvas.width / 2), (tmpCanvas.height / 2));
  7997. tmpContext.rotate(asIcon ? 0 : (Math.PI / 2));
  7998. tmpContext.strokeStyle = outlineColor;
  7999. tmpContext.lineWidth = outlineWidth * (asIcon ? (tmpCanvas.width / 81) : 1);
  8000. if (!asIcon) {
  8001. tmpContext.shadowColor = `rgba(0, 0, 0, ${Math.min(obj.name == "pit trap" ? 0.8 : 0.5, obj.alpha)})`;
  8002. }
  8003.  
  8004. if (obj.name == "apple") {
  8005. tmpContext.fillStyle = "#595f92";
  8006. renderCircle(0, 0, obj.scale, tmpContext);
  8007. tmpContext.fillStyle = "#5db1d7";
  8008. let leafDir = -(Math.PI / 2);
  8009. renderLeaf(obj.scale * Math.cos(leafDir), obj.scale * Math.sin(leafDir),
  8010. 25, leafDir + Math.PI / 2, tmpContext);
  8011. } else if (obj.name == "cookie") {
  8012. tmpContext.fillStyle = "#595f92";
  8013. renderCircle(0, 0, obj.scale, tmpContext);
  8014. tmpContext.fillStyle = "#f0fcfb";
  8015. let chips = 4;
  8016. let rotVal = (Math.PI * 2) / chips;
  8017. let tmpRange;
  8018. for (let i = 0; i < chips; ++i) {
  8019. tmpRange = UTILS.randInt(obj.scale / 2.5, obj.scale / 1.7);
  8020. renderCircle(tmpRange * Math.cos(rotVal * i), tmpRange * Math.sin(rotVal * i),
  8021. UTILS.randInt(4, 5), tmpContext, true);
  8022. }
  8023. } else if (obj.name == "cheese") {
  8024. tmpContext.fillStyle = "#595f92";
  8025. renderCircle(0, 0, obj.scale, tmpContext);
  8026. tmpContext.fillStyle = "#f0fcfb";
  8027. let chips = 4;
  8028. let rotVal = (Math.PI * 2) / chips;
  8029. let tmpRange;
  8030. for (let i = 0; i < chips; ++i) {
  8031. tmpRange = UTILS.randInt(obj.scale / 2.5, obj.scale / 1.7);
  8032. renderCircle(tmpRange * Math.cos(rotVal * i), tmpRange * Math.sin(rotVal * i),
  8033. UTILS.randInt(4, 5), tmpContext, true);
  8034. }
  8035. } else if (obj.name == "wood wall" || obj.name == "stone wall" || obj.name == "castle wall") {
  8036. tmpContext.fillStyle = (obj.name == "castle wall") ? "#595f92" : (obj.name == "wood wall") ?
  8037. "#595f92" : "#263860";
  8038. let sides = (obj.name == "castle wall") ? 4 : 3;
  8039. renderStar(tmpContext, sides, obj.scale * 1.1, obj.scale * 1.1);
  8040. tmpContext.fill();
  8041. tmpContext.stroke();
  8042. tmpContext.fillStyle = (obj.name == "castle wall") ? "#9da4aa" : (obj.name == "wood wall") ?
  8043. "#c9b758" : "#bcbcbc";
  8044. renderStar(tmpContext, sides, obj.scale * 0.65, obj.scale * 0.65);
  8045. tmpContext.fill();
  8046. } else if (obj.name == "spikes" || obj.name == "greater spikes" || obj.name == "poison spikes" ||
  8047. obj.name == "spinning spikes") {
  8048. tmpContext.fillStyle = (obj.name == "poison spikes") ? "#7b935d" : "#939393";
  8049. let tmpScale = (obj.scale * 0.6);
  8050. renderStar(tmpContext, (obj.name == "spikes") ? 5 : 6, obj.scale, tmpScale);
  8051. tmpContext.fill();
  8052. tmpContext.stroke();
  8053. tmpContext.fillStyle = "#a5974c";
  8054. renderCircle(0, 0, tmpScale, tmpContext);
  8055. tmpContext.fillStyle = "#7DDA58";
  8056. renderCircle(0, 0, tmpScale / 2, tmpContext, true);
  8057. } else if (obj.name == "windmill" || obj.name == "faster windmill" || obj.name == "power mill") {
  8058. tmpContext.fillStyle = "#a5974c";
  8059. renderCircle(0, 0, reScale, tmpContext);
  8060. tmpContext.fillStyle = "#c9b758";
  8061. renderRectCircle(0, 0, reScale * 1.5, 29, 4, tmpContext);
  8062. tmpContext.fillStyle = "#a5974c";
  8063. renderCircle(0, 0, reScale * 0.5, tmpContext);
  8064. } else if (obj.name == "mine") {
  8065. tmpContext.fillStyle = "#939393";
  8066. renderStar(tmpContext, 3, obj.scale, obj.scale);
  8067. tmpContext.fill();
  8068. tmpContext.stroke();
  8069. tmpContext.fillStyle = "#bcbcbc";
  8070. renderStar(tmpContext, 3, obj.scale * 0.55, obj.scale * 0.65);
  8071. tmpContext.fill();
  8072. } else if (obj.name == "sapling") {
  8073. for (let i = 0; i < 2; ++i) {
  8074. let tmpScale = obj.scale * (!i ? 1 : 0.5);
  8075. renderStar(tmpContext, 7, tmpScale, tmpScale * 0.7);
  8076. tmpContext.fillStyle = (!i ? "#9ebf57" : "#b4db62");
  8077. tmpContext.fill();
  8078. if (!i) tmpContext.stroke();
  8079. }
  8080. } else if (obj.name == "pit trap") {
  8081. tmpContext.fillStyle = "#a5974c";
  8082. renderStar(tmpContext, 3, obj.scale * 1.1, obj.scale * 1.1);
  8083. tmpContext.fill();
  8084. tmpContext.stroke();
  8085. tmpContext.fillStyle = outlineColor;
  8086. renderStar(tmpContext, 3, obj.scale * 0.65, obj.scale * 0.65);
  8087. tmpContext.fill();
  8088. } else if (obj.name == "boost pad") {
  8089. tmpContext.fillStyle = "#7e7f82";
  8090. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8091. tmpContext.fill();
  8092. tmpContext.stroke();
  8093. tmpContext.fillStyle = "#dbd97d";
  8094. renderTriangle(obj.scale * 1, tmpContext);
  8095. } else if (obj.name == "turret") {
  8096. tmpContext.fillStyle = "#a5974c";
  8097. renderCircle(0, 0, obj.scale, tmpContext);
  8098. tmpContext.fill();
  8099. tmpContext.stroke();
  8100. tmpContext.fillStyle = "#939393";
  8101. let tmpLen = 50;
  8102. renderRect(0, -tmpLen / 2, obj.scale * 0.9, tmpLen, tmpContext);
  8103. renderCircle(0, 0, obj.scale * 0.6, tmpContext);
  8104. tmpContext.fill();
  8105. tmpContext.stroke();
  8106. } else if (obj.name == "platform") {
  8107. tmpContext.fillStyle = "#cebd5f";
  8108. let tmpCount = 4;
  8109. let tmpS = obj.scale * 2;
  8110. let tmpW = tmpS / tmpCount;
  8111. let tmpX = -(obj.scale / 2);
  8112. for (let i = 0; i < tmpCount; ++i) {
  8113. renderRect(tmpX - (tmpW / 2), 0, tmpW, obj.scale * 2, tmpContext);
  8114. tmpContext.fill();
  8115. tmpContext.stroke();
  8116. tmpX += tmpS / tmpCount;
  8117. }
  8118. } else if (obj.name == "healing pad") {
  8119. tmpContext.fillStyle = "#7e7f82";
  8120. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8121. tmpContext.fill();
  8122. tmpContext.stroke();
  8123. tmpContext.fillStyle = "#db6e6e";
  8124. renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true);
  8125. } else if (obj.name == "spawn pad") {
  8126. tmpContext.fillStyle = "#7e7f82";
  8127. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8128. tmpContext.fill();
  8129. tmpContext.stroke();
  8130. tmpContext.fillStyle = "#71aad6";
  8131. renderCircle(0, 0, obj.scale * 0.6, tmpContext);
  8132. } else if (obj.name == "blocker") {
  8133. tmpContext.fillStyle = "#7e7f82";
  8134. renderCircle(0, 0, obj.scale, tmpContext);
  8135. tmpContext.fill();
  8136. tmpContext.stroke();
  8137. tmpContext.rotate(Math.PI / 4);
  8138. tmpContext.fillStyle = "#db6e6e";
  8139. renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true);
  8140. } else if (obj.name == "teleporter") {
  8141. tmpContext.fillStyle = "#7e7f82";
  8142. renderCircle(0, 0, obj.scale, tmpContext);
  8143. tmpContext.fill();
  8144. tmpContext.stroke();
  8145. tmpContext.rotate(Math.PI / 4);
  8146. tmpContext.fillStyle = "#d76edb";
  8147. renderCircle(0, 0, obj.scale * 0.5, tmpContext, true);
  8148. }
  8149. }
  8150. tmpSprite = tmpCanvas;
  8151. if (!asIcon) {
  8152. itemSprites[obj.id] = tmpSprite;
  8153. }
  8154. }
  8155. return tmpSprite;
  8156. }
  8157.  
  8158.  
  8159. function getItemSprite2(obj, tmpX, tmpY) {
  8160. let tmpContext = mainContext;
  8161. let reScale = (obj.name == "windmill" ? items.list[4].scale : obj.scale);
  8162. tmpContext.save();
  8163. tmpContext.translate(tmpX, tmpY);
  8164. tmpContext.rotate(obj.dir);
  8165. tmpContext.strokeStyle = outlineColor;
  8166. tmpContext.lineWidth = outlineWidth;
  8167. if (obj.name == "apple") {
  8168. tmpContext.fillStyle = "#c15555";
  8169. renderCircle(0, 0, obj.scale, tmpContext);
  8170. tmpContext.fillStyle = "#89a54c";
  8171. let leafDir = -(Math.PI / 2);
  8172. renderLeaf(obj.scale * Math.cos(leafDir), obj.scale * Math.sin(leafDir),
  8173. 25, leafDir + Math.PI / 2, tmpContext);
  8174. } else if (obj.name == "cookie") {
  8175. tmpContext.fillStyle = "#cca861";
  8176. renderCircle(0, 0, obj.scale, tmpContext);
  8177. tmpContext.fillStyle = "#937c4b";
  8178. let chips = 4;
  8179. let rotVal = (Math.PI * 2) / chips;
  8180. let tmpRange;
  8181. for (let i = 0; i < chips; ++i) {
  8182. tmpRange = UTILS.randInt(obj.scale / 2.5, obj.scale / 1.7);
  8183. renderCircle(tmpRange * Math.cos(rotVal * i), tmpRange * Math.sin(rotVal * i),
  8184. UTILS.randInt(4, 5), tmpContext, true);
  8185. }
  8186. } else if (obj.name == "cheese") {
  8187. tmpContext.fillStyle = "#f4f3ac";
  8188. renderCircle(0, 0, obj.scale, tmpContext);
  8189. tmpContext.fillStyle = "#c3c28b";
  8190. let chips = 4;
  8191. let rotVal = (Math.PI * 2) / chips;
  8192. let tmpRange;
  8193. for (let i = 0; i < chips; ++i) {
  8194. tmpRange = UTILS.randInt(obj.scale / 2.5, obj.scale / 1.7);
  8195. renderCircle(tmpRange * Math.cos(rotVal * i), tmpRange * Math.sin(rotVal * i),
  8196. UTILS.randInt(4, 5), tmpContext, true);
  8197. }
  8198. } else if (obj.name == "wood wall" || obj.name == "stone wall" || obj.name == "castle wall") {
  8199. tmpContext.fillStyle = (obj.name == "castle wall") ? "#83898e" : (obj.name == "wood wall") ?
  8200. "#a5974c" : "#939393";
  8201. let sides = (obj.name == "castle wall") ? 4 : 3;
  8202. renderStar(tmpContext, sides, obj.scale * 1.1, obj.scale * 1.1);
  8203. tmpContext.fill();
  8204. tmpContext.stroke();
  8205. tmpContext.fillStyle = (obj.name == "castle wall") ? "#9da4aa" : (obj.name == "wood wall") ?
  8206. "#c9b758" : "#bcbcbc";
  8207. renderStar(tmpContext, sides, obj.scale * 0.65, obj.scale * 0.65);
  8208. tmpContext.fill();
  8209. } else if (obj.name == "spikes" || obj.name == "greater spikes" || obj.name == "poison spikes" ||
  8210. obj.name == "spinning spikes") {
  8211. tmpContext.fillStyle = (obj.name == "poison spikes") ? "#7b935d" : "#939393";
  8212. let tmpScale = (obj.scale * 0.6);
  8213. renderStar(tmpContext, (obj.name == "spikes") ? 5 : 6, obj.scale, tmpScale);
  8214. tmpContext.fill();
  8215. tmpContext.stroke();
  8216. tmpContext.fillStyle = "#a5974c";
  8217. renderCircle(0, 0, tmpScale, tmpContext);
  8218. tmpContext.fillStyle = "#c9b758";
  8219. renderCircle(0, 0, tmpScale / 2, tmpContext, true);
  8220. } else if (obj.name == "windmill" || obj.name == "faster windmill" || obj.name == "power mill") {
  8221. tmpContext.fillStyle = "#a5974c";
  8222. renderCircle(0, 0, reScale, tmpContext);
  8223. tmpContext.fillStyle = "#c9b758";
  8224. renderRectCircle(0, 0, reScale * 1.5, 29, 4, tmpContext);
  8225. tmpContext.fillStyle = "#a5974c";
  8226. renderCircle(0, 0, reScale * 0.5, tmpContext);
  8227. } else if (obj.name == "mine") {
  8228. tmpContext.fillStyle = "#939393";
  8229. renderStar(tmpContext, 3, obj.scale, obj.scale);
  8230. tmpContext.fill();
  8231. tmpContext.stroke();
  8232. tmpContext.fillStyle = "#bcbcbc";
  8233. renderStar(tmpContext, 3, obj.scale * 0.55, obj.scale * 0.65);
  8234. tmpContext.fill();
  8235. } else if (obj.name == "sapling") {
  8236. for (let i = 0; i < 2; ++i) {
  8237. let tmpScale = obj.scale * (!i ? 1 : 0.5);
  8238. renderStar(tmpContext, 7, tmpScale, tmpScale * 0.7);
  8239. tmpContext.fillStyle = (!i ? "#9ebf57" : "#b4db62");
  8240. tmpContext.fill();
  8241. if (!i) tmpContext.stroke();
  8242. }
  8243. } else if (obj.name == "pit trap") {
  8244. tmpContext.fillStyle = "#a5974c";
  8245. renderStar(tmpContext, 3, obj.scale * 1.1, obj.scale * 1.1);
  8246. tmpContext.fill();
  8247. tmpContext.stroke();
  8248. tmpContext.fillStyle = outlineColor;
  8249. renderStar(tmpContext, 3, obj.scale * 0.65, obj.scale * 0.65);
  8250. tmpContext.fill();
  8251. } else if (obj.name == "boost pad") {
  8252. tmpContext.fillStyle = "#7e7f82";
  8253. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8254. tmpContext.fill();
  8255. tmpContext.stroke();
  8256. tmpContext.fillStyle = "#dbd97d";
  8257. renderTriangle(obj.scale * 1, tmpContext);
  8258. } else if (obj.name == "turret") {
  8259. tmpContext.fillStyle = "#a5974c";
  8260. renderCircle(0, 0, obj.scale, tmpContext);
  8261. tmpContext.fill();
  8262. tmpContext.stroke();
  8263. tmpContext.fillStyle = "#939393";
  8264. let tmpLen = 50;
  8265. renderRect(0, -tmpLen / 2, obj.scale * 0.9, tmpLen, tmpContext);
  8266. renderCircle(0, 0, obj.scale * 0.6, tmpContext);
  8267. tmpContext.fill();
  8268. tmpContext.stroke();
  8269. } else if (obj.name == "platform") {
  8270. tmpContext.fillStyle = "#cebd5f";
  8271. let tmpCount = 4;
  8272. let tmpS = obj.scale * 2;
  8273. let tmpW = tmpS / tmpCount;
  8274. let tmpX = -(obj.scale / 2);
  8275. for (let i = 0; i < tmpCount; ++i) {
  8276. renderRect(tmpX - (tmpW / 2), 0, tmpW, obj.scale * 2, tmpContext);
  8277. tmpContext.fill();
  8278. tmpContext.stroke();
  8279. tmpX += tmpS / tmpCount;
  8280. }
  8281. } else if (obj.name == "healing pad") {
  8282. tmpContext.fillStyle = "#7e7f82";
  8283. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8284. tmpContext.fill();
  8285. tmpContext.stroke();
  8286. tmpContext.fillStyle = "#db6e6e";
  8287. renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true);
  8288. } else if (obj.name == "spawn pad") {
  8289. tmpContext.fillStyle = "#7e7f82";
  8290. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8291. tmpContext.fill();
  8292. tmpContext.stroke();
  8293. tmpContext.fillStyle = "#71aad6";
  8294. renderCircle(0, 0, obj.scale * 0.6, tmpContext);
  8295. } else if (obj.name == "blocker") {
  8296. tmpContext.fillStyle = "#7e7f82";
  8297. renderCircle(0, 0, obj.scale, tmpContext);
  8298. tmpContext.fill();
  8299. tmpContext.stroke();
  8300. tmpContext.rotate(Math.PI / 4);
  8301. tmpContext.fillStyle = "#db6e6e";
  8302. renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true);
  8303. } else if (obj.name == "teleporter") {
  8304. tmpContext.fillStyle = "#7e7f82";
  8305. renderCircle(0, 0, obj.scale, tmpContext);
  8306. tmpContext.fill();
  8307. tmpContext.stroke();
  8308. tmpContext.rotate(Math.PI / 4);
  8309. tmpContext.fillStyle = "#d76edb";
  8310. renderCircle(0, 0, obj.scale * 0.5, tmpContext, true);
  8311. }
  8312. tmpContext.restore();
  8313. }
  8314.  
  8315. let objSprites = [];
  8316.  
  8317. function getObjSprite(obj) {
  8318. let tmpSprite = objSprites[obj.id];
  8319. if (!tmpSprite) {
  8320. let tmpCanvas = document.createElement("canvas");
  8321. tmpCanvas.width = tmpCanvas.height = obj.scale * 2.5 + outlineWidth + (items.list[obj.id].spritePadding || 0);
  8322. let tmpContext = tmpCanvas.getContext("2d");
  8323. tmpContext.translate(tmpCanvas.width / 2, tmpCanvas.height / 2);
  8324. tmpContext.rotate(Math.PI / 2);
  8325. tmpContext.strokeStyle = outlineColor;
  8326. tmpContext.lineWidth = outlineWidth;
  8327. if (obj.name == "spikes" || obj.name == "greater spikes" || obj.name == "poison spikes" || obj.name == "spinning spikes") {
  8328. tmpContext.fillStyle = obj.name == "poison spikes" ? "#7b935d" : "#939393";
  8329. let tmpScale = obj.scale * 0.6;
  8330. renderStar(tmpContext, obj.name == "spikes" ? 5 : 6, obj.scale, tmpScale);
  8331. tmpContext.fill();
  8332. tmpContext.stroke();
  8333. tmpContext.fillStyle = "#a5974c";
  8334. renderCircle(0, 0, tmpScale, tmpContext);
  8335. tmpContext.fillStyle = "#E4080A";
  8336. renderCircle(0, 0, tmpScale / 2, tmpContext, true);
  8337. } else if (obj.name == "pit trap") {
  8338. tmpContext.fillStyle = "#a5974c";
  8339. renderStar(tmpContext, 3, obj.scale * 1.1, obj.scale * 1.1);
  8340. tmpContext.fill();
  8341. tmpContext.stroke();
  8342. tmpContext.fillStyle = "#E4080A";
  8343. renderStar(tmpContext, 3, obj.scale * 0.65, obj.scale * 0.65);
  8344. tmpContext.fill();
  8345. }
  8346. tmpSprite = tmpCanvas;
  8347. objSprites[obj.id] = tmpSprite;
  8348. }
  8349. return tmpSprite;
  8350. }
  8351.  
  8352. function getMarkSprite(obj, tmpContext, tmpX, tmpY) {
  8353. let center = {
  8354. x: screenWidth / 2,
  8355. y: screenHeight / 2,
  8356. };
  8357. tmpContext.lineWidth = outlineWidth;
  8358. mainContext.globalAlpha = 0.8;
  8359. tmpContext.strokeStyle = outlineColor;
  8360. tmpContext.save();
  8361. tmpContext.translate(tmpX, tmpY);
  8362. tmpContext.rotate(obj.dir || getAttackDir());
  8363. if (obj.name == "spikes" || obj.name == "greater spikes" || obj.name == "poison spikes" || obj.name == "spinning spikes") {
  8364. tmpContext.fillStyle = (obj.name == "poison spikes")?"#00ff00":"#00ff00";
  8365. var tmpScale = (obj.scale * 0.6);
  8366. renderStar(tmpContext, (obj.name == "spikes")?5:6, obj.scale, tmpScale);
  8367. tmpContext.fill();
  8368. tmpContext.stroke();
  8369. tmpContext.fillStyle = "#a5974c";
  8370. renderCircle(0, 0, tmpScale, tmpContext);
  8371. if (player && obj.owner && player.sid != obj.owner.sid && !tmpObj.findAllianceBySid(obj.owner.sid)) {
  8372. tmpContext.fillStyle = "#a34040";
  8373. } else {
  8374. tmpContext.fillStyle = "#c9b758";
  8375. }
  8376. renderCircle(0, 0, tmpScale/2, tmpContext, true);
  8377. } else if (obj.name == "turret") {
  8378. tmpContext.fillStyle = "#a5974c";
  8379. renderCircle(0, 0, obj.scale, tmpContext);
  8380. tmpContext.fill();
  8381. tmpContext.stroke();
  8382. tmpContext.fillStyle = "#939393";
  8383. let tmpLen = 50;
  8384. renderRect(0, -tmpLen / 2, obj.scale * 0.9, tmpLen, tmpContext);
  8385. renderCircle(0, 0, obj.scale * 0.6, tmpContext);
  8386. tmpContext.fill();
  8387. tmpContext.stroke();
  8388. } else if (obj.name == "teleporter") {
  8389. tmpContext.fillStyle = "#7e7f82";
  8390. renderCircle(0, 0, obj.scale, tmpContext);
  8391. tmpContext.fill();
  8392. tmpContext.stroke();
  8393. tmpContext.rotate(Math.PI / 4);
  8394. tmpContext.fillStyle = "#d76edb";
  8395. renderCircle(0, 0, obj.scale * 0.5, tmpContext, true);
  8396. } else if (obj.name == "platform") {
  8397. tmpContext.fillStyle = "#cebd5f";
  8398. let tmpCount = 4;
  8399. let tmpS = obj.scale * 2;
  8400. let tmpW = tmpS / tmpCount;
  8401. let tmpX = -(obj.scale / 2);
  8402. for (let i = 0; i < tmpCount; ++i) {
  8403. renderRect(tmpX - (tmpW / 2), 0, tmpW, obj.scale * 2, tmpContext);
  8404. tmpContext.fill();
  8405. tmpContext.stroke();
  8406. tmpX += tmpS / tmpCount;
  8407. }
  8408. } else if (obj.name == "healing pad") {
  8409. tmpContext.fillStyle = "#7e7f82";
  8410. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8411. tmpContext.fill();
  8412. tmpContext.stroke();
  8413. tmpContext.fillStyle = "#db6e6e";
  8414. renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true);
  8415. } else if (obj.name == "spawn pad") {
  8416. tmpContext.fillStyle = "#7e7f82";
  8417. renderRect(0, 0, obj.scale * 2, obj.scale * 2, tmpContext);
  8418. tmpContext.fill();
  8419. tmpContext.stroke();
  8420. tmpContext.fillStyle = "#71aad6";
  8421. renderCircle(0, 0, obj.scale * 0.6, tmpContext);
  8422. } else if (obj.name == "blocker") {
  8423. tmpContext.fillStyle = "#7e7f82";
  8424. renderCircle(0, 0, obj.scale, tmpContext);
  8425. tmpContext.fill();
  8426. tmpContext.stroke();
  8427. tmpContext.rotate(Math.PI / 4);
  8428. tmpContext.fillStyle = "#db6e6e";
  8429. renderRectCircle(0, 0, obj.scale * 0.65, 20, 4, tmpContext, true);
  8430. } else if (obj.name == "windmill" || obj.name == "faster windmill" || obj.name == "power mill") {
  8431. tmpContext.fillStyle = "#a5974c";
  8432. renderCircle(0, 0, obj.scale, tmpContext);
  8433. tmpContext.fillStyle = "#c9b758";
  8434. renderRectCircle(0, 0, obj.scale * 1.5, 29, 4, tmpContext);
  8435. tmpContext.fillStyle = "#a5974c";
  8436. renderCircle(0, 0, obj.scale * 0.5, tmpContext);
  8437. } else if (obj.name == "pit trap") {
  8438. tmpContext.fillStyle = "#a5974c";
  8439. renderStar(tmpContext, 3, obj.scale * 1.1, obj.scale * 1.1);
  8440. tmpContext.fill();
  8441. tmpContext.stroke();
  8442. if (player && obj.owner && player.sid != obj.owner.sid && !tmpObj.findAllianceBySid(obj.owner.sid)) {
  8443. tmpContext.fillStyle = "#a34040";
  8444. } else {
  8445. tmpContext.fillStyle = outlineColor;
  8446. }
  8447. renderStar(tmpContext, 3, obj.scale * 0.65, obj.scale * 0.65);
  8448. tmpContext.fill();
  8449. }
  8450. tmpContext.restore();
  8451. }
  8452.  
  8453. const renderDistance = 900;
  8454.  
  8455. function isOnScreen(x, y, s) {
  8456. const distanceSquared = (x - maxScreenWidth / 2) ** 2 + (y - maxScreenHeight / 2) ** 2;
  8457. // if you see this it means (SUPER T R A S H) is original owner of this mod.
  8458. return distanceSquared <= renderDistance ** 2;
  8459. }
  8460.  
  8461. function renderGameObjects(layer, xOffset, yOffset) {
  8462. let tmpSprite;
  8463. let tmpX;
  8464. let tmpY;
  8465. liztobj.forEach((tmp) => {
  8466. tmpObj = tmp;
  8467. if (tmpObj.active && liztobj.includes(tmp) && tmpObj.render) {
  8468. tmpX = tmpObj.x + tmpObj.xWiggle - xOffset;
  8469. tmpY = tmpObj.y + tmpObj.yWiggle - yOffset;
  8470. if (layer == 0) {
  8471. tmpObj.update(delta);
  8472. }
  8473. mainContext.globalAlpha = tmpObj.alpha;
  8474. if (tmpObj.layer == layer && isOnScreen(tmpX, tmpY)) {
  8475. if (tmpObj.isItem) {
  8476. if ((tmpObj.dmg || tmpObj.trap) && !tmpObj.isTeamObject(player)) {
  8477. tmpSprite = getObjSprite(tmpObj);
  8478. } else {
  8479. tmpSprite = getItemSprite(tmpObj);
  8480. }
  8481.  
  8482. mainContext.save();
  8483. mainContext.translate(tmpX, tmpY);
  8484. mainContext.rotate(tmpObj.dir);
  8485. if (!tmpObj.active) {
  8486. mainContext.scale(tmpObj.visScale / tmpObj.scale, tmpObj.visScale / tmpObj.scale);
  8487. }
  8488. mainContext.drawImage(tmpSprite, -(tmpSprite.width / 2), -(tmpSprite.height / 2));
  8489.  
  8490. if (tmpObj.blocker) {
  8491. mainContext.strokeStyle = "cyan";
  8492. mainContext.globalAlpha = 0.3;
  8493. mainContext.lineWidth = 6;
  8494. renderCircle(0, 0, tmpObj.blocker, mainContext, false, true);
  8495. }
  8496. mainContext.restore();
  8497. } else {
  8498. tmpSprite = getResSprite(tmpObj);
  8499. mainContext.drawImage(tmpSprite, tmpX - (tmpSprite.width / 2), tmpY - (tmpSprite.height / 2));
  8500. }
  8501. }
  8502. if (layer == 3) {
  8503. if (tmpObj.health < tmpObj.maxHealth) {
  8504. const radius = 25;
  8505. mainContext.strokeStyle = '#333';
  8506. mainContext.lineWidth = 5;
  8507. mainContext.fillStyle = '#FFF';
  8508. mainContext.beginPath();
  8509. mainContext.arc(tmpX, tmpY, radius + 5, 0, 2 * Math.PI);
  8510. mainContext.fill();
  8511. mainContext.stroke();
  8512.  
  8513. const healthAngle = (tmpObj.health / tmpObj.maxHealth) * 2 * Math.PI;
  8514. mainContext.fillStyle = tmpObj.isTeamObject(player) ? "#FFB6C1" : "#FF6F61";
  8515. mainContext.beginPath();
  8516. mainContext.moveTo(tmpX, tmpY);
  8517. mainContext.arc(tmpX, tmpY, radius, -Math.PI / 2, -Math.PI / 2 + healthAngle);
  8518. mainContext.lineTo(tmpX, tmpY);
  8519. mainContext.fill();
  8520. }
  8521. }
  8522. }
  8523. });
  8524.  
  8525. if (layer == 0) {
  8526. if (placeVisible.length) {
  8527. placeVisible.forEach((places) => {
  8528. tmpX = places.x - xOffset;
  8529. tmpY = places.y - yOffset;
  8530. markObject(places, tmpX, tmpY);
  8531. });
  8532. }
  8533. }
  8534. }
  8535.  
  8536.  
  8537. function markObject(tmpObj, tmpX, tmpY) {
  8538. getMarkSprite(tmpObj, mainContext, tmpX, tmpY);
  8539. }
  8540.  
  8541. class MapPing {
  8542. constructor(color, scale) {
  8543. this.init = function(x, y) {
  8544. this.scale = 0;
  8545. this.x = x;
  8546. this.y = y;
  8547. this.active = true;
  8548. };
  8549. this.update = function(ctxt, delta) {
  8550. if (this.active) {
  8551. this.scale += 0.05 * delta;
  8552. if (this.scale >= scale) {
  8553. this.active = false;
  8554. } else {
  8555. ctxt.globalAlpha = (1 - Math.max(0, this.scale / scale));
  8556. ctxt.beginPath();
  8557. ctxt.arc((this.x / config.mapScale) * mapDisplay.width, (this.y / config.mapScale) *
  8558. mapDisplay.width, this.scale, 0, 2 * Math.PI);
  8559. ctxt.stroke();
  8560. }
  8561. }
  8562. };
  8563. this.color = color;
  8564. }
  8565. }
  8566.  
  8567. function pingMap(x, y) {
  8568. tmpPing = mapPings.find(pings => !pings.active);
  8569. if (!tmpPing) {
  8570. tmpPing = new MapPing("#FFB6C1", config.mapPingScale);
  8571. mapPings.push(tmpPing);
  8572. }
  8573. tmpPing.init(x, y);
  8574. }
  8575.  
  8576. function updateMapMarker() {
  8577. mapMarker.x = player.x;
  8578. mapMarker.y = player.y;
  8579. }
  8580.  
  8581. function renderMinimap(delta) {
  8582. if (player && player.alive) {
  8583. mapContext.clearRect(0, 0, mapDisplay.width, mapDisplay.height);
  8584.  
  8585. mapContext.lineWidth = 4;
  8586. for (let i = 0; i < mapPings.length; ++i) {
  8587. tmpPing = mapPings[i];
  8588. mapContext.strokeStyle = tmpPing.color;
  8589. tmpPing.update(mapContext, delta);
  8590. }
  8591.  
  8592. mapContext.globalAlpha = 1;
  8593. mapContext.fillStyle = "#FFB6C1";
  8594. renderCircle((player.x / config.mapScale) * mapDisplay.width,
  8595. (player.y / config.mapScale) * mapDisplay.height, 7, mapContext, true);
  8596. mapContext.fillStyle = "rgba(255, 182, 193, 0.35)";
  8597. if (player.team && minimapData) {
  8598. for (let i = 0; i < minimapData.length;) {
  8599. renderCircle((minimapData[i] / config.mapScale) * mapDisplay.width,
  8600. (minimapData[i + 1] / config.mapScale) * mapDisplay.height, 7, mapContext, true);
  8601. i += 2;
  8602. }
  8603. }
  8604.  
  8605. if (lastDeath) {
  8606. mapContext.fillStyle = "#fc5553";
  8607. mapContext.font = "34px 'Comic Sans MS', cursive";
  8608. mapContext.textBaseline = "middle";
  8609. mapContext.textAlign = "center";
  8610. mapContext.fillText("x", (lastDeath.x / config.mapScale) * mapDisplay.width,
  8611. (lastDeath.y / config.mapScale) * mapDisplay.height);
  8612. }
  8613.  
  8614. if (mapMarker) {
  8615. mapContext.fillStyle = "#fff";
  8616. mapContext.font = "34px 'Comic Sans MS', cursive";
  8617. mapContext.textBaseline = "middle";
  8618. mapContext.textAlign = "center";
  8619. mapContext.fillText("x", (mapMarker.x / config.mapScale) * mapDisplay.width,
  8620. (mapMarker.y / config.mapScale) * mapDisplay.height);
  8621. }
  8622. }
  8623. }
  8624.  
  8625. let iconSprites = {};
  8626. let icons = ["crown", "skull"];
  8627.  
  8628. function loadIcons() {
  8629. for (let i = 0; i < icons.length; ++i) {
  8630. let tmpSprite = new Image();
  8631. tmpSprite.onload = function() {
  8632. this.isLoaded = true;
  8633. };
  8634. tmpSprite.src = "./../img/icons/" + icons[i] + ".png";
  8635. iconSprites[icons[i]] = tmpSprite;
  8636. }
  8637. }
  8638. loadIcons();
  8639.  
  8640. function cdf (e, t){
  8641. try {
  8642. return Math.hypot((t.y2||t.y)-(e.y2||e.y), (t.x2||t.x)-(e.x2||e.x));
  8643. } catch(e){
  8644. return Infinity;
  8645. }
  8646. }
  8647.  
  8648. function updateGame() {
  8649. if(gameObjects.length && inGame) {
  8650. gameObjects.forEach((tmp) => {
  8651. if(UTILS.getDistance(tmp.x, tmp.y, player.x, player.y) <= 1200) {
  8652. if(!liztobj.includes(tmp)) {
  8653. liztobj.push(tmp);
  8654. tmp.render = true;
  8655. }
  8656. } else {
  8657. if(liztobj.includes(tmp)) {
  8658. if(UTILS.getDistance(tmp.x, tmp.y, player.x, player.y) >= 1200) {
  8659. tmp.render = false;
  8660. const index = liztobj.indexOf(tmp);
  8661. if (index > -1) {
  8662. liztobj.splice(index, 1);
  8663. }
  8664. }
  8665. } else if(UTILS.getDistance(tmp.x, tmp.y, player.x, player.y) >= 1200) {
  8666. tmp.render = false;
  8667. const index = liztobj.indexOf(tmp);
  8668. if (index > -1) {
  8669. liztobj.splice(index, 1);
  8670. }
  8671. } else {
  8672. tmp.render = false;
  8673. const index = liztobj.indexOf(tmp);
  8674. if (index > -1) {
  8675. liztobj.splice(index, 1);
  8676. }
  8677. }
  8678. }
  8679. })
  8680. }
  8681.  
  8682. mainContext.beginPath();
  8683. mainContext.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
  8684. mainContext.globalAlpha = 1;
  8685.  
  8686. if (player) {
  8687. let easingFactor = 0.1;
  8688. camX += (player.x - camX) * easingFactor;
  8689. camY += (player.y - camY) * easingFactor;
  8690. let time = performance.now() * 0.002;
  8691. let floatFactor = 1.5;
  8692. camX += floatFactor * Math.sin(time);
  8693. camY += floatFactor * Math.cos(time);
  8694. } else {
  8695. camX = config.mapScale / 2;
  8696. camY = config.mapScale / 2;
  8697. }
  8698.  
  8699. let lastTime = now - (1000 / config.serverUpdateRate);
  8700. let tmpDiff;
  8701. for (let i = 0; i < players.length + ais.length; ++i) {
  8702. tmpObj = players[i] || ais[i - players.length];
  8703. if (tmpObj && tmpObj.visible) {
  8704. if (tmpObj.forcePos) {
  8705. tmpObj.x = tmpObj.x2;
  8706. tmpObj.y = tmpObj.y2;
  8707. tmpObj.dir = tmpObj.d2;
  8708. } else {
  8709. let total = tmpObj.t2 - tmpObj.t1;
  8710. let fraction = lastTime - tmpObj.t1;
  8711. let ratio = (fraction / total);
  8712. let rate = 170;
  8713. tmpObj.dt += delta;
  8714. let tmpRate = Math.min(1.7, tmpObj.dt / rate);
  8715. tmpDiff = (tmpObj.x2 - tmpObj.x1);
  8716. tmpObj.x = tmpObj.x1 + (tmpDiff * tmpRate);
  8717. tmpDiff = (tmpObj.y2 - tmpObj.y1);
  8718. tmpObj.y = tmpObj.y1 + (tmpDiff * tmpRate);
  8719. if (config.anotherVisual) {
  8720. tmpObj.dir = Math.lerpAngle(tmpObj.d2, tmpObj.d1, Math.min(1.2, ratio));
  8721. } else {
  8722. tmpObj.dir = Math.lerpAngle(tmpObj.d2, tmpObj.d1, Math.min(1.2, ratio));
  8723. }
  8724. }
  8725. }
  8726. }
  8727.  
  8728. let xOffset = camX - (maxScreenWidth / 2);
  8729. let yOffset = camY - (maxScreenHeight / 2);
  8730.  
  8731. if (config.snowBiomeTop - yOffset <= 0 && config.mapScale - config.snowBiomeTop - yOffset >= maxScreenHeight) {
  8732. mainContext.fillStyle = "#b6db66";
  8733. mainContext.fillRect(0, 0, maxScreenWidth, maxScreenHeight);
  8734. } else if (config.mapScale - config.snowBiomeTop - yOffset <= 0) {
  8735. mainContext.fillStyle = "#dbc666";
  8736. mainContext.fillRect(0, 0, maxScreenWidth, maxScreenHeight);
  8737. } else if (config.snowBiomeTop - yOffset >= maxScreenHeight) {
  8738. mainContext.fillStyle = "#fff";
  8739. mainContext.fillRect(0, 0, maxScreenWidth, maxScreenHeight);
  8740. } else if (config.snowBiomeTop - yOffset >= 0) {
  8741. mainContext.fillStyle = "#fff";
  8742. mainContext.fillRect(0, 0, maxScreenWidth, config.snowBiomeTop - yOffset);
  8743. mainContext.fillStyle = "#b6db66";
  8744. mainContext.fillRect(0, config.snowBiomeTop - yOffset, maxScreenWidth,
  8745. maxScreenHeight - (config.snowBiomeTop - yOffset));
  8746. } else {
  8747. mainContext.fillStyle = "#b6db66";
  8748. mainContext.fillRect(0, 0, maxScreenWidth,
  8749. (config.mapScale - config.snowBiomeTop - yOffset));
  8750. mainContext.fillStyle = "#dbc666";
  8751. mainContext.fillRect(0, (config.mapScale - config.snowBiomeTop - yOffset), maxScreenWidth,
  8752. maxScreenHeight - (config.mapScale - config.snowBiomeTop - yOffset));
  8753. }
  8754.  
  8755. if (!firstSetup) {
  8756. waterMult += waterPlus * config.waveSpeed * delta;
  8757. if (waterMult >= config.waveMax) {
  8758. waterMult = config.waveMax;
  8759. waterPlus = -1;
  8760. } else if (waterMult <= 1) {
  8761. waterMult = waterPlus = 1;
  8762. }
  8763. mainContext.globalAlpha = 1;
  8764. mainContext.fillStyle = "#dbc666";
  8765. renderWaterBodies(xOffset, yOffset, mainContext, config.riverPadding);
  8766. mainContext.fillStyle = "#91b2db";
  8767. renderWaterBodies(xOffset, yOffset, mainContext, (waterMult - 1) * 250);
  8768. }
  8769.  
  8770. mainContext.lineWidth = 6;
  8771. mainContext.strokeStyle = "#000";
  8772. mainContext.globalAlpha = 0.06;
  8773. mainContext.beginPath();
  8774. for (let x = -camX; x < maxScreenWidth; x += useWasd ? 60 : 60) {
  8775. if (x > 0) {
  8776. mainContext.moveTo(x, 0);
  8777. mainContext.lineTo(x, maxScreenHeight);
  8778. }
  8779. }
  8780. for (let y = -camY; y < maxScreenHeight; y += useWasd ? 60 : 60) {
  8781. if (y > 0) {
  8782. mainContext.moveTo(0, y);
  8783. mainContext.lineTo(maxScreenWidth, y);
  8784. }
  8785. }
  8786. mainContext.stroke();
  8787.  
  8788. mainContext.globalAlpha = 1;
  8789. mainContext.strokeStyle = outlineColor;
  8790. renderGameObjects(-1, xOffset, yOffset);
  8791.  
  8792. mainContext.globalAlpha = 1;
  8793. mainContext.lineWidth = outlineWidth;
  8794. renderProjectiles(0, xOffset, yOffset);
  8795.  
  8796. renderPlayers(xOffset, yOffset, 0);
  8797.  
  8798. mainContext.globalAlpha = 1;
  8799. for (let i = 0; i < ais.length; ++i) {
  8800. tmpObj = ais[i];
  8801. if (tmpObj.active && tmpObj.visible) {
  8802. tmpObj.animate(delta);
  8803. mainContext.save();
  8804. mainContext.translate(tmpObj.x - xOffset, tmpObj.y - yOffset);
  8805. mainContext.rotate(tmpObj.dir + tmpObj.dirPlus - (Math.PI / 2));
  8806. renderAI(tmpObj, mainContext);
  8807. mainContext.restore();
  8808. }
  8809. }
  8810.  
  8811. renderGameObjects(0, xOffset, yOffset);
  8812. renderProjectiles(1, xOffset, yOffset);
  8813. renderGameObjects(1, xOffset, yOffset);
  8814. renderPlayers(xOffset, yOffset, 1);
  8815. renderGameObjects(2, xOffset, yOffset);
  8816. renderGameObjects(3, xOffset, yOffset);
  8817.  
  8818. mainContext.fillStyle = "#000";
  8819. mainContext.globalAlpha = 0.09;
  8820. if (xOffset <= 0) {
  8821. mainContext.fillRect(0, 0, -xOffset, maxScreenHeight);
  8822. }
  8823. if (config.mapScale - xOffset <= maxScreenWidth) {
  8824. let tmpY = Math.max(0, -yOffset);
  8825. mainContext.fillRect(config.mapScale - xOffset, tmpY, maxScreenWidth - (config.mapScale - xOffset), maxScreenHeight - tmpY);
  8826. }
  8827. if (yOffset <= 0) {
  8828. mainContext.fillRect(-xOffset, 0, maxScreenWidth + xOffset, -yOffset);
  8829. }
  8830. if (config.mapScale - yOffset <= maxScreenHeight) {
  8831. let tmpX = Math.max(0, -xOffset);
  8832. let tmpMin = 0;
  8833. if (config.mapScale - xOffset <= maxScreenWidth)
  8834. tmpMin = maxScreenWidth - (config.mapScale - xOffset);
  8835. mainContext.fillRect(tmpX, config.mapScale - yOffset,
  8836. (maxScreenWidth - tmpX) - tmpMin, maxScreenHeight - (config.mapScale - yOffset));
  8837. }
  8838.  
  8839. mainContext.globalAlpha = 1;
  8840. mainContext.fillStyle = "rgba(0, 0, 70, 0.35)";
  8841. mainContext.fillRect(0, 0, maxScreenWidth, maxScreenHeight);
  8842.  
  8843. const FallenHero = {
  8844. darkOutline: "#880808",
  8845. healthBarFriend: "#7DDA58",
  8846. healthBarFoe: "#E4080A",
  8847. background: "#880808",
  8848. tracer: "#E4080A",
  8849. nameFill: "#000000"
  8850. };
  8851. mainContext.strokeStyle = FallenHero.darkOutline;
  8852. mainContext.globalAlpha = 1;
  8853. for (let i = 0; i < players.length + ais.length; ++i) {
  8854. tmpObj = players[i] || ais[i - players.length];
  8855. if (tmpObj.visible) {
  8856. mainContext.strokeStyle = FallenHero.darkOutline;
  8857. if (tmpObj.skinIndex != 10 || (tmpObj === player) || (tmpObj.team && tmpObj.team == player.team)) {
  8858. let tmpText = (tmpObj.team ? "[" + tmpObj.team + "] " : "") + (tmpObj.name || "") + (" [" + tmpObj.shameCount + "]");
  8859. if (!recording) {
  8860. player.name = originalName;
  8861. } else {
  8862. player.name = "unknown";
  8863. }
  8864. if (tmpText != "") {
  8865. mainContext.font = (tmpObj.nameScale || 30) + "px 'Comic Sans MS', cursive";
  8866. mainContext.fillStyle = FallenHero.nameFill;
  8867. mainContext.textBaseline = "middle";
  8868. mainContext.textAlign = "center";
  8869. mainContext.lineWidth = (tmpObj.nameScale ? 11 : 8);
  8870. mainContext.lineJoin = "round";
  8871. mainContext.strokeText(tmpText, tmpObj.x - xOffset, (tmpObj.y - yOffset - tmpObj.scale) - config.nameY);
  8872. mainContext.fillText(tmpText, tmpObj.x - xOffset, (tmpObj.y - yOffset - tmpObj.scale) - config.nameY);
  8873. config.healthBarPad = 4;
  8874. if (tmpObj.isLeader && iconSprites.crown.isLoaded) {
  8875. let tmpS = config.crownIconScale;
  8876. let tmpX = tmpObj.x - xOffset - (tmpS / 2) - (mainContext.measureText(tmpText).width / 2) - config.crownPad;
  8877. mainContext.drawImage(iconSprites.crown, tmpX, (tmpObj.y - yOffset - tmpObj.scale)
  8878. - config.nameY - (tmpS / 2) - 5, tmpS, tmpS);
  8879. }
  8880. if (tmpObj.iconIndex == 1 && iconSprites.skull.isLoaded) {
  8881. let tmpS = config.crownIconScale;
  8882. let tmpX = tmpObj.x - xOffset - (tmpS / 2) + (mainContext.measureText(tmpText).width / 2) + config.crownPad;
  8883. mainContext.drawImage(iconSprites.skull, tmpX, (tmpObj.y - yOffset - tmpObj.scale)
  8884. - config.nameY - (tmpS / 2) - 5, tmpS, tmpS);
  8885. }
  8886. if (tmpObj.isPlayer && instaC.wait && near == tmpObj && enemy.length) {
  8887. let tmpS = tmpObj.scale * 20;
  8888. mainContext.beginPath();
  8889. mainContext.arc(tmpObj.x - xOffset, tmpObj.y - yOffset, 3, 0, 2 * Math.PI);
  8890. mainContext.fillStyle = 'red';
  8891. mainContext.fill();
  8892. }
  8893. }
  8894. if (tmpObj.health > 0) {
  8895. mainContext.fillStyle = FallenHero.darkOutline;
  8896. mainContext.roundRect(
  8897. tmpObj.x - xOffset - (config.healthBarWidth + config.healthBarPad),
  8898. tmpObj.y - yOffset + tmpObj.scale + config.nameY,
  8899. (config.healthBarWidth * 2) + (config.healthBarPad * 2),
  8900. 17,
  8901. 8
  8902. );
  8903. mainContext.fill();
  8904.  
  8905. const healthBarColor = (tmpObj === player || (tmpObj.team && tmpObj.team === player.team)) ? FallenHero.healthBarFriend : FallenHero.healthBarFoe;
  8906. mainContext.fillStyle = healthBarColor;
  8907. mainContext.roundRect(
  8908. tmpObj.x - xOffset - config.healthBarWidth,
  8909. tmpObj.y - yOffset + tmpObj.scale + config.nameY + config.healthBarPad,
  8910. (config.healthBarWidth * 2) * (tmpObj.health / tmpObj.maxHealth),
  8911. 17 - (config.healthBarPad * 2),
  8912. 7
  8913. );
  8914. mainContext.fill();
  8915.  
  8916. mainContext.save();
  8917. if (tmpObj.isPlayer) {
  8918. let reloads = {
  8919. primary: (tmpObj.primaryIndex == undefined ? 1 : ((items.weapons[tmpObj.primaryIndex].speed - tmpObj.reloads[tmpObj.primaryIndex]) / items.weapons[tmpObj.primaryIndex].speed)),
  8920. secondary: (tmpObj.secondaryIndex == undefined ? 1 : ((items.weapons[tmpObj.secondaryIndex].speed - tmpObj.reloads[tmpObj.secondaryIndex]) / items.weapons[tmpObj.secondaryIndex].speed)),
  8921. turret: (2500 - tmpObj.reloads[53]) / 2500
  8922. };
  8923.  
  8924. const playerX = player.x - xOffset;
  8925. const playerY = player.y - yOffset;
  8926. const enemyX = tmpObj.x - xOffset;
  8927. const enemyY = tmpObj.y - yOffset;
  8928. const distance = Math.sqrt(Math.pow(playerX - enemyX, 2) + Math.pow(playerY - enemyY, 2));
  8929. const maxTracingDistance = 250;
  8930. if (!tmpObj.isTeam(player) && distance >= maxTracingDistance) {
  8931. mainContext.lineWidth = 3;
  8932. mainContext.strokeStyle = FallenHero.tracer;
  8933. mainContext.beginPath();
  8934. mainContext.moveTo(playerX, playerY);
  8935. mainContext.lineTo(enemyX, enemyY);
  8936. mainContext.stroke();
  8937. }
  8938. }
  8939. mainContext.restore();
  8940. }
  8941. }
  8942. }
  8943. }
  8944.  
  8945. textManager.update(delta, mainContext, xOffset, yOffset);
  8946.  
  8947. CanvasRenderingContext2D.prototype.roundRectWithTailAndEars = function(x, y, width, height, radius, tailSize, earSize) {
  8948. if (width < 2 * radius) radius = width / 2;
  8949. if (height < 2 * radius) radius = height / 2;
  8950. this.beginPath();
  8951. this.moveTo(x + radius, y);
  8952. this.arcTo(x + width, y, x + width, y + height, radius);
  8953. this.arcTo(x + width, y + height, x, y + height, radius);
  8954. this.arcTo(x, y + height, x, y, radius);
  8955. this.arcTo(x, y, x + width, y, radius);
  8956. this.closePath();
  8957.  
  8958. this.moveTo(x + width / 2 - tailSize / 2, y + height);
  8959. this.lineTo(x + width / 2, y + height + tailSize);
  8960. this.lineTo(x + width / 2 + tailSize / 2, y + height);
  8961. this.closePath();
  8962.  
  8963. this.moveTo(x + width / 4 - earSize / 2, y);
  8964. this.quadraticCurveTo(x + width / 4, y - earSize, x + width / 4 + earSize / 2, y);
  8965. this.closePath();
  8966.  
  8967. this.moveTo(x + 3 * width / 4 - earSize / 2, y);
  8968. this.quadraticCurveTo(x + 3 * width / 4, y - earSize, x + 3 * width / 4 + earSize / 2, y);
  8969. this.closePath();
  8970.  
  8971. return this;
  8972. };
  8973.  
  8974. players.forEach((tmp) => {
  8975. tmpObj = tmp;
  8976. if (tmpObj.visible && tmpObj.chatCountdown > 0) {
  8977. tmpObj.chatCountdown = Math.max(0, (tmpObj.chatCountdown -= delta));
  8978. mainContext.font = "32px 'Comic Sans MS', cursive";
  8979. var tmpSize = mainContext.measureText(tmpObj.chatMessage);
  8980. mainContext.textBaseline = "middle";
  8981. mainContext.textAlign = "center";
  8982. var tmpX = tmpObj.x - xOffset;
  8983. var tmpY = tmpObj.y - tmpObj.scale - yOffset - 90;
  8984. var tmpH = 47;
  8985. var tmpW = tmpSize.width + 30;
  8986. var padding = 10;
  8987. var tailSize = 12;
  8988. var earSize = 30;
  8989. var bubbleColor = "rgba(152, 245, 249)";
  8990. var textColor = "#fff";
  8991.  
  8992. mainContext.roundRectWithTailAndEars(tmpX - tmpW / 2, tmpY - tmpH / 2, tmpW, tmpH, 15, tailSize, earSize);
  8993. mainContext.fillStyle = bubbleColor;
  8994. mainContext.fill();
  8995.  
  8996. mainContext.fillStyle = textColor;
  8997. mainContext.fillText(tmpObj.chatMessage, tmpX, tmpY);
  8998. }
  8999. });
  9000.  
  9001. mainContext.globalAlpha = 1;
  9002. renderMinimap(delta);
  9003. }
  9004.  
  9005. window.requestAnimFrame = function() {
  9006. return null;
  9007. }
  9008. window.rAF = (function() {
  9009. return window.requestAnimationFrame ||
  9010. window.webkitRequestAnimationFrame ||
  9011. window.mozRequestAnimationFrame ||
  9012. function(callback) {
  9013. window.setTimeout(callback, 1000/9);
  9014. };
  9015. })();
  9016.  
  9017. function doUpdate() {
  9018. now = performance.now();
  9019. delta = now - lastUpdate;
  9020. lastUpdate = now;
  9021. updateGame();
  9022. rAF(doUpdate);
  9023. ms.avg = Math.round((ms.min+ms.max)/2);
  9024. }
  9025.  
  9026. prepareMenuBackground();
  9027. doUpdate();
  9028.  
  9029. function toggleUseless(boolean) {
  9030. getEl("instaType").disabled = boolean;
  9031. getEl("antiBullType").disabled = boolean;
  9032. getEl("predictType").disabled = boolean;
  9033. }
  9034. toggleUseless(useWasd);
  9035.  
  9036. window.debug = function() {
  9037. my.waitHit = 0;
  9038. my.autoAim = false;
  9039. instaC.isTrue = false;
  9040. traps.inTrap = false;
  9041. itemSprites = [];
  9042. objSprites = [];
  9043. gameObjectSprites = [];
  9044. skinSprites = [];
  9045. skinPointers = [];
  9046. skinSprites2 = [];
  9047. skinPointers2 = [];
  9048. accessSprites = [];
  9049. toolSprites = [];
  9050. projectileSprites = [];
  9051. aiSprites = [];
  9052. console.clear();
  9053. };
  9054.  
  9055. window.wasdMode = function() {
  9056. useWasd = !useWasd;
  9057. toggleUseless(useWasd);
  9058. };
  9059.  
  9060. window.startGrind = function() {
  9061. if (getEl("weaponGrind").checked) {
  9062. for (let i = 0; i < Math.PI * 2; i += Math.PI / 2) {
  9063. checkPlace(player.getItemType(22), i);
  9064. }
  9065. }
  9066. };
  9067.  
  9068. window.resBuild = function() {
  9069. if (gameObjects.length) {
  9070. gameObjects.forEach((tmp) => {
  9071. tmp.breakObj = false;
  9072. });
  9073. breakObjects = [];
  9074. }
  9075. };
  9076.  
  9077. window.toggleVisual = function() {
  9078. config.anotherVisual = !config.anotherVisual;
  9079. gameObjects.forEach((tmp) => {
  9080. if (tmp.active) {
  9081. tmp.dir = tmp.lastDir;
  9082. }
  9083. });
  9084. };
  9085.  
  9086. window.prepareUI = function(tmpObj) {
  9087. resize();
  9088. var chatBox = document.getElementById("chatBox");
  9089. var chatHolder = document.getElementById("chatHolder");
  9090. var suggestBox = document.createElement("div");
  9091. suggestBox.id = "suggestBox";
  9092.  
  9093. var prevChats = [];
  9094. var prevChatsIndex = 0;
  9095.  
  9096. function toggleChat() {
  9097. if (!usingTouch) {
  9098. if (chatHolder.style.display == "block") {
  9099. if (chatBox.value) {
  9100. sendChat(chatBox.value);
  9101. }
  9102. closeChat();
  9103. } else {
  9104. storeMenu.style.display = "none";
  9105. allianceMenu.style.display = "none";
  9106. chatHolder.style.display = "block";
  9107. chatBox.focus();
  9108. resetMoveDir();
  9109. }
  9110. } else {
  9111. setTimeout(function () {
  9112. var chatMessage = prompt("chat message");
  9113. if (chatMessage) {
  9114. sendChat(chatMessage);
  9115. }
  9116. }, 1);
  9117. }
  9118. chatBox.value = "";
  9119. (() => {
  9120. prevChatsIndex = 0;
  9121. })();
  9122. }
  9123.  
  9124. function closeChat() {
  9125. chatBox.value = "";
  9126. chatHolder.style.display = "none";
  9127. }
  9128.  
  9129. for (let i = 0; i < (items.list.length + items.weapons.length); ++i) {
  9130. (function (i) {
  9131. let tmpCanvas = document.createElement("canvas");
  9132. tmpCanvas.width = tmpCanvas.height = 66;
  9133. let tmpContext = tmpCanvas.getContext("2d");
  9134. tmpContext.translate((tmpCanvas.width / 2), (tmpCanvas.height / 2));
  9135. tmpContext.imageSmoothingEnabled = false;
  9136. tmpContext.webkitImageSmoothingEnabled = false;
  9137. tmpContext.mozImageSmoothingEnabled = false;
  9138.  
  9139. if (items.weapons[i]) {
  9140. tmpContext.rotate((Math.PI / 4) + Math.PI);
  9141. let tmpSprite = new Image();
  9142. toolSprites[items.weapons[i].src] = tmpSprite;
  9143. tmpSprite.onload = function () {
  9144. this.isLoaded = true;
  9145. let tmpPad = 1 / (this.height / this.width);
  9146. let tmpMlt = (items.weapons[i].iPad || 1);
  9147. tmpContext.drawImage(this, -(tmpCanvas.width * tmpMlt * config.iconPad * tmpPad) / 2, -(tmpCanvas.height * tmpMlt * config.iconPad) / 2,
  9148. tmpCanvas.width * tmpMlt * tmpPad * config.iconPad, tmpCanvas.height * tmpMlt * config.iconPad);
  9149. tmpContext.fillStyle = "rgba(0, 0, 70, 0.1)";
  9150. tmpContext.globalCompositeOperation = "source-atop";
  9151. tmpContext.fillRect(-tmpCanvas.width / 2, -tmpCanvas.height / 2, tmpCanvas.width, tmpCanvas.height);
  9152. getEl('actionBarItem' + i).style.backgroundImage = "url(" + tmpCanvas.toDataURL() + ")";
  9153. };
  9154. tmpSprite.src = "./../img/weapons/" + items.weapons[i].src + ".png";
  9155. let tmpUnit = getEl('actionBarItem' + i);
  9156. tmpUnit.onmouseover = UTILS.checkTrusted(function () {
  9157. showItemInfo(items.weapons[i], true);
  9158. });
  9159. tmpUnit.onclick = UTILS.checkTrusted(function () {
  9160. selectWeapon(tmpObj.weapons[items.weapons[i].type]);
  9161. });
  9162. UTILS.hookTouchEvents(tmpUnit);
  9163. } else {
  9164. let tmpSprite = getItemSprite(items.list[i - items.weapons.length], true);
  9165. let tmpScale = Math.min(tmpCanvas.width - config.iconPadding, tmpSprite.width);
  9166. tmpContext.globalAlpha = 1;
  9167. tmpContext.drawImage(tmpSprite, -tmpScale / 2, -tmpScale / 2, tmpScale, tmpScale);
  9168. tmpContext.fillStyle = "rgba(0, 0, 70, 0.1)";
  9169. tmpContext.globalCompositeOperation = "source-atop";
  9170. tmpContext.fillRect(-tmpScale / 2, -tmpScale / 2, tmpScale, tmpScale);
  9171. getEl('actionBarItem' + i).style.backgroundImage = "url(" + tmpCanvas.toDataURL() + ")";
  9172. let tmpUnit = getEl('actionBarItem' + i);
  9173. tmpUnit.onmouseover = UTILS.checkTrusted(function () {
  9174. showItemInfo(items.list[i - items.weapons.length]);
  9175. });
  9176. tmpUnit.onclick = UTILS.checkTrusted(function () {
  9177. selectToBuild(tmpObj.items[tmpObj.getItemType(i - items.weapons.length)]);
  9178. });
  9179. UTILS.hookTouchEvents(tmpUnit);
  9180. }
  9181. })(i);
  9182. }
  9183. };
  9184. window.profineTest = function(data) {
  9185. if (data) {
  9186. let name = data + "";
  9187. name = name.slice(0, config.maxNameLength);
  9188.  
  9189. return name;
  9190. }
  9191. };
  9192. // ==UserScript==
  9193. // @name New Userscript
  9194. // @namespace http://tampermonkey.net/
  9195. // @version 2024-10-28
  9196. // @description try to take over the world!
  9197. // @author You
  9198. // @match http://*/*
  9199. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9200. // @grant none
  9201. // ==/UserScript==
  9202.  
  9203. (function() {
  9204. 'use strict';
  9205.  
  9206. // Your code here...
  9207. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址