Frozen client v3

Good insta and heal

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