.:HACKER:.

ESC menu

  1. // ==UserScript==
  2. // @name .:HACKER:.
  3. // @author unknown
  4. // @namespace http://tampermonkey.net/
  5. // @license MIT
  6. // @description ESC menu
  7. // @version finals
  8. // @match *://sploop.io/*
  9. // @run-at document-start
  10. // @icon https://cdn.discordapp.com/attachments/664899301247287298/878019963900817448/743a8ebae02a90a9b147c97fb03faff4.jpg
  11. // ==/UserScript==
  12. Function("(" + ((GM_info) => {
  13. var __webpack_modules__ = {
  14. 147: module => {
  15. module.exports = {
  16. i8: ""
  17. };
  18. }
  19. };
  20. var __webpack_module_cache__ = {};
  21. function __webpack_require__(moduleId) {
  22. var cachedModule = __webpack_module_cache__[moduleId];
  23. if (cachedModule !== undefined) {
  24. return cachedModule.exports;
  25. }
  26. var module = __webpack_module_cache__[moduleId] = {
  27. exports: {}
  28. };
  29. __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  30. return module.exports;
  31. }
  32. (() => {
  33. __webpack_require__.d = (exports, definition) => {
  34. for (var key in definition) {
  35. if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  36. Object.defineProperty(exports, key, {
  37. enumerable: true,
  38. get: definition[key]
  39. });
  40. }
  41. }
  42. };
  43. })();
  44. (() => {
  45. __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
  46. })();
  47. var __webpack_exports__ = {};
  48. (() => {
  49. __webpack_require__.d(__webpack_exports__, {
  50. sv: () => Sploop,
  51. Ih: () => controller,
  52. vU: () => error,
  53. cM: () => log,
  54. });
  55. var ELayer;
  56. (function(ELayer) {
  57. ELayer[ELayer["enemy"] = -1] = "enemy;"
  58. ELayer[ELayer["PLAYER"] = 0] = "PLAYER";
  59. ELayer[ELayer["HARDSPIKE"] = 2] = "HARDSPIKE";
  60. ELayer[ELayer["TRAP"] = 6] = "TRAP";
  61. ELayer[ELayer["SPIKE"] = 7] = "SPIKE";
  62. ELayer[ELayer["WOODWALL"] = 8] = "WOODWALL";
  63. ELayer[ELayer["BOOST"] = 10] = "BOOST";
  64. ELayer[ELayer["PROJECTILE"] = 12] = "PROJECTILE";
  65. ELayer[ELayer["WINDMILL"] = 13] = "WINDMILL";
  66. ELayer[ELayer["SPAWN"] = 15] = "SPAWN";
  67. ELayer[ELayer["POWERMILL"] = 16] = "POWERMILL";
  68. ELayer[ELayer["WOODFARM"] = 19] = "WOODFARM";
  69. ELayer[ELayer["CHERRYWOODFARM"] = 20] = "CHERRYWOODFARM";
  70.  
  71. })(ELayer || (ELayer = {}));
  72. const LayerDataArray = [ {
  73. id: ELayer.enemy,
  74. radius: 35,
  75. maxHealth: 100,
  76. Qa: 1
  77. },{
  78. id: ELayer.PLAYER,
  79. radius: 35,
  80. maxHealth: 100,
  81. Qa: 1
  82. }, {
  83. id: ELayer.STONE,
  84. shoot: true,
  85. radius: 75,
  86. Qa: 1,
  87. Pa: 1
  88. }, {
  89. id: ELayer.HARDSPIKE,
  90. shoot: true,
  91. qa: 35,
  92. radius: 45,
  93. maxHealth: 500,
  94. Qa: 1
  95. }, {
  96. id: ELayer.TREE,
  97. shoot: true,
  98. cannotShoot: true,
  99. radius: 90,
  100. Qa: 1,
  101. Ka: 1
  102. }, {
  103. id: ELayer.GOLD,
  104. shoot: true,
  105. radius: 76,
  106. Qa: 1,
  107. Xa: 5
  108. }, {
  109. id: ELayer.BUSH,
  110. shoot: true,
  111. radius: 50,
  112. Qa: 1,
  113. Na: 1
  114. }, {
  115. id: ELayer.TRAP,
  116. radius: 40,
  117. maxHealth: 500,
  118. Qa: 1
  119. }, {
  120. id: ELayer.SPIKE,
  121. shoot: true,
  122. qa: 20,
  123. radius: 45,
  124. maxHealth: 375,
  125. Ia: 20,
  126. Qa: 1
  127. }, {
  128. id: ELayer.WOODWALL,
  129. shoot: true,
  130. radius: 45,
  131. maxHealth: 380,
  132. Qa: 1
  133. }, {
  134. id: ELayer.PLATFORM,
  135. radius: 60,
  136. maxHealth: 300,
  137. Qa: 1
  138. }, {
  139. id: ELayer.BOOST,
  140. radius: 40,
  141. maxHealth: 300,
  142. Qa: 1
  143. }, {
  144. id: ELayer.LOOTBOX,
  145. radius: 40,
  146. maxHealth: 4,
  147. Qa: 1
  148. }, {
  149. id: ELayer.PROJECTILE,
  150. radius: 0,
  151. maxHealth: 0
  152. }, {
  153. id: ELayer.WINDMILL,
  154. shoot: true,
  155. radius: 45,
  156. maxHealth: 400,
  157. rotateSpeed: Math.PI / 4,
  158. Qa: 1
  159. }, {
  160. id: ELayer.COW,
  161. radius: 90,
  162. maxHealth: 380,
  163. animal: true,
  164. Qa: 1,
  165. Ja: 1.6,
  166. $a: 9,
  167. ts: 0
  168. }, {
  169. id: ELayer.SPAWN,
  170. shoot: true,
  171. radius: 50,
  172. maxHealth: 380,
  173. Qa: 1
  174. }, {
  175. id: ELayer.POWERMILL,
  176. shoot: true,
  177. radius: 54,
  178. maxHealth: 400,
  179. rotateSpeed: 0,
  180. Qa: 1
  181. }, {
  182. id: ELayer.CASTLESPIKE,
  183. shoot: true,
  184. qa: 5,
  185. radius: 42,
  186. maxHealth: 1200,
  187. Ia: 24,
  188. Qa: 1
  189. }, {
  190. id: ELayer.TURRET,
  191. shoot: true,
  192. radius: 45,
  193. maxHealth: 800,
  194. Qa: 1
  195. }, {
  196. id: ELayer.WOODFARM,
  197. shoot: true,
  198. cannotShoot: true,
  199. radius: 80,
  200. Qa: 1,
  201. Ka: 1
  202. }, {
  203. id: ELayer.CHERRYWOODFARM,
  204. shoot: true,
  205. cannotShoot: true,
  206. radius: 80,
  207. Qa: 1,
  208. Ka: 1
  209. }, {
  210. id: ELayer.STONEWARM,
  211. shoot: true,
  212. radius: 60,
  213. Qa: 1,
  214. Pa: 1
  215. }, {
  216. id: ELayer.CASTLEWALL,
  217. shoot: true,
  218. radius: 59,
  219. maxHealth: 1750,
  220. Qa: 1
  221. }, {
  222. id: ELayer.SHARK,
  223. radius: 90,
  224. maxHealth: 380,
  225. animal: true,
  226. Qa: 1,
  227. Ja: 1.2,
  228. $a: 49,
  229. qa: 14,
  230. ts: 3
  231. }, {
  232. id: ELayer.WOLF,
  233. radius: 50,
  234. maxHealth: 380,
  235. animal: true,
  236. Qa: 1,
  237. Ja: 1.6,
  238. $a: 17,
  239. qa: 14,
  240. ts: 0
  241. }, {
  242. id: ELayer.GOLDENCOW,
  243. radius: 90,
  244. maxHealth: 1e3,
  245. animal: true,
  246. Qa: 1,
  247. Ja: 1.6,
  248. $a: 17,
  249. qa: 19
  250. }, {
  251. id: ELayer.ROOF,
  252. radius: 50,
  253. maxHealth: 300,
  254. Qa: 1
  255. }, {
  256. id: ELayer.DRAGON,
  257. radius: 100,
  258. maxHealth: 5e3,
  259. animal: true,
  260. Qa: 1,
  261. Ja: 1.15,
  262. $a: 17,
  263. qa: 30,
  264. ts: 0
  265. }, {
  266. id: ELayer.MAMMOTH,
  267. radius: 90,
  268. maxHealth: 5e3,
  269. animal: true,
  270. Qa: 1,
  271. Ja: 1.6,
  272. $a: 17,
  273. qa: 30,
  274. ts: 1
  275. }, {
  276. id: ELayer.FIREBALL,
  277. radius: 100,
  278. maxHealth: 380,
  279. Qa: 1,
  280. Ja: .4,
  281. $a: 1,
  282. qa: 15,
  283. ts: 0
  284. }, {
  285. id: ELayer.CHEST,
  286. shoot: true,
  287. radius: 45,
  288. maxHealth: 380,
  289. Qa: 1,
  290. Xa: 50,
  291. Lr: 20
  292. }, {
  293. id: ELayer.DRAGONWALLBIG,
  294. shoot: true,
  295. radius: 92,
  296. Qa: 1,
  297. Pa: 1
  298. }, {
  299. id: ELayer.DRAGONWALLMEDIUM,
  300. shoot: true,
  301. radius: 92,
  302. Qa: 1,
  303. Pa: 1
  304. }, {
  305. id: ELayer.DRAGONWALLSMALL,
  306. shoot: true,
  307. radius: 58,
  308. Qa: 1,
  309. Pa: 1
  310. }, {
  311. id: ELayer.MAMMOTHWALL,
  312. shoot: true,
  313. radius: 92,
  314. Qa: 1,
  315. Pa: 0
  316. }, {
  317. id: ELayer.MAMMOTHWALLSMALL,
  318. shoot: true,
  319. radius: 20,
  320. Qa: 1,
  321. Pa: 0
  322. }, {
  323. id: ELayer.DUCK,
  324. radius: 20,
  325. maxHealth: 380,
  326. animal: true,
  327. Qa: 1,
  328. Ja: 1.6,
  329. $a: 9,
  330. ts: 0
  331. }, {
  332. id: ELayer.TELEPORT,
  333. shoot: true,
  334. radius: 35,
  335. maxHealth: 150,
  336. Qa: 1
  337. }, {
  338. id: ELayer.CACTUS,
  339. shoot: true,
  340. radius: 50,
  341. Qa: 1,
  342. Na: 5,
  343. qa: 20
  344. }, {
  345. id: ELayer.TORNADO,
  346. radius: 220,
  347. rotateSpeed: Math.PI / 4,
  348. Qa: 0,
  349. Na: 5,
  350. qa: 1
  351. } ];
  352. const LayerData = LayerDataArray;
  353. const LayerObjects = LayerData.filter((layer => layer.shoot));
  354. const Animals = LayerData.filter((layer => layer.animal));
  355. var EObjects;
  356. (function(EObjects) {
  357. EObjects[EObjects["BOOST"] = 6] = "BOOST";
  358. EObjects[EObjects["PLATFORM"] = 8] = "PLATFORM";
  359. EObjects[EObjects["TRAP"] = 9] = "TRAP";
  360. EObjects[EObjects["WINDMILL"] = 14] = "WINDMILL";
  361. EObjects[EObjects["SPAWN"] = 16] = "SPAWN";
  362. EObjects[EObjects["POWERMILL"] = 19] = "POWERMILL";
  363. EObjects[EObjects["ROOF"] = 48] = "ROOF";
  364. })(EObjects || (EObjects = {}));
  365. var PlacementType;
  366. (function(PlacementType) {
  367. PlacementType[PlacementType["DEFAULT"] = 0] = "DEFAULT";
  368. PlacementType[PlacementType["INVISIBLE"] = 1] = "INVISIBLE";
  369. PlacementType[PlacementType["HOLDING"] = 2] = "HOLDING";
  370. PlacementType[PlacementType["MACRO"] = 3] = "MACRO"
  371. })(PlacementType || (PlacementType = {}));
  372. var EServers;
  373. (function(EServers) {
  374. EServers["SAND_EU1"] = "SFRA";
  375. EServers["SAND_EU2"] = "SFRA2BIS";
  376. EServers["SAND_USA1"] = "SCA";
  377. EServers["SAND_USA2"] = "SCA2";
  378. EServers["SAND_AS1"] = "SGP";
  379. EServers["SAND_AS2"] = "SGP2";
  380. EServers["SAND_AS3"] = "SGP3BIS";
  381. EServers["NORM_EU1"] = "FRA1FFA";
  382. EServers["NORM_USA1"] = "CA1FFA";
  383. EServers["NORM_AS1"] = "SGP1FFA";
  384. EServers["BATTLE_USA1"] = "BRSCA";
  385. })(EServers || (EServers = {}));
  386. const selectData = {
  387. placementType: PlacementType,
  388. connectTo: EServers
  389. };
  390. var TargetReload;
  391. (function(TargetReload) {
  392. TargetReload[TargetReload["TURRET"] = 3e3] = "TURRET";
  393. TargetReload[TargetReload["HAT"] = 1300] = "HAT";
  394. TargetReload[TargetReload["DRAGON"] = 3e3] = "DRAGON";
  395. })(TargetReload || (TargetReload = {}));
  396. var Hit;
  397. (function(Hit) {
  398. Hit[Hit["CANNOT"] = 0] = "CANNOT";
  399. Hit[Hit["CAN"] = 1] = "CAN";
  400. Hit[Hit["NEEDDESTROY"] = 2] = "NEEDDESTROY";
  401. })(Hit || (Hit = {}));
  402. const Reload = {
  403. hat: {
  404. current: TargetReload.HAT,
  405. lerp: TargetReload.HAT,
  406. max: TargetReload.HAT,
  407. color: () => Settings.hatReloadBarColor
  408. },
  409. weapon: {
  410. current: 0,
  411. lerp: 0,
  412. max: 0,
  413. color: () => Settings.weaponReloadBarColor
  414. },
  415. turret: {
  416. current: TargetReload.TURRET,
  417. lerp: TargetReload.TURRET,
  418. max: TargetReload.TURRET,
  419. color: () => Settings.turretReloadBarColor
  420. },
  421. fireball: {
  422. current: TargetReload.DRAGON,
  423. lerp: TargetReload.DRAGON,
  424. max: TargetReload.DRAGON,
  425. color: () => Settings.fireballReloadBarColor
  426. }
  427. };
  428. class Storage {
  429. static get(key) {
  430. const item = localStorage.getItem(key);
  431. return item !== null ? JSON.parse(item) : null;
  432. }
  433. static set(key, value) {
  434. localStorage.setItem(key, JSON.stringify(value));
  435. }
  436. static delete(key) {
  437. const has = localStorage.hasOwnProperty(key) && key in localStorage;
  438. localStorage.removeItem(key);
  439. return has;
  440. }
  441. }
  442. const defaultSettings = {
  443. primary: "Digit1",
  444. secondary: "Digit2",
  445. heal: "KeyQ",
  446. wall: "Digit4",
  447. spike: "KeyV",
  448. bockquote: "Backquote",
  449. windmill: "KeyN",
  450. trap: "KeyF",
  451. turret: "KeyH",
  452. tree: "KeyU",
  453. platform: "KeyT",
  454. spawn: "KeyJ",
  455. up: "KeyW",
  456. left: "KeyA",
  457. down: "KeyS",
  458. right: "KeyD",
  459. autoattack: "KeyE",
  460. lockRotation: "KeyX",
  461. invisibleHit: 2,
  462. openChat: "Enter",
  463. upgradeScythe: "KeyL",
  464. unequip: "KeyI",
  465. bush: "KeyP",
  466. berserker: "KeyB",
  467. jungle: "...",
  468. crystal: "KeyC",
  469. spikegear: "KeyG",
  470. immunity: 4,
  471. boost: "ShiftLeft",
  472. applehat: "...",
  473. scuba: "...",
  474. hood: "Backquote",
  475. demolist: "KeyZ",
  476. placementType: PlacementType.INVISIBLE,
  477. placementSpeed: 1,
  478. autobed: false,
  479. automill: true,
  480. antiFireball: true,
  481. autoheal: true,
  482. jungleOnClown: false,
  483. lastHat: true,
  484. autoScuba: true,
  485. meleeAim: false,
  486. bowAim: true,
  487. spikeInstaAim: true,
  488. autosync: true,
  489. autoboostFollow: true,
  490. enemyTracers: true,
  491. teammateTracers: true,
  492. animalTracers: false,
  493. enemyColor: "#cc5151",
  494. teammateColor: "#8ecc51",
  495. animalColor: "#518ccc",
  496. arrows: true,
  497. rainbow: false,
  498. drawHP: true,
  499. showHoods: true,
  500. itemCounter: true,
  501. visualAim: true,
  502. hideMessages: false,
  503. customSkins: false,
  504. skin: Storage.get("skin") || 27,
  505. accessory: Storage.get("accessory") || 30,
  506. back: Storage.get("back") || 2,
  507. itemMarkers: true,
  508. teammateMarkers: true,
  509. enemyMarkers: true,
  510. trapActivated: true,
  511. itemMarkersColor: "#8ecc51",
  512. teammateMarkersColor: "#cfbc5f",
  513. enemyMarkersColor: "#cc5151",
  514. trapActivatedColor: "#48b2b8",
  515. hatReloadBar: true,
  516. hatReloadBarColor: "#5155cc",
  517. fireballReloadBar: true,
  518. fireballReloadBarColor: "#cf7148",
  519. turretReloadBar: true,
  520. turretReloadBarColor: "#51cc80",
  521. weaponReloadBar: true,
  522. weaponReloadBarColor: "#cc8251",
  523. smoothReloadBar: true,
  524. windmillRotation: false,
  525. possibleShots: true,
  526. autochat: true,
  527. autochatMessages: [ "Sploop Client", "What is it?", "The most advanced hack for Sploop.io!", "Download on greasyfork" ],
  528. kill: true,
  529. killMessage: "{NAME}, you suck! {KILL}x",
  530. autospawn: false,
  531. smoothZoom: true,
  532. skipUpgrades: true,
  533. invisHitToggle: false,
  534. reverseZoom: false,
  535. autoAccept: false,
  536. connectTo: "SFRA",
  537. menuTransparency: false,
  538. blindUsers: [ 0, 0, 0 ]
  539. };
  540. const settings = {
  541. primary: "Digit1",
  542. secondary: "Digit2",
  543. heal: "KeyQ",
  544. wall: "Digit4",
  545. spike: "KeyV",
  546. bockquote: "Backquote",
  547. windmill: "KeyN",
  548. trap: "KeyF",
  549. turret: "KeyH",
  550. tree: "KeyU",
  551. platform: "KeyT",
  552. spawn: "KeyJ",
  553. up: "KeyW",
  554. left: "KeyA",
  555. down: "KeyS",
  556. right: "KeyD",
  557. autoattack: "KeyE",
  558. lockRotation: "KeyX",
  559. openChat: "Enter",
  560. invisibleHit: 2,
  561. upgradeScythe: "KeyL",
  562. unequip: "KeyI",
  563. bush: "KeyP",
  564. berserker: "KeyB",
  565. jungle: "...",
  566. crystal: "KeyC",
  567. spikegear: "KeyG",
  568. immunity: 4,
  569. boost: "ShiftLeft",
  570. applehat: "...",
  571. scuba: "...",
  572. hood: "Backquote",
  573. demolist: "KeyZ",
  574. placementType: PlacementType.INVISIBLE,
  575. placementSpeed: 1,
  576. autobed: false,
  577. automill: true,
  578. antiFireball: false,
  579. autoheal: true,
  580. jungleOnClown: false,
  581. lastHat: false,
  582. autoScuba: false,
  583. meleeAim: false,
  584. bowAim: false,
  585. spikeInstaAim: false,
  586. autosync: false,
  587. autoboostFollow: false,
  588. enemyTracers: true,
  589. teammateTracers: true,
  590. animalTracers: false,
  591. enemyColor: "#cc5151",
  592. teammateColor: "#8ecc51",
  593. animalColor: "#518ccc",
  594. arrows: false,
  595. rainbow: false,
  596. drawHP: false,
  597. showHoods: false,
  598. itemCounter: false,
  599. visualAim: false,
  600. hideMessages: false,
  601. customSkins: false,
  602. skin: Storage.get("skin") || 27,
  603. accessory: Storage.get("accessory") || 30,
  604. back: Storage.get("back") || 2,
  605. itemMarkers: false,
  606. teammateMarkers: false,
  607. enemyMarkers: false,
  608. trapActivated: false,
  609. itemMarkersColor: "#8ecc51",
  610. teammateMarkersColor: "#cfbc5f",
  611. enemyMarkersColor: "#cc5151",
  612. trapActivatedColor: "#48b2b8",
  613. hatReloadBar: false,
  614. hatReloadBarColor: "#5155cc",
  615. fireballReloadBar: false,
  616. fireballReloadBarColor: "#cf7148",
  617. turretReloadBar: false,
  618. turretReloadBarColor: "#51cc80",
  619. weaponReloadBar: false,
  620. weaponReloadBarColor: "#cc8251",
  621. smoothReloadBar: false,
  622. windmillRotation: false,
  623. possibleShots: false,
  624. autochat: false,
  625. autochatMessages: [ "Sploop Client", "What is it?", "The most advanced hack for Sploop.io!", "Download on greasyfork" ],
  626. kill: false,
  627. killMessage: "{NAME}, you suck! {KILL}x",
  628. autospawn: false,
  629. smoothZoom: true,
  630. skipUpgrades: true,
  631. invisHitToggle: false,
  632. reverseZoom: false,
  633. autoAccept: false,
  634. connectTo: "SFRA",
  635. menuTransparency: false,
  636. blindUsers: [ 0, 0, 0 ]
  637. /*...defaultSettings,
  638. ...Storage.get("Sploop-settings")*/
  639. };
  640. for (const key in settings) {
  641. if (!defaultSettings.hasOwnProperty(key)) {
  642. delete settings[key];
  643. }
  644. }
  645. Storage.set("Sploop-settings", settings);
  646. const Settings = settings;
  647. class Formatter {
  648. static object(target) {
  649. const layer = LayerData[target.type];
  650. return {
  651. id: target[Sploop.props.id],
  652. type: target.type,
  653. x: target[Sploop.props.x],
  654. y: target[Sploop.props.y],
  655. x1: target[Sploop.props.x1],
  656. y1: target[Sploop.props.y1],
  657. x2: target[Sploop.props.x2],
  658. y2: target[Sploop.props.y2],
  659. angle: target[Sploop.props.angle],
  660. angle1: target[Sploop.props.angle1],
  661. angle2: target[Sploop.props.angle2],
  662. ownerID: target[Sploop.props.ownerID],
  663. radius: layer.radius,
  664. layerData: layer,
  665. target
  666. };
  667. }
  668. static projectile(target) {
  669. const object = this.object(target);
  670. return {
  671. ...object,
  672. range: target.range,
  673. projectileType: target[Sploop.props.projectileType]
  674. };
  675. }
  676. static entity(target) {
  677. const object = this.object(target);
  678. const healthValue = target[Sploop.props.health];
  679. const maxHealth = object.layerData.maxHealth || 1;
  680. return {
  681. ...object,
  682. healthValue,
  683. health: Math.ceil(healthValue / 257 * maxHealth),
  684. maxHealth,
  685. entityValue: target[Sploop.props.entityValue]
  686. };
  687. }
  688. static player(target) {
  689. const entity = this.entity(target);
  690. return {
  691. ...entity,
  692. hat: target[Sploop.props.hat],
  693. isClown: entity.entityValue === 128,
  694. currentItem: target[Sploop.props.currentItem]
  695. };
  696. }
  697. }
  698. const TYPEOF = value => Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
  699. const removeClass = (target, name) => {
  700. if (target instanceof HTMLElement) {
  701. target.classList.remove(name);
  702. return;
  703. }
  704. for (const element of target) {
  705. element.classList.remove(name);
  706. }
  707. };
  708. const removeChildren = target => {
  709. while (target.firstChild) {
  710. target.removeChild(target.firstChild);
  711. }
  712. };
  713. const formatCode = code => {
  714. code = code + "";
  715. if (code === "0") return "LBTN";
  716. if (code === "1") return "MBTN";
  717. if (code === "2") return "RBTN";
  718. if (code === "3") return "XBTN2";
  719. if (code === "4") return "XBTN1";
  720. if (code === "Escape") return "ESC";
  721. if (code === "BracketLeft") return "[";
  722. if (code === "BracketRight") return "]";
  723. if (code === "NumpadDivide") return "NUMDIV";
  724. if (code === "NumpadMultiply") return "NUMMULT";
  725. if (code === "NumpadSubtract") return "NUMSUB";
  726. if (code === "NumpadDecimal") return "NUMDEC";
  727. if (code === "CapsLock") return "CAPS";
  728. if (code === "PrintScreen") return "PRNT";
  729. if (code === "Backslash") return "\\";
  730. if (code === "Backquote") return "BQUOTE";
  731. if (code === "PageDown") return "PAGEDN";
  732. const NumpadDigitArrowKey = /^(?:Numpad|Digit|Arrow|Key)(\w+)$/;
  733. if (NumpadDigitArrowKey.test(code)) {
  734. code = code.replace(NumpadDigitArrowKey, "$1").replace(/Numpad/, "NUM");
  735. }
  736. const ExtraKeysRegex = /^(Control|Shift|Alt)(.).*/;
  737. if (ExtraKeysRegex.test(code)) {
  738. code = code.replace(ExtraKeysRegex, "$2$1").replace(/Control/, "CTRL");
  739. }
  740. return code.toUpperCase();
  741. };
  742. const contains = (target, name) => target.classList.contains(name);
  743. const isInput = target => {
  744. const element = target || document.activeElement || document.body;
  745. return [ "TEXTAREA", "INPUT" ].includes(element.tagName);
  746. };
  747. const random = (min, max) => {
  748. const isInteger = Number.isInteger(min) && Number.isInteger(max);
  749. if (isInteger) return Math.floor(Math.random() * (max - min + 1) + min);
  750. return Math.random() * (max - min) + min;
  751. };
  752. const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
  753. const lerp = (start, stop, amt) => amt * (stop - start) + start;
  754. const sleep = ms => new Promise((resolve => setTimeout(resolve, ms)));
  755. const GM = (property, value) => {
  756. if (!Sploop.PRODUCTION) return true;
  757. try {
  758. return GM_info.script[property] === value;
  759. } catch (err) {
  760. return false;
  761. }
  762. };
  763. const fromCharCode = codes => codes.map((code => String.fromCharCode(code))).join("");
  764. const isBlind = () => !Settings.blindUsers.every((a => a === 1));
  765. const angle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1);
  766. const formatAge = age => Math.floor(Math.log(1 + Math.max(0, age)) ** 2.4 / 13);
  767. const doWhile = (condition, callback, delay) => {
  768. if (!condition()) return;
  769. const interval = setInterval((() => {
  770. if (condition()) {
  771. callback();
  772. } else {
  773. clearInterval(interval);
  774. }
  775. }), delay);
  776. };
  777. const Common_define = (target, key, value) => {
  778. Object.defineProperty(target, key, {
  779. get: () => value,
  780. configurable: true
  781. });
  782. };
  783. const resetSkin = () => {
  784. const player = Sploop.myPlayer.target;
  785. if (!player) return;
  786. delete player[Sploop.props.skin];
  787. delete player[Sploop.props.accessory];
  788. delete player[Sploop.props.back];
  789. };
  790. const updateSkin = () => {
  791. if (!Settings.customSkins) return resetSkin();
  792. const player = Sploop.myPlayer.target;
  793. if (!player) return;
  794. Common_define(player, Sploop.props.skin, Settings.skin);
  795. Common_define(player, Sploop.props.accessory, Settings.accessory);
  796. Common_define(player, Sploop.props.back, Settings.back);
  797. };
  798. const Scale = {
  799. Default: {
  800. w: 1824,
  801. h: 1026
  802. },
  803. lerp: {
  804. w: 1824,
  805. h: 1026
  806. },
  807. current: {
  808. w: 1824,
  809. h: 1026
  810. }
  811. };
  812. const getMinScale = scale => {
  813. let w = Scale.Default.w;
  814. let h = Scale.Default.h;
  815. while (w > scale && h > scale) {
  816. w -= scale;
  817. h -= scale;
  818. }
  819. return {
  820. w,
  821. h
  822. };
  823. };
  824. const zoomHandler = () => {
  825. let wheels = 0;
  826. const scaleFactor = 150;
  827. window.addEventListener("wheel", (event => {
  828. if (!(event.target instanceof HTMLCanvasElement) || event.ctrlKey || event.shiftKey || event.altKey || isInput() || !controller.inGame) return;
  829. const {Default, current, lerp} = Scale;
  830. // if (current.w === Default.w && current.h === Default.h && (wheels = (wheels + 1) % 5) !== 0) return;
  831. const {w, h} = getMinScale(scaleFactor);
  832. const zoom = !Settings.reverseZoom && event.deltaY > 0 || Settings.reverseZoom && event.deltaY < 0 ? -scaleFactor : scaleFactor;
  833. current.w = Math.max(w, current.w + zoom);
  834. current.h = Math.max(h, current.h + zoom);
  835. if (Settings.smoothZoom) return;
  836. lerp.w = current.w;
  837. lerp.h = current.h;
  838. window.dispatchEvent(new Event("resize"));
  839. }));
  840. };
  841. const modules_zoomHandler = zoomHandler;
  842. let context;
  843. let _clearRect;
  844. const toggleHook = () => {
  845. delete context.clearRect;
  846. if (!Settings.smoothZoom) return;
  847. context.clearRect = new Proxy(_clearRect, {
  848. apply(target, _this, args) {
  849. target.apply(_this, args);
  850. if (controller.inGame && Settings.smoothZoom) {
  851. Scale.lerp.w = lerp(Scale.lerp.w, Scale.current.w, .030);
  852. Scale.lerp.h = lerp(Scale.lerp.h, Scale.current.h, .030);
  853. window.dispatchEvent(new Event("resize"));
  854. }
  855. }
  856. });
  857. };
  858. HTMLCanvasElement.prototype.getContext = new Proxy(HTMLCanvasElement.prototype.getContext, {
  859. apply(target, _this, args) {
  860. const ctx = target.apply(_this, args);
  861. if (_this.id === "game-canvas") {
  862. context = ctx;
  863. _clearRect = ctx.clearRect;
  864. toggleHook();
  865. HTMLCanvasElement.prototype.getContext = target;
  866. }
  867. return ctx;
  868. }
  869. });
  870. const skins = {
  871. skin: [ [ "Sploop Classic", 0, 0 ], [ "Yellow Classic", 1, 0 ], [ "Brown Classic", 2, 0 ], [ "Pink Classic", 3, 0 ], [ "Blue Classic", 4, 0 ], [ "Green Classic", 5, 0 ], [ "White Cat", 6, 100 ], [ "Ginger Cat", 7, 100 ], [ "Pit Bull", 8, 150 ], [ "Pig", 9, 100 ], [ "Crocodile", 10, 200 ], [ "Fox", 11, 200 ], [ "Panda", 12, 300 ], [ "Bear", 13, 300 ], [ "Penguin", 14, 300 ], [ "Cactus", 15, 400 ], [ "Strawberry", 16, 800 ], [ "Wolf", 17, 400 ], [ "Mammoth", 18, 2e3 ], [ "Golden Cow", 19, 3e3 ], [ "Shark", 20, 1e3 ], [ "Apple", 21, 200 ], [ "Stone", 22, 500 ], [ "Cave Stone", 23, 600 ], [ "Ice", 24, 700 ], [ "Gold", 25, 800 ], [ "Cow", 26, 350 ], [ "Dragon", 27, 5e3 ], [ "Black Ice", 28, 1e3 ], [ "Magma", 29, 1500 ], [ "Kawak", 30, 2500 ], [ "Snowman", 31, 400 ], [ "Elf", 32, 1e3 ], [ "Green Bauble", 33, 300 ], [ "Red Bauble", 34, 300 ], [ "Golden Bauble", 35, 800 ], [ "Duck", 36, 300 ], [ "Tornado", 37, 3e3 ], [ "Golden Beetle", 38, 1500 ] ],
  872. accessory: [ [ "None", 0, 0 ], [ "Mustache", 1, 100 ], [ "Sun Glasses", 2, 500 ], [ "Yellow Cap", 3, 0 ], [ "Blue Cap", 4, 0 ], [ "Purple Cap", 5, 0 ], [ "Green Cap", 6, 0 ], [ "Pink Bow", 7, 0 ], [ "3D Glasses", 8, 300 ], [ "Scar", 9, 150 ], [ "Turban", 10, 250 ], [ "Bandage", 11, 250 ], [ "Crazy Glasses", 12, 150 ], [ "Cow's Snout", 13, 300 ], [ "Carrot", 14, 150 ], [ "Horn", 15, 1e3 ], [ "Tusk", 16, 800 ], [ "Mammoth Hair", 17, 600 ], [ "Mammoth Ears", 18, 500 ], [ "Leaf", 19, 150 ], [ "Black Mustache", 20, 500 ], [ "Snowman Hat", 21, 1e3 ], [ "Blue Beanie", 22, 200 ], [ "Green Beanie", 23, 200 ], [ "Purple Beanie", 24, 200 ], [ "Orange Beanie", 25, 200 ], [ "Yellow Scarf", 26, 250 ], [ "Red Scarf", 27, 350 ], [ "Green Scarf", 28, 300 ], [ "Red Nose", 29, 400 ], [ "Mask", 30, 1e3 ], [ "Garlands", 31, 500 ] ],
  873. back: [ [ "None", 0, 0 ], [ "Mammoth Tail", 1, 500 ], [ "Dragon Wings", 2, 5e3 ], [ "Swords", 3, 2e3 ], [ "Blue Cape", 4, 400 ], [ "Christmas Cape", 5, 400 ], [ "Speedy Cape", 6, 400 ], [ "Garland", 7, 300 ], [ "Baby Elf", 8, 1500 ], [ "Gift", 9, 1e3 ], [ "Yellow Bag", 10, 300 ] ]
  874. };
  875. const Skins = skins;
  876. const createImage = src => {
  877. const img = new Image;
  878. img.src = src;
  879. return img;
  880. };
  881. const getURL = (type, id) => `${location.origin}/img/ui/${type}${id}.png`;
  882. const Images = {
  883. gaugeBackground: createImage("https://i.imgur.com/xincrX4.png"),
  884. gaugeFront: createImage("https://i.imgur.com/6AkHQM4.png"),
  885. discord: createImage("https://i.imgur.com/RcTl09i.png"),
  886. github: createImage("https://i.imgur.com/q0z20jB.png"),
  887. greasyfork: createImage("https://i.imgur.com/y6OYX0D.png")
  888. };
  889. const utils_Images = Images;
  890. const createMenu = () => {
  891. const IFRAME_CONTENT = `\n <style>${styles}</style>\n <div id="menu-container" class="open">\n <div id="menu-wrapper">\n ${Header}\n\n <main>\n ${Navbar}\n\n <div id="menu-page-container">\n ${Keybinds}\n ${Combat}\n ${Visuals}\n ${Misc}\n ${Credits}\n </div>\n </main>\n </div>\n </div>\n `;
  892. const IFRAME_STYLE = `\n #iframe-page-container {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n z-index: 99;\n border: none;\n outline: none;\n overflow: scroll;\n display: none;\n }\n\n .iframe-opened {\n display: block!important;\n }\n\n #main-content {\n background: none;\n }\n\n #game-content {\n justify-content: center;\n }\n `;
  893. const IFRAME = document.createElement("iframe");
  894. const blob = new Blob([ IFRAME_CONTENT ], {
  895. type: "text/html; charset=utf-8"
  896. });
  897. IFRAME.src = URL.createObjectURL(blob);
  898. IFRAME.id = "iframe-page-container";
  899. document.body.appendChild(IFRAME);
  900. const style = document.createElement("style");
  901. style.innerHTML = IFRAME_STYLE;
  902. document.head.appendChild(style);
  903. IFRAME.onload = () => {
  904. const iframeWindow = IFRAME.contentWindow;
  905. const iframeDocument = iframeWindow.document;
  906. URL.revokeObjectURL(IFRAME.src);
  907. const menuContainer = iframeDocument.getElementById("menu-container");
  908. const menuWrapper = iframeDocument.getElementById("menu-wrapper");
  909. const openMenu = iframeDocument.querySelectorAll(".open-menu");
  910. const menuPage = iframeDocument.querySelectorAll(".menu-page");
  911. const sections = iframeDocument.querySelectorAll(".section");
  912. const hotkeyInputs = iframeDocument.querySelectorAll(".section-option-hotkeyInput[id]");
  913. const closeMenu = iframeDocument.querySelector("#close-menu");
  914. const checkboxs = iframeDocument.querySelectorAll("input[type='checkbox'][id]");
  915. const sliders = iframeDocument.querySelectorAll("input[type='range'][id]");
  916. const headerVersion = iframeDocument.querySelector("#version > span");
  917. const autochatInputs = iframeDocument.querySelectorAll(".input.autochat");
  918. const killMessage = iframeDocument.querySelector("#killMessage");
  919. const resetSettings = iframeDocument.querySelector("#reset-settings");
  920. const downloadSettings = iframeDocument.querySelector("#download-settings");
  921. const uploadSettings = iframeDocument.querySelector("#upload-settings");
  922. const menuTransparency = iframeDocument.querySelector("#menuTransparency");
  923. const colorPickers = iframeDocument.querySelectorAll("input[type='color'][id]");
  924. const selects = iframeDocument.querySelectorAll("select[id]");
  925. const buttonPopups = iframeDocument.querySelectorAll("button[data-type='popup'][data-id]");
  926. let popupCount = 0;
  927. const popups = [ {
  928. index: 0,
  929. title: "YouTube",
  930. description: "",
  931. link: "https://www.youtube.com/channel/UCtCT9P2JcUoJlF3KCr5etjA",
  932. prev: "https://i.imgur.com/agwC9na.png"
  933. }, {
  934. index: 1,
  935. title: "YouTube",
  936. description: "!",
  937. link: "https://www.youtube.com/channel/UCtCT9P2JcUoJlF3KCr5etjA",
  938. prev: "https://i.imgur.com/agwC9na.png"
  939. }, {
  940. index: 2,
  941. title: "Instagram",
  942. description: "Follow!",
  943. link: "https://www.instagram.com/_ma_te_x_/",
  944. prev: "https://i.imgur.com/7QFa9F6.png"
  945. } ];
  946. const pickPopup = () => {
  947. const pups = popups.filter(((popup, index) => Settings.blindUsers[index] === 0));
  948. if (pups.length) {
  949. const popup = pups[popupCount++];
  950. popupCount %= pups.length;
  951. return popup;
  952. }
  953. return null;
  954. };
  955. const fadeOut = "transition: all 150ms ease 0s; transform: scale(0); opacity: 0;";
  956. let popupOpened = false;
  957. const createPopup = () => {
  958. /*
  959. if (popupOpened) return;
  960. const popup = pickPopup();
  961. if (!popup) return;
  962. popupOpened = true;
  963. // const div = document.createElement("div");
  964. //div.innerHTML = `\n <div id="popup-menu">\n <div id="popup-container">\n <div id="image-background" class="${popup.title.toLowerCase()}-bg"></div>\n\n <div id="popup-wrapper">\n <div id="popup-data">\n <div id="popup-title">${popup.title}</div>\n <div id="popup-description">${popup.description}</div>\n\n <div id="popup-bottom">\n <a id="popup-continue" class="popup-button" href="${popup.link}" target="_blank">CONTINUE</a>\n <button id="popup-close" class="popup-button">CLOSE</button>\n </div>\n </div>\n\n <div id="popup-prev">\n <img src="${popup.prev}"></img>\n </div>\n </div>\n </div>\n </div>\n `;
  965. //const popupMenu = div.querySelector("#popup-menu");
  966. //const container = div.querySelector("#popup-container");
  967. //const continuePopup = div.querySelector("#popup-continue");
  968. const closePopup = div.querySelector("#popup-close");
  969. continuePopup.onclick = () => {
  970. popupCount -= 1;
  971. Settings.blindUsers[popup.index] = 1;
  972. Storage.set("Sploop-settings", Settings);
  973. };
  974. closePopup.onclick = () => {
  975. container.style.cssText = fadeOut;
  976. setTimeout((() => {
  977. popupMenu.remove();
  978. popupOpened = false;
  979. }), 150);
  980. };
  981. menuWrapper.appendChild(popupMenu);
  982. */
  983. };
  984. const update = () => {
  985. updateSkin();
  986. for (const button of buttonPopups) {
  987. const type = button.getAttribute("data-id");
  988. const img = button.previousElementSibling;
  989. if (img) {
  990. img.src = getURL(type, Settings[type]);
  991. }
  992. button.onclick = () => {
  993. const div = document.createElement("div");
  994. div.innerHTML = `\n <div id="popup-menu">\n <div id="popup-container" style="height: 70%">\n <svg\n id="close-popup"\n class="icon"\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 30 30"\n width="30px" height="30px"\n >\n <path d="M 7 4 C 6.744125 4 6.4879687 4.0974687 6.2929688 4.2929688 L 4.2929688 6.2929688 C 3.9019687 6.6839688 3.9019687 7.3170313 4.2929688 7.7070312 L 11.585938 15 L 4.2929688 22.292969 C 3.9019687 22.683969 3.9019687 23.317031 4.2929688 23.707031 L 6.2929688 25.707031 C 6.6839688 26.098031 7.3170313 26.098031 7.7070312 25.707031 L 15 18.414062 L 22.292969 25.707031 C 22.682969 26.098031 23.317031 26.098031 23.707031 25.707031 L 25.707031 23.707031 C 26.098031 23.316031 26.098031 22.682969 25.707031 22.292969 L 18.414062 15 L 25.707031 7.7070312 C 26.098031 7.3170312 26.098031 6.6829688 25.707031 6.2929688 L 23.707031 4.2929688 C 23.316031 3.9019687 22.682969 3.9019687 22.292969 4.2929688 L 15 11.585938 L 7.7070312 4.2929688 C 7.5115312 4.0974687 7.255875 4 7 4 z"/>\n </svg>\n <div id="popup-wrapper">\n <div id="popup-content">\n </div>\n </div>\n </div>\n </div>\n `;
  995. const popupMenu = div.querySelector("#popup-menu");
  996. const container = div.querySelector("#popup-container");
  997. const popupContent = div.querySelector("#popup-content");
  998. const closePopup = div.querySelector("#close-popup");
  999. const close = () => {
  1000. container.style.cssText = fadeOut;
  1001. setTimeout((() => {
  1002. popupMenu.remove();
  1003. }), 150);
  1004. };
  1005. for (const skin of Skins[type]) {
  1006. const div = document.createElement("div");
  1007. const url = getURL(type, skin[1]);
  1008. div.innerHTML = `\n <div class="img-prev">\n <img src="${url}">\n </div>\n `;
  1009. const setURL = () => {
  1010. if (!img) return;
  1011. img.src = url;
  1012. Settings[type] = skin[1];
  1013. Storage.set("Sploop-settings", Settings);
  1014. close();
  1015. updateSkin();
  1016. };
  1017. const imgPrev = div.querySelector(".img-prev");
  1018. imgPrev.onclick = setURL;
  1019. closePopup.onclick = close;
  1020. popupContent.appendChild(imgPrev);
  1021. }
  1022. menuWrapper.appendChild(popupMenu);
  1023. };
  1024. }
  1025. for (const select of selects) {
  1026. removeChildren(select);
  1027. const data = selectData[select.id];
  1028. for (const key in data) {
  1029. if (!isNaN(Number(key))) continue;
  1030. const keyValue = key;
  1031. const option = document.createElement("option");
  1032. option.value = data[keyValue];
  1033. option.textContent = keyValue;
  1034. if (data[keyValue] === Settings[select.id]) {
  1035. option.selected = true;
  1036. option.defaultSelected = true;
  1037. }
  1038. select.appendChild(option);
  1039. }
  1040. select.onchange = () => {
  1041. const dataValue = /^\d+$/.test(String(select.value)) ? Number(select.value) : select.value;
  1042. Settings[select.id] = dataValue;
  1043. if (select.id === "placementType" && dataValue === PlacementType.DEFAULT) {
  1044. Settings.autoheal = false;
  1045. Settings.autoheal2 = false;
  1046. Settings.autoboostFollow = false;
  1047. update();
  1048. }
  1049. Storage.set("Sploop-settings", Settings);
  1050. };
  1051. }
  1052. for (const picker of colorPickers) {
  1053. const resetColor = picker.previousElementSibling;
  1054. if (resetColor) {
  1055. const defaultColor = defaultSettings[picker.id];
  1056. resetColor.style.backgroundColor = defaultColor;
  1057. resetColor.onclick = () => {
  1058. picker.value = defaultColor;
  1059. Settings[picker.id] = defaultColor;
  1060. Storage.set("Sploop-settings", Settings);
  1061. };
  1062. }
  1063. picker.value = Settings[picker.id];
  1064. picker.onchange = () => {
  1065. Settings[picker.id] = picker.value;
  1066. Storage.set("Sploop-settings", Settings);
  1067. picker.blur();
  1068. };
  1069. }
  1070. menuContainer.classList[Settings.menuTransparency ? "add" : "remove"]("transparent");
  1071. killMessage.value = Settings.killMessage;
  1072. killMessage.onchange = () => {
  1073. Settings.killMessage = killMessage.value;
  1074. Storage.set("Sploop-settings", Settings);
  1075. killMessage.blur();
  1076. };
  1077. for (let i = 0; i < autochatInputs.length; i++) {
  1078. const input = autochatInputs[i];
  1079. input.value = Settings.autochatMessages[i] || "";
  1080. input.onchange = () => {
  1081. Settings.autochatMessages[i] = input.value;
  1082. Storage.set("Sploop-settings", Settings);
  1083. input.blur();
  1084. };
  1085. }
  1086. headerVersion.textContent = "v" + Sploop.version;
  1087. for (const slider of sliders) {
  1088. const sliderValue = slider.nextElementSibling;
  1089. slider.value = Settings[slider.id];
  1090. if (sliderValue) {
  1091. sliderValue.textContent = slider.value;
  1092. }
  1093. slider.oninput = () => {
  1094. const value = Number(slider.value) % 1;
  1095. slider.value -= value;
  1096. if (sliderValue) {
  1097. sliderValue.textContent = slider.value;
  1098. }
  1099. Settings[slider.id] = Number(slider.value);
  1100. Storage.set("Sploop-settings", Settings);
  1101. };
  1102. }
  1103. for (const checkbox of checkboxs) {
  1104. checkbox.checked = Settings[checkbox.id];
  1105. checkbox.onchange = () => {
  1106. Settings[checkbox.id] = checkbox.checked;
  1107. if (checkbox.id === "smoothZoom") {
  1108. toggleHook();
  1109. } else if (checkbox.id === "customSkins") {
  1110. if (checkbox.checked) {
  1111. updateSkin();
  1112. } else {
  1113. resetSkin();
  1114. }
  1115. }
  1116. Storage.set("Sploop-settings", Settings);
  1117. checkbox.blur();
  1118. };
  1119. }
  1120. let popupCount = 0;
  1121. Sploop.toggleMenu = () => {
  1122. menuContainer.classList.toggle("close");
  1123. if (menuContainer.classList.toggle("open") && !popupOpened) {
  1124. popupCount += 1;
  1125. if ((popupCount %= 5) === 0) {
  1126. createPopup();
  1127. }
  1128. }
  1129. setTimeout((() => {
  1130. IFRAME.classList.toggle("iframe-opened");
  1131. }), 100);
  1132. };
  1133. closeMenu.onclick = Sploop.toggleMenu;
  1134. for (let i = 0; i < openMenu.length; i++) {
  1135. openMenu[i].onclick = () => {
  1136. removeClass(openMenu, "active");
  1137. openMenu[i].classList.add("active");
  1138. removeClass(menuPage, "opened");
  1139. menuPage[i].classList.add("opened");
  1140. };
  1141. }
  1142. for (const section of sections) {
  1143. const title = section.children[0];
  1144. const content = section.children[1];
  1145. if (!title || !content) continue;
  1146. if (contains(section, "opened")) {
  1147. content.classList.add("opened");
  1148. continue;
  1149. }
  1150. content.style.display = "none";
  1151. title.onclick = () => {
  1152. if (!content.classList.contains("opened")) {
  1153. content.style.display = "grid";
  1154. } else {
  1155. setTimeout((() => {
  1156. content.style.display = "none";
  1157. }), 100);
  1158. }
  1159. setTimeout((() => {
  1160. content.classList.toggle("opened");
  1161. title.children[1].classList.toggle("rotate");
  1162. }), 0);
  1163. };
  1164. }
  1165. for (const hotkeyInput of hotkeyInputs) {
  1166. try {
  1167. hotkeyInput.textContent = formatCode(Settings[hotkeyInput.id]);
  1168. } catch (err) {
  1169. throw new Error(hotkeyInput.id + " doesn't exist in settings");
  1170. }
  1171. }
  1172. checkForRepeats();
  1173. };
  1174. menuTransparency.addEventListener("change", (() => {
  1175. menuContainer.classList[menuTransparency.checked ? "add" : "remove"]("transparent");
  1176. }));
  1177. resetSettings.onclick = () => {
  1178. Object.assign(Settings, defaultSettings);
  1179. Storage.set("Sploop-settings", Settings);
  1180. update();
  1181. };
  1182. downloadSettings.onclick = () => {
  1183. download(Settings, "SploopSettings" + Sploop.version);
  1184. };
  1185. uploadSettings.onchange = async event => {
  1186. const target = event.target;
  1187. const parent = uploadSettings.parentElement;
  1188. const spanText = parent.children[1];
  1189. parent.classList.remove("red");
  1190. parent.classList.remove("green");
  1191. try {
  1192. const text = await target.files[0].text();
  1193. const sets = JSON.parse(text);
  1194. if (Object.keys(sets).every((key => defaultSettings.hasOwnProperty(key)))) {
  1195. Object.assign(Settings, sets);
  1196. Storage.set("Sploop-settings", Settings);
  1197. update();
  1198. parent.classList.add("green");
  1199. spanText.innerHTML = `SETTINGS LOADED SUCCESSFULLY`;
  1200. } else {
  1201. throw new Error("Invalid settings");
  1202. }
  1203. } catch (err) {
  1204. parent.classList.add("red");
  1205. spanText.innerHTML = "SETTINGS ARE NOT VALID, TRY ANOTHER";
  1206. }
  1207. };
  1208. const checkForRepeats = () => {
  1209. const list = new Map;
  1210. for (const hotkeyInput of hotkeyInputs) {
  1211. const value = Settings[hotkeyInput.id];
  1212. const [count, inputs] = list.get(value) || [ 0, [] ];
  1213. list.set(value, [ (count || 0) + 1, [ ...inputs, hotkeyInput ] ]);
  1214. hotkeyInput.classList.remove("red");
  1215. }
  1216. for (const data of list) {
  1217. const [number, hotkeyInputs] = data[1];
  1218. if (number === 1) continue;
  1219. for (const hotkeyInput of hotkeyInputs) {
  1220. hotkeyInput.classList.add("red");
  1221. }
  1222. }
  1223. };
  1224. Sploop.active = null;
  1225. const applyCode = code => {
  1226. if (!Sploop.active) return;
  1227. const key = code === "Backspace" ? "..." : formatCode(code);
  1228. Settings[Sploop.active.id] = code === "Backspace" ? "..." : code;
  1229. Sploop.active.textContent = key;
  1230. Storage.set("Sploop-settings", Settings);
  1231. Sploop.active = null;
  1232. checkForRepeats();
  1233. };
  1234. menuContainer.addEventListener("keyup", (event => {
  1235. if (event.keyCode < 5 || !Sploop.active) return;
  1236. applyCode(event.code);
  1237. }));
  1238. menuContainer.addEventListener("mouseup", (event => {
  1239. const target = event.target;
  1240. if (Sploop.active) return applyCode(event.button);
  1241. if (!contains(target, "section-option-hotkeyInput") || !target.id) return;
  1242. target.textContent = "Wait...";
  1243. Sploop.active = target;
  1244. }));
  1245. iframeWindow.addEventListener("keydown", (event => controller.handleKeydown(event, event.code)));
  1246. iframeWindow.addEventListener("keyup", (event => controller.handleKeyup(event, event.code)));
  1247. const resize = () => {
  1248. const width = window.innerWidth;
  1249. const height = window.innerHeight;
  1250. const scale = Math.min(1, Math.min(width / 1024, height / 700));
  1251. menuContainer.style.transform = `translate(-50%, -50%) scale(${scale})`;
  1252. };
  1253. resize();
  1254. window.addEventListener("resize", resize);
  1255. setTimeout((() => IFRAME.classList.add("iframe-opened")), 0);
  1256. iframeWindow.addEventListener("contextmenu", (event => event.preventDefault()));
  1257. iframeWindow.addEventListener("mousedown", (event => 1 === event.button && event.preventDefault()));
  1258. iframeWindow.addEventListener("mouseup", (event => [ 3, 4 ].includes(event.button) && event.preventDefault()));
  1259. window.addEventListener("mouseup", (event => [ 3, 4 ].includes(event.button) && event.preventDefault()));
  1260. update();
  1261. };
  1262. };
  1263. const modules_createMenu = createMenu;
  1264. var Hat;
  1265. (function(Hat) {
  1266. Hat[Hat["UNEQUIP"] = 0] = "UNEQUIP";
  1267. Hat[Hat["BUSH"] = 1] = "BUSH";
  1268. Hat[Hat["BERSERKER"] = 2] = "BERSERKER";
  1269. Hat[Hat["JUNGLE"] = 3] = "JUNGLE";
  1270. Hat[Hat["CRYSTAL"] = 4] = "CRYSTAL";
  1271. Hat[Hat["SPIKEGEAR"] = 5] = "SPIKEGEAR";
  1272. Hat[Hat["IMMUNITY"] = 6] = "IMMUNITY";
  1273. Hat[Hat["BOOST"] = 7] = "BOOST";
  1274. Hat[Hat["APPLEHAT"] = 8] = "APPLEHAT";
  1275. Hat[Hat["SCUBA"] = 9] = "SCUBA";
  1276. Hat[Hat["HOOD"] = 10] = "HOOD";
  1277. Hat[Hat["DEMOLIST"] = 11] = "DEMOLIST";
  1278. })(Hat || (Hat = {}));
  1279. const Hats = [ {
  1280. bought: true,
  1281. equipped: true,
  1282. default: true,
  1283. price: 0
  1284. }, {
  1285. image: 109,
  1286. price: 250,
  1287. axisY: 0,
  1288. description: "Become a bush",
  1289. name: "Bush Hat",
  1290. bought: false,
  1291. equipped: false,
  1292. rs: true
  1293. }, {
  1294. image: 41,
  1295. price: 5e3,
  1296. description: "Increased melee damage",
  1297. axisY: 10,
  1298. cs: 1.25,
  1299. speed: .85,
  1300. name: "Berserker Gear",
  1301. bought: false,
  1302. equipped: false
  1303. }, {
  1304. image: 44,
  1305. price: 3e3,
  1306. description: "Regenerate health",
  1307. axisY: 13,
  1308. hs: 25,
  1309. name: "Jungle Gear",
  1310. bought: false,
  1311. equipped: false
  1312. }, {
  1313. image: 45,
  1314. price: 5e3,
  1315. description: "Receive reduced damage",
  1316. axisY: 10,
  1317. reduceDmg: .75,
  1318. speed: .95,
  1319. name: "Crystal Gear",
  1320. bought: false,
  1321. equipped: false
  1322. }, {
  1323. image: 48,
  1324. price: 1e3,
  1325. description: "Attacker's receive damage",
  1326. axisY: 10,
  1327. reflect: .45,
  1328. name: "Spike Gear",
  1329. bought: false,
  1330. equipped: false
  1331. }, {
  1332. image: 49,
  1333. price: 4e3,
  1334. description: "Gain more health",
  1335. axisY: 15,
  1336. ls: 150,
  1337. reduceDmg: .75,
  1338. name: "Immunity Gear",
  1339. bought: false,
  1340. equipped: false
  1341. }, {
  1342. image: 50,
  1343. price: 1500,
  1344. description: "Move quicker",
  1345. axisY: 23,
  1346. speed: 1.23,
  1347. name: "Boost Hat",
  1348. bought: false,
  1349. equipped: false
  1350. }, {
  1351. image: 93,
  1352. price: 150,
  1353. description: "Apples become more succulent",
  1354. axisY: 5,
  1355. speed: 1.05,
  1356. name: "Apple hat",
  1357. bought: false,
  1358. equipped: false
  1359. }, {
  1360. image: 121,
  1361. price: 4e3,
  1362. description: "Move fast in ocean",
  1363. axisY: 5,
  1364. speed: .75,
  1365. river: 1.5,
  1366. name: "Scuba Gear",
  1367. bought: false,
  1368. equipped: false
  1369. }, {
  1370. image: 126,
  1371. price: 3500,
  1372. description: "Become invisible when still",
  1373. axisY: 5,
  1374. name: "Hood",
  1375. bought: false,
  1376. equipped: false,
  1377. rs: true
  1378. }, {
  1379. image: 197,
  1380. price: 4e3,
  1381. description: "Destroy buildings faster",
  1382. axisY: 10,
  1383. name: "Demolist",
  1384. bought: false,
  1385. equipped: false,
  1386. speed: .3
  1387. } ];
  1388. var EWeapons;
  1389. (function(EWeapons) {
  1390. EWeapons[EWeapons["TOOL_HAMMER"] = 0] = "TOOL_HAMMER";
  1391. EWeapons[EWeapons["STONE_SWORD"] = 1] = "STONE_SWORD";
  1392. EWeapons[EWeapons["STONE_SPEAR"] = 2] = "STONE_SPEAR";
  1393. EWeapons[EWeapons["STONE_AXE"] = 3] = "STONE_AXE";
  1394. EWeapons[EWeapons["MUSKET"] = 4] = "MUSKET";
  1395. EWeapons[EWeapons["SHIELD"] = 11] = "SHIELD";
  1396. EWeapons[EWeapons["STICK"] = 13] = "STICK";
  1397. EWeapons[EWeapons["HAMMER"] = 15] = "HAMMER";
  1398. EWeapons[EWeapons["KATANA"] = 17] = "KATANA";
  1399. EWeapons[EWeapons["BOW"] = 26] = "BOW";
  1400. EWeapons[EWeapons["XBOW"] = 27] = "XBOW";
  1401. EWeapons[EWeapons["NAGINATA"] = 28] = "NAGINATA";
  1402. EWeapons[EWeapons["GREAT_AXE"] = 30] = "GREAT_AXE";
  1403. EWeapons[EWeapons["BAT"] = 31] = "BAT";
  1404. EWeapons[EWeapons["PEARL"] = 50] = "PEARL";
  1405. EWeapons[EWeapons["SCYTHE"] = 57] = "SCYTHE";
  1406. })(EWeapons || (EWeapons = {}));
  1407. var ActionType;
  1408. (function(ActionType) {
  1409. ActionType[ActionType["MELEE"] = 0] = "MELEE";
  1410. ActionType[ActionType["RANGED"] = 1] = "RANGED";
  1411. ActionType[ActionType["PLACEABLE"] = 2] = "PLACEABLE";
  1412. ActionType[ActionType["EATABLE"] = 3] = "EATABLE";
  1413. })(ActionType || (ActionType = {}));
  1414. var ItemType;
  1415. (function(ItemType) {
  1416. ItemType[ItemType["PRIMARY"] = 0] = "PRIMARY";
  1417. ItemType[ItemType["SECONDARY"] = 1] = "SECONDARY";
  1418. ItemType[ItemType["FOOD"] = 2] = "FOOD";
  1419. ItemType[ItemType["WALL"] = 3] = "WALL";
  1420. ItemType[ItemType["SPIKE"] = 4] = "SPIKE";
  1421. ItemType[ItemType["WINDMILL"] = 5] = "WINDMILL";
  1422. ItemType[ItemType["FARM"] = 6] = "FARM";
  1423. ItemType[ItemType["TRAP"] = 7] = "TRAP";
  1424. ItemType[ItemType["PLATFORM"] = 8] = "PLATFORM";
  1425. ItemType[ItemType["SPAWN"] = 9] = "SPAWN";
  1426. ItemType[ItemType["TURRET"] = 10] = "TURRET";
  1427. })(ItemType || (ItemType = {}));
  1428. var upgradeType;
  1429. (function(upgradeType) {
  1430. upgradeType[upgradeType["STONE"] = 1] = "STONE";
  1431. upgradeType[upgradeType["GOLD"] = 2] = "GOLD";
  1432. upgradeType[upgradeType["DIAMOND"] = 3] = "DIAMOND";
  1433. upgradeType[upgradeType["RUBY"] = 4] = "RUBY";
  1434. })(upgradeType || (upgradeType = {}));
  1435. const ItemData = [ {
  1436. id: EWeapons.TOOL_HAMMER,
  1437. gs: 46,
  1438. upgradeType: upgradeType.STONE,
  1439. imageinv: 29,
  1440. image: 25,
  1441. name: "Tool Hammer",
  1442. description: "Gather materials",
  1443. range: 80,
  1444. itemType: ItemType.PRIMARY,
  1445. damage: 25,
  1446. reload: 300,
  1447. _s: 30,
  1448. Ms: 200,
  1449. actionType: ActionType.MELEE,
  1450. ps: 0,
  1451. As: -3.5,
  1452. os: 1
  1453. }, {
  1454. id: EWeapons.STONE_SWORD,
  1455. ks: 1,
  1456. ys: 2,
  1457. imageinv: 28,
  1458. image: 24,
  1459. name: "Stone Sword",
  1460. description: "Sharp and pointy",
  1461. range: 135,
  1462. Ms: 250,
  1463. itemType: ItemType.PRIMARY,
  1464. damage: 35,
  1465. reload: 300,
  1466. Us: .85,
  1467. actionType: ActionType.MELEE,
  1468. ps: 0,
  1469. As: -8,
  1470. os: -4
  1471. }, {
  1472. id: EWeapons.STONE_SPEAR,
  1473. gs: 39,
  1474. upgradeType: upgradeType.STONE,
  1475. ks: 1,
  1476. ys: 4,
  1477. imageinv: 31,
  1478. image: 26,
  1479. name: "Stone Spear",
  1480. description: "Long melee range",
  1481. range: 160,
  1482. itemType: ItemType.PRIMARY,
  1483. damage: 49,
  1484. Us: .81,
  1485. Ms: 450,
  1486. reload: 700,
  1487. actionType: ActionType.MELEE,
  1488. ps: 0,
  1489. As: 0,
  1490. os: 2
  1491. }, {
  1492. id: EWeapons.STONE_AXE,
  1493. gs: 33,
  1494. upgradeType: upgradeType.STONE,
  1495. ks: 1,
  1496. ys: 128,
  1497. imageinv: 32,
  1498. image: 35,
  1499. name: "Stone Axe",
  1500. description: "Gathers materials faster",
  1501. range: 90,
  1502. itemType: ItemType.PRIMARY,
  1503. damage: 30,
  1504. Ms: 250,
  1505. reload: 400,
  1506. actionType: ActionType.MELEE,
  1507. ps: 0,
  1508. As: -2,
  1509. os: 2,
  1510. Es: 2,
  1511. Cs: 2,
  1512. Bs: 2,
  1513. zs: 2
  1514. }, {
  1515. id: EWeapons.MUSKET,
  1516. cost: {
  1517. food: 0,
  1518. wood: 0,
  1519. stone: 10,
  1520. gold: 0
  1521. },
  1522. ks: 16,
  1523. xs: 2,
  1524. ys: 8,
  1525. imageinv: 30,
  1526. image: 27,
  1527. name: "Stone Musket",
  1528. description: "Deal Long Range Damage",
  1529. range: 1e3,
  1530. itemType: ItemType.SECONDARY,
  1531. damage: 49,
  1532. reload: 1500,
  1533. projectile: 17,
  1534. Ls: 1500,
  1535. actionType: ActionType.RANGED,
  1536. ps: 1,
  1537. Us: .63,
  1538. As: 0,
  1539. os: 0
  1540. }, {
  1541. id: 5,
  1542. cost: {
  1543. food: 0,
  1544. wood: 10,
  1545. stone: 0,
  1546. gold: 0
  1547. },
  1548. imageinv: 33,
  1549. image: 103,
  1550. name: "Wood Wall",
  1551. description: "A sturdy wall",
  1552. itemType: ItemType.WALL,
  1553. actionType: ActionType.PLACEABLE,
  1554. Hs: 5,
  1555. As: 0,
  1556. os: 15,
  1557. layer: ELayer.WOODWALL,
  1558. ps: 2
  1559. }, {
  1560. id: 6,
  1561. cost: {
  1562. food: 0,
  1563. wood: 5,
  1564. stone: 20,
  1565. gold: 0
  1566. },
  1567. ks: 1,
  1568. ys: 512,
  1569. imageinv: 36,
  1570. image: 106,
  1571. name: "Boost",
  1572. description: "Provides a thrust",
  1573. itemType: ItemType.TRAP,
  1574. actionType: ActionType.PLACEABLE,
  1575. Hs: -5,
  1576. As: 0,
  1577. os: 3,
  1578. layer: ELayer.BOOST,
  1579. ps: 2
  1580. }, {
  1581. id: 7,
  1582. cost: {
  1583. food: 0,
  1584. wood: 20,
  1585. stone: 5,
  1586. gold: 0
  1587. },
  1588. imageinv: 37,
  1589. image: 104,
  1590. name: "Spike",
  1591. description: "Sharp defence",
  1592. itemType: ItemType.SPIKE,
  1593. actionType: ActionType.PLACEABLE,
  1594. Hs: 2,
  1595. As: 0,
  1596. os: 15,
  1597. layer: ELayer.SPIKE,
  1598. ps: 2
  1599. }, {
  1600. id: 8,
  1601. cost: {
  1602. food: 0,
  1603. wood: 20,
  1604. stone: 0,
  1605. gold: 0
  1606. },
  1607. ks: 1,
  1608. imageinv: 38,
  1609. image: 114,
  1610. name: "Platform",
  1611. description: "Shoot over structures",
  1612. itemType: ItemType.PLATFORM,
  1613. actionType: ActionType.PLACEABLE,
  1614. Hs: -2,
  1615. As: 0,
  1616. os: 8,
  1617. layer: ELayer.PLATFORM,
  1618. ps: 2
  1619. }, {
  1620. id: 9,
  1621. cost: {
  1622. food: 0,
  1623. wood: 30,
  1624. stone: 30,
  1625. gold: 0
  1626. },
  1627. ks: 1,
  1628. ys: 1024,
  1629. imageinv: 39,
  1630. image: 107,
  1631. name: "Trap",
  1632. description: "Snared enemies are stuck",
  1633. itemType: ItemType.TRAP,
  1634. actionType: ActionType.PLACEABLE,
  1635. Hs: 2,
  1636. As: 0,
  1637. os: 26,
  1638. layer: ELayer.TRAP,
  1639. ps: 2
  1640. }, {
  1641. id: 10,
  1642. cost: {
  1643. food: 10,
  1644. wood: 0,
  1645. stone: 0,
  1646. gold: 0
  1647. },
  1648. imageinv: 43,
  1649. image: 42,
  1650. name: "Apple",
  1651. description: "Heals you",
  1652. itemType: ItemType.FOOD,
  1653. actionType: ActionType.EATABLE,
  1654. restore: 20,
  1655. As: 0,
  1656. os: 22,
  1657. ps: 2
  1658. }, {
  1659. id: EWeapons.SHIELD,
  1660. ks: 1,
  1661. ys: 256,
  1662. imageinv: 47,
  1663. image: 46,
  1664. name: "Shield",
  1665. description: "Reduces damage",
  1666. itemType: ItemType.SECONDARY,
  1667. actionType: ActionType.MELEE,
  1668. Us: .7,
  1669. shieldAngle: .75,
  1670. range: 55,
  1671. Ms: 350,
  1672. damage: 15,
  1673. _s: 40,
  1674. reload: 500,
  1675. As: -15,
  1676. os: 10,
  1677. ps: 3
  1678. }, {
  1679. id: 12,
  1680. cost: {
  1681. food: 15,
  1682. wood: 0,
  1683. stone: 0,
  1684. gold: 0
  1685. },
  1686. ks: 1,
  1687. ys: 64,
  1688. imageinv: 52,
  1689. image: 51,
  1690. name: "Cookie",
  1691. description: "Heals you",
  1692. itemType: ItemType.FOOD,
  1693. actionType: ActionType.EATABLE,
  1694. restore: 35,
  1695. As: 0,
  1696. os: 22,
  1697. ps: 2
  1698. }, {
  1699. id: EWeapons.STICK,
  1700. gs: 41,
  1701. upgradeType: upgradeType.STONE,
  1702. ks: 1,
  1703. ys: 32,
  1704. imageinv: 55,
  1705. image: 54,
  1706. name: "Stick",
  1707. description: "Gathers resources quickly",
  1708. range: 100,
  1709. itemType: ItemType.PRIMARY,
  1710. damage: 1,
  1711. reload: 400,
  1712. actionType: ActionType.MELEE,
  1713. Ms: 60,
  1714. ps: 0,
  1715. As: 4,
  1716. os: 0,
  1717. Es: 7,
  1718. Cs: 7,
  1719. Bs: 7,
  1720. zs: 4
  1721. }, {
  1722. id: 14,
  1723. cost: {
  1724. food: 0,
  1725. wood: 50,
  1726. stone: 10,
  1727. gold: 0
  1728. },
  1729. imageinv: 57,
  1730. image: 61,
  1731. name: "Windmill",
  1732. description: "Generates score over time",
  1733. itemType: ItemType.WINDMILL,
  1734. actionType: ActionType.PLACEABLE,
  1735. rotateSpeed: Math.PI / 4,
  1736. Hs: -5,
  1737. As: 0,
  1738. os: 38,
  1739. layer: ELayer.WINDMILL,
  1740. ps: 2
  1741. }, {
  1742. id: EWeapons.HAMMER,
  1743. ks: 1,
  1744. ys: 1,
  1745. imageinv: 63,
  1746. image: 62,
  1747. name: "Hammer",
  1748. description: "Breaks structures faster",
  1749. range: 80,
  1750. itemType: ItemType.SECONDARY,
  1751. damage: 12,
  1752. _s: 76,
  1753. Us: .89,
  1754. Ms: 200,
  1755. reload: 400,
  1756. actionType: ActionType.MELEE,
  1757. ps: 0,
  1758. As: 5,
  1759. os: 2
  1760. }, {
  1761. id: 16,
  1762. ks: 1,
  1763. ys: 1,
  1764. cost: {
  1765. food: 0,
  1766. wood: 200,
  1767. stone: 200,
  1768. gold: 200
  1769. },
  1770. imageinv: 65,
  1771. image: 115,
  1772. name: "Cosy Bed",
  1773. description: "Respawn at the bed",
  1774. itemType: ItemType.SPAWN,
  1775. actionType: ActionType.PLACEABLE,
  1776. Hs: 8,
  1777. As: 0,
  1778. os: 25,
  1779. layer: ELayer.SPAWN,
  1780. ps: 2
  1781. }, {
  1782. id: EWeapons.KATANA,
  1783. gs: 37,
  1784. upgradeType: upgradeType.STONE,
  1785. ks: 2,
  1786. ys: 2,
  1787. imageinv: 68,
  1788. image: 67,
  1789. name: "Katana",
  1790. description: "Excellent melee weapon",
  1791. range: 140,
  1792. Ms: 150,
  1793. itemType: ItemType.PRIMARY,
  1794. damage: 40,
  1795. reload: 300,
  1796. Us: .85,
  1797. actionType: ActionType.MELEE,
  1798. ps: 0,
  1799. As: 1,
  1800. os: 3
  1801. }, {
  1802. id: 18,
  1803. cost: {
  1804. food: 0,
  1805. wood: 30,
  1806. stone: 30,
  1807. gold: 0
  1808. },
  1809. ks: 160,
  1810. ys: 1,
  1811. imageinv: 69,
  1812. image: 113,
  1813. name: "Castle Spike",
  1814. description: "Great for bases",
  1815. itemType: ItemType.SPIKE,
  1816. actionType: ActionType.PLACEABLE,
  1817. damage: {
  1818. hit: 24,
  1819. touch: 5
  1820. },
  1821. Hs: -8,
  1822. As: 0,
  1823. os: 14,
  1824. layer: ELayer.CASTLESPIKE,
  1825. ps: 2
  1826. }, {
  1827. id: 19,
  1828. cost: {
  1829. food: 0,
  1830. wood: 100,
  1831. stone: 50,
  1832. gold: 0
  1833. },
  1834. ks: 1,
  1835. ys: 1,
  1836. imageinv: 57,
  1837. image: 61,
  1838. name: "Powermill",
  1839. description: "Generates more score over time",
  1840. itemType: ItemType.WINDMILL,
  1841. actionType: ActionType.PLACEABLE,
  1842. rotateSpeed: Math.PI / 2,
  1843. Hs: 5,
  1844. As: 0,
  1845. os: 38,
  1846. layer: ELayer.POWERMILL,
  1847. ps: 2
  1848. }, {
  1849. id: 20,
  1850. ks: 1,
  1851. ys: 1,
  1852. cost: {
  1853. food: 0,
  1854. wood: 30,
  1855. stone: 10,
  1856. gold: 0
  1857. },
  1858. imageinv: 73,
  1859. image: 112,
  1860. name: "Hard Spike",
  1861. description: "Sharper defence",
  1862. itemType: ItemType.SPIKE,
  1863. actionType: ActionType.PLACEABLE,
  1864. Hs: 2,
  1865. As: 0,
  1866. os: 15,
  1867. layer: ELayer.HARDSPIKE,
  1868. ps: 2
  1869. }, {
  1870. id: 21,
  1871. cost: {
  1872. food: 0,
  1873. wood: 200,
  1874. stone: 150,
  1875. gold: 10
  1876. },
  1877. ks: 1,
  1878. ys: 1,
  1879. imageinv: 77,
  1880. image: 74,
  1881. name: "Turret",
  1882. description: "Defence for your base",
  1883. itemType: ItemType.TURRET,
  1884. actionType: ActionType.PLACEABLE,
  1885. Hs: 6,
  1886. As: 0,
  1887. os: 25,
  1888. layer: ELayer.TURRET,
  1889. ps: 2
  1890. }, {
  1891. id: 22,
  1892. ks: 1,
  1893. ys: 1,
  1894. cost: {
  1895. food: 0,
  1896. wood: 200,
  1897. stone: 0,
  1898. gold: 0
  1899. },
  1900. imageinv: 78,
  1901. image: 110,
  1902. name: "Cherry wood farm",
  1903. description: "Used for decoration and wood",
  1904. itemType: ItemType.FARM,
  1905. actionType: ActionType.PLACEABLE,
  1906. Hs: 3,
  1907. As: 0,
  1908. os: 47,
  1909. layer: ELayer.CHERRYWOODFARM,
  1910. ps: 2
  1911. }, {
  1912. id: 23,
  1913. ks: 1,
  1914. ys: 1,
  1915. cost: {
  1916. food: 0,
  1917. wood: 200,
  1918. stone: 0,
  1919. gold: 0
  1920. },
  1921. imageinv: 80,
  1922. image: 111,
  1923. name: "Wood farm",
  1924. description: "Used for decoration and wood",
  1925. itemType: ItemType.FARM,
  1926. actionType: ActionType.PLACEABLE,
  1927. Hs: 3,
  1928. As: 0,
  1929. os: 47,
  1930. layer: ELayer.WOODFARM,
  1931. ps: 2
  1932. }, {
  1933. id: 24,
  1934. ks: 1,
  1935. ys: 1,
  1936. cost: {
  1937. food: 200,
  1938. wood: 0,
  1939. stone: 0,
  1940. gold: 0
  1941. },
  1942. imageinv: 85,
  1943. image: 109,
  1944. name: "Berry farm",
  1945. description: "Used for decoration and berries",
  1946. itemType: ItemType.FARM,
  1947. actionType: ActionType.PLACEABLE,
  1948. Hs: 3,
  1949. As: 0,
  1950. os: 17,
  1951. layer: ELayer.BUSH,
  1952. ps: 2
  1953. }, {
  1954. id: 25,
  1955. ks: 1,
  1956. ys: 1,
  1957. cost: {
  1958. food: 0,
  1959. wood: 0,
  1960. stone: 200,
  1961. gold: 0
  1962. },
  1963. imageinv: 83,
  1964. image: 108,
  1965. name: "Stone farm",
  1966. description: "Used for decoration and stone",
  1967. itemType: ItemType.FARM,
  1968. actionType: ActionType.PLACEABLE,
  1969. Hs: 3,
  1970. As: 0,
  1971. os: 20,
  1972. layer: ELayer.STONEWARM,
  1973. ps: 2
  1974. }, {
  1975. id: EWeapons.BOW,
  1976. cost: {
  1977. food: 0,
  1978. wood: 4,
  1979. stone: 0,
  1980. gold: 0
  1981. },
  1982. ks: 1,
  1983. ys: 16,
  1984. imageinv: 86,
  1985. image: 87,
  1986. name: "Bow",
  1987. description: "Deal Long Range Damage",
  1988. range: 800,
  1989. itemType: ItemType.SECONDARY,
  1990. damage: 25,
  1991. reload: 600,
  1992. projectile: 88,
  1993. Ls: 1200,
  1994. actionType: ActionType.RANGED,
  1995. ps: 1,
  1996. Us: .75,
  1997. As: 0,
  1998. os: 35
  1999. }, {
  2000. id: EWeapons.XBOW,
  2001. cost: {
  2002. food: 0,
  2003. wood: 10,
  2004. stone: 0,
  2005. gold: 0
  2006. },
  2007. ks: 16,
  2008. ys: 176,
  2009. imageinv: 90,
  2010. image: 91,
  2011. name: "XBow",
  2012. description: "Rapid fire bow",
  2013. range: 800,
  2014. itemType: ItemType.SECONDARY,
  2015. damage: 27,
  2016. reload: 235,
  2017. projectile: 88,
  2018. Ls: 1200,
  2019. actionType: ActionType.RANGED,
  2020. ps: 1,
  2021. Us: .35,
  2022. As: 0,
  2023. os: 30
  2024. }, {
  2025. id: EWeapons.NAGINATA,
  2026. gs: 45,
  2027. upgradeType: upgradeType.STONE,
  2028. ks: 4,
  2029. ys: 4,
  2030. imageinv: 100,
  2031. image: 99,
  2032. name: "Naginata",
  2033. description: "Long melee range",
  2034. range: 165,
  2035. itemType: ItemType.PRIMARY,
  2036. damage: 52,
  2037. Us: .81,
  2038. Ms: 470,
  2039. reload: 700,
  2040. actionType: ActionType.MELEE,
  2041. ps: 0,
  2042. As: 0,
  2043. os: -4
  2044. }, {
  2045. id: 29,
  2046. cost: {
  2047. food: 0,
  2048. wood: 0,
  2049. stone: 35,
  2050. gold: 10
  2051. },
  2052. ks: 1,
  2053. ys: 1,
  2054. imageinv: 101,
  2055. image: 105,
  2056. name: "Castle Wall",
  2057. description: "A very sturdy wall",
  2058. itemType: ItemType.WALL,
  2059. actionType: ActionType.PLACEABLE,
  2060. Hs: 8,
  2061. As: 0,
  2062. os: 13,
  2063. layer: ELayer.CASTLEWALL,
  2064. ps: 2
  2065. }, {
  2066. id: EWeapons.GREAT_AXE,
  2067. gs: 35,
  2068. upgradeType: upgradeType.STONE,
  2069. ks: 128,
  2070. ys: 128,
  2071. imageinv: 117,
  2072. image: 116,
  2073. name: "Great Axe",
  2074. description: "More powerful axe.",
  2075. range: 94,
  2076. itemType: ItemType.PRIMARY,
  2077. damage: 37,
  2078. Ms: 250,
  2079. reload: 400,
  2080. actionType: ActionType.MELEE,
  2081. ps: 0,
  2082. As: 4,
  2083. os: 2,
  2084. Es: 4,
  2085. Cs: 4,
  2086. Bs: 4,
  2087. zs: 2
  2088. }, {
  2089. id: EWeapons.BAT,
  2090. ks: 1,
  2091. ys: 2048,
  2092. imageinv: 128,
  2093. image: 127,
  2094. name: "Bat",
  2095. description: "Hit enemies for a home run",
  2096. range: 115,
  2097. itemType: ItemType.PRIMARY,
  2098. damage: 28,
  2099. Us: .92,
  2100. Ms: 870,
  2101. reload: 700,
  2102. actionType: ActionType.MELEE,
  2103. ps: 0,
  2104. As: 10,
  2105. os: 2
  2106. }, {
  2107. id: 32,
  2108. ks: 1,
  2109. ys: 128,
  2110. imageinv: 131,
  2111. image: 130,
  2112. name: "Diamond Axe",
  2113. description: "Gathers materials faster",
  2114. range: 90,
  2115. itemType: ItemType.PRIMARY,
  2116. damage: 35.5,
  2117. Ms: 250,
  2118. reload: 400,
  2119. actionType: ActionType.MELEE,
  2120. ps: 0,
  2121. As: -2,
  2122. os: 2,
  2123. Es: 2,
  2124. Cs: 2,
  2125. Bs: 2,
  2126. zs: 2
  2127. }, {
  2128. id: 33,
  2129. gs: 32,
  2130. upgradeType: upgradeType.GOLD,
  2131. ks: 1,
  2132. ys: 128,
  2133. imageinv: 133,
  2134. image: 132,
  2135. name: "Gold Axe",
  2136. description: "Gathers materials faster",
  2137. range: 90,
  2138. itemType: ItemType.PRIMARY,
  2139. damage: 33,
  2140. Ms: 250,
  2141. reload: 400,
  2142. actionType: ActionType.MELEE,
  2143. ps: 0,
  2144. As: -2,
  2145. os: 2,
  2146. Es: 2,
  2147. Cs: 2,
  2148. Bs: 2,
  2149. zs: 2
  2150. }, {
  2151. id: 34,
  2152. ks: 128,
  2153. ys: 128,
  2154. imageinv: 135,
  2155. image: 134,
  2156. name: "Diamond Great Axe",
  2157. description: "More powerful axe.",
  2158. range: 94,
  2159. itemType: ItemType.PRIMARY,
  2160. damage: 47,
  2161. Ms: 250,
  2162. reload: 400,
  2163. actionType: ActionType.MELEE,
  2164. ps: 0,
  2165. As: 4,
  2166. os: 2,
  2167. Es: 4,
  2168. Cs: 4,
  2169. Bs: 4,
  2170. zs: 2
  2171. }, {
  2172. id: 35,
  2173. gs: 34,
  2174. upgradeType: upgradeType.GOLD,
  2175. ks: 128,
  2176. ys: 128,
  2177. imageinv: 145,
  2178. image: 144,
  2179. name: "Gold Great Axe",
  2180. description: "More powerful axe.",
  2181. range: 94,
  2182. itemType: ItemType.PRIMARY,
  2183. damage: 40,
  2184. Ms: 250,
  2185. reload: 400,
  2186. actionType: ActionType.MELEE,
  2187. ps: 0,
  2188. As: 4,
  2189. os: 2,
  2190. Es: 4,
  2191. Cs: 4,
  2192. Bs: 4,
  2193. zs: 2
  2194. }, {
  2195. id: 36,
  2196. gs: 40,
  2197. upgradeType: upgradeType.DIAMOND,
  2198. ks: 2,
  2199. ys: 2,
  2200. imageinv: 137,
  2201. image: 136,
  2202. name: "Diamond Katana",
  2203. description: "Excellent melee weapon",
  2204. range: 140,
  2205. Ms: 150,
  2206. itemType: ItemType.PRIMARY,
  2207. damage: 46.5,
  2208. reload: 300,
  2209. Us: .85,
  2210. actionType: ActionType.MELEE,
  2211. ps: 0,
  2212. As: 1,
  2213. os: 3
  2214. }, {
  2215. id: 37,
  2216. gs: 36,
  2217. upgradeType: upgradeType.GOLD,
  2218. ks: 2,
  2219. ys: 2,
  2220. imageinv: 139,
  2221. image: 138,
  2222. name: "Gold Katana",
  2223. description: "Excellent melee weapon",
  2224. range: 140,
  2225. Ms: 150,
  2226. itemType: ItemType.PRIMARY,
  2227. damage: 43,
  2228. reload: 300,
  2229. Us: .85,
  2230. actionType: ActionType.MELEE,
  2231. ps: 0,
  2232. As: 1,
  2233. os: 3
  2234. }, {
  2235. id: 38,
  2236. ks: 1,
  2237. ys: 4,
  2238. imageinv: 141,
  2239. image: 140,
  2240. name: "Diamond Spear",
  2241. description: "Long melee range",
  2242. range: 160,
  2243. itemType: ItemType.PRIMARY,
  2244. damage: 53,
  2245. Us: .81,
  2246. Ms: 450,
  2247. reload: 700,
  2248. actionType: ActionType.MELEE,
  2249. ps: 0,
  2250. As: 0,
  2251. os: 2
  2252. }, {
  2253. id: 39,
  2254. gs: 38,
  2255. upgradeType: upgradeType.GOLD,
  2256. ks: 1,
  2257. ys: 4,
  2258. imageinv: 143,
  2259. image: 142,
  2260. name: "Gold Spear",
  2261. description: "Long melee range",
  2262. range: 160,
  2263. itemType: ItemType.PRIMARY,
  2264. damage: 51,
  2265. Us: .81,
  2266. Ms: 450,
  2267. reload: 700,
  2268. actionType: ActionType.MELEE,
  2269. ps: 0,
  2270. As: 0,
  2271. os: 2
  2272. }, {
  2273. id: 40,
  2274. ks: 2,
  2275. ys: 2,
  2276. imageinv: 147,
  2277. image: 148,
  2278. name: "Chillrend",
  2279. description: "A powerful force flows through this blade.",
  2280. range: 140,
  2281. Ms: 150,
  2282. itemType: ItemType.PRIMARY,
  2283. damage: 48.5,
  2284. reload: 300,
  2285. Us: .9,
  2286. actionType: ActionType.MELEE,
  2287. ps: 0,
  2288. As: 1,
  2289. os: 3
  2290. }, {
  2291. id: 41,
  2292. gs: 42,
  2293. upgradeType: upgradeType.GOLD,
  2294. ks: 1,
  2295. ys: 32,
  2296. imageinv: 150,
  2297. image: 149,
  2298. name: "Gold Stick",
  2299. description: "Gathers resources quickly",
  2300. range: 100,
  2301. itemType: ItemType.PRIMARY,
  2302. damage: 1,
  2303. reload: 400,
  2304. actionType: ActionType.MELEE,
  2305. Ms: 60,
  2306. ps: 0,
  2307. As: 4,
  2308. os: 0,
  2309. Es: 8,
  2310. Cs: 8,
  2311. Bs: 8,
  2312. zs: 5
  2313. }, {
  2314. id: 42,
  2315. gs: 43,
  2316. upgradeType: upgradeType.DIAMOND,
  2317. ks: 1,
  2318. ys: 32,
  2319. imageinv: 167,
  2320. image: 151,
  2321. name: "Diamond Stick",
  2322. description: "Gathers resources quickly",
  2323. range: 100,
  2324. itemType: ItemType.PRIMARY,
  2325. damage: 1,
  2326. reload: 400,
  2327. actionType: ActionType.MELEE,
  2328. Ms: 60,
  2329. ps: 0,
  2330. As: 4,
  2331. os: 0,
  2332. Es: 9,
  2333. Cs: 9,
  2334. Bs: 9,
  2335. zs: 6
  2336. }, {
  2337. upgradeType: upgradeType.RUBY,
  2338. id: 43,
  2339. ks: 1,
  2340. ys: 32,
  2341. imageinv: 168,
  2342. image: 152,
  2343. name: "Ruby Stick",
  2344. description: "Gathers resources quickly",
  2345. range: 100,
  2346. itemType: ItemType.PRIMARY,
  2347. damage: 1,
  2348. reload: 400,
  2349. actionType: ActionType.MELEE,
  2350. Ms: 60,
  2351. ps: 0,
  2352. As: 4,
  2353. os: 0,
  2354. Es: 10,
  2355. Cs: 10,
  2356. Bs: 10,
  2357. zs: 7
  2358. }, {
  2359. id: 44,
  2360. ks: 4,
  2361. ys: 4,
  2362. imageinv: 154,
  2363. image: 153,
  2364. name: "Diamond Naginata",
  2365. description: "Long melee range",
  2366. range: 165,
  2367. itemType: ItemType.PRIMARY,
  2368. damage: 56,
  2369. Us: .81,
  2370. Ms: 470,
  2371. reload: 700,
  2372. actionType: ActionType.MELEE,
  2373. ps: 0,
  2374. As: 0,
  2375. os: -4
  2376. }, {
  2377. id: 45,
  2378. gs: 44,
  2379. upgradeType: upgradeType.GOLD,
  2380. ks: 4,
  2381. ys: 4,
  2382. imageinv: 156,
  2383. image: 155,
  2384. name: "Gold Naginata",
  2385. description: "Long melee range",
  2386. range: 165,
  2387. itemType: ItemType.PRIMARY,
  2388. damage: 54,
  2389. Us: .81,
  2390. Ms: 470,
  2391. reload: 700,
  2392. actionType: ActionType.MELEE,
  2393. ps: 0,
  2394. As: 0,
  2395. os: -4
  2396. }, {
  2397. id: 46,
  2398. gs: 47,
  2399. upgradeType: upgradeType.GOLD,
  2400. imageinv: 158,
  2401. image: 157,
  2402. name: "Gold Tool Hammer",
  2403. description: "Gather materials",
  2404. range: 80,
  2405. itemType: ItemType.PRIMARY,
  2406. damage: 32,
  2407. reload: 300,
  2408. _s: 30,
  2409. Ms: 200,
  2410. actionType: ActionType.MELEE,
  2411. ps: 0,
  2412. As: -3.5,
  2413. os: 1
  2414. }, {
  2415. id: 47,
  2416. gs: 48,
  2417. upgradeType: upgradeType.DIAMOND,
  2418. imageinv: 160,
  2419. image: 159,
  2420. name: "Diamond Tool Hammer",
  2421. description: "Gather materials",
  2422. range: 80,
  2423. itemType: ItemType.PRIMARY,
  2424. damage: 38,
  2425. reload: 300,
  2426. _s: 30,
  2427. Ms: 200,
  2428. actionType: ActionType.MELEE,
  2429. ps: 0,
  2430. As: -3.5,
  2431. os: 1
  2432. }, {
  2433. upgradeType: upgradeType.RUBY,
  2434. id: 48,
  2435. imageinv: 162,
  2436. image: 161,
  2437. name: "Ruby Tool Hammer",
  2438. description: "Gather materials",
  2439. range: 80,
  2440. itemType: ItemType.PRIMARY,
  2441. damage: 41,
  2442. reload: 300,
  2443. _s: 30,
  2444. Ms: 200,
  2445. actionType: ActionType.MELEE,
  2446. ps: 0,
  2447. As: -3.5,
  2448. os: 1
  2449. }, {
  2450. id: 49,
  2451. cost: {
  2452. food: 0,
  2453. wood: 20,
  2454. stone: 0,
  2455. gold: 0
  2456. },
  2457. ks: 1,
  2458. imageinv: 170,
  2459. image: 169,
  2460. name: "Roof",
  2461. description: "Take cover from projectiles",
  2462. itemType: ItemType.PLATFORM,
  2463. actionType: ActionType.PLACEABLE,
  2464. Hs: 0,
  2465. As: 0,
  2466. os: 15,
  2467. layer: ELayer.ROOF,
  2468. ps: 2
  2469. }, {
  2470. id: 50,
  2471. cost: {
  2472. food: 80,
  2473. wood: 80,
  2474. stone: 80,
  2475. gold: 80
  2476. },
  2477. ks: 1,
  2478. ys: 256,
  2479. imageinv: 182,
  2480. image: 182,
  2481. name: "Pearl",
  2482. description: "Teleport on impact",
  2483. range: 700,
  2484. itemType: ItemType.SECONDARY,
  2485. damage: 10,
  2486. reload: 1e4,
  2487. projectile: 182,
  2488. Ls: 1e3,
  2489. actionType: ActionType.RANGED,
  2490. ps: 1,
  2491. Us: .4,
  2492. As: 0,
  2493. os: 35
  2494. }, {
  2495. id: 51,
  2496. cost: {
  2497. food: 0,
  2498. wood: 50,
  2499. stone: 50,
  2500. gold: 0
  2501. },
  2502. ks: 2208,
  2503. ys: 1,
  2504. imageinv: 183,
  2505. image: 183,
  2506. name: "Teleporter",
  2507. description: "Teleports to location on map",
  2508. itemType: ItemType.SPAWN,
  2509. actionType: ActionType.PLACEABLE,
  2510. Hs: 5,
  2511. As: 0,
  2512. os: 15,
  2513. layer: ELayer.TELEPORT,
  2514. ps: 2
  2515. }, {
  2516. gs: 53,
  2517. upgradeType: upgradeType.STONE,
  2518. id: 52,
  2519. ks: 1,
  2520. ys: 4096,
  2521. imageinv: 189,
  2522. image: 193,
  2523. name: "Stone Dagger",
  2524. description: "A stubbier sword",
  2525. range: 80,
  2526. Ms: 100,
  2527. itemType: ItemType.PRIMARY,
  2528. damage: 22,
  2529. reload: 150,
  2530. actionType: ActionType.MELEE,
  2531. ps: 0,
  2532. As: 10,
  2533. os: 20
  2534. }, {
  2535. gs: 54,
  2536. upgradeType: upgradeType.GOLD,
  2537. id: 53,
  2538. ks: 1,
  2539. ys: 4096,
  2540. imageinv: 190,
  2541. image: 194,
  2542. name: "Gold Dagger",
  2543. description: "A stubbier sword",
  2544. range: 80,
  2545. Ms: 100,
  2546. itemType: ItemType.PRIMARY,
  2547. damage: 24,
  2548. reload: 150,
  2549. actionType: ActionType.MELEE,
  2550. ps: 0,
  2551. As: 10,
  2552. os: 20
  2553. }, {
  2554. gs: 55,
  2555. upgradeType: upgradeType.DIAMOND,
  2556. id: 54,
  2557. ks: 1,
  2558. ys: 4096,
  2559. imageinv: 191,
  2560. image: 195,
  2561. name: "Diamond Dagger",
  2562. description: "A stubbier sword",
  2563. range: 80,
  2564. Ms: 100,
  2565. itemType: ItemType.PRIMARY,
  2566. damage: 26,
  2567. reload: 150,
  2568. actionType: ActionType.MELEE,
  2569. ps: 0,
  2570. As: 10,
  2571. os: 20
  2572. }, {
  2573. upgradeType: upgradeType.RUBY,
  2574. id: 55,
  2575. ks: 1,
  2576. ys: 4096,
  2577. imageinv: 192,
  2578. image: 196,
  2579. name: "Ruby Dagger",
  2580. description: "A stubbier sword",
  2581. range: 80,
  2582. Ms: 100,
  2583. itemType: ItemType.PRIMARY,
  2584. damage: 29,
  2585. reload: 150,
  2586. actionType: ActionType.MELEE,
  2587. ps: 0,
  2588. As: 10,
  2589. os: 20
  2590. }, {
  2591. id: 56,
  2592. gs: 57,
  2593. upgradeType: upgradeType.GOLD,
  2594. ks: 1,
  2595. ys: 1,
  2596. imageinv: 198,
  2597. image: 198,
  2598. name: "Secret Item",
  2599. description: "Dont leak how to get it :)",
  2600. range: 115,
  2601. itemType: ItemType.PRIMARY,
  2602. damage: 28,
  2603. Us: .92,
  2604. Ms: 1570,
  2605. reload: 2e3,
  2606. actionType: ActionType.MELEE,
  2607. ps: 0,
  2608. As: 40,
  2609. os: 40
  2610. }, {
  2611. id: 57,
  2612. ks: 2,
  2613. ys: 2,
  2614. imageinv: 199,
  2615. image: 199,
  2616. name: "Daedric Scythe",
  2617. description: "Whispers fill the air",
  2618. range: 160,
  2619. Ms: 150,
  2620. itemType: ItemType.PRIMARY,
  2621. damage: 52,
  2622. reload: 450,
  2623. Us: .85,
  2624. actionType: ActionType.MELEE,
  2625. ps: 0,
  2626. As: -5,
  2627. os: 20
  2628. } ];
  2629. const Items = ItemData;
  2630. const ItemList = Items.filter((item => item.actionType === ActionType.PLACEABLE));
  2631. const Shooting = Items.filter((item => item.actionType === ActionType.RANGED));
  2632. class Vector {
  2633. constructor(x, y) {
  2634. this.x = x;
  2635. this.y = y;
  2636. }
  2637. static fromAngle(angle) {
  2638. return new Vector(Math.cos(angle), Math.sin(angle));
  2639. }
  2640. add(vec) {
  2641. this.x += vec.x;
  2642. this.y += vec.y;
  2643. return this;
  2644. }
  2645. sub(vec) {
  2646. this.x -= vec.x;
  2647. this.y -= vec.y;
  2648. return this;
  2649. }
  2650. mult(scalar) {
  2651. this.x *= scalar;
  2652. this.y *= scalar;
  2653. return this;
  2654. }
  2655. div(scalar) {
  2656. this.x /= scalar;
  2657. this.y /= scalar;
  2658. return this;
  2659. }
  2660. get length() {
  2661. return Math.sqrt(this.x * this.x + this.y * this.y);
  2662. }
  2663. normalize() {
  2664. return this.length > 0 ? this.div(this.length) : this;
  2665. }
  2666. setLength(value) {
  2667. return this.normalize().mult(value);
  2668. }
  2669. copy() {
  2670. return new Vector(this.x, this.y);
  2671. }
  2672. distance(vec) {
  2673. return this.copy().sub(vec).length;
  2674. }
  2675. angle(vec) {
  2676. const copy = vec.copy().sub(this);
  2677. return Math.atan2(copy.y, copy.x);
  2678. }
  2679. dot(vec) {
  2680. return this.x * vec.x + this.y * vec.y;
  2681. }
  2682. direction(angle, scalar) {
  2683. return this.copy().add(Vector.fromAngle(angle).mult(scalar));
  2684. }
  2685. }
  2686. const getAngleDist = (a, b) => {
  2687. const p = Math.abs(b - a) % (Math.PI * 2);
  2688. return p > Math.PI ? Math.PI * 2 - p : p;
  2689. };
  2690. class EntityManager {
  2691. static isPlayer(entity) {
  2692. return entity.type === ELayer.PLAYER;
  2693. }
  2694. static animals() {
  2695. const layers = Sploop.saves.entityList();
  2696. const animals = [];
  2697. for (let i = 0; i < Animals.length; i++) {
  2698. const layer = layers[Animals[i].id];
  2699. const formatted = layer.map((target => Formatter.entity(target)));
  2700. animals.push(...formatted);
  2701. }
  2702. return animals;
  2703. }
  2704. static enemies() {
  2705. const players = Sploop.saves.entityList()[ELayer.PLAYER];
  2706. const enemies = [];
  2707. for (let i = 0; i < players.length; i++) {
  2708. const player = Formatter.player(players[i]);
  2709. if (controller.isEnemy(player)) enemies.push(player);
  2710. }
  2711. return enemies.sort(((a, b) => this.sortDistance(a, b)));
  2712. }
  2713. static distance(a, b) {
  2714. return new Vector(a.x2, a.y2).distance(new Vector(b.x2, b.y2));
  2715. }
  2716. static angle(a, b) {
  2717. return new Vector(a.x2, a.y2).angle(new Vector(b.x2, b.y2));
  2718. }
  2719. static sortDistance(a, b, sorted) {
  2720. const target = sorted || Sploop.myPlayer;
  2721. return this.distance(a, target) - this.distance(b, target);
  2722. }
  2723. static shield(a, b, sorted) {
  2724. const target = sorted || Sploop.myPlayer;
  2725. const shieldA = this.lookingAt(a, target, 1.58927) && a.currentItem === EWeapons.SHIELD;
  2726. const shieldB = this.lookingAt(b, target, 1.58927) && b.currentItem === EWeapons.SHIELD;
  2727. return shieldA ? 1 : shieldB ? -1 : 0;
  2728. }
  2729. static canHitEntity(a, b, sorted) {
  2730. const target = sorted || Sploop.myPlayer;
  2731. const hitA = this.projectileCanHitEntity(a, target);
  2732. const hitB = this.projectileCanHitEntity(b, target);
  2733. return hitA === Hit.NEEDDESTROY ? 1 : hitB === Hit.NEEDDESTROY ? -1 : 0;
  2734. }
  2735. static lookingAt(entity, point, angle) {
  2736. const pos1 = new Vector(entity.x2, entity.y2);
  2737. const pos2 = new Vector(point.x2, point.y2);
  2738. const dir = getAngleDist(pos1.angle(pos2) + Math.PI, entity.angle2);
  2739. return dir > angle;
  2740. }
  2741. static entities(sorted) {
  2742. return [ ...this.enemies().sort(((a, b) => this.sortDistance(a, b, sorted))).sort(((a, b) => this.shield(a, b, sorted))), ...this.animals().sort(((a, b) => this.sortDistance(a, b, sorted))) ];
  2743. }
  2744. static predict(entity) {
  2745. const pos1 = new Vector(entity.x1, entity.y1);
  2746. const pos2 = new Vector(entity.x2, entity.y2);
  2747. const distance = pos1.distance(pos2) * (entity === Sploop.myPlayer ? 1 : 2.2);
  2748. const direction = Vector.fromAngle(pos1.angle(pos2));
  2749. return pos2.add(direction.mult(distance));
  2750. }
  2751. static entityIn(entity, layer, extraRadius = 0) {
  2752. const targets = Sploop.saves.entityList()[layer];
  2753. return targets.some((target => {
  2754. const object = Formatter.object(target);
  2755. const radius = entity.radius + object.radius + extraRadius;
  2756. return this.distance(entity, object) <= radius;
  2757. }));
  2758. }
  2759. static intersects(pos1, pos2, pos3, r) {
  2760. const linear = pos2.copy().sub(pos1);
  2761. const constant = pos1.copy().sub(pos3);
  2762. const a = linear.dot(linear);
  2763. const b = linear.dot(constant);
  2764. const c = constant.dot(constant) - r * r;
  2765. return b * b >= a * c && (-b <= a || c + b + b + a <= 0) && (b <= 0 || c <= 0);
  2766. }
  2767. static projectileCanHitEntity(entity, sorted) {
  2768. const target = sorted || Sploop.myPlayer;
  2769. if (!controller.canShoot()) return Hit.CANNOT;
  2770. const pos1 = new Vector(target.x2, target.y2);
  2771. const pos2 = new Vector(entity.x2, entity.y2);
  2772. const myPlayerOnPlatform = this.entityIn(target, ELayer.PLATFORM);
  2773. const entityInRoof = this.entityIn(entity, ELayer.ROOF);
  2774. if (myPlayerOnPlatform && entityInRoof) return Hit.CANNOT;
  2775. const layers = Sploop.saves.entityList();
  2776. for (const layer of LayerObjects) {
  2777. if (myPlayerOnPlatform && !layer.cannotShoot) continue;
  2778. for (const target of layers[layer.id]) {
  2779. const object = Formatter.object(target);
  2780. const pos3 = new Vector(object.x2, object.y2);
  2781. if (pos1.distance(pos3) > pos1.distance(pos2)) continue;
  2782. if (this.intersects(pos1, pos2, pos3, object.radius)) {
  2783. if (object.layerData.maxHealth === undefined) return Hit.CANNOT;
  2784. return Hit.NEEDDESTROY;
  2785. }
  2786. }
  2787. }
  2788. return Hit.CAN;
  2789. }
  2790. static inWeaponRange(entity1, entity2, weapon) {
  2791. const range = Items[weapon].range || 10;
  2792. return this.distance(entity1, entity2) <= range + entity2.radius;
  2793. }
  2794. static nearestPossible(weapon, sorted) {
  2795. const target = sorted || Sploop.myPlayer;
  2796. const item = Items[weapon];
  2797. const shoot = controller.canShoot() && item.actionType === ActionType.RANGED;
  2798. const entities = this.entities().filter((entity => shoot ? this.projectileCanHitEntity(entity, target) : this.inWeaponRange(target, entity, weapon)));
  2799. if (shoot) {
  2800. entities.sort(((a, b) => this.canHitEntity(a, b, target)));
  2801. }
  2802. return entities.length ? entities[0] : null;
  2803. }
  2804. static nearestLayer(entity, layer) {
  2805. const objects = Sploop.saves.entityList()[layer].map((target => Formatter.object(target)));
  2806. return objects.sort(((a, b) => this.sortDistance(a, b, entity)))[0];
  2807. }
  2808. }
  2809. const attackAnimation = () => {
  2810. if (!Settings.weaponReloadBar && !Settings.autosync) return;
  2811. const b = Sploop.saves.buffer;
  2812. const len = Sploop.saves.byteLength;
  2813. const players = Sploop.saves.players();
  2814. for (let i = 1; i < len; i += 5) {
  2815. const type = b[i];
  2816. const id = b[i + 1] | b[i + 2] << 8;
  2817. const weapon = b[i + 3];
  2818. const isObject = b[i + 4];
  2819. const target = players.get(id);
  2820. if (type === ELayer.PLAYER && target) {
  2821. if (Settings.weaponReloadBar) {
  2822. const reload = target.weaponReload;
  2823. reload.current = -Sploop.step;
  2824. reload.lerp = 0;
  2825. reload.max = Items[weapon].reload || 0;
  2826. }
  2827. if (Settings.autosync && controller.canAutosync()) {
  2828. const player = Formatter.player(target);
  2829. if (controller.isTeammate(player) && controller.isPrimary(weapon)) {
  2830. const nearest = EntityManager.nearestPossible(weapon, player);
  2831. if (nearest !== null && EntityManager.inWeaponRange(Sploop.myPlayer, nearest, controller.itemBar[0])) {
  2832. const previousWeapon = controller.weapon;
  2833. controller.whichWeapon(false);
  2834. controller.attack(EntityManager.angle(Sploop.myPlayer, nearest));
  2835. controller.PacketManager.stopAttack();
  2836. controller.whichWeapon(previousWeapon);
  2837.  
  2838. }
  2839. }
  2840. }
  2841. }
  2842. }
  2843. };
  2844. const hooks_attackAnimation = attackAnimation;
  2845. window.teammates = [];
  2846. const createClan = () => {
  2847. const b = window.Sploop.saves.buffer2();
  2848. const len = window.Sploop.saves.byteLength2();
  2849. teammates = [...b.slice(3, len)];
  2850. };
  2851. const updateClan = () => {
  2852. const b = window.Sploop.saves.buffer2();
  2853. const len = window.Sploop.saves.byteLength2();
  2854. teammates = [...b.slice(2, len)];
  2855. };
  2856. const deleteClan = () => {
  2857. teammates = [];
  2858. };
  2859.  
  2860. window.WebSocket = new Proxy(window.WebSocket, {
  2861. construct(target, args) {
  2862. const ws = new target(...args);
  2863. ws.addEventListener("message", (event => {
  2864. const data = event.data;
  2865. if (typeof data === "string" && /^\[.+\]$/.test(data)) {
  2866. //
  2867. } else {
  2868. switch (window.Sploop.saves.buffer2()[0]) {
  2869. case 27:
  2870. deleteClan();
  2871. break;
  2872.  
  2873. case 24:
  2874. createClan();
  2875. break;
  2876.  
  2877. case 16:
  2878. updateClan();
  2879. break;
  2880. }
  2881. }
  2882. }));
  2883. return ws;
  2884. }
  2885. });
  2886. const playerStats = () => {
  2887. const b = window.Sploop.saves.buffer2()
  2888. const age = formatAge(b[1] | b[2] << 8 | b[3] << 16 | b[4] << 24);
  2889. const food = b[5] | b[6] << 8 | b[7] << 16 | b[8] << 24;
  2890. const wood = b[9] | b[10] << 8 | b[11] << 16 | b[12] << 24;
  2891. const stone = b[13] | b[14] << 8 | b[15] << 16 | b[16] << 24;
  2892. const gold = b[17] | b[18] << 8 | b[19] << 16 | b[20] << 24;
  2893. if (age !== 0) {
  2894. controller.age = age;
  2895. }
  2896. controller.resources = {
  2897. food,
  2898. wood,
  2899. stone,
  2900. gold
  2901. };
  2902. };
  2903. const hooks_playerStats = playerStats;
  2904. const stringMessage = data => {
  2905. const id = data[0];
  2906. if (id === 35) {
  2907. controller.myPlayerID = data[1];
  2908. controller.reset(data[4]);
  2909. controller.inGame = true;
  2910. controller.automillSpawn = true;
  2911. if (Settings.lastHat) {
  2912. const hat = controller.toggleJungle || controller.toggleScuba ? controller.previousHat : controller.actualHat;
  2913. window.equip(hat, true, true);
  2914. }
  2915. }
  2916. if (id === WebsocketServer.UPGRADE) {
  2917. const bar = data[1];
  2918. const canAutobed = Settings.autobed && bar.includes(EObjects.SPAWN);
  2919. controller.autobed = canAutobed;
  2920. if (Settings.skipUpgrades && bar.length === 1 || canAutobed) {
  2921. controller.PacketManager.upgrade(canAutobed ? EObjects.SPAWN : bar[0]);
  2922. }
  2923. }
  2924. if (id === WebsocketServer.DIED) {
  2925. controller.myPlayerID = 0;
  2926. controller.inGame = false;
  2927. if (Settings.autospawn) {
  2928. controller.spawn();
  2929. }
  2930. }
  2931. if (id === WebsocketServer.KILL_UPDATE) {
  2932. controller.kills = data[1][0];
  2933. }
  2934. if (id === WebsocketServer.KILLED && Settings.kill) {
  2935. const killMessage = Settings.killMessage.length ? Settings.killMessage : "{KILL}x";
  2936. const name = data[1].replace(/^Killed\s/, "").trim();
  2937. const message = killMessage.replace(/\{KILL\}/g, controller.kills + "").replace(/\{NAME\}/g, name);
  2938. controller.PacketManager.chat(message);
  2939. }
  2940. };
  2941. const hooks_stringMessage = stringMessage;
  2942. var WebsocketServer;
  2943. (function(WebsocketServer) {
  2944. WebsocketServer[WebsocketServer["LEADERBOARD"] = 3] = "LEADERBOARD";
  2945. WebsocketServer[WebsocketServer["DAMAGE"] = 6] = "DAMAGE";
  2946. WebsocketServer[WebsocketServer["PLAYERSTATS"] = 8] = "PLAYERSTATS";
  2947. WebsocketServer[WebsocketServer["CONNECT"] = 12] = "CONNECT";
  2948. WebsocketServer[WebsocketServer["UPGRADE"] = 14] = "UPGRADE";
  2949. WebsocketServer[WebsocketServer["UPDATECLAN"] = 16] = "UPDATECLAN";
  2950. WebsocketServer[WebsocketServer["DIED"] = 19] = "DIED";
  2951. WebsocketServer[WebsocketServer["MOVEUPDATE"] = 20] = "MOVEUPDATE";
  2952. WebsocketServer[WebsocketServer["KILL_UPDATE"] = 22] = "KILL_UPDATE";
  2953. WebsocketServer[WebsocketServer["JOINCREATECLAN"] = 24] = "JOINCREATECLAN";
  2954. WebsocketServer[WebsocketServer["DELETECLAN"] = 27] = "DELETECLAN";
  2955. WebsocketServer[WebsocketServer["KILLED"] = 28] = "KILLED";
  2956. WebsocketServer[WebsocketServer["ATTACK_ANIMATION"] = 29] = "ATTACK_ANIMATION";
  2957. WebsocketServer[WebsocketServer["PLAYER_SPAWNED"] = 32] = "PLAYER_SPAWNED";
  2958. WebsocketServer[WebsocketServer["DEFAULT"] = 33] = "DEFAULT";
  2959. WebsocketServer[WebsocketServer["SPAWN"] = 35] = "SPAWN";
  2960. })(WebsocketServer || (WebsocketServer = {}));
  2961. var WebsocketClient;
  2962. (function(WebsocketClient) {
  2963. WebsocketClient[WebsocketClient["MOVE"] = 6] = "MOVE";
  2964. WebsocketClient[WebsocketClient["ANGLE"] = 13] = "ANGLE";
  2965. WebsocketClient[WebsocketClient["selectByID"] = 2] = "selectByID";
  2966. WebsocketClient[WebsocketClient["ATTACK"] = 19] = "ATTACK";
  2967. WebsocketClient[WebsocketClient["STOPATTACK"] = 18] = "STOPATTACK";
  2968. WebsocketClient[WebsocketClient["LOGIN"] = 10] = "LOGIN";
  2969. WebsocketClient[WebsocketClient["SCYTHE"] = 20] = "SCYTHE";
  2970. WebsocketClient[WebsocketClient["SELECTITEM"] = 0] = "SELECTITEM";
  2971. WebsocketClient[WebsocketClient["HAT"] = 5] = "HAT";
  2972. WebsocketClient[WebsocketClient["CHAT"] = 7] = "CHAT";
  2973. WebsocketClient[WebsocketClient["UPGRADE"] = 14] = "UPGRADE";
  2974. WebsocketClient[WebsocketClient["AUTOATTACK"] = 23] = "AUTOATTACK";
  2975. WebsocketClient[WebsocketClient["MOVEANGLE"] = 1] = "MOVEANGLE";
  2976. WebsocketClient[WebsocketClient["LEAVECLAN"] = 24] = "LEAVECLAN";
  2977. WebsocketClient[WebsocketClient["JOIN"] = 21] = "JOIN";
  2978. WebsocketClient[WebsocketClient["ACCEPTDECLINE"] = 17] = "ACCEPTDECLINE";
  2979. WebsocketClient[WebsocketClient["KICK"] = 25] = "KICK";
  2980. WebsocketClient[WebsocketClient["CREATECLAN"] = 22] = "CREATECLAN";
  2981. })(WebsocketClient || (WebsocketClient = {}));
  2982. let start = Date.now();
  2983. window.WebSocket = new Proxy(window.WebSocket, {
  2984. construct(target, args) {
  2985. if (typeof args[0] === "string") {
  2986. if (args[0] !== Sploop.connectURL) {
  2987. controller.myPlayerID = 0;
  2988. controller.age = 0;
  2989. for (const hat of Hats) {
  2990. hat.bought = !!hat.default;
  2991. hat.equipped = !!hat.default;
  2992. }
  2993. }
  2994. Sploop.connectURL = args[0];
  2995. }
  2996. const ws = new target(...args);
  2997. ws.addEventListener("message", (event => {
  2998. const data = event.data;
  2999. if (typeof data === "string" && /^\[.+\]$/.test(data)) {
  3000. hooks_stringMessage(JSON.parse(data));
  3001. } else {
  3002. switch (Sploop.saves.buffer[0]) {
  3003. case WebsocketServer.PLAYERSTATS:
  3004. hooks_playerStats();
  3005. break;
  3006.  
  3007. case WebsocketServer.DELETECLAN:
  3008. deleteClan();
  3009. break;
  3010.  
  3011. case WebsocketServer.JOINCREATECLAN:
  3012. createClan();
  3013. break;
  3014.  
  3015. case WebsocketServer.UPDATECLAN:
  3016. updateClan();
  3017. break;
  3018.  
  3019. case WebsocketServer.MOVEUPDATE:
  3020. {
  3021. const now = Date.now();
  3022. Sploop.step = now - start;
  3023. start = now;
  3024. break;
  3025. }
  3026.  
  3027. case WebsocketServer.ATTACK_ANIMATION:
  3028. {
  3029. hooks_attackAnimation();
  3030. break;
  3031. }
  3032. }
  3033. }
  3034. }));
  3035. return ws;
  3036. }
  3037. });
  3038. class PacketManager {
  3039. constructor() {
  3040. this.encoder = new TextEncoder;
  3041. }
  3042. send(...args) {
  3043. Sploop.saves.send(new Uint8Array(args));
  3044. }
  3045. moveByBitmask(bitmask) {
  3046. this.send(WebsocketClient.MOVE, bitmask);
  3047. }
  3048. changeAngle(angle) {
  3049. angle = 65535 * (angle + Math.PI) / (2 * Math.PI), this.send(WebsocketClient.ANGLE, 255 & angle, angle >> 8 & 255);
  3050. }
  3051. selectByID(id) {
  3052. this.send(WebsocketClient.selectByID, id);
  3053. }
  3054. attack(angle) {
  3055. angle = 65535 * (angle + Math.PI) / (2 * Math.PI), this.send(WebsocketClient.ATTACK, 255 & angle, angle >> 8 & 255);
  3056. }
  3057. stopAttack() {
  3058. this.send(WebsocketClient.STOPATTACK);
  3059. }
  3060. upgradeScythe(goldenCowID) {
  3061. this.send(WebsocketClient.SCYTHE, 255 & goldenCowID, goldenCowID >> 8);
  3062. }
  3063. selectItemByType(type) {
  3064. this.send(WebsocketClient.SELECTITEM, type);
  3065. }
  3066. equip(id) {
  3067. this.send(WebsocketClient.HAT, id);
  3068. }
  3069. chat(message) {
  3070. const bytes = this.encoder.encode(message);
  3071. this.send(WebsocketClient.CHAT, ...bytes);
  3072. }
  3073. upgrade(id) {
  3074. this.send(WebsocketClient.UPGRADE, id);
  3075. controller.upgradeItem(id);
  3076. }
  3077. autoattack(toggle) {
  3078. this.send(WebsocketClient.AUTOATTACK, Number(toggle));
  3079. }
  3080. moveAngle(angle) {
  3081. angle = 65535 * (angle + Math.PI) / (2 * Math.PI), this.send(WebsocketClient.MOVEANGLE, angle, angle >> 8 & 255);
  3082. }
  3083. leaveClan() {
  3084. this.send(WebsocketClient.LEAVECLAN);
  3085. }
  3086. joinClan(id) {
  3087. this.send(WebsocketClient.JOIN, id);
  3088. }
  3089. accept(which) {
  3090. this.send(WebsocketClient.ACCEPTDECLINE, which);
  3091. }
  3092. kick(id) {
  3093. this.send(WebsocketClient.KICK, id);
  3094. }
  3095. createClan(name) {
  3096. const bytes = this.encoder.encode(name);
  3097. this.send(WebsocketClient.CREATECLAN, ...bytes);
  3098. }
  3099. }
  3100. class TimeoutManager {
  3101. constructor(callbacks, delay) {
  3102. this.callbacks = callbacks;
  3103. this.delay = delay;
  3104. this.active = false;
  3105. this.old = Date.now();
  3106. }
  3107. static waitUntil(condition, time, callback) {
  3108. return new Promise((resolve => {
  3109. const start = Date.now();
  3110. const int = setInterval((() => {
  3111. if (typeof time === "number" && Number.isFinite(time) && Date.now() - start > time || condition()) {
  3112. clearInterval(int);
  3113. }
  3114. if (condition()) {
  3115. if (typeof callback === "function") return callback();
  3116. resolve();
  3117. }
  3118. }), 50);
  3119. }));
  3120. }
  3121. start() {
  3122. if (this.active) return;
  3123. this.active = true;
  3124. this.old = Date.now();
  3125. this.callbacks[0]();
  3126. }
  3127. async stop() {
  3128. if (!this.active) return;
  3129. this.callbacks[1]();
  3130. if (!this.delay(this.old)) await TimeoutManager.waitUntil((() => this.delay(this.old)), 3e3);
  3131. this.callbacks[2]();
  3132. this.active = false;
  3133. }
  3134. isActive() {
  3135. return this.active;
  3136. }
  3137. }
  3138. class Controller {
  3139. constructor() {
  3140. this.myPlayerID = 0;
  3141. this.move = 0;
  3142. this.playerList = [];
  3143. this.attacking = false;
  3144. this.autoattack = false;
  3145. this.rotation = false;
  3146. this.weapon = false;
  3147. this.healing = false;
  3148. this.attackingInvis = false;
  3149. this.toggleInvis = false;
  3150. this.currentItem = null;
  3151. this.chatToggle = false;
  3152. this.chatCount = 0;
  3153. this.autobed = false;
  3154. this.automill = false;
  3155. this.automillSpawn = false;
  3156. this.mousemove = true;
  3157. this.kills = 0;
  3158. this.inGame = false;
  3159. this.itemBar = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ];
  3160. this.hsl = 0;
  3161. this.aimTarget = null;
  3162. this.wasAutoboost = false;
  3163. this.count = 0;
  3164. this.toggleJungle = false;
  3165. this.toggleScuba = false;
  3166. this.resources = {
  3167. food: 200,
  3168. wood: 200,
  3169. stone: 200,
  3170. gold: 200
  3171. };
  3172. this.mouse = {
  3173. x: 0,
  3174. y: 0,
  3175. angle: 0
  3176. };
  3177. this.equipStart = Date.now();
  3178. this.actualHat = 0;
  3179. this.currentHat = 0;
  3180. this.previousHat = 0;
  3181. this.maxCount = [ 0, 0, 0, 100, 30, 8, 2, 12, 32, 1, 2 ];
  3182. this.age = 0;
  3183. this.hotkeys = new Map;
  3184. this.PacketManager = new PacketManager;
  3185. this.previousWeapon = false;
  3186. this.fastbreak = new TimeoutManager([ () => {
  3187. const primary = this.itemBar[ItemType.PRIMARY];
  3188. const secondary = this.itemBar[ItemType.SECONDARY];
  3189. const pickWeapon = secondary === EWeapons.HAMMER || primary === EWeapons.STICK && secondary === EWeapons.SHIELD;
  3190. this.previousWeapon = this.weapon;
  3191. this.whichWeapon(pickWeapon);
  3192. window.equip(11);
  3193. this.attacking = true;
  3194. this.attack();
  3195. }, () => {
  3196. this.PacketManager.stopAttack();
  3197. this.attacking = false;
  3198. this.whichWeapon(this.previousWeapon);
  3199. }, () => {
  3200. if (!Sploop.myPlayer.isClown) {
  3201. window.equip(this.previousHat);
  3202. }
  3203. } ], (start => Sploop.myPlayer.target.hatReload === TargetReload.HAT && Date.now() - start > TargetReload.HAT));
  3204. this.attachMouse();
  3205. }
  3206. reset(items) {
  3207. this.move = 0;
  3208. this.attacking = false;
  3209. this.autoattack = false;
  3210. this.rotation = false;
  3211. this.weapon = false;
  3212. this.healing = false;
  3213. this.attackingInvis = false;
  3214. this.toggleInvis = false;
  3215. this.currentItem = null;
  3216. this.chatToggle = false;
  3217. this.chatCount = 0;
  3218. this.autobed = false;
  3219. this.automill = false;
  3220. this.automillSpawn = false;
  3221. this.mousemove = true;
  3222. this.kills = 0;
  3223. this.inGame = false;
  3224. this.itemBar = [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ];
  3225. this.hsl = 0;
  3226. this.aimTarget = null;
  3227. this.count = 0;
  3228. const target = Sploop.myPlayer.target;
  3229. if (target) {
  3230. target.hatReload = TargetReload.HAT;
  3231. }
  3232. for (const id of items) {
  3233. this.upgradeItem(id);
  3234. }
  3235. for (const [key] of this.hotkeys) {
  3236. this.hotkeys.delete(key);
  3237. }
  3238. }
  3239. attachMouse() {
  3240. window.addEventListener("mousemove", (event => {
  3241. this.mouse.x = event.clientX;
  3242. this.mouse.y = event.clientY;
  3243. if (!this.rotation) {
  3244. this.mouse.angle = angle(innerWidth / 2, innerHeight / 2, this.mouse.x, this.mouse.y);
  3245. }
  3246. }));
  3247. }
  3248.  
  3249. hasItem(type) {
  3250. return this.itemBar[type] !== -1;
  3251. }
  3252. hasSecondary() {
  3253. return this.itemBar[ItemType.SECONDARY] !== -1;
  3254. }
  3255. updateWeapon(type) {
  3256. const weapon = Sploop.saves.defaultData[Sploop.props.itemBar][type];
  3257. if (this.isWeapon(weapon) && this.itemBar[type] !== weapon) {
  3258. this.itemBar[type] = weapon;
  3259. }
  3260. }
  3261. isMyPlayer(entity) {
  3262. return entity.id === this.myPlayerID;
  3263. }
  3264. isTeammate(entity) {
  3265. return entity.id !== this.myPlayerID && teammates.includes(entity.ownerID);
  3266. }
  3267. isEnemy(entity) {
  3268. return !this.isMyPlayer(entity) && !this.isTeammate(entity);
  3269. }
  3270. canShoot() {
  3271. const id = this.itemBar[ItemType.SECONDARY];
  3272. return this.hasSecondary() && Items[id].actionType === ActionType.RANGED;
  3273. }
  3274. isWeapon(id) {
  3275. const type = Items[id].itemType;
  3276. return type === ItemType.PRIMARY || type === ItemType.SECONDARY;
  3277. }
  3278. isPrimary(id) {
  3279. return Items[id].itemType === ItemType.PRIMARY;
  3280. }
  3281. isSecondary(id) {
  3282. return Items[id].itemType === ItemType.SECONDARY;
  3283. }
  3284. currentCount(type) {
  3285. return Sploop.saves.defaultData[Sploop.props.currentCount][type];
  3286. }
  3287. hasCount(type) {
  3288. return this.currentCount(type) < this.maxCount[type];
  3289. }
  3290. isDoingNothing() {
  3291. return !this.healing && !this.attackingInvis && !this.toggleInvis && !this.attacking && this.currentItem === null;
  3292. }
  3293. canAutosync() {
  3294. return !this.attacking && !this.attackingInvis && !this.toggleInvis && !this.autoattack;
  3295. }
  3296. hasResources(id) {
  3297. const cost = Items[id].cost || {
  3298. food: 0,
  3299. wood: 0,
  3300. stone: 0,
  3301. gold: 0
  3302. };
  3303. const {food, wood, stone, gold} = this.resources;
  3304. const hasFood = food >= cost.food;
  3305. const hasWood = wood >= cost.wood;
  3306. const hasStone = stone >= cost.stone;
  3307. const hasGold = gold >= cost.gold;
  3308. return hasFood && hasWood && hasStone && hasGold;
  3309. }
  3310. getAngleFromBitmask(bitmask, rotate) {
  3311. const vec = {
  3312. x: 0,
  3313. y: 0
  3314. };
  3315. if (bitmask & 1) vec.y--;
  3316. if (bitmask & 2) vec.y++;
  3317. if (bitmask & 4) vec.x--;
  3318. if (bitmask & 8) vec.x++;
  3319. if (rotate) {
  3320. vec.x *= -1;
  3321. vec.y *= -1;
  3322. }
  3323. return Math.atan2(vec.y, vec.x);
  3324. }
  3325. upgradeItem(id) {
  3326. const item = Items[id];
  3327. this.itemBar[item.itemType] = id;
  3328. }
  3329. upgradeScythe() {
  3330. const target = Sploop.saves.entityList()[ELayer.GOLDENCOW][0];
  3331. if (target !== undefined) {
  3332. this.PacketManager.upgradeScythe(target[Sploop.props.id]);
  3333. }
  3334. }
  3335. buyHat(id) {
  3336. if (!Hats[id].bought && controller.resources.gold >= Hats[id].price) {
  3337. Hats[id].bought = true;
  3338. this.PacketManager.equip(id);
  3339. }
  3340. return Hats[id].bought;
  3341. }
  3342. hatReloaded() {
  3343. return Sploop.myPlayer.target.hatReload.current === TargetReload.HAT;
  3344. }
  3345. equipHat(id, actual = true, force = false) {
  3346. const hatID = id === Hat.UNEQUIP ? this.actualHat : id;
  3347. if (!this.buyHat(hatID) || !this.inGame) return false;
  3348. const now = Date.now();
  3349. if (!Hats[id].equipped && this.hatReloaded() && now - this.equipStart >= TargetReload.HAT || force) {
  3350. this.equipStart = now;
  3351. this.PacketManager.equip(hatID);
  3352. for (const hat of Hats) {
  3353. hat.equipped = false;
  3354. }
  3355. Hats[id].equipped = true;
  3356. this.previousHat = this.currentHat;
  3357. this.currentHat = id;
  3358. if (actual) {
  3359. this.actualHat = id;
  3360. }
  3361. return true;
  3362. }
  3363. return false;
  3364. }
  3365. async autochat() {
  3366. if (this.chatToggle) return;
  3367. this.chatToggle = true;
  3368. const messages = Settings.autochatMessages.filter((msg => msg.length));
  3369. if (!messages.length) return;
  3370. this.PacketManager.chat(messages[this.chatCount++]);
  3371. this.chatCount %= messages.length;
  3372. await sleep(2e3);
  3373. this.chatToggle = false;
  3374. }
  3375. accept(which) {
  3376. this.PacketManager.accept(which);
  3377. const acceptList = Sploop.saves.clanData[Sploop.props.acceptList];
  3378. acceptList.shift();
  3379. }
  3380. async spawn() {
  3381. await sleep(100);
  3382. const play = document.querySelector("#play");
  3383. play.click();
  3384. }
  3385. whichWeapon(type) {
  3386. if (type !== undefined) {
  3387. this.weapon = type;
  3388. }
  3389. this.PacketManager.selectByID(this.itemBar[+this.weapon]);
  3390. }
  3391. attack(angle) {
  3392. const dir = angle ? angle : this.mouse.angle;
  3393. this.PacketManager.attack(dir);
  3394. }
  3395. place(type, angle, placementType) {
  3396. if (this.wasAutoboost) {
  3397. const nearest = EntityManager.enemies()[0];
  3398. if (nearest !== undefined) {
  3399. angle = EntityManager.angle(Sploop.myPlayer, nearest);
  3400. this.PacketManager.moveAngle(angle);
  3401. }
  3402. }
  3403. const placeType = placementType === undefined ? Settings.placementType : placementType;
  3404. const isHolding = placeType === PlacementType.HOLDING;
  3405. this.whichWeapon();
  3406. if (isHolding && this.attacking) this.attack(angle);
  3407. this.PacketManager.selectItemByType(type);
  3408. this.attack(angle);
  3409. this.PacketManager.stopAttack();
  3410. if (!isHolding) this.whichWeapon();
  3411. if (this.attacking) this.attack(angle);
  3412. }
  3413. placement() {
  3414. if (this.currentItem === null) return;
  3415. this.place(this.currentItem);
  3416. this.count = (this.count + 1) % Settings.placementSpeed;
  3417. const method = this.count === 0 ? setTimeout : queueMicrotask;
  3418. method(this.placement.bind(this));
  3419. }
  3420. placementHandler(type, code) {
  3421. if (!this.hasItem(type)) return;
  3422. if (Settings.placementType === PlacementType.DEFAULT) {
  3423. this.PacketManager.selectItemByType(type);
  3424. return;
  3425. }
  3426. this.hotkeys.set(code, type);
  3427. this.currentItem = type;
  3428. const isBoost = type === ItemType.TRAP && this.itemBar[ItemType.TRAP] === EObjects.BOOST;
  3429. this.wasAutoboost = Settings.autoboostFollow && isBoost;
  3430. if (this.hotkeys.size === 1) {
  3431. this.placement();
  3432. this.placement();
  3433. }
  3434. }
  3435. heal() {
  3436. this.PacketManager.selectItemByType(ItemType.FOOD);
  3437. this.attack();
  3438. this.PacketManager.stopAttack();
  3439. this.whichWeapon();
  3440. if (this.attacking) {
  3441. this.attack();
  3442. }
  3443. }
  3444. invisibleHit() {
  3445. this.mousemove = true;
  3446. this.aimTarget = null;
  3447. if (Settings.invisHitToggle && !this.toggleInvis || !Settings.invisHitToggle && !this.attackingInvis) {
  3448. this.toggleInvis = false;
  3449. this.attackingInvis = false;
  3450. return;
  3451. }
  3452. let angle;
  3453. const nearest = EntityManager.nearestPossible(this.itemBar[+!this.weapon]);
  3454. const shoot = this.canShoot() && !this.weapon;
  3455. if (nearest && (Settings.meleeAim && !shoot || Settings.bowAim && shoot)) {
  3456. const pos1 = EntityManager.predict(Sploop.myPlayer);
  3457. const pos2 = EntityManager.predict(nearest);
  3458. angle = pos1.angle(pos2);
  3459. this.mousemove = false;
  3460. this.aimTarget = nearest.target;
  3461. }
  3462. if (nearest && shoot || !shoot) {
  3463. this.whichWeapon(!this.weapon);
  3464. this.attack(angle);
  3465. this.PacketManager.stopAttack();
  3466. this.whichWeapon(!this.weapon);
  3467. }
  3468. setTimeout(this.invisibleHit.bind(this), 85);
  3469. }
  3470. spikeInsta() {
  3471. let angle;
  3472. if (Settings.spikeInstaAim) {
  3473. const nearest = EntityManager.nearestPossible(this.itemBar[0]);
  3474. if (nearest) {
  3475. angle = EntityManager.angle(Sploop.myPlayer, nearest);
  3476. }
  3477. }
  3478. const previousWeapon = this.weapon;
  3479. this.equipHat(Hat.BERSERKER);
  3480. this.whichWeapon(false);
  3481. this.place(ItemType.SPIKE, angle);
  3482. this.attack(angle);
  3483. this.PacketManager.stopAttack();
  3484. this.whichWeapon(previousWeapon);
  3485. }
  3486. handleKeydown(event, code) {
  3487. if (code === 1) event.preventDefault();
  3488. if (event instanceof KeyboardEvent && event.repeat) return;
  3489. if (Sploop.active) return;
  3490. if (code === Settings.toggleMenu && !isInput(event.target)) {
  3491. if (typeof Sploop.toggleMenu === "function") Sploop.toggleMenu();
  3492. }
  3493. if (!this.inGame) return;
  3494. if (code === Settings.openChat) {
  3495. if (!isInput()) event.preventDefault();
  3496. Sploop.saves.toggleChat();
  3497. }
  3498. if (isInput(event.target)) return;
  3499. if (code === Settings.primary) this.whichWeapon(false);
  3500. if (code === Settings.secondary && this.hasSecondary()) this.whichWeapon(true);
  3501. if (code === Settings.heal && !this.healing) {
  3502. this.healing = true;
  3503. if (Settings.placementType === PlacementType.DEFAULT) {
  3504. this.PacketManager.selectItemByType(ItemType.FOOD);
  3505. } else {
  3506. doWhile((() => this.healing), this.heal.bind(this), 0);
  3507. }
  3508. }
  3509. //var boenmytimestartkey = "Backquote"
  3510. if (code === Settings.wall) this.placementHandler(ItemType.WALL, code);
  3511. //if (code === boenmytimestartkey) my_time();
  3512. if (code === Settings.spike) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.SPIKE, code);
  3513. if (code === Settings.windmill) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.WINDMILL, code);
  3514. if (code === Settings.trap) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.TRAP, code);
  3515. if (code === Settings.turret) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.TURRET, code);
  3516. if (code === Settings.tree) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.FARM, code);
  3517. if (code === Settings.platform) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.PLATFORM, code);
  3518. if (code === Settings.spawn) for(let i = 0; i < Settings.placementSpeed; i++) this.placementHandler(ItemType.SPAWN, code);
  3519. if (code === Settings.unequip) window.equip(0);
  3520. if (code === Settings.bush) window.equip(1);
  3521. if (code === Settings.berserker) window.equip(2);
  3522. if (code === Settings.jungle) window.equip(3);
  3523. if (code === Settings.crystal) window.equip(4);
  3524. if (code === Settings.spikegear) window.equip(5);
  3525. if (code === Settings.immunity) window.equip(6);
  3526. if (code === Settings.boost) window.equip(7);
  3527. if (code === Settings.applehat) window.equip(8);
  3528. if (code === Settings.scuba) window.equip(9);
  3529. if (code === Settings.hood) window.equip(10);
  3530. if (code === Settings.demolist) window.equip(11);
  3531. if (code === Settings.invisibleHit && this.hasSecondary()) {
  3532. if (Settings.invisHitToggle) {
  3533. this.toggleInvis = !this.toggleInvis;
  3534. } else {
  3535. this.attackingInvis = true;
  3536. }
  3537. if (this.toggleInvis || this.attackingInvis) this.invisibleHit();
  3538. }
  3539. if (code === Settings.spikeInsta) this.spikeInsta();
  3540. if (code === Settings.fastBreak && !this.fastbreak.isActive() && this.hatReloaded()) {
  3541. this.fastbreak.start();
  3542. }
  3543. const copyMove = this.move;
  3544. if (code === Settings.up) this.move |= 1;
  3545. if (code === Settings.left) this.move |= 4;
  3546. if (code === Settings.down) this.move |= 2;
  3547. if (code === Settings.right) this.move |= 8;
  3548. if (copyMove !== this.move) this.PacketManager.moveByBitmask(this.move);
  3549. if (event instanceof MouseEvent && code === 0) {
  3550. this.attacking = true;
  3551. }
  3552. if (code === Settings.autoattack) {
  3553. this.autoattack = !this.autoattack;
  3554. this.PacketManager.autoattack(this.autoattack);
  3555. }
  3556. if (code === Settings.lockRotation) {
  3557. this.rotation = !this.rotation;
  3558. Sploop.saves.toggleRotation(this.rotation);
  3559. }
  3560. if (code === Settings.upgradeScythe) this.upgradeScythe();
  3561. }
  3562. handleKeyup(event, code) {
  3563. if (code === Settings.heal && this.healing) {
  3564. this.healing = false;
  3565. }
  3566. if (code === Settings.invisibleHit && this.attackingInvis) {
  3567. this.attackingInvis = false;
  3568. }
  3569. if (code === Settings.fastBreak && this.fastbreak.isActive()) {
  3570. this.fastbreak.stop();
  3571. }
  3572. const copyMove = this.move;
  3573. if (code === Settings.up) this.move &= -2;
  3574. if (code === Settings.left) this.move &= -5;
  3575. if (code === Settings.down) this.move &= -3;
  3576. if (code === Settings.right) this.move &= -9;
  3577. if (copyMove !== this.move) this.PacketManager.moveByBitmask(this.move);
  3578. if (event instanceof MouseEvent && code === 0) {
  3579. this.attacking = false;
  3580. }
  3581. if (code === Settings.trap && this.wasAutoboost) {
  3582. this.wasAutoboost = false;
  3583. this.PacketManager.moveByBitmask(this.move);
  3584. }
  3585. if (this.currentItem !== null && this.hotkeys.delete(code)) {
  3586. const entries = [ ...this.hotkeys ];
  3587. this.currentItem = entries.length ? entries[entries.length - 1][1] : null;
  3588. if (this.currentItem === null) {
  3589. this.whichWeapon();
  3590. }
  3591. }
  3592. }
  3593. }
  3594. const createEntity = target => {
  3595. const id = target[Sploop.props.id];
  3596. const type = target.type;
  3597. const entities = Sploop.saves.entityList();
  3598. if (type === ELayer.PLAYER) {
  3599. if (id === controller.myPlayerID) {
  3600. Sploop.myPlayer.target = target;
  3601. updateSkin();
  3602. }
  3603. const player = Formatter.player(target);
  3604. target.hatReload = {
  3605. ...Reload.hat
  3606. };
  3607. target.weaponReload = {
  3608. ...Reload.weapon
  3609. };
  3610. target.prevHat = player.hat;
  3611. const weaponReload = target.weaponReload;
  3612. if (controller.isWeapon(player.currentItem)) {
  3613. weaponReload.max = Items[player.currentItem].reload || 0;
  3614. weaponReload.current = weaponReload.max;
  3615. weaponReload.lerp = weaponReload.max;
  3616. }
  3617. } else if (type === ELayer.TURRET) {
  3618. target.turretReload = {
  3619. ...Reload.turret
  3620. };
  3621. } else if (type === ELayer.DRAGON) {
  3622. target.fireballReload = {
  3623. ...Reload.fireball
  3624. };
  3625. } else if (type === ELayer.PROJECTILE) {
  3626. const projectile = Formatter.projectile(target);
  3627. const type = projectile.projectileType;
  3628. const isTurret = Settings.turretReloadBar && entities[ELayer.TURRET].find((target => {
  3629. const turret = Formatter.object(target);
  3630. const isOwner = turret.ownerID === projectile.ownerID;
  3631. const isX = turret.x2 === projectile.x2;
  3632. const isY = turret.y2 === projectile.y2;
  3633. return isOwner && isX && isY;
  3634. }));
  3635. const isPlayer = Settings.weaponReloadBar && entities[ELayer.PLAYER].find((target => {
  3636. const player = Formatter.player(target);
  3637. const isOwner = player.ownerID === projectile.ownerID;
  3638. return isOwner;
  3639. }));
  3640. if (isTurret) {
  3641. const reload = isTurret.turretReload;
  3642. reload.current = -Sploop.step;
  3643. reload.lerp = 0;
  3644. } else if (isPlayer) {
  3645. const weapon = Shooting.find((weapon => weapon.projectile === type));
  3646. if (weapon === undefined) return;
  3647. let delay = weapon.reload || 0;
  3648. if (type === 88) {
  3649. const id = isPlayer.secondary === EWeapons.XBOW ? EWeapons.XBOW : EWeapons.BOW;
  3650. delay = Items[id].reload || 0;
  3651. }
  3652. const reload = isPlayer.weaponReload;
  3653. reload.current = -Sploop.step;
  3654. reload.lerp = 0;
  3655. reload.max = delay;
  3656. }
  3657. } else if (type === ELayer.FIREBALL && entities[ELayer.DRAGON].length && Settings.fireballReloadBar) {
  3658. const dragon = entities[ELayer.DRAGON][0];
  3659. const reload = dragon.fireballReload;
  3660. reload.current = -Sploop.step;
  3661. reload.lerp = 0;
  3662. }
  3663. };
  3664. const hooks_createEntity = createEntity;
  3665. const TextOptions = {
  3666. font: "bold 15px Montserrat",
  3667. textBaseline: "top"
  3668. };
  3669. class RenderManager {
  3670. static marker(ctx, color) {
  3671. /*
  3672. ctx.strokeStyle = "#303030"; // outline color i think
  3673. ctx.fillStyle = color;
  3674. ctx.beginPath();
  3675. ctx.arc(0, 0, 7, 0, 2 * Math.PI);
  3676. ctx.fill();
  3677. /*
  3678. ctx.stroke(); // remove this = no outline
  3679. ctx.closePath();
  3680. */
  3681. }
  3682. static circle(ctx, x, y, radius, color) {
  3683. ctx.strokeStyle = color;
  3684. ctx.lineWidth = 0;
  3685. ctx.beginPath();
  3686. ctx.arc(1, 1, radius, 0, 1 * Math.PI);
  3687. ctx.stroke();
  3688. ctx.closePath();
  3689. }
  3690. static arrow(ctx, len, x, y, angle, color) {
  3691. ctx.save();
  3692. ctx.translate(x, y);
  3693. ctx.rotate(Math.PI / 6);
  3694. ctx.rotate(angle);
  3695. ctx.globalAlpha = .36;
  3696. ctx.strokeStyle = color;
  3697. ctx.lineCap = "triangle";
  3698. ctx.lineWidth = 8;
  3699. ctx.beginPath();
  3700. ctx.moveTo(-len, -len);
  3701. ctx.lineTo(len, -len);
  3702. ctx.lineTo(len, len);
  3703. ctx.stroke();
  3704. ctx.closePath();
  3705. ctx.restore();
  3706. }
  3707. static lines(ctx, x1, y1, x2, y2, color) {
  3708. ctx.save();
  3709. ctx.globalAlpha = .50;
  3710. ctx.strokeStyle = color;
  3711. ctx.lineCap = "triangle";
  3712. ctx.lineWidth = 1.1;
  3713. ctx.beginPath();
  3714. ctx.moveTo(x1, y1);
  3715. ctx.lineTo(x2, y2);
  3716. ctx.stroke();
  3717. ctx.restore();
  3718. }
  3719. static tracerColor(entity, isTeammate) {
  3720. if (isTeammate) return Settings.teammateColor;
  3721. if (entity.type === ELayer.PLAYER) return Settings.enemyColor;
  3722. return Settings.animalColor;
  3723. }
  3724. static trapActive(trap) {
  3725. return EntityManager.entities().some((entity => {
  3726. const radius = trap.radius + entity.radius;
  3727. return EntityManager.distance(entity, trap) < radius - 25;
  3728. }));
  3729. }
  3730. static markerColor(target, ownerID) {
  3731. let color = null;
  3732. const object = Formatter.object(target);
  3733. const isMyPlayer = Sploop.myPlayer.ownerID === ownerID;
  3734. const isTeammate = teammates.includes(ownerID);
  3735. const isTeammateTrap = object.type === ELayer.TRAP && (isMyPlayer || isTeammate);
  3736. if (Settings.itemMarkers && isMyPlayer) {
  3737. color = "#4a86ff";
  3738. } else if (Settings.teammateMarkers && isTeammate && !isMyPlayer) {
  3739. color = Settings.teammateMarkersColor;
  3740. } else if (Settings.enemyMarkers && !isMyPlayer && !isTeammate) {
  3741. color = "#E2322F";
  3742. }
  3743. if (Settings.trapActivated && isTeammateTrap) {
  3744. if (!target.active && this.trapActive(object)) {
  3745. target.active = object.id;
  3746. }
  3747. if (target.active === object.id) {
  3748. return Settings.trapActivatedColor;
  3749. }
  3750. target.active = null;
  3751. }
  3752. return color;
  3753. }
  3754. static renderText(ctx, text, callback, options) {
  3755. ctx.save();
  3756. ctx.fillStyle = "#fff";
  3757. ctx.strokeStyle = "#303030";
  3758. ctx.lineWidth = 5;
  3759. ctx.transparenct = .3;
  3760. ctx.lineJoin = "round";
  3761. Object.assign(ctx, TextOptions, options);
  3762. const width = ctx.measureText(text).width;
  3763. const height = parseInt((ctx.font.match(/\d+/) || [])[0]) || 1;
  3764. const data = callback(width, height);
  3765. ctx.strokeText(text, ...data);
  3766. ctx.fillText(text, ...data);
  3767. ctx.restore();
  3768. }
  3769. static renderHP(ctx, entity, height = 0) {
  3770. if (!Settings.drawHP) return;
  3771. const {x, y, health, maxHealth, radius} = entity;
  3772. this.renderText(ctx, `${health}`, (width => [ x - width / 2, y + radius + -90 + height ]));
  3773. }
  3774. static drawImage(ctx, image) {
  3775. if (!(image && image.naturalHeight !== 0)) return;
  3776. const w = image.width;
  3777. const h = image.height;
  3778. const s = .5;
  3779. ctx.drawImage(image, -s * w / 2, -s * h, w * s, h * s);
  3780. }
  3781. static renderBar(ctx, entity, value, maxValue, color, extraHeight = 0) {
  3782. const {x, y, radius} = entity;
  3783. const background = utils_Images.gaugeBackground;
  3784. const front = utils_Images.gaugeFront;
  3785. const scale = .5;
  3786. const width = front.width * scale;
  3787. const fill = value / maxValue * (width - 10);
  3788. const h = (entity.type === ELayer.TURRET ? 25 : 50) + extraHeight;
  3789. ctx.save();
  3790. if (entity.type === ELayer.TURRET) {
  3791. ctx.rotate(Math.PI - entity.angle);
  3792. ctx.rotate(Math.PI);
  3793. }
  3794. ctx.translate(x, y + radius + h + front.height * scale);
  3795. this.drawImage(ctx, background);
  3796. ctx.fillStyle = color;
  3797. ctx.fillRect(-width / 2 + 5, -scale * front.height + 5, fill, scale * front.height - 10);
  3798. this.drawImage(ctx, front);
  3799. ctx.restore();
  3800. return front.height * scale;
  3801. }
  3802. static reloadBar(ctx, entity, reload, height) {
  3803. const fill = clamp(reload.current, 0, reload.max);
  3804. reload.lerp = lerp(reload.lerp, fill, .2);
  3805. const value = Settings.smoothReloadBar ? reload.lerp : fill;
  3806. return this.renderBar(ctx, entity, value, reload.max, reload.color(), height);
  3807. }
  3808. static windmillRotation(target) {
  3809. const rotateSpeed = LayerData[target.type].rotateSpeed;
  3810. if (rotateSpeed === undefined) return;
  3811. const speed = Settings.windmillRotation ? rotateSpeed : 0;
  3812. if (target[Sploop.props.rotateSpeed] !== speed) {
  3813. target[Sploop.props.rotateSpeed] = speed;
  3814. }
  3815. }
  3816. static renderMarker(ctx, target) {
  3817. const object = Formatter.object(target);
  3818. if (object.ownerID === 0) return;
  3819. if (object.type === ELayer.TURRET && Settings.turretReloadBar) {
  3820. this.reloadBar(ctx, {
  3821. ...object,
  3822. x: 0,
  3823. y: 0
  3824. }, target.turretReload, 0);
  3825. }
  3826. this.windmillRotation(target);
  3827. const color = this.markerColor(target, object.ownerID);
  3828. if (color === null) return;
  3829. this.marker(ctx, color);
  3830. }
  3831. static renderTracer(ctx, entity, isTeammate) {
  3832. const player = Formatter.player(Sploop.myPlayer.target);
  3833. const color = Settings.rainbow ? `hsl(${controller.hsl}, 100%, 50%)` : this.tracerColor(entity, isTeammate);
  3834. const pos1 = new Vector(player.x, player.y);
  3835. const pos2 = new Vector(entity.x, entity.y);
  3836. if (Settings.arrows) {
  3837. const w = 8;
  3838. const distance = Math.min(100 + w * 2, pos1.distance(pos2) - w * 2);
  3839. const angle = pos1.angle(pos2);
  3840. const pos = pos1.direction(angle, distance);
  3841. this.arrow(ctx, w, pos.x, pos.y, angle, color);
  3842. } else {
  3843. this.lines(ctx, pos1.x, pos1.y, pos2.x, pos2.y, color);
  3844. }
  3845. }
  3846. }
  3847. const drawEntityInfo = (target, ctx, isTeammate) => {
  3848. const entity = Formatter.entity(target);
  3849. if (controller.myPlayerID === entity.id) {
  3850. if (Settings.rainbow) {
  3851. Sploop.controller.hsl = (Sploop.controller.hsl + .3) % 360;
  3852. }
  3853. if (controller.aimTarget !== null) {
  3854. const aim = Formatter.entity(controller.aimTarget);
  3855. const dir = Settings.visualAim ? angle(entity.x, entity.y, aim.x, aim.y) : controller.mouse.angle;
  3856. Sploop.myPlayer.target[Sploop.props.angle] = dir;
  3857. }
  3858. }
  3859. let height = 0;
  3860. if (entity.type === ELayer.PLAYER) {
  3861. if (Settings.hatReloadBar) {
  3862. height += RenderManager.reloadBar(ctx, entity, target.hatReload, height);
  3863. }
  3864. if (Settings.weaponReloadBar) {
  3865. height += RenderManager.reloadBar(ctx, entity, target.weaponReload, height);
  3866. }
  3867. }
  3868. if (entity.type === ELayer.DRAGON && Settings.fireballReloadBar) {
  3869. height += RenderManager.reloadBar(ctx, entity, target.fireballReload, height);
  3870. }
  3871. RenderManager.renderHP(ctx, entity, height);
  3872. if (controller.myPlayerID === entity.id || !Sploop.myPlayer.target) return;
  3873. if (Settings.possibleShots && !isTeammate) {
  3874. const hit = EntityManager.projectileCanHitEntity(entity);
  3875. if (hit === Hit.CAN) {
  3876. const color = Settings.rainbow ? `hsl(${controller.hsl}, 100%, 50%)` : RenderManager.tracerColor(entity, isTeammate);
  3877. RenderManager.circle(ctx, entity.x, entity.y, entity.radius, color);
  3878. }
  3879. }
  3880. if (Settings.enemyTracers && entity.type === 0 && !isTeammate || Settings.teammateTracers && entity.type === 0 && isTeammate || Settings.animalTracers && entity.type !== 0) {
  3881. RenderManager.renderTracer(ctx, entity, isTeammate);
  3882. }
  3883. };
  3884. const hooks_drawEntityInfo = drawEntityInfo;
  3885. const drawItemBar = (ctx, imageData, index) => {
  3886. if (!Settings.itemCounter) return;
  3887. const id = Sploop.saves.defaultData[Sploop.props.itemBar][index];
  3888. const type = Items[id].itemType;
  3889. const currentCount = Sploop.saves.defaultData[Sploop.props.currentCount][type];
  3890. const maxCount = controller.maxCount[type];
  3891. if (maxCount === 0) return;
  3892. const x = imageData[Sploop.props.x] - 10;
  3893. const y = imageData[Sploop.props.y] + 10;
  3894. const w = imageData.width;
  3895. RenderManager.renderText(ctx, `${currentCount}/${maxCount}`, (width => [ x + w - width, y ]), {
  3896. font: "bold 16px Montserrat"
  3897. });
  3898. };
  3899. const hooks_drawItemBar = drawItemBar;
  3900. const renderItems = (target, id, ctx, step) => {
  3901. RenderManager.renderMarker(ctx, target);
  3902. };
  3903. const hooks_renderItems = renderItems;
  3904. let isHealing = false;
  3905. let updatePlayer_start = Date.now();
  3906. const healing = () => {
  3907. const {health, maxHealth, isClown} = Sploop.myPlayer;
  3908. if (Settings.autoheal && health < maxHealth && controller.inGame) controller.heal()
  3909. }
  3910. setInterval(() => { // automill | am
  3911. const automill = controller.age < 10 && controller.hasCount(ItemType.WINDMILL);
  3912. const automillSpawn = controller.age > 9 && controller.currentCount(ItemType.WINDMILL) === 0 && controller.automillSpawn;
  3913. controller.automill = A_M && (automill || automillSpawn);
  3914. if (controller.automill && controller.hasResources(controller.itemBar[ItemType.WINDMILL])) {
  3915. const angle = controller.getAngleFromBitmask(controller.move, true);
  3916. setTimeout(() => {
  3917. controller.place(ItemType.WINDMILL, angle + 0.75, PlacementType.INVISIBLE);
  3918. }, 50);
  3919. setTimeout(() => {
  3920. controller.place(ItemType.WINDMILL, angle - 0.75, PlacementType.INVISIBLE);
  3921. }, 150);
  3922. }
  3923. }, 150);
  3924. const updatePlayer = target => {
  3925. const entity = Formatter.entity(target);
  3926. switch (entity.type) {
  3927. case ELayer.PLAYER:
  3928. {
  3929. const player = Formatter.player(target);
  3930. if (controller.isWeapon(player.currentItem)) {
  3931. if (controller.isSecondary(player.currentItem)) {
  3932. target.secondary = player.currentItem;
  3933. } else {
  3934. target.primary = player.currentItem;
  3935. }
  3936. }
  3937. if (player.id === controller.myPlayerID) {
  3938. Sploop.myPlayer = {
  3939. ...Sploop.myPlayer,
  3940. ...player
  3941. };
  3942. const {x2, y2, health, maxHealth, isClown, hat} = Sploop.myPlayer;
  3943. if (health < 100) {
  3944. setTimeout(() => {
  3945. controller.heal();
  3946. }, Math.round(Sploop.myPlayer.health * 1.66))
  3947. }
  3948. if (controller.isDoingNothing()) {
  3949. if (controller.autobed && controller.hasResources(EObjects.SPAWN)) {
  3950. controller.place(ItemType.SPAWN, random(-Math.PI, Math.PI));
  3951. }
  3952. }
  3953. break;
  3954. }}
  3955. break;
  3956. case ELayer.TURRET:
  3957. {
  3958. if (Settings.turretReloadBar) {
  3959. const turretReload = target.turretReload;
  3960. turretReload.current = Math.min(turretReload.current + Sploop.step, turretReload.max);
  3961. }
  3962. break;
  3963. }
  3964.  
  3965. case ELayer.DRAGON:
  3966. {
  3967. if (Settings.fireballReloadBar) {
  3968. const fireballReload = target.fireballReload;
  3969. fireballReload.current = Math.min(fireballReload.current + Sploop.step, fireballReload.max);
  3970. }
  3971. break;
  3972. }
  3973. }
  3974. };
  3975. const hooks_updatePlayer = updatePlayer;
  3976. const ANY_LETTER = "(?:[^\\x00-\\x7F-]|\\$|\\w)";
  3977. const NumberSystem = [ {
  3978. radix: 2,
  3979. prefix: "0b0*"
  3980. }, {
  3981. radix: 8,
  3982. prefix: "0+"
  3983. }, {
  3984. radix: 10,
  3985. prefix: ""
  3986. }, {
  3987. radix: 16,
  3988. prefix: "0x0*"
  3989. } ];
  3990. var Template;
  3991. (function(Template) {
  3992. Template[Template["APPEND"] = 0] = "APPEND";
  3993. Template[Template["PREPEND"] = 1] = "PREPEND";
  3994. })(Template || (Template = {}));
  3995. class Regex {
  3996.  
  3997. constructor(code, unicode) {
  3998. this.code = code;
  3999. this.COPY_CODE = code;
  4000. this.unicode = unicode || false;
  4001. this.hooks = {};
  4002. this.totalHooks = 0;
  4003. }
  4004. static parseValue(value) {
  4005. try {
  4006. return Function(`return (${value})`)();
  4007. } catch (err) {
  4008. return null;
  4009. }
  4010. }
  4011. isRegexp(value) {
  4012. return TYPEOF(value) === "regexp";
  4013. }
  4014. generateNumberSystem(int) {
  4015. const copy = [ ...NumberSystem ];
  4016. const template = copy.map((({prefix, radix}) => prefix + int.toString(radix)));
  4017. return `(?:${template.join("|")})`;
  4018. }
  4019.  
  4020. parseVariables(regex) {
  4021. regex = regex.replace(/\{VAR\}/g, "(?:let|var|const)");
  4022. regex = regex.replace(/\{QUOTE\}/g, "['\"`]");
  4023. regex = regex.replace(/ARGS\{(\d+)\}/g, ((...args) => {
  4024. let count = Number(args[1]), arr = [];
  4025. while (count--) arr.push("\\w+");
  4026. return arr.join("\\s*,\\s*");
  4027. }));
  4028. regex = regex.replace(/NUMBER\{(\d+)\}/g, ((...args) => {
  4029. const int = Number(args[1]);
  4030. return this.generateNumberSystem(int);
  4031. }));
  4032. return regex;
  4033. }
  4034. format(name, inputRegex, flags) {
  4035. this.totalHooks += 1;
  4036. let regex = "";
  4037. if (Array.isArray(inputRegex)) {
  4038. regex = inputRegex.map((exp => this.isRegexp(exp) ? exp.source : exp)).join("\\s*");
  4039. } else if (this.isRegexp(inputRegex)) {
  4040. regex = inputRegex.source;
  4041. }
  4042. regex = this.parseVariables(regex);
  4043. if (this.unicode) {
  4044. regex = regex.replace(/\\w/g, ANY_LETTER);
  4045. }
  4046. const expression = new RegExp(regex.replace(/\{INSERT\}/, ""), flags);
  4047. const match = this.code.match(expression);
  4048. if (match === null) error("Failed to find: " + name);
  4049. return regex.includes("{INSERT}") ? new RegExp(regex, flags) : expression;
  4050. }
  4051. template(type, name, regex, substr) {
  4052. const expression = new RegExp(`(${this.format(name, regex).source})`);
  4053. const match = this.code.match(expression) || [];
  4054. this.code = this.code.replace(expression, type === Template.APPEND ? "$1" + substr : substr + "$1");
  4055. return match;
  4056. }
  4057.  
  4058. match(name, regex, flags, debug = false) {
  4059. const expression = this.format(name, regex, flags);
  4060. const match = this.code.match(expression) || [];
  4061. this.hooks[name] = {
  4062. expression,
  4063. match
  4064. };
  4065. if (debug) log(name, this.hooks[name]);
  4066. return match;
  4067. }
  4068. matchAll(name, regex, debug = false) {
  4069. const expression = this.format(name, regex, "g");
  4070. const matches = [ ...this.code.matchAll(expression) ];
  4071. this.hooks[name] = {
  4072. expression,
  4073. match: matches
  4074. };
  4075. if (debug) log(name, this.hooks[name]);
  4076. return matches;
  4077. }
  4078. replace(name, regex, substr, flags) {
  4079. const expression = this.format(name, regex, flags);
  4080. this.code = this.code.replace(expression, substr);
  4081. return this.code.match(expression) || [];
  4082. }
  4083. append(name, regex, substr) {
  4084. return this.template(Template.APPEND, name, regex, substr);
  4085. }
  4086. prepend(name, regex, substr) {
  4087. return this.template(Template.PREPEND, name, regex, substr);
  4088. }
  4089. insert(name, regex, substr) {
  4090. const {source} = this.format(name, regex);
  4091. if (!source.includes("{INSERT}")) throw new Error("Your regexp must contain {INSERT} keyword");
  4092. const findExpression = new RegExp(source.replace(/^(.*)\{INSERT\}(.*)$/, "($1)($2)"));
  4093. this.code = this.code.replace(findExpression, `$1${substr}$2`);
  4094. return this.code.match(findExpression);
  4095. }
  4096. }
  4097. const modules_Regex = Regex;
  4098. const applyHooks = code => {
  4099. const Hook = new modules_Regex(code, true);
  4100. window.COPY_CODE = (Hook.COPY_CODE.match(/^\((.+)\)\(.+\);$/) || [])[1];
  4101. Hook.append("EXTERNAL fix", /\(function (\w+)\(\w+\)\{/, `EXTERNAL.__proto__.toString=()=>COPY_CODE;`);
  4102. Hook.replace("strict", /{QUOTE}use strict{QUOTE};/, "");
  4103. Hook.append("toggleRotation", /return (\w+)\?\w+:.+?\}/, `Sploop.saves.toggleRotation=(value)=>{$2=value};`);
  4104. Hook.replace("buffer", /((\w+)=new \w+\(NUMBER{4096}\).+?(\w+)=.+?)function/, `$1window.Sploop.saves.buffer2=()=>$2;window.Sploop.saves.byteLength2=()=>$3;function`);
  4105. Hook.append("upgradeItem", /\.001.+?for\(let \w+=0,.+?\w+\(new \w+\(\[.+?,(\w+)\]\)(,|;)?/, `,Sploop.controller.upgradeItem($2)$3`);
  4106. Hook.replace("zoom", /(\w+):NUMBER{1824},(\w+):NUMBER{1026}/, "get $1(){return Sploop.scale.lerp.w},get $2(){return Sploop.scale.lerp.h}");
  4107. Hook.insert("send", /=NUMBER{9999}.+?\(null\).+?{INSERT}function (\w+)\(\w+\)\{/, `Sploop.saves.send=$3;`);
  4108. Hook.replace("toggleChat", /(return \(?(\w+&&\w+.+?)(?:,)?(?:\))?void.+?)function/, `$1Sploop.saves.toggleChat=()=>{$2};function`);
  4109. Hook.replace("updatePlayer", /(\w+\(ARGS{16}\).+?(\w+)\.\w+=0[,;]?)\}function/, `$1;Sploop.hooks.updatePlayer($2)}function`);
  4110. Hook.replace("createEntity", /(function \w+\((\w+),ARGS{16}\).+?\})(\}\w+\(\))/, `$1Sploop.hooks.createEntity($2)$3`);
  4111. Hook.append("drawEntityInfo", /-NUMBER{50},.+?function \w+\((ARGS{3})\)\{/, `Sploop.hooks.drawEntityInfo($2);Sploop.hooks.ally($2);`);
  4112. const id = Hook.match("id", /-NUMBER{1}!==\w+\.(\w+)&&/)[1];
  4113. Sploop.props.id = id;
  4114. const [, x, x1, x2, y, y1, y2, angle, angle1, angle2] =
  4115. Hook.match("PositionFormat", [ /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+,/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+,/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+\.(\w+)/, /=/, /\w+,/ ]);
  4116. Sploop.props.x = x;
  4117. Sploop.props.x1 = x1;
  4118. Sploop.props.x2 = x2;
  4119. Sploop.props.y = y;
  4120. Sploop.props.y1 = y1;
  4121. Sploop.props.y2 = y2;
  4122. Sploop.props.angle = angle;
  4123. Sploop.props.angle1 = angle1;
  4124. Sploop.props.angle2 = angle2;
  4125. const ownerID = Hook.match("ownerID", /\|\|\w+&&\w+===\w+\.(\w+)\)/)[1];
  4126. Sploop.props.ownerID = ownerID;
  4127. const health = Hook.match("health", /\w+\.(\w+)\/NUMBER{255}\*/)[1];
  4128. Sploop.props.health = health;
  4129. const name = Hook.match("name", /\w+\.(\w+),[a-z]\(\).\w{2},[a-z]\(\).\w{2},\w\(\d{3}\)/)[1];
  4130. Sploop.props.name = name;
  4131. const entityValue = Hook.match("entityValue", /!\(\w+\.(\w+)&/)[1];
  4132. Sploop.props.entityValue = entityValue;
  4133. const [, currentItem, hat] = Hook.match("hat", /\(\w+\.(\w+)\|\w+\.(\w+)<<NUMBER{8}\)/);
  4134. Sploop.props.hat = hat;
  4135. Sploop.props.currentItem = currentItem;
  4136. const projectileType = Hook.match("projectileType", /,\w+\[\w+\]\.(\w+),/)[1];
  4137. Sploop.props.projectileType = projectileType;
  4138. const playerList = Hook.match('get', /const \w=\w\[\w\],\w=\w{2}.\w{2}\[\w\.\w{2}\]/)[0].slice(15, this.length - 6);
  4139. const itemBar = Hook.replace("defaultData", /(\W\w+>NUMBER{1}\W.+?(\w+)\.(\w+).+?)function/, `$1Sploop.saves.defaultData=$2;Sploop.controller.playerList=${playerList};function`)[3];
  4140. Sploop.props.itemBar = itemBar;
  4141. const currentCount = Hook.match("currentCount", /(\w+):\[ARGS{11}\],/)[1];
  4142. Sploop.props.currentCount = currentCount;
  4143. Hook.replace("entityList", /(\(this,.+?typeof window.+?(\w+)=\[\].+?)function/, `$1Sploop.saves.entityList=()=>$2;function`);
  4144. const rotateSpeed = Hook.match("rotateSpeed", /\w+\(ARGS{17}\)\{.+?\/NUMBER{4}.+?\/NUMBER{4}.+?\w+\.(\w+)=/)[1];
  4145. Sploop.props.rotateSpeed = rotateSpeed;
  4146. Hook.replace('r_s', /AGE \D\+\w(,\d{2},\D{6})/, `"$1,"#fff"`);
  4147. Hook.replace('r_a', /(\(\)\.\w{2}\()([a-z]\(\d{3}\))(\,\d{2})/, `$1""$3`);
  4148. //Hook.replace('c', /"\D"+\W(\w.\w{2})\W+"\D",[a-z]\(\).\w{2},"#96C949","#404040"/, `"["+ $1 + "]", 25, "#404040","#2b2626"`);
  4149. Hook.append("showHoods", /\w+\.\w+!==\w+\)/, `||Sploop.settings.showHoods`);
  4150. Hook.append("itemCounter", /AGE 0.+?\[(\w+)\][,;](\w+)\.\w+\((\w+)\)([,;])/, `Sploop.hooks.drawItemBar($4,$3,$2)$5`);
  4151. Hook.replace("renderItems", /(\(\w+\.\w+\+\w+,\w+\.\w+\+\w+\).+?\w+\(\).+?\w+\.\w+\.\w+\)([,;]))/, `$1Sploop.hooks.renderItems(...arguments)$2`);
  4152. Hook.replace("mousemove", /(\+NUMBER{110}.+?)(const \w+=\w+\(\).+?\w+!==\w+.+?\w+\(\w+\))/, `$1if(Sploop.controller.mousemove){$2}`);
  4153. Hook.replace("players", /(\)\)\(\).+?(\w+)=new.+?)function/, `$1Sploop.saves.players=()=>$2;function`);
  4154. Hook.replace("showIDS", /===(\w+)(&&\w+\(\)&&\w+\(\).+?)return void\((\w+)=!0/, "===$1$2;if('/ids'==$1)return void($3 = !$3");
  4155. const [skin, accessory, back] = Hook.matchAll("skins", /=\w+\.(\w+)\|\|NUMBER{0}/).map((a => a[1]));
  4156. Sploop.props.skin = skin;
  4157. Sploop.props.accessory = accessory;
  4158. Sploop.props.back = back;
  4159. log("Total hooks: " + Hook.totalHooks);
  4160. return Hook.code;
  4161. };
  4162. let Allies = []
  4163. let Enemys = []
  4164. const modules_applyHooks = applyHooks;
  4165. const version = __webpack_require__(147).i8;
  4166. const log = console.log;
  4167. const error = console.error;
  4168. const controller = new Controller;
  4169. window.log = log;
  4170. window.Sploop = {
  4171. props: {},
  4172. hooks: {
  4173. drawEntityInfo: hooks_drawEntityInfo,
  4174. updatePlayer: hooks_updatePlayer,
  4175. createEntity: hooks_createEntity,
  4176. drawItemBar: hooks_drawItemBar,
  4177. renderItems: hooks_renderItems,
  4178. ally: (entity, p2, p3) => {
  4179. if (p3 && entity[Sploop.props.id] !== Sploop.controller.myPlayerID && entity.type === 0 && !Allies.find(A => A.id == entity[Sploop.props.id])) {
  4180. Allies.push({
  4181. x: entity[Sploop.props.x],
  4182. y: entity[Sploop.props.y],
  4183. type: entity.type,
  4184. hp: entity[Sploop.props.health] / 255 * 100,
  4185. hat: entity[Sploop.props.hat],
  4186. pid: entity[Sploop.props.ownerID],
  4187. id: entity[Sploop.props.id]
  4188. })
  4189. }
  4190. if (!p3 && entity[Sploop.props.id] !== Sploop.controller.myPlayerID && entity.type === 0 && !Enemys.find(A => A.id == entity[Sploop.props.id])) {
  4191. Enemys.push({
  4192. x: entity[Sploop.props.x],
  4193. y: entity[Sploop.props.y],
  4194. type: entity.type,
  4195. hp: entity[Sploop.props.health] / 255 * 100,
  4196. hat: entity[Sploop.props.hat],
  4197. pid: entity[Sploop.props.ownerID],
  4198. id: entity[Sploop.props.id]
  4199. })
  4200. }
  4201. }
  4202. },
  4203. chat: () => {
  4204. return document.getElementById('chat-wrapper').style.display == "" || document.getElementById('chat-wrapper').style.display == "none";
  4205. },
  4206. saves: {},
  4207. controller,
  4208. scale: Scale,
  4209. settings: Settings,
  4210. myPlayer: {},
  4211. version,
  4212. step: 0,
  4213. PRODUCTION: true,
  4214. active: null,
  4215. connectURL: ""
  4216. };
  4217. // 2t
  4218. let A_H = true;
  4219. let A_B = true;
  4220. let A_T = true;
  4221. let A_P = true;
  4222. let A_R = true;
  4223. let A_M = true;
  4224. let A_I = true;
  4225.  
  4226. // 2f
  4227. let A_A = false;
  4228. let A_N = false;
  4229. let A_F = false;
  4230. let B_I = false;
  4231.  
  4232. // 3f
  4233. let A_GM = false;
  4234.  
  4235. // 3t
  4236. let A_BO = true;
  4237. let A_BS = true;
  4238.  
  4239. window.addEventListener("keydown", function(e) {
  4240. if(e.code == "Enter" && window.chat && window.chat.value != '') {
  4241. if(window.chat.value == "!md -ah") {
  4242. if (!A_H) {
  4243. A_H = true, setTimeout(() => { controller.PacketManager.chat("Autoheal enabled.") }, 510);
  4244. } else {
  4245. A_H = false, setTimeout(() => { controller.PacketManager.chat("Autoheal disabled.") }, 510);
  4246. }
  4247. }
  4248. if(window.chat.value == "!md -ab") {
  4249. if (!A_B) {
  4250. A_B = true, setTimeout(() => { controller.PacketManager.chat("Autobreak enabled.") }, 510);
  4251. } else {
  4252. A_B = false, setTimeout(() => { controller.PacketManager.chat("Autobreak disabled.") }, 510);
  4253. }
  4254. }
  4255. if(window.chat.value == "!md -at") {
  4256. if (!A_T) {
  4257. A_T = true, setTimeout(() => { controller.PacketManager.chat("AntiTrap enabled.") }, 510);
  4258. } else {
  4259. A_T = false, setTimeout(() => { controller.PacketManager.chat("AntiTrap disabled.") }, 510);
  4260. }
  4261. }
  4262. if(window.chat.value == "!md -tr") {
  4263. if (!Settings.enemyTracers) {
  4264. Settings.enemyTracers = true, setTimeout(() => { controller.PacketManager.chat("Tracers enabled.") }, 510);
  4265. } else {
  4266. Settings.enemyTracers = false, setTimeout(() => { controller.PacketManager.chat("Tracers disabled.") }, 510);
  4267. }
  4268. }
  4269. if(window.chat.value == "!md -ap") {
  4270. if (!A_P) {
  4271. A_P = true, setTimeout(() => { controller.PacketManager.chat("Autoplacer enabled.") }, 510);
  4272. } else {
  4273. A_P = false, setTimeout(() => { controller.PacketManager.chat("Autoplacer disabled.") }, 510);
  4274. }
  4275. }
  4276. if(window.chat.value == "!md -aa") {
  4277. if (!A_A) {
  4278. A_A = true, setTimeout(() => { controller.PacketManager.chat("AutoAttack enabled.") }, 510);
  4279. } else {
  4280. A_A = false, setTimeout(() => { controller.PacketManager.chat("AutoAttack disabled.") }, 510);
  4281. }
  4282. }
  4283. if(window.chat.value == "!md -ai") {
  4284. if (!A_R) {
  4285. A_R = true, setTimeout(() => { controller.PacketManager.chat("AutoInsta enabled.") }, 510);
  4286. } else {
  4287. A_R = false, setTimeout(() => { controller.PacketManager.chat("AutoInsta disabled.") }, 510);
  4288. }
  4289. }
  4290. if(window.chat.value == "!md -am") {
  4291. if (!A_M) {
  4292. A_M = true, setTimeout(() => { controller.PacketManager.chat("AutoMill enabled.") }, 510);
  4293. } else {
  4294. A_M = false, setTimeout(() => { controller.PacketManager.chat("AutoMill disabled.") }, 510);
  4295. }
  4296. }
  4297. if(window.chat.value == "!md -aai") {
  4298. if (!A_I) {
  4299. A_I = true, setTimeout(() => { controller.PacketManager.chat("AntiAutoInsta enabled.") }, 510);
  4300. } else {
  4301. A_I = false, setTimeout(() => { controller.PacketManager.chat("AntiAutoInsta disabled.") }, 510);
  4302. }
  4303. }
  4304. if(window.chat.value == "!md -abo") {
  4305. if (!A_BO) {
  4306. A_BO = true, setTimeout(() => { controller.PacketManager.chat("AntiBoost enabled.") }, 510);
  4307. } else {
  4308. A_BO = false, setTimeout(() => { controller.PacketManager.chat("AntiBoost disabled.") }, 510);
  4309. }
  4310. }
  4311. if(window.chat.value == "!md -abs") {
  4312. if (!A_BS) {
  4313. A_BS = true, setTimeout(() => { controller.PacketManager.chat("AutoBreakSpike enabled.") }, 510);
  4314. } else {
  4315. A_BS = false, setTimeout(() => { controller.PacketManager.chat("AutoBreakSpike disabled.") }, 510); // lmao scuffed name
  4316. }
  4317. }
  4318. if(window.chat.value == "!md -bi") {
  4319. if (!B_I) {
  4320. B_I = true, setTimeout(() => { controller.PacketManager.chat("BuildingIndicators enabled.") }, 510);
  4321. } else {
  4322. B_I = false, setTimeout(() => { controller.PacketManager.chat("BuildingIndicators disabled.") }, 510); // def original name not skidded from moomoo.io
  4323. }
  4324. }
  4325. }
  4326. });
  4327. function fgdo(a, b) {
  4328. return Math.sqrt(Math.pow(b.y - a.y, 2) + Math.pow(b.x - a.x, 2));
  4329. }
  4330. function calcAngleDegrees(x, y) {
  4331. return Math.atan2(y, x) * 180 / Math.PI;
  4332. }
  4333.  
  4334. let primaryWeapon = 1;
  4335. const canvas = document.querySelector('#game-canvas');
  4336. const placeObject = function (key, code) {
  4337. const clickObject = {
  4338. isTrusted: true,
  4339. key: key,
  4340. code: code,
  4341. target: canvas,
  4342. constructor: KeyboardEvent,
  4343. preventDefault: () => {},
  4344. };
  4345. window.onkeydown(clickObject);
  4346. window.onkeyup(clickObject);
  4347. };
  4348. const deployObject = function (key, code) {
  4349. placeObject(key, code);
  4350. placeObject('Space', 'Space');
  4351. placeObject(primaryWeapon, `Digit${String(primaryWeapon)}`);
  4352. };
  4353. let spikey, spikeId, spikeNear = false;
  4354. let trapy, trapId, inTrap = false;
  4355. let enemyTrapY, enemyTrapId, enemyInTrap = false;
  4356. let nearSY, nearSID, nearS = false;
  4357. const toRad = t => t * Math.PI / 180
  4358. let toDegree = function(angle) {
  4359. return ((angle * 180) / 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679);
  4360. }
  4361. String.prototype.shuffle = function() {
  4362. var a = this.split(""),
  4363. n = a.length;
  4364.  
  4365. for (var i = n - 1; i > 0; i--) {
  4366. var j = Math.floor(Math.random() * (i + 1));
  4367. var tmp = a[i];
  4368. a[i] = a[j];
  4369. a[j] = tmp;
  4370. }
  4371. return a.join("");
  4372. }
  4373. let self = {}
  4374. let autobreak = true
  4375. addEventListener('keydown', e => {
  4376. if (e.code == "Digit1") {
  4377. self.activeweapon = 0
  4378. }
  4379. if (e.code == "Digit2") {
  4380. self.activeweapon = 1
  4381. }
  4382. if (e.code == "Period" && Sploop.chat()) {
  4383. controller.PacketManager.chat("p")
  4384. }
  4385. })
  4386. window.equip = (e) => {
  4387. if (Sploop.myPlayer.hat !== e) {
  4388. Sploop.controller.PacketManager.equip(e)
  4389. }
  4390. }
  4391. window.e2 = (e) => {
  4392. Sploop.controller.PacketManager.equip(e);
  4393. }
  4394. let nearestEnemy;
  4395. let currentHat = 0;
  4396. let currentWeapon = null;
  4397. let retrapcount = 0;
  4398. let testy = 0;
  4399. let spinCount = 0;
  4400. let bS = false;
  4401. let alreadydone = false;
  4402. /////////////////// MAIN INTERVAL START
  4403. setInterval(() => {
  4404. const nearest = EntityManager.enemies()[0];
  4405. let distance = fgdo(nearest, Sploop.myPlayer);
  4406. const nEA = EntityManager.angle(Sploop.myPlayer, nearest);
  4407. try {
  4408. testy += 0.10; testy > 3 && (testy = -3);
  4409. } catch(err) {}
  4410. // AUTOBREAK, ANTITRAP
  4411. trapy = null
  4412. for (let i = 0; i < Sploop.saves.entityList()[ELayer.TRAP].length; i++) {
  4413. const trapx = Sploop.saves.entityList()[ELayer.TRAP][i];
  4414. if (trapx && trapx[Sploop.props.ownerID] !== Sploop.myPlayer.ownerID && !teammates.includes(trapx[Sploop.props.ownerID]) && Math.hypot(trapx[Sploop.props.x] - Sploop.myPlayer.x, trapx[Sploop.props.y] - Sploop.myPlayer.y) <= 55) {
  4415. trapy = trapx;
  4416. if (!inTrap) {
  4417. let trapangle = Math.atan2(trapy[Sploop.props.y] - Sploop.myPlayer.y, trapy[Sploop.props.x] - Sploop.myPlayer.x);
  4418. inTrap = true;
  4419. currentHat = Sploop.myPlayer.hat
  4420. currentWeapon = Sploop.controller.weapon
  4421. //////////////////////////////////
  4422. // ANTITRAP
  4423. if(A_T) {
  4424. setTimeout(() => {
  4425. controller.place(4, trapangle + 95 * 2);
  4426. }, 50);
  4427. setTimeout(() => {
  4428. controller.place(4, trapangle + -95 * 2);
  4429. }, 150);
  4430. setTimeout(() => {
  4431. controller.place(4, trapangle + 110);
  4432. }, 250);
  4433. }
  4434. // ANTITRAP
  4435. //////////////////////////////////
  4436. } else {
  4437. //////////////////////////////////
  4438. // AUTOBREAK, PART OF ANTITRAP (HIT)
  4439. if(A_B) {
  4440. let trapangle = Math.atan2(trapy[Sploop.props.y] - Sploop.myPlayer.y, trapy[Sploop.props.x] - Sploop.myPlayer.x);
  4441. if(A_T) {
  4442. if(controller.itemBar[ItemType.TRAP] === EObjects.TRAP && controller.itemBar[ItemType.TRAP] !== undefined || null) {
  4443. controller.place(7, testy);
  4444. controller.place(4, testy);
  4445. }
  4446. }
  4447. window.equip(11);
  4448. Sploop.controller.whichWeapon(true);
  4449. if(!bS) Sploop.controller.PacketManager.attack(trapangle);
  4450. Sploop.controller.PacketManager.stopAttack();
  4451. }
  4452. // AUTOBREAK, PART OF ANTITRAP (HIT)
  4453. //////////////////////////////////
  4454. }
  4455. trapId = trapy[Sploop.props.id];
  4456. break
  4457. }
  4458. }
  4459. if (!trapy && inTrap) {
  4460. //////////////////////////////////
  4461. // RETRAP COUNT CHAT
  4462. setTimeout(() => {
  4463. if(inTrap) {
  4464. retrapcount++
  4465. controller.PacketManager.chat(retrapcount);
  4466. } else {
  4467. retrapcount = 0;
  4468. }
  4469. }, 230);
  4470. // RETRAP COUNT CHAT
  4471. //////////////////////////////////
  4472. if (Sploop.myPlayer.hat != currentHat && Sploop.myPlayer.hat == 11 && A_B) window.equip(currentHat);
  4473. setTimeout(() => {
  4474. if (Sploop.myPlayer.hat != currentHat && Sploop.myPlayer.hat == 11 && A_B) window.equip(currentHat);
  4475. }, 1300);
  4476. setTimeout(() => {
  4477. if (Sploop.myPlayer.hat != currentHat && Sploop.myPlayer.hat == 11 && A_B) window.equip(currentHat);
  4478. }, 900);
  4479. self.activeweapon = currentWeapon
  4480. Sploop.controller.whichWeapon(currentWeapon)
  4481. currentWeapon = 0;
  4482. currentHat = currentHat;
  4483. trapId = null;
  4484. inTrap = false;
  4485. }
  4486. // AUTOBREAK, ANTITRAP
  4487. //////////////////////////////////
  4488. // ENEMY INTRAP
  4489. enemyTrapY = null
  4490. for (let i = 0; i < Sploop.saves.entityList()[ELayer.TRAP].length; i++) {
  4491. const enemyTrapX = Sploop.saves.entityList()[ELayer.TRAP][i];
  4492. if (enemyTrapX && enemyTrapX[Sploop.props.ownerID] === Sploop.myPlayer.ownerID && !teammates.includes(enemyTrapX[Sploop.props.ownerID]) && Math.hypot(enemyTrapX[Sploop.props.x] - nearest.x, enemyTrapX[Sploop.props.y] - nearest.y) <= 55) {
  4493. enemyTrapY = enemyTrapX;
  4494. if(!enemyInTrap) {
  4495. //controller.PacketManager.chat("in");
  4496. enemyInTrap = true;
  4497. }
  4498. enemyTrapId = enemyTrapY[Sploop.props.id];
  4499. break
  4500. }
  4501. }
  4502. if (!enemyTrapY && enemyInTrap) {
  4503. enemyTrapId = null;
  4504. enemyInTrap = false;
  4505. }
  4506. // ENEMY INTRAP
  4507. ///////////////////////////////////
  4508. // SPIKENEAR
  4509. nearSY = null
  4510. for (let i = 0; i < Sploop.saves.entityList()[ELayer.HARDSPIKE].length; i++) {
  4511. const nearS2 = Sploop.saves.entityList()[ELayer.HARDSPIKE][i];
  4512. if (nearS2 && nearS2[Sploop.props.ownerID] !== Sploop.myPlayer.ownerID && !teammates.includes(nearS2[Sploop.props.ownerID]) && Math.hypot(nearS2[Sploop.props.x] - Sploop.myPlayer.x, nearS2[Sploop.props.y] - Sploop.myPlayer.y) <= 125) {
  4513. nearSY = nearS2;
  4514. if(!nearS) {
  4515. nearS = true;
  4516. }
  4517. if(nearS && inTrap && A_BS) {
  4518. let spikeangle = Math.atan2(nearSY[Sploop.props.y] - Sploop.myPlayer.y, nearSY[Sploop.props.x] - Sploop.myPlayer.x);
  4519. Sploop.controller.PacketManager.attack(spikeangle);
  4520. bS = true;
  4521. }
  4522. nearSID = nearSY[Sploop.props.id];
  4523. break
  4524. }
  4525. }
  4526. if (!nearSY && nearS) {
  4527. bS = false;
  4528. nearSID = null;
  4529. nearS = false;
  4530. }
  4531. // SPIKENEAR
  4532. //////////////////////////////////
  4533. // AUTOPUSH
  4534. for (let i = 0; i < Sploop.saves.entityList()[ELayer.HARDSPIKE].length; i++) {
  4535. const spikex = Sploop.saves.entityList()[ELayer.HARDSPIKE][i];
  4536. if (spikex && spikex[Sploop.props.ownerID] === Sploop.myPlayer.ownerID && !teammates.includes(spikex[Sploop.props.ownerID]) && Math.hypot(spikex[Sploop.props.x] - nearest.x, spikex[Sploop.props.y] - nearest.y) <= 130) {
  4537. //spikeNear = true;
  4538. //const pushAngle = EntityManager.angle(nearest, spikex);
  4539. /*
  4540. let pAngle = EntityManager.angle(nearest, spikex);
  4541. let distance = fgdo(nearest, spikex) + 70;
  4542. let position = { x: spikex[Sploop.props.x] + (distance * Math.cos(pAngle)), y: spikex[Sploop.props.y] + (distance * Math.sin(pAngle)) };
  4543.  
  4544. let distance2 = fgdo(position, Sploop.myPlayer);
  4545. let pushAngle = Math.atan2(spikex[Sploop.props.y] - nearest.y, spikex[Sploop.props.x] - nearest.x);
  4546. let pushAngle2 = Math.atan2(spikex[Sploop.props.y] + (distance * Math.cos(pAngle)) - Sploop.myPlayer.y, spikex[Sploop.props.x] + (distance * Math.sin(pAngle)) - Sploop.myPlayer.x); // distance2 > 40
  4547. let pushAngle3 = Math.atan2(Sploop.myPlayer.y - nearest.y, Sploop.myPlayer.x - nearest.x); // else
  4548.  
  4549. */
  4550. const nEA = EntityManager.angle(Sploop.myPlayer, nearest);
  4551. let distance3 = fgdo(nearest, Sploop.myPlayer);
  4552. if(enemyInTrap && !inTrap && distance3 <= 250) {
  4553. //controller.PacketManager.moveAngle(nEA + Math.atan2(nearest.y - (Sploop.myPlayer.y - spikex[Sploop.props.y]), nearest.x - (Sploop.myPlayer.x - spikex[Sploop.props.x])));
  4554. }
  4555. } /*else if(spikex && spikex[Sploop.props.ownerID] === Sploop.myPlayer.ownerID && !teammates.includes(spikex[Sploop.props.ownerID]) && Math.hypot(spikex[Sploop.props.x] - nearest.x, spikex[Sploop.props.y] - nearest.y) > 130) {
  4556. spikeNear = false; // just something
  4557. break
  4558. }*/
  4559. }
  4560. // AUTOPUSH
  4561. //////////////////////////////////
  4562. // ANTIBOOST
  4563. for (let i = 0; i < Sploop.saves.entityList()[ELayer.BOOST].length; i++) {
  4564. const spikex = Sploop.saves.entityList()[ELayer.BOOST][i];
  4565. if (spikex && spikex[Sploop.props.ownerID] !== Sploop.myPlayer.ownerID && !teammates.includes(spikex[Sploop.props.ownerID]) && Math.hypot(spikex[Sploop.props.x] - nearest.x, spikex[Sploop.props.y] - nearest.y) <= 55) {
  4566. const nEA = EntityManager.angle(Sploop.myPlayer, nearest);
  4567. let distance = fgdo(nearest, Sploop.myPlayer);
  4568. if(!enemyInTrap && !inTrap && A_BO && distance < 333) {
  4569. controller.PacketManager.chat(Math.atan2(spikex[Sploop.props.y] - Sploop.myPlayer.y, spikex[Sploop.props.x] - Sploop.myPlayer.x) + "a:" + nEA);
  4570. controller.place(ItemType.TRAP, nEA, PlacementType.INVISIBLE);
  4571. }
  4572. }
  4573. }
  4574. // ANTIBOOST
  4575. //////////////////////////////////
  4576. // AUTOPLACE
  4577. if(A_P) {
  4578. if(A_P && distance > 177) {
  4579. return
  4580. }
  4581. if (A_P && distance <= 160 && enemyInTrap) {
  4582. /*
  4583. controller.PacketManager.changeAngle(controller.mouse.angle);
  4584. controller.place(ItemType.SPIKE, nEA + fgdo(nearest, Sploop.myPlayer) / fgdo(nearest, Sploop.myPlayer) + 0.2, PlacementType.INVISIBLE);
  4585. controller.PacketManager.changeAngle(controller.mouse.angle);
  4586. controller.place(ItemType.SPIKE, nEA - fgdo(nearest, Sploop.myPlayer) / fgdo(nearest, Sploop.myPlayer) + 0.2, PlacementType.INVISIBLE);
  4587. controller.PacketManager.changeAngle(controller.mouse.angle);
  4588. log(nEA + fgdo(nearest, Sploop.myPlayer) / fgdo(nearest, Sploop.myPlayer) + " + ");
  4589. log(nEA - fgdo(nearest, Sploop.myPlayer) / fgdo(nearest, Sploop.myPlayer) + " - ");
  4590. */
  4591. controller.PacketManager.changeAngle(controller.mouse.angle);
  4592. controller.place(ItemType.SPIKE, nEA + random(Math.PI / 1.78, Math.PI / 6.32), PlacementType.INVISIBLE);
  4593. controller.PacketManager.changeAngle(controller.mouse.angle);
  4594. controller.place(ItemType.SPIKE, nEA - random(Math.PI / 1.78, Math.PI / 6.32), PlacementType.INVISIBLE);
  4595. controller.PacketManager.changeAngle(controller.mouse.angle);
  4596. } else {
  4597. controller.PacketManager.changeAngle(controller.mouse.angle);
  4598. controller.place(ItemType.TRAP, EntityManager.angle(Sploop.myPlayer, nearest), PlacementType.INVISIBLE);
  4599. controller.PacketManager.changeAngle(controller.mouse.angle);
  4600. }
  4601. }
  4602. // AUTOPLACE
  4603. //////////////////////////////////
  4604. // AUTOATTACK
  4605. const previousWeapon = controller.weapon;
  4606. if (A_A && EntityManager.inWeaponRange(Sploop.myPlayer, nearest, controller.itemBar[0]) && !inTrap) {
  4607. window.equip(5);
  4608. controller.whichWeapon(false);
  4609. controller.attack(EntityManager.angle(Sploop.myPlayer, nearest));
  4610. controller.whichWeapon(previousWeapon);
  4611. controller.PacketManager.stopAttack();
  4612. //controller.PacketManager.chat(`Attacking ${controller.playerList[nearest.ownerID][Sploop.props.name]}`)
  4613. if(nearest.health <= 30) {
  4614. window.equip(2);
  4615. controller.whichWeapon(false);
  4616. controller.attack(EntityManager.angle(Sploop.myPlayer, nearest));
  4617. controller.whichWeapon(previousWeapon);
  4618. controller.PacketManager.stopAttack();
  4619. }
  4620. }
  4621. // AUTOATTACK
  4622. //////////////////////////////////
  4623. // AUTOINSTA
  4624. if(A_R) {
  4625. if(nearest.hat != 6 && nearest.hat != 4 && nearest.health <= 65 && EntityManager.inWeaponRange(Sploop.myPlayer, nearest, controller.itemBar[0]) && !inTrap && !controller.autoattack && !controller.attacking) {
  4626. const previousWeapon = controller.weapon;
  4627. let previousHat;
  4628. previousHat = Sploop.myPlayer.hat
  4629. controller.whichWeapon(false);
  4630. window.equip(2);
  4631. controller.attack(EntityManager.angle(Sploop.myPlayer, nearest));
  4632. controller.PacketManager.stopAttack();
  4633. controller.whichWeapon(previousWeapon);
  4634. controller.PacketManager.changeAngle(controller.mouse.angle);
  4635. if(!inTrap && !Settings.aetoggle) {
  4636. controller.mousemove = true;
  4637. }
  4638. setTimeout(() => {
  4639. if (Sploop.myPlayer.hat != previousHat && Sploop.myPlayer.hat == 2) window.equip(previousHat)
  4640. }, 1300);
  4641. }else if(nearest.health <= 65 && EntityManager.inWeaponRange(Sploop.myPlayer, nearest, controller.itemBar[0]) && !inTrap && !controller.autoattack && !controller.attacking){
  4642. const previousWeapon = controller.weapon;
  4643. controller.whichWeapon(false);
  4644. controller.attack(EntityManager.angle(Sploop.myPlayer, nearest));
  4645. controller.PacketManager.stopAttack();
  4646. controller.whichWeapon(previousWeapon);
  4647. controller.PacketManager.changeAngle(controller.mouse.angle);
  4648. }
  4649. };
  4650. // AUTOINSTA
  4651. //////////////////////////////////
  4652. }, 40);
  4653. /////////////////// MAIN INTERVAL END
  4654. //----------------------------------------------------------------------//
  4655. /////////////////// AUTOPPLAY INTERVAL START - antiinsta
  4656. setInterval(() => {
  4657. // ANTIINSTA
  4658. let distance = fgdo(nearest, Sploop.myPlayer);
  4659. const nearest = EntityManager.enemies()[0];
  4660. if (A_I && nearest.currentItem != undefined && nearest.currentItem == 29 && Sploop.myPlayer.health === 60 && distance < 310) {
  4661. window.equip(6);
  4662. //controller.PacketManager.chat("anti-insta");
  4663. }
  4664. // ANTIINSTA
  4665. //////////////////////////////////
  4666. /*
  4667. // << BOT TEST >>
  4668. let distance = fgdo(nearest, Sploop.myPlayer);
  4669. const nearest = EntityManager.enemies()[0];
  4670. const nEA = EntityManager.angle(Sploop.myPlayer, nearest);
  4671. const previousWeapon = controller.weapon;
  4672. if(BOT) {
  4673. controller.PacketManager.moveAngle(EntityManager.angle(Sploop.myPlayer, nearest));
  4674. }
  4675. */// << BOT TEST >>
  4676. });
  4677. /////////////////// AUTOPPLAY INTERVAL END - antiinsta
  4678. const Sploop = window.Sploop;
  4679. Storage["delete"]("_adIds");
  4680. Object.freeze(Array.prototype);
  4681. window.alert = function() {};
  4682. Object.defineProperty(Object.prototype, "region", {
  4683. get: () => Settings.connectTo,
  4684. set: () => true,
  4685. configurable: true
  4686. });
  4687. window.eval = new Proxy(window.eval, {
  4688. apply(target, _this, args) {
  4689. const code = args[0];
  4690. if (code.length > 1e5) {
  4691. args[0] = modules_applyHooks(code);
  4692. window.eval = target;
  4693. target.apply(_this, args);
  4694. load();
  4695. return;
  4696. }
  4697. return target.apply(_this, args);
  4698. }
  4699. });
  4700.  
  4701. const load = () => {
  4702. const canvas = document.querySelector("#game-canvas");
  4703. const gridToggle = document.querySelector("#grid-toggle");
  4704. const displayPingToggle = document.querySelector("#display-ping-toggle");
  4705. const itemMarkerToggle = document.querySelector("#native-helper-toggle");
  4706. const hat_menu_content = document.querySelector("#hat_menu_content");
  4707. if (gridToggle.checked) gridToggle.click();
  4708. ///if (!displayPingToggle.checked) //displayPingToggle.click();
  4709. ///if (itemMarkerToggle.checked) itemMarkerToggle.click();
  4710. const toRemoveElements = [ "google_play", "cross-promo", "right-content", "game-left-main", "game-right-main", "bottom-content" ];
  4711. for (const id of toRemoveElements) {
  4712. const element = document.getElementById(id);
  4713. if (element !== null) {
  4714. element.style.display = "none";
  4715. }
  4716. }
  4717. window.onkeydown = null;
  4718. window.onkeyup = null;
  4719. if (canvas.onmousedown && canvas.onmouseup) {
  4720. const mousedown = canvas.onmousedown.bind(canvas);
  4721. const mouseup = canvas.onmouseup.bind(canvas);
  4722. canvas.onmousedown = null;
  4723. canvas.onmouseup = null;
  4724. canvas.addEventListener("mousedown", (event => {
  4725. if (event.button !== 0) return;
  4726. mousedown(event);
  4727. }));
  4728. canvas.addEventListener("mouseup", (event => {
  4729. if (event.button !== 0) return;
  4730. mouseup(event);
  4731. }));
  4732. }
  4733. new MutationObserver((mutations => {
  4734. if (!controller.inGame || isInput()) return;
  4735. for (let i = 0; i < mutations.length; i++) {
  4736. if (mutations[i].target.textContent === "UNEQUIP") {
  4737. controller.actualHat = i + 1;
  4738. break;
  4739. }
  4740. }
  4741. })).observe(hat_menu_content, {
  4742. childList: true,
  4743. subtree: true
  4744. });
  4745. window.addEventListener("keydown", (event => controller.handleKeydown(event, event.code)));
  4746. window.addEventListener("keyup", (event => controller.handleKeyup(event, event.code)));
  4747. canvas.addEventListener("mousedown", (event => controller.handleKeydown(event, event.button)));
  4748. canvas.addEventListener("mouseup", (event => controller.handleKeyup(event, event.button)));
  4749. modules_zoomHandler();
  4750.  
  4751. class Weapon {
  4752. constructor(range, xOffset, yOffset, animType) {
  4753. this.range = range;
  4754. this.xOffset = xOffset;
  4755. this.yOffset = yOffset;
  4756. this.animType = animType;
  4757. }
  4758. };
  4759. const animTypes = { HIT: 0, MOVING: 1, RANGE: 2 };
  4760. const toolHammerStats = new Weapon(80, 40, 50, animTypes.HIT);
  4761. const daggerStats = new Weapon(80, 5, 40, animTypes.HIT);
  4762. const swordStats = new Weapon(135, 40, 56, animTypes.HIT);
  4763. const katanaStats = new Weapon(140, 30, 48, animTypes.HIT);
  4764. const naginataStats = new Weapon(165, 42, 47, animTypes.HIT);
  4765. const spearStats = new Weapon(160, 35, 47, animTypes.HIT);
  4766. const greatAxeStats = new Weapon(94, 32, 43, animTypes.HIT);
  4767. const axeStats = new Weapon(90, 37, 47, animTypes.HIT);
  4768. const stickStats = new Weapon(100, 40, 45, animTypes.HIT);
  4769. const batStats = new Weapon(115, 5, 37, animTypes.HIT);
  4770. const memeStats = new Weapon(115, -12, 10, animTypes.HIT);
  4771. const scytheStats = new Weapon(160, 20, 50, animTypes.HIT);
  4772. const bowStats = new Weapon(865, 23, 65, animTypes.RANGE);
  4773. const xBowStats = new Weapon(865, 18, 65, animTypes.RANGE);
  4774. const musketStats = new Weapon(1065, 27, 100, animTypes.RANGE);
  4775. const pearlStats = new Weapon(765, -7, 37, animTypes.RANGE);
  4776. const shieldStats = new Weapon(55, 24, 62, animTypes.MOVING);
  4777. const hammerStats = new Weapon(80, 33, 45, animTypes.HIT);
  4778. const weaponsList = {
  4779. stone_toolhammer: toolHammerStats, g_toolhammer: toolHammerStats, d_toolhammer: toolHammerStats, r_toolhammer: toolHammerStats,
  4780. s_dagger: daggerStats, g_dagger: daggerStats, d_dagger: daggerStats, r_dagger: daggerStats,
  4781. stone_sword: swordStats, katana: katanaStats, g_katana: katanaStats, d_katana: katanaStats, c_katana: katanaStats,
  4782. cut_spear: naginataStats, g_cutspear: naginataStats, d_cutspear: naginataStats,
  4783. stone_spear: spearStats, g_spear: spearStats, d_spear: spearStats,
  4784. great_axe: greatAxeStats, g_great_axe: greatAxeStats, d_great_axe: greatAxeStats,
  4785. stone_axe: axeStats, g_axe: axeStats, d_axe: axeStats,
  4786. stick: stickStats, g_stick: stickStats, d_stick: stickStats, r_stick: stickStats,
  4787. bat: batStats, meme: memeStats, scythe: scytheStats,
  4788. bow: bowStats, Xbow: xBowStats, s_musket: musketStats, pearl: pearlStats,
  4789. shield: shieldStats, hammer: hammerStats
  4790. };
  4791.  
  4792. const canvasPrototype = CanvasRenderingContext2D.prototype;
  4793. canvasPrototype.drawImage = new Proxy(canvasPrototype.drawImage, {
  4794. apply(sourceFunction, that, callingArguments) {
  4795. const [image, x, y, width, height] = callingArguments;
  4796. if(typeof image.src == "string") {
  4797. const weaponName = image.src.split("/")[5].replace(/\.png.+?$/, "");
  4798. const weapon = weaponsList[weaponName];
  4799.  
  4800. if(weapon && (height != 100 || width !== 100)) {
  4801. if(weapon.animType == animTypes.RANGE) {
  4802. that.beginPath();
  4803. that.strokeStyle = "#ab0000";
  4804. that.moveTo(x + weapon.xOffset + 30, y + weapon.yOffset);
  4805. that.lineTo(x + weapon.xOffset + weapon.range, y + weapon.yOffset);
  4806. that.stroke();
  4807. that.closePath();
  4808. } else {
  4809. that.beginPath();
  4810. that.save();
  4811. that.translate(x + weapon.xOffset, y + weapon.yOffset);
  4812. that.rotate(weapon.animType == animTypes.HIT ? window.hitAngle : 0);
  4813. that.fillStyle = "#78025e";
  4814. that.strokeStyle = "#78025e";
  4815. that.arc(0, 0, weapon.range, -17*Math.PI/30, 17*Math.PI/30);
  4816. that.lineTo(30, 0);
  4817. that.lineTo(Math.cos(17*Math.PI/30) * weapon.range, -Math.sin(17*Math.PI/30) * weapon.range);
  4818. that.stroke();
  4819. that.globalAlpha = 0.1;
  4820. that.fill();
  4821. that.globalAlpha = 0;
  4822. that.restore();
  4823. that.closePath();
  4824. };
  4825. };
  4826. };
  4827.  
  4828. return sourceFunction.apply(that, callingArguments);
  4829. }
  4830. });
  4831.  
  4832. window.hitAngle = 0;
  4833. const proto = Object.prototype;
  4834. window.addEventListener("load", function() {
  4835. proto.__defineSetter__("value", function(val) {
  4836. return this.val = val;
  4837. });
  4838. proto.__defineGetter__("value", function() {
  4839. return window.hitAngle = this.val;
  4840. });
  4841. });
  4842.  
  4843. const menuKey = 'Escape';
  4844.  
  4845. const keybindsMenu = document.createElement('div');
  4846. keybindsMenu.style.position = 'absolute';
  4847. keybindsMenu.style.top = '50%';
  4848. keybindsMenu.style.left = '50%';
  4849. keybindsMenu.style.transform = 'translate(-50%, -50%)';
  4850. keybindsMenu.style.width = '300px';
  4851. keybindsMenu.style.height = '200px';
  4852. keybindsMenu.style.background = '#AAE496';
  4853. keybindsMenu.style.color = 'white';
  4854. keybindsMenu.style.zIndex = '9999';
  4855. keybindsMenu.style.display = 'none';
  4856. keybindsMenu.setAttribute('id', 'keybindsMenu');
  4857.  
  4858. const title = document.createElement('div');
  4859. title.textContent = 'Commands';
  4860. title.style.padding = '10px';
  4861. title.style.textAlign = 'center';
  4862. title.style.fontWeight = 'bold';
  4863. keybindsMenu.appendChild(title);
  4864.  
  4865. const bind1 = document.createElement('div');
  4866. bind1.textContent = '!md -am = off/on AutoMills';
  4867. bind1.style.padding = '5px';
  4868. bind1.style.cursor = 'pointer';
  4869. bind1.addEventListener('click', () => {
  4870. // Handle bind 1 action
  4871. });
  4872. keybindsMenu.appendChild(bind1);
  4873.  
  4874. const bind2 = document.createElement('div');
  4875. bind2.textContent = '!md -ab = off/on Autobreak';
  4876. bind2.style.padding = '5px';
  4877. bind2.style.cursor = 'pointer';
  4878. bind2.addEventListener('click', () => {
  4879. // Handle bind 2 action
  4880. });
  4881. keybindsMenu.appendChild(bind2);
  4882.  
  4883. const bind3 = document.createElement('div');
  4884. bind3.textContent = '!md -at = off/on AntiTrap';
  4885. bind3.style.padding = '5px';
  4886. bind3.style.cursor = 'pointer';
  4887. bind3.addEventListener('click', () => {
  4888. // Handle bind 3 action
  4889. });
  4890. keybindsMenu.appendChild(bind3);
  4891.  
  4892. const bind4 = document.createElement('div');
  4893. bind4.textContent = '!md -ap = off/on AutoPlacer';
  4894. bind4.style.padding = '5px';
  4895. bind4.style.cursor = 'pointer';
  4896. bind4.addEventListener('click', () => {
  4897. // Handle bind 4 action
  4898. });
  4899. keybindsMenu.appendChild(bind4);
  4900.  
  4901. const bind5 = document.createElement('div');
  4902. bind5.textContent = '!md -ah = off/on Autoheal';
  4903. bind5.style.padding = '5px';
  4904. bind5.style.cursor = 'pointer';
  4905. bind5.addEventListener('click', () => {
  4906. // Handle bind 5 action
  4907. });
  4908. keybindsMenu.appendChild(bind5);
  4909.  
  4910. const bind6 = document.createElement('div');
  4911. bind5.textContent = 'Ну короче команды сами чекните в коде мне лень писать ^_^';
  4912. bind5.style.padding = '5px';
  4913. bind5.style.cursor = 'pointer';
  4914. bind5.addEventListener('click', () => {
  4915. // Handle bind 6 action
  4916. });
  4917. keybindsMenu.appendChild(bind6);
  4918.  
  4919.  
  4920. document.body.appendChild(keybindsMenu);
  4921.  
  4922. document.addEventListener('keydown', (event) => {
  4923. if (event.key === menuKey) {
  4924. if (keybindsMenu.style.display === 'none') {
  4925. keybindsMenu.style.display = 'block';
  4926. } else {
  4927. keybindsMenu.style.display = 'none';
  4928. }
  4929. }
  4930. });
  4931.  
  4932. };
  4933. })();
  4934. }).toString() + `)(${JSON.stringify(GM_info)});`)();