artorias

untched ok?

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

QingJ © 2025

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