Diep.io+ (added Leader Arrow Color changer)

autorespawn(auto ad watcher with 2min timer), leader arrow + minimap arrow, FOV & diepUnits & windowScaling() calculator, Factory controls overlay, bullet distance (FOR EVERY BULLET SPEED BUILD) of 75% tanks, copy party link, leave game, no privacy settings button, no apes.io advertisment, net_predict_movement false

当前为 2024-09-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Diep.io+ (added Leader Arrow Color changer)
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0.3.1
  5. // @description autorespawn(auto ad watcher with 2min timer), leader arrow + minimap arrow, FOV & diepUnits & windowScaling() calculator, Factory controls overlay, bullet distance (FOR EVERY BULLET SPEED BUILD) of 75% tanks, copy party link, leave game, no privacy settings button, no apes.io advertisment, net_predict_movement false
  6. // @author r!PsAw
  7. // @match https://diep.io/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=diep.io
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. //!!!WARNING!!! Ui scale has to be at 0.9x for this script to work//
  14. let ingamescreen = document.getElementById("in-game-screen");
  15. let your_name = document.getElementById('spawn-nickname').value;
  16.  
  17. //GUI
  18. const container = document.createElement('div');
  19. container.style.position = 'fixed';
  20. container.style.top = '10px';
  21. container.style.left = '75px';
  22. container.style.padding = '15px';
  23. container.style.backgroundImage = 'linear-gradient(#ffffff, #79c7ff)';
  24. container.style.color = 'white';
  25. container.style.borderRadius = '10px';
  26. container.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)';
  27. container.style.minWidth = '200px';
  28. container.style.zIndex = '10';
  29.  
  30. const title = document.createElement('h1');
  31. title.textContent = 'Diep.io+ (hide with J)';
  32. title.style.margin = '0 0 5px 0';
  33. title.style.fontSize = '24px';
  34. title.style.textAlign = 'center';
  35. title.style.color = '#fb2a7b';
  36. title.style.zIndex = '11';
  37. container.appendChild(title);
  38.  
  39. const subtitle = document.createElement('h3');
  40. subtitle.textContent = 'made by r!PsAw';
  41. subtitle.style.margin = '0 0 15px 0';
  42. subtitle.style.fontSize = '14px';
  43. subtitle.style.textAlign = 'center';
  44. subtitle.style.color = '#6fa8dc';
  45. subtitle.style.zIndex = '11';
  46. container.appendChild(subtitle);
  47.  
  48. const categories = ['Debug', 'Visual', 'Functional', 'Addons'];
  49. const categoryButtons = {};
  50. const categoryContainer = document.createElement('div');
  51. categoryContainer.style.display = 'flex';
  52. categoryContainer.style.justifyContent = 'space-between';
  53. categoryContainer.style.marginBottom = '15px';
  54. categoryContainer.style.zIndex = '12';
  55.  
  56. categories.forEach(category => {
  57. const button = document.createElement('button');
  58. button.textContent = category;
  59. button.style.flex = '1';
  60. button.style.padding = '8px';
  61. button.style.margin = '0 5px';
  62. button.style.cursor = 'pointer';
  63. button.style.border = 'none';
  64. button.style.borderRadius = '5px';
  65. button.style.backgroundColor = '#0000ff';
  66. button.style.color = 'white';
  67. button.style.transition = 'background-color 0.3s';
  68. button.style.zIndex = '13';
  69.  
  70. button.addEventListener('mouseover', () => {
  71. button.style.backgroundColor = '#0000ff';
  72. });
  73. button.addEventListener('mouseout', () => {
  74. button.style.backgroundColor = '#fb2a7b';
  75. });
  76.  
  77. categoryContainer.appendChild(button);
  78. categoryButtons[category] = button;
  79. });
  80.  
  81. container.appendChild(categoryContainer);
  82.  
  83. const contentArea = document.createElement('div');
  84. contentArea.style.marginTop = '15px';
  85. contentArea.style.zIndex = '12';
  86. container.appendChild(contentArea);
  87.  
  88. const toggleButtons = {
  89. Debug: {
  90. 'Toggle Text': false,
  91. 'Toggle Middle Circle': false,
  92. 'Toggle Upgrades': false,
  93. 'Toggle Arrow pos': false
  94. },
  95. Visual: {
  96. 'Toggle Aim Lines': false,
  97. 'Toggle Bullet Distance': false,
  98. 'Toggle Minimap': false,
  99. 'Highlight Leader Score': false
  100. },
  101. Functional: {
  102. 'Auto Respawn': false,
  103. 'Auto Bonus Level': false,
  104. 'Toggle Leave Button': false,
  105. 'Toggle Level Seeker': false
  106. },
  107. Addons: {
  108. 'Toggle Leader Angle': false,
  109. 'Change Leader Arrow Color': '#fb2a7b', // Initial color
  110. 'Toggle Base Zones(soon!)': false
  111. }
  112. };
  113.  
  114. function createToggleButton(text, initialState) {
  115. const button = document.createElement('button');
  116. button.textContent = text;
  117. button.style.display = 'block';
  118. button.style.width = '100%';
  119. button.style.marginBottom = '10px';
  120. button.style.padding = '8px';
  121. button.style.cursor = 'pointer';
  122. button.style.border = 'none';
  123. button.style.borderRadius = '5px';
  124. button.style.transition = 'background-color 0.3s';
  125. button.style.zIndex = '13';
  126.  
  127. if (text === 'Change Leader Arrow Color') {
  128. updateButtonColor(button, initialState);
  129. button.addEventListener('click', () => {
  130. const colorPicker = document.createElement('input');
  131. colorPicker.type = 'color';
  132. colorPicker.value = toggleButtons[currentCategory][text];
  133. colorPicker.style.display = 'none';
  134. document.body.appendChild(colorPicker);
  135.  
  136. colorPicker.addEventListener('change', (event) => {
  137. const newColor = event.target.value;
  138. toggleButtons[currentCategory][text] = newColor;
  139. updateButtonColor(button, newColor);
  140. document.body.removeChild(colorPicker);
  141. });
  142.  
  143. colorPicker.click();
  144. });
  145. } else {
  146. updateButtonColor(button, initialState);
  147. button.addEventListener('click', () => {
  148. toggleButtons[currentCategory][text] = !toggleButtons[currentCategory][text];
  149. updateButtonColor(button, toggleButtons[currentCategory][text]);
  150. });
  151. }
  152.  
  153. return button;
  154. }
  155.  
  156. function updateButtonColor(button, state) {
  157. if (typeof state === 'string') {
  158. // For color picker button
  159. button.style.backgroundColor = state;
  160. window.choose_color = state;
  161. button.style.color = 'white';
  162. } else {
  163. // For toggle buttons
  164. if (state) {
  165. button.style.backgroundColor = '#63a5d4';
  166. button.style.color = 'white';
  167. } else {
  168. button.style.backgroundColor = '#a11a4e';
  169. button.style.color = 'white';
  170. }
  171. }
  172. }
  173.  
  174. let currentCategory = '';
  175.  
  176. function showCategory(category) {
  177. contentArea.innerHTML = '';
  178. currentCategory = category;
  179.  
  180. Object.keys(categoryButtons).forEach(cat => {
  181. if (cat === category) {
  182. categoryButtons[cat].style.backgroundColor = '#0000ff';
  183. } else {
  184. categoryButtons[cat].style.backgroundColor = '#fb2a7b';
  185. }
  186. });
  187.  
  188. if (category === 'Functional') {
  189. const copyLinkButton = document.createElement('button');
  190. copyLinkButton.textContent = 'Copy Party Link';
  191. copyLinkButton.style.display = 'block';
  192. copyLinkButton.style.width = '100%';
  193. copyLinkButton.style.marginBottom = '10px';
  194. copyLinkButton.style.padding = '8px';
  195. copyLinkButton.style.cursor = 'pointer';
  196. copyLinkButton.style.border = 'none';
  197. copyLinkButton.style.borderRadius = '5px';
  198. copyLinkButton.style.backgroundColor = '#2196F3';
  199. copyLinkButton.style.color = 'white';
  200. copyLinkButton.style.transition = 'background-color 0.3s';
  201. copyLinkButton.style.zIndex = '13';
  202.  
  203. copyLinkButton.addEventListener('mouseover', () => {
  204. copyLinkButton.style.backgroundColor = '#1E88E5';
  205. });
  206. copyLinkButton.addEventListener('mouseout', () => {
  207. copyLinkButton.style.backgroundColor = '#2196F3';
  208. });
  209.  
  210. copyLinkButton.addEventListener('click', () => {
  211. document.getElementById("copy-party-link").click();
  212. });
  213. contentArea.appendChild(copyLinkButton);
  214. }
  215.  
  216. Object.keys(toggleButtons[category]).forEach(text => {
  217. const button = createToggleButton(text, toggleButtons[category][text]);
  218. contentArea.appendChild(button);
  219. });
  220. }
  221.  
  222. Object.keys(categoryButtons).forEach(category => {
  223. categoryButtons[category].addEventListener('click', () => showCategory(category));
  224. });
  225.  
  226. document.body.appendChild(container);
  227.  
  228. //visibility of gui
  229. let visibility_gui = true;
  230.  
  231. function change_visibility() {
  232. visibility_gui = !visibility_gui;
  233. if (visibility_gui) {
  234. container.style.display = 'block';
  235. } else {
  236. container.style.display = 'none';
  237. }
  238. }
  239.  
  240. //ui scale
  241.  
  242. let ui_scale = document.querySelector("#settings-modal > div > div:nth-child(1) > div > div:nth-child(1) > label > span")
  243.  
  244. function ui_scale_check() {
  245. if (ui_scale.innerHTML != "-" && ui_scale.innerHTML != null && ingamescreen.classList.contains("screen") && ingamescreen.classList.contains("active")) {
  246. if (ui_scale.innerHTML != "0.9x") {
  247. input.inGameNotification("please change your ui_scale to 0.9x in Menu -> Settings");
  248. console.log(ui_scale.innerHTML);
  249. } else {
  250. console.log("no alert");
  251. }
  252. clearInterval(interval_for_ui_scale);
  253. }
  254. }
  255. let interval_for_ui_scale = setInterval(ui_scale_check, 0);
  256.  
  257. //check scripts
  258. let script_list = {
  259. minimap_leader_v1: null,
  260. minimap_leader_v2: null,
  261. fov: null,
  262. set_transform_debug: null,
  263. moveToLineTo_debug: null,
  264. gamemode_detect: null
  265. };
  266.  
  267. function check_ripsaw_scripts() {
  268. if (ingamescreen.classList.contains("screen") && ingamescreen.classList.contains("active")) {
  269. script_list.minimap_leader_v1 = !!window.m_arrow;
  270. script_list.minimap_leader_v2 = !!window.M_X;
  271. script_list.fov = !!window.HEAPF32;
  272. script_list.set_transform_debug = !!window.crx_container;
  273. script_list.moveToLineTo_debug = !!window.y_and_x;
  274. script_list.gamemode_detect = !!window.gm;
  275. }
  276. }
  277. setInterval(check_ripsaw_scripts, 500);
  278.  
  279. //detect gamemode
  280. let gamemode;
  281.  
  282. function check_gamemode() {
  283. if (script_list.gamemode_detect) {
  284. gamemode = window.gm;
  285. } else {
  286. let gamemode_sel_btn = document.querySelector("#gamemode-selector > div > div.selected");
  287. switch (gamemode_sel_btn.getAttribute("value")) {
  288. case "ffa":
  289. gamemode = "ffa";
  290. break
  291. case "teams":
  292. gamemode = "2tdm";
  293. break
  294. case "4teams":
  295. gamemode = "4tdm";
  296. break
  297. case "maze":
  298. gamemode = "maze";
  299. break
  300. case "event":
  301. gamemode = document.querySelector("#gamemode-selector > div > div.selected > div.dropdown-label").innerHTML;
  302. console.log(gamemode);
  303. break
  304. case "sandbox":
  305. gamemode = "sandbox";
  306. break
  307. }
  308. }
  309. }
  310.  
  311. setInterval(check_gamemode, 100);
  312.  
  313. //detect if dead or alive
  314. let state = "idk yet";
  315.  
  316. function check_state() {
  317. switch (input.doesHaveTank()) {
  318. case 0:
  319. state = "in menu";
  320. break
  321. case 1:
  322. state = "in game";
  323. break
  324. }
  325. }
  326.  
  327. setInterval(check_state, 100);
  328. //config
  329. var two = canvas.width / window.innerWidth;
  330. var debugboolean = false;
  331. var script_boolean = true;
  332.  
  333. // Mouse coordinates
  334. var uwuX = '0';
  335. var uwuY = '0';
  336. document.addEventListener('mousemove', function(e) {
  337. uwuX = e.clientX;
  338. uwuY = e.clientY;
  339. });
  340.  
  341. //net_predict_movement false
  342. (function() {
  343. function applySettings() {
  344. input.execute("net_predict_movement false");
  345. }
  346.  
  347. function waitForGame() {
  348. if (window.input && input.execute) {
  349. applySettings();
  350. } else {
  351. setTimeout(waitForGame, 100);
  352. }
  353. }
  354. waitForGame();
  355. })();
  356.  
  357. //annoying html elements
  358. let ads_removed = false;
  359.  
  360. function instant_remove() {
  361. let privacy_btn = document.getElementById("cmpPersistentLink");
  362. let apes_btn = document.getElementById("apes-io-promo");
  363. let discord_ad = document.querySelector("#apes-io-promo > img");
  364. let annoying = document.querySelector("#last-updated");
  365. if (privacy_btn) {
  366. privacy_btn.remove();
  367. }
  368.  
  369. if (annoying) {
  370. annoying.remove();
  371. }
  372.  
  373. if (apes_btn) {
  374. apes_btn.remove();
  375. }
  376.  
  377. if (discord_ad) {
  378. discord_ad.remove();
  379. }
  380.  
  381. if (!privacy_btn && !apes_btn && !discord_ad && !annoying) {
  382. console.log("removed buttons, quitting...");
  383. clearInterval(interval);
  384. }
  385. };
  386.  
  387. let interval = setInterval(instant_remove, 100);
  388.  
  389. //timer for bonus reward
  390. const gameOverScreen = document.getElementById('game-over-screen');
  391. const ad_btn = document.getElementById("game-over-video-ad");
  392. var ad_btn_free = true;
  393.  
  394. const timerDisplay = document.createElement('h1');
  395. timerDisplay.textContent = "Time left to collect next bonus levels: 02:00";
  396. gameOverScreen.appendChild(timerDisplay);
  397.  
  398. let timer;
  399. let totalTime = 120; // 2 minutes in seconds
  400.  
  401. function startTimer() {
  402. clearInterval(timer);
  403. timer = setInterval(function() {
  404. if (totalTime <= 0) {
  405. clearInterval(timer);
  406. timerDisplay.textContent = "00:00";
  407. } else {
  408. totalTime--;
  409. let minutes = Math.floor(totalTime / 60);
  410. let seconds = totalTime % 60;
  411. timerDisplay.textContent =
  412. `Time left to collect next bonus levels: ${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
  413. }
  414. }, 1000);
  415. }
  416.  
  417. function resetTimer() {
  418. if (totalTime === 0) {
  419. clearInterval(timer);
  420. totalTime = 120; // Reset to 2 minutes
  421. timerDisplay.textContent = "02:00";
  422. }
  423. }
  424.  
  425. ad_btn.addEventListener('click', check_ad_state);
  426.  
  427. function check_ad_state() {
  428. if (totalTime === 0) {
  429. resetTimer();
  430. } else if (totalTime === 120) {
  431. ad_btn_free = true;
  432. startTimer();
  433. } else {
  434. ad_btn_free = false;
  435. }
  436. }
  437.  
  438. //autorespawn old method
  439.  
  440. let autorespawn = false;
  441.  
  442. function respawn() {
  443. if (toggleButtons.Functional['Auto Respawn']) {
  444. if (state === "in game") {
  445. return;
  446. } else {
  447. if ((totalTime === 120 || totalTime === 0) && toggleButtons.Functional['Auto Bonus Level']) {
  448. ad_btn.click();
  449. } else {
  450. let spawnbtn = document.getElementById("spawn-button");
  451. spawnbtn.click();
  452. }
  453. }
  454. }
  455. }
  456.  
  457. setInterval(respawn, 1000);
  458.  
  459. /*
  460. //autorespawn new method (no bonus level)
  461. function respawn(){
  462. if(toggleButtons.Functional['Auto Respawn']){
  463. if(state === "in menu"){
  464. let spawnbtn = document.getElementById("spawn-button");
  465. spawnbtn.click();
  466. }
  467. }
  468. }
  469.  
  470. setInterval(respawn, 1000);
  471. */
  472. //toggle leave game
  473. let ingame_quit_btn = document.getElementById("quick-exit-game");
  474.  
  475. function check_class() {
  476. if (toggleButtons.Functional['Toggle Leave Button']) {
  477. ingame_quit_btn.classList.remove("hidden");
  478. ingame_quit_btn.classList.add("shown");
  479. } else {
  480. ingame_quit_btn.classList.remove("shown");
  481. ingame_quit_btn.classList.add("hidden");
  482. }
  483. }
  484.  
  485. setInterval(check_class, 300);
  486.  
  487. //score logic
  488. let your_nameFont;
  489. let scoreBoardFont;
  490. let highest_score;
  491. let highest_score_addon;
  492. let highest_score_string;
  493. let is_highest_score_alive;
  494. let scores = {
  495. millions: 0,
  496. thousands: 0,
  497. lessThan1k: 0
  498. };
  499.  
  500. function get_highest_score() {
  501. if (scores.millions > 0) {
  502. highest_score = scores.millions;
  503. highest_score_addon = "m";
  504. } else if (scores.thousands > 0) {
  505. highest_score = scores.thousands;
  506. highest_score_addon = "k";
  507. } else if (scores.lessThan1k > 0) {
  508. highest_score = scores.lessThan1k;
  509. }
  510. }
  511. //getting text information (credits to abc)
  512. CanvasRenderingContext2D.prototype.fillText = new Proxy(CanvasRenderingContext2D.prototype.fillText, {
  513. apply(fillRect, ctx, [text, x, y, ...blah]) {
  514. const isNumeric = (string) => /^[+-]?\d+(\.\d+)?$/.test(string)
  515. if (text.startsWith('Lvl ')) {
  516. currentLevel = text.split(' ')[1];
  517. if (text.split(' ')[3] != undefined) {
  518. tanky = text.split(' ')[2] + text.split(' ')[3];
  519. } else {
  520. tanky = text.split(' ')[2]
  521. }
  522. } else if (text === your_name) {
  523. your_nameFont = ctx.font;
  524. } else if (text === " - ") {
  525. scoreBoardFont = ctx.font
  526. } else if (isNumeric(text) && ctx.font === scoreBoardFont) {
  527. scores.lessThan1k = parseFloat(text);
  528. } else if (text.includes('.') && text.includes('k') && ctx.font === scoreBoardFont) {
  529. if (parseFloat(text.split('k')[0]) > scores.thousands) {
  530. scores.thousands = parseFloat(text.split('k')[0]);
  531. }
  532. } else if (text.includes('.') && text.includes('m') && ctx.font === scoreBoardFont) {
  533. if (parseFloat(text.split('m')[0]) > scores.millions) {
  534. scores.millions = parseFloat(text.split('m')[0]);
  535. }
  536. }
  537.  
  538. get_highest_score();
  539. if (highest_score != null) {
  540. if (highest_score_addon != null) {
  541. highest_score_string = `${highest_score}${highest_score_addon}`;
  542. } else {
  543. highest_score_string = `${highest_score}`;
  544. }
  545. if (text === highest_score_string && toggleButtons.Visual['Highlight Leader Score']) {
  546. ctx.fillStyle = "orange";
  547. }
  548. }
  549. fillRect.call(ctx, text, x, y, ...blah);
  550. }
  551. });
  552.  
  553. //display level
  554. const pointsNeeded = [
  555. 0, 4, 13, 28, 50, 78, 113, 157, 211, 275,
  556. 350, 437, 538, 655, 787, 938, 1109, 1301,
  557. 1516, 1757, 2026, 2325, 2658, 3026, 3433,
  558. 3883, 4379, 4925, 5525, 6184, 6907, 7698,
  559. 8537, 9426, 10368, 11367, 12426, 13549,
  560. 14739, 16000, 17337, 18754, 20256, 21849,
  561. 23536, 999999 //this one is not lvl 46, just a value to make my code work
  562. ];
  563.  
  564. const crx = CanvasRenderingContext2D.prototype;
  565. crx.fillText = new Proxy(crx.fillText, {
  566. apply: function(f, _this, args) {
  567. if (scoreBoardFont != null && toggleButtons.Functional['Toggle Level Seeker']) {
  568. const isNumeric = (string) => /^[+-]?\d+(\.\d+)?$/.test(string);
  569. if (_this.font != scoreBoardFont) {
  570. if (isNumeric(args[0])) {
  571. for (let i = 0; i < 16; i++) {
  572. if (parseFloat(args[0]) < pointsNeeded[i]) {
  573. args[0] = `L: ${i}`;
  574. }
  575. }
  576. } else if (args[0].includes('.')) {
  577. if (args[0].includes('k')) {
  578. for (let i = 16; i < pointsNeeded.length; i++) {
  579. if (parseFloat(args[0].split('k')[0]) * 1000 < pointsNeeded[i]) {
  580. args[0] = `L: ${i}`;
  581. }
  582. }
  583. } else if (args[0].includes('m')) {
  584. args[0] = `L: 45}`;
  585. }
  586. }
  587. }
  588. }
  589. f.apply(_this, args);
  590. }
  591. });
  592. crx.strokeText = new Proxy(crx.strokeText, {
  593. apply: function(f, _this, args) {
  594. if (scoreBoardFont != null && toggleButtons.Functional['Toggle Level Seeker']) {
  595. const isNumeric = (string) => /^[+-]?\d+(\.\d+)?$/.test(string);
  596. if (_this.font != scoreBoardFont) {
  597. if (isNumeric(args[0])) {
  598. for (let i = 0; i < 16; i++) {
  599. if (parseFloat(args[0]) < pointsNeeded[i]) {
  600. args[0] = `L: ${i}`;
  601. console.log(args[0]);
  602. }
  603. }
  604. } else if (args[0].includes('.')) {
  605. if (args[0].includes('k')) {
  606. for (let i = 16; i < pointsNeeded.length; i++) {
  607. if (parseFloat(args[0].split('k')[0]) * 1000 < pointsNeeded[i]) {
  608. args[0] = `L: ${i}`;
  609. console.log(args[0]);
  610. }
  611. }
  612. } else if (args[0].includes('m')) {
  613. args[0] = `L: 45`;
  614. console.log(args[0]);
  615. }
  616. }
  617. }
  618. }
  619. f.apply(_this, args);
  620. }
  621. });
  622.  
  623. //Detect AutoFire/AutoSpin
  624. let auto_fire = false;
  625. let auto_spin = false;
  626.  
  627. function f_s(f_or_s) {
  628. switch (f_or_s) {
  629. case "fire":
  630. auto_fire = !auto_fire;
  631. break
  632. case "spin":
  633. auto_spin = !auto_spin;
  634. break
  635. }
  636. }
  637. //Diep Units & fov calculator
  638. //NOTE: I removed spaces between tank names for this script only. Also since glider came out and diepindepth was unupdated it didn't update correctly, I fixed that.
  639.  
  640. /*
  641. =============================================================================
  642. Skid & Noob friendly calculation explained:
  643.  
  644. Read this in order to understand, how the position calculation works.
  645.  
  646. 1. Canvas/window coords
  647. When you load diep.io in a browser window, it also loads a canvas where the game is drawn.
  648. Imagine a piece of paper where you draw things, this is canvas. If you place a pen on that piece of paper, this is html element.
  649. Diep.io uses canvas mainly. Your window and the canvas use different coordinate systems, even tho they appear the same at first:
  650.  
  651. start->x
  652. |
  653. \/
  654. y
  655.  
  656. if x is for example 3 and y is 5, you find the point of your mouse.
  657.  
  658. start->x...
  659. |_________|
  660. \/________|
  661. y_________|
  662. ._________|
  663. ._________|
  664. ._________|
  665. ._________|
  666. ._________HERE
  667.  
  668. the right upper corner of your window is the x limit, called window.innerWidth
  669. the left bottom corner of your window is the y limit, called window.innerHeight
  670.  
  671. canvas is the same, but multiplied by 2. So for x, it's canvas.height = window.innerHeight * 2
  672. same goes for y, canvas.width = window.innerWidth * 2
  673.  
  674. This can work the other way around too. canvas.height/2 = window.innerHeight
  675. and canvas.width/2 = window.innerWidth
  676.  
  677. NOTE: when you use input.mouse(x, y) you're using the canvas coordinate system.
  678.  
  679. 2. DiepUnits
  680. Read this first: https://github.com/ABCxFF/diepindepth/blob/main/canvas/scaling.md
  681. if you're curious about what l and Fv means, like I was I can tell you now.
  682.  
  683. L stands for your Tank level, that you currently have.
  684. Fv is the fieldFactor. You can find them here for each tank: https://github.com/ABCxFF/diepindepth/blob/main/extras/tankdefs.json
  685. (The formula from the picture as code: const FOV = (level, fieldFactor) => (.55*fieldFactor)/Math.pow(1.01, (level-1)/2); )
  686.  
  687. Additions:
  688. DiepUnits are used, to draw all entities in game in the right size. For example when you go Ranger, they appear smaller
  689. because your entire ingame map shrinks down, so you see more without changing the size of the canvas or the window.
  690. So if a square is 55 diepunits big and it gets visually smaller, it's still 55 diepunits big.
  691.  
  692. Coordinate system: x*scalingFactor, y*scalingFactor
  693.  
  694. IMPORTANT!!! Note that your Tank is getting additional DiepUnits with every level it grows.
  695. This formula descritbes it's growth
  696. 53 * (1.01 ** (currentLevel - 1));
  697.  
  698. 3. WindowScaling
  699. Read this first: https://github.com/ABCxFF/diepindepth/blob/main/canvas/scaling.md
  700. (you can use the function given in there, if you don't want to make your own)
  701.  
  702. it's used for all ui elements, like scoreboard, minimap or stats upgrades.
  703. NOTE: It's not used for html Elements, only canvas. So the starting menu or gameover screen aren't part of it.
  704.  
  705. Coordinate system: x*windowScaling(), y*windowScaling()
  706.  
  707. 4. Converting coordinate systems into each other
  708. canvas -> window = a/(canvas.width/window.innerWidth) -> b
  709. window -> canvas = a*(canvas.width/window.innerWidth) -> b
  710. windowScaling -> window = ( a*windowScaling() )/(canvas.width/window.innerWidth) -> b
  711. windowScaling -> canvas = a*windowScaling() - > b
  712. diepUnits -> canvas = a/scalingFactor -> b
  713. diepUnits -> window = ( a/scalingFactor )/(canvas.width/window.innerWidth) -> b
  714. window -> diepUnits = ( a*scalingFactor )*(canvas.width/window.innerWidth) -> b
  715. canvas -> diepUnits = a*scalingFactor -> b
  716. window -> windowScaling() = ( a*windowScaling() )*(canvas.width/window.innerWidth) -> b
  717. canvas -> windowScaling() = a*windowScaling() - > b
  718. diepUnits -> windowScaling() = ( a/scalingFactor ) * fieldFactor -> b
  719. windowScaling()-> diepUnits = ( a/fieldFactor ) * scalingFactor -> b
  720.  
  721. =============================================================================
  722.  
  723. My todo list or fix:
  724.  
  725. - simulate diep.io moving and knockback physics
  726.  
  727. - simulate diep.io bullets
  728.  
  729. - figure out how to simulate mouse click events
  730.  
  731. - Finish bullet speed hybrid tanks
  732.  
  733. - Figure out physics for sniper, Ranger etc.
  734.  
  735. =============================================================================
  736.  
  737. Useful info:
  738.  
  739. -shape sizes:
  740.  
  741. tank lvl 1 size = 53 diep units
  742.  
  743. grid square side length = 50 diep units
  744. square, triangle = 55 diep units
  745. pentagon = 75 diep units
  746. small crasher = 35 diep units
  747. big crasher = 55 diep units
  748. alpha pentagon = 200 diep units
  749.  
  750. =============================================================================
  751. */
  752. var currentLevel = 0;
  753. var lastLevel = 0;
  754. var tanky = "";
  755. let ripsaw_radius;
  756. let fieldFactor = 1.0;
  757. let found = false;
  758. let loltank;
  759. let lolztank;
  760. let diepUnits = 53 * (1.01 ** (currentLevel - 1));
  761. let FOV = (0.55 * fieldFactor) / Math.pow(1.01, (currentLevel - 1) / 2);
  762. let scalingFactor = FOV * windowScaling();
  763. const fieldFactors = [
  764. {
  765. tank: "Sniper",
  766. factor: 0.899
  767. },
  768. {
  769. tank: "Overseer",
  770. factor: 0.899
  771. },
  772. {
  773. tank: "Overlord",
  774. factor: 0.899
  775. },
  776. {
  777. tank: "Assassin",
  778. factor: 0.8
  779. },
  780. {
  781. tank: "Necromancer",
  782. factor: 0.899
  783. },
  784. {
  785. tank: "Hunter",
  786. factor: 0.85
  787. },
  788. {
  789. tank: "Stalker",
  790. factor: 0.8
  791. },
  792. {
  793. tank: "Ranger",
  794. factor: 0.699
  795. },
  796. {
  797. tank: "Manager",
  798. factor: 0.899
  799. },
  800. {
  801. tank: "Predator",
  802. factor: 0.85
  803. },
  804. {
  805. tank: "Trapper",
  806. factor: 0.899
  807. },
  808. {
  809. tank: "GunnerTrapper",
  810. factor: 0.899
  811. },
  812. {
  813. tank: "Overtrapper",
  814. factor: 0.899
  815. },
  816. {
  817. tank: "MegaTrapper",
  818. factor: 0.899
  819. },
  820. {
  821. tank: "Tri-Trapper",
  822. factor: 0.899
  823. },
  824. {
  825. tank: "Smasher",
  826. factor: 0.899
  827. },
  828. {
  829. tank: "Landmine",
  830. factor: 0.899
  831. },
  832. {
  833. tank: "Streamliner",
  834. factor: 0.85
  835. },
  836. {
  837. tank: "AutoTrapper",
  838. factor: 0.899
  839. },
  840. {
  841. tank: "Battleship",
  842. factor: 0.899
  843. },
  844. {
  845. tank: "AutoSmasher",
  846. factor: 0.899
  847. },
  848. {
  849. tank: "Spike",
  850. factor: 0.899
  851. },
  852. {
  853. tank: "Factory",
  854. factor: 0.899
  855. },
  856. {
  857. tank: "Skimmer",
  858. factor: 0.899
  859. },
  860. {
  861. tank: "Glider",
  862. factor: 0.899
  863. },
  864. {
  865. tank: "Rocketeer",
  866. factor: 0.899
  867. },
  868. ]
  869.  
  870. function windowScaling() {
  871. const a = canvas.height / 1080;
  872. const b = canvas.width / 1920;
  873. return b < a ? a : b;
  874. }
  875.  
  876. function calculateFOV(Fv, l) {
  877. const numerator = 0.55 * Fv;
  878. const denominator = Math.pow(1.01, (l - 1) / 2);
  879. if (typeof window.HEAPF32 !== 'undefined' && typeof window.fov !== 'undefined' && window.fov.length > 0) {
  880. //use this part, if you have a fov script that can share it's fov value with you
  881. FOV = HEAPF32[fov[0]];
  882. } else {
  883. //use this part if you have no fov script
  884. FOV = numerator / denominator;
  885. }
  886. return FOV;
  887. }
  888.  
  889. function apply_values(FF) {
  890. calculateFOV(FF, currentLevel);
  891. scalingFactor = FOV * windowScaling();
  892. ripsaw_radius = diepUnits * scalingFactor;
  893. diepUnits = 53 * (1.01 ** (currentLevel - 1));
  894. }
  895.  
  896. function apply_changes(value) {
  897. if (found) {
  898. fieldFactor = fieldFactors[value].factor;
  899. loltank = tanky;
  900. lastLevel = currentLevel;
  901. apply_values(fieldFactor);
  902. } else {
  903. if (value === null) {
  904. fieldFactor = 1.0;
  905. loltank = "default";
  906. lolztank = tanky;
  907. lastLevel = currentLevel;
  908. apply_values(fieldFactor);
  909. }
  910. }
  911. }
  912.  
  913. function bruteforce_tanks() {
  914. for (let i = 0; i < fieldFactors.length; i++) {
  915. if (tanky.includes(fieldFactors[i].tank)) {
  916. found = true;
  917. console.log("FOUND TANK " + fieldFactors[i].tank);
  918. apply_changes(i);
  919. break;
  920. } else {
  921. found = false;
  922. if (i < fieldFactors.length - 1) {
  923. console.log(`checking tank ${i}`);
  924. } else {
  925. console.log("No Tank was found, resetting to default")
  926. apply_changes(null);
  927. }
  928. }
  929. }
  930. }
  931.  
  932. window.addEventListener("resize", bruteforce_tanks);
  933.  
  934. function check_lvl_change() {
  935. if (lastLevel === currentLevel) {
  936. //console.log("level wasn't changed");
  937. } else {
  938. console.log("changed level, bruteforcing");
  939. bruteforce_tanks();
  940. }
  941. }
  942.  
  943. function check_change() {
  944. //console.log("lastLevel: " + lastLevel + " currentLevel: " + currentLevel);
  945. check_lvl_change();
  946. if (loltank != tanky) {
  947. if (loltank === "default") {
  948. if (lolztank != tanky) {
  949. bruteforce_tanks();
  950. } else {
  951. return;
  952. }
  953. } else {
  954. bruteforce_tanks();
  955. }
  956. }
  957. }
  958.  
  959. setInterval(check_change, 250);
  960.  
  961. //canvas gui
  962. let offsetX = 0;
  963. let offsetY = 0;
  964. //for canvas text height and space between it
  965. let text_startingY = 450 * windowScaling();
  966. let textAdd = 25 * windowScaling();
  967. let selected_box = null;
  968. const boxes = [
  969. {
  970. color: "lightblue",
  971. LUcornerX: 47,
  972. LUcornerY: 67
  973. },
  974. {
  975. color: "green",
  976. LUcornerX: 47 + 90 + 13,
  977. LUcornerY: 67
  978. },
  979. {
  980. color: "red",
  981. LUcornerX: 47,
  982. LUcornerY: 67 + 90 + 9
  983. },
  984. {
  985. color: "yellow",
  986. LUcornerX: 47 + 90 + 13,
  987. LUcornerY: 67 + 90 + 9
  988. },
  989. {
  990. color: "blue",
  991. LUcornerX: 47,
  992. LUcornerY: 67 + ((90 + 9) * 2)
  993. },
  994. {
  995. color: "rainbow",
  996. LUcornerX: 47 + 90 + 13,
  997. LUcornerY: 67 + ((90 + 9) * 2)
  998. }
  999. ]
  1000.  
  1001. const ctx = canvas.getContext('2d');
  1002.  
  1003. function ctx_text(fcolor, scolor, lineWidth, font, text, textX, textY) {
  1004. ctx.fillStyle = fcolor;
  1005. ctx.lineWidth = lineWidth;
  1006. ctx.font = font;
  1007. ctx.strokeStyle = scolor;
  1008. ctx.strokeText(`${text}`, textX, textY)
  1009. ctx.fillText(`${text}`, textX, textY)
  1010. }
  1011.  
  1012. function ctx_arc(x, y, r, sAngle, eAngle, counterclockwise, c) {
  1013. ctx.beginPath();
  1014. ctx.arc(x, y, r, sAngle, eAngle, counterclockwise);
  1015. ctx.fillStyle = c;
  1016. ctx.fill();
  1017. }
  1018.  
  1019. function ctx_rect(x, y, a, b, c) {
  1020. ctx.beginPath();
  1021. ctx.strokeStyle = c;
  1022. ctx.strokeRect(x, y, a, b);
  1023. }
  1024.  
  1025. //use this for game entities
  1026. function dot_in_diepunits(diepunits_X, diepunits_Y) {
  1027. ctx_arc(diepunits_X * scalingFactor, diepunits_Y * scalingFactor, 5, 0, 2 * Math.PI, false, "lightblue");
  1028. }
  1029.  
  1030. function circle_in_diepunits(diepunits_X, diepunits_Y, diepunits_R, c) {
  1031. ctx.beginPath();
  1032. ctx.arc(diepunits_X * scalingFactor, diepunits_Y * scalingFactor, diepunits_R * scalingFactor, 0, 2 * Math.PI, false);
  1033. ctx.strokeStyle = c;
  1034. ctx.stroke();
  1035. }
  1036.  
  1037. //use this for ui elements like upgrades or scoreboard
  1038. function dot_in_diepunits_FOVless(diepunits_X, diepunits_Y) {
  1039. ctx_arc(diepunits_X * windowScaling(), diepunits_Y * windowScaling(), 5, 0, 2 * Math.PI, false, "lightblue");
  1040. }
  1041.  
  1042. function square_for_grid(x, y, a, b, color) {
  1043. ctx.beginPath();
  1044. ctx.rect(x * windowScaling(), y * windowScaling(), a * windowScaling(), b * windowScaling());
  1045. ctx.strokeStyle = color;
  1046. ctx.stroke();
  1047. }
  1048.  
  1049. function draw_upgrade_grid() {
  1050. for (let i = 0; i < boxes.length; i++) {
  1051. let start_x = (boxes[i].LUcornerX * windowScaling()) / two;
  1052. let start_y = (boxes[i].LUcornerY * windowScaling()) / two;
  1053. let end_x = ((boxes[i].LUcornerX + 43 * 2) * windowScaling()) / two;
  1054. let end_y = ((boxes[i].LUcornerY + 43 * 2) * windowScaling()) / two;
  1055. let temp_color = "black";
  1056. if (uwuX > start_x && uwuY > start_y && uwuX < end_x && uwuY < end_y) {
  1057. temp_color = "red";
  1058. selected_box = i;
  1059. } else {
  1060. temp_color = "black";
  1061. selected_box = null;
  1062. }
  1063. square_for_grid(boxes[i].LUcornerX, boxes[i].LUcornerY, 86, 86, temp_color);
  1064. }
  1065. for (let i = 0; i < boxes.length; i++) {
  1066. dot_in_diepunits_FOVless(boxes[i].LUcornerX, boxes[i].LUcornerY);
  1067. dot_in_diepunits_FOVless(boxes[i].LUcornerX + 43, boxes[i].LUcornerY);
  1068. dot_in_diepunits_FOVless(boxes[i].LUcornerX + 43 * 2, boxes[i].LUcornerY);
  1069. dot_in_diepunits_FOVless(boxes[i].LUcornerX + 43 * 2, boxes[i].LUcornerY + 43);
  1070. dot_in_diepunits_FOVless(boxes[i].LUcornerX + 43 * 2, boxes[i].LUcornerY + 43 * 2);
  1071. dot_in_diepunits_FOVless(boxes[i].LUcornerX, boxes[i].LUcornerY + 43);
  1072. dot_in_diepunits_FOVless(boxes[i].LUcornerX, boxes[i].LUcornerY + 43 * 2);
  1073. dot_in_diepunits_FOVless(boxes[i].LUcornerX + 43, boxes[i].LUcornerY + 43);
  1074. }
  1075. }
  1076.  
  1077. const gradients = ["#94b3d0", "#96b0c7", "#778daa", "#4c7299", "#52596c", "#19254e", "#2d445f", "#172631"];
  1078. const tank_group1 = ["Trapper", "Overtrapper", "MegaTrapper", "Tri-Trapper"]; //Traps only
  1079. const tank_group2 = ["Tank", "Twin", "TripleShot", "SpreadShot", "PentaShot", "TwinFlank", "TripleTwin", "QuadTank", "OctoTank", "MachineGun", "Sprayer", "Triplet", "FlankGuard"]; //constant bullets [initial speed = 0.699]
  1080. //const tank_group3 = ["GunnerTrapper", "AutoTrapper"]; //Traps AND constant bullets (UNFINISHED)
  1081. //const tank_group4 = []; //mix of bullets (UNFINISHED)
  1082. //const tank_group5 = ["Sniper", "Assassin", "Stalker", "Ranger"]; //sniper+ bullets (UNFINISHED)
  1083. const tank_group6 = ["Destroyer", "Hybrid", "Annihilator"]; //slower bullets [intitial speed = 0.699]
  1084. //const tank_group7 = ["Overseer", "Overlord", "Manager", "Necromancer"]; //infinite bullets(drones) (UNFINISHED)
  1085. const tank_group8 = ["Factory"]; //drones with spreading abilities
  1086. const tank_group9 = ["Battleship"]; //special case
  1087.  
  1088. function draw_cirle_radius_for_tank() {
  1089. if (tank_group1.includes(tanky)) {
  1090. for (let i = 0; i < gradients.length; i++) {
  1091. circle_in_diepunits(canvas.width / 2 / scalingFactor, canvas.height / 2 / scalingFactor, 485 + (52.5 * i), gradients[i]);
  1092. }
  1093. } else if (tank_group2.includes(tanky)) {
  1094. for (let i = 0; i < gradients.length; i++) {
  1095. circle_in_diepunits(canvas.width / 2 / scalingFactor, canvas.height / 2 / scalingFactor, 1850 + (210 * i), gradients[i]);
  1096. }
  1097. /*
  1098. }else if(tank_group5.includes(tanky)){
  1099. for(let i = 0; i < gradients.length; i++){
  1100. circle_in_diepunits(canvas.width/2/scalingFactor, canvas.height/2/scalingFactor, 2703 + (420*i), gradients[i]);
  1101. }*/
  1102. } else if (tank_group6.includes(tanky)) {
  1103. for (let i = 0; i < gradients.length; i++) {
  1104. circle_in_diepunits(canvas.width / 2 / scalingFactor, canvas.height / 2 / scalingFactor, 1443.21 + (146.79 * i), gradients[i]);
  1105. }
  1106. /*
  1107. }else if(tank_group7.includes(tanky)){
  1108. for(let i = 0; i < gradients.length; i++){
  1109. circle_in_diepunits( canvas.width/2/scalingFactor , canvas.height/2/scalingFactor, 1607 + (145*i), gradients[i]);
  1110. circle_in_diepunits( uwuX*2/scalingFactor , uwuY*2/scalingFactor, 1607 + (145*i), gradients[i]);
  1111. }*/
  1112. } else if (tank_group8.includes(tanky)) {
  1113. circle_in_diepunits(uwuX * two / scalingFactor, uwuY * two / scalingFactor, 200, gradients[0]);
  1114. circle_in_diepunits(uwuX * two / scalingFactor, uwuY * two / scalingFactor, 800, gradients[1]);
  1115. circle_in_diepunits(uwuX * two / scalingFactor, uwuY * two / scalingFactor, 900, gradients[2]);
  1116. } else if (tank_group9.includes(tanky)) {
  1117. for (let i = 0; i < gradients.length; i++) {
  1118. circle_in_diepunits(canvas.width / 2 / scalingFactor, canvas.height / 2 / scalingFactor, 1640 + (210 * i), gradients[i]);
  1119. }
  1120. } else {
  1121. return;
  1122. }
  1123.  
  1124. }
  1125.  
  1126. //let's calculate the angle
  1127. var vector_l = [null, null];
  1128. var angle_l = 0;
  1129.  
  1130. function calc_leader() {
  1131. if (script_list.minimap_leader_v1) {
  1132. let xc = canvas.width / 2;
  1133. let yc = canvas.height / 2;
  1134. vector_l[0] = window.l_arrow.xl - xc;
  1135. vector_l[1] = window.l_arrow.yl - yc;
  1136. angle_l = Math.atan2(vector_l[1], vector_l[0]) * (180 / Math.PI);
  1137. } else if (script_list.minimap_leader_v2) {
  1138. let xc = canvas.width / 2;
  1139. let yc = canvas.height / 2;
  1140. vector_l[0] = window.L_X - xc;
  1141. vector_l[1] = window.L_Y - yc;
  1142. angle_l = Math.atan2(vector_l[1], vector_l[0]) * (180 / Math.PI);
  1143. } else {
  1144. console.log("waiting for leader script to give us values");
  1145. }
  1146. }
  1147.  
  1148. //setInterval(calc_l, 0);
  1149.  
  1150. // Minimap logic
  1151. var minimap_elements = [
  1152. {
  1153. name: "minimap",
  1154. x: 177.5,
  1155. y: 177.5,
  1156. width: 162.5,
  1157. height: 162.5,
  1158. color: "purple"
  1159. },
  1160. {
  1161. name: "2tdm Blue Team",
  1162. x: 177.5,
  1163. y: 177.5,
  1164. width: 17.5,
  1165. height: 162.5,
  1166. color: "blue"
  1167. },
  1168. {
  1169. name: "2tdm Red Team",
  1170. x: 32.5,
  1171. y: 177.5,
  1172. width: 17.5,
  1173. height: 162.5,
  1174. color: "red"
  1175. },
  1176. {
  1177. name: "4tdm Blue Team",
  1178. x: 177.5,
  1179. y: 177.5,
  1180. width: 25,
  1181. height: 25,
  1182. color: "blue"
  1183. },
  1184. {
  1185. name: "4tdm Purple Team",
  1186. x: 40,
  1187. y: 177.5,
  1188. width: 25,
  1189. height: 25,
  1190. color: "purple"
  1191. },
  1192. {
  1193. name: "4tdm Green Team",
  1194. x: 177.5,
  1195. y: 40,
  1196. width: 25,
  1197. height: 25,
  1198. color: "green"
  1199. },
  1200. {
  1201. name: "4tdm Red Team",
  1202. x: 40,
  1203. y: 40,
  1204. width: 25,
  1205. height: 25,
  1206. color: "red"
  1207. },
  1208. ];
  1209.  
  1210. var m_e_ctx_coords = [
  1211. {
  1212. name: "minimap",
  1213. startx: null,
  1214. stary: null,
  1215. endx: null,
  1216. endy: null
  1217. },
  1218. {
  1219. name: "2tdm Blue Team",
  1220. startx: null,
  1221. stary: null,
  1222. endx: null,
  1223. endy: null
  1224. },
  1225. {
  1226. name: "2tdm Red Team",
  1227. startx: null,
  1228. stary: null,
  1229. endx: null,
  1230. endy: null
  1231. },
  1232. {
  1233. name: "4tdm Blue Team",
  1234. startx: null,
  1235. stary: null,
  1236. endx: null,
  1237. endy: null
  1238. },
  1239. {
  1240. name: "4tdm Purple Team",
  1241. startx: null,
  1242. stary: null,
  1243. endx: null,
  1244. endy: null
  1245. },
  1246. {
  1247. name: "4tdm Green Team",
  1248. startx: null,
  1249. stary: null,
  1250. endx: null,
  1251. endy: null
  1252. },
  1253. {
  1254. name: "4tdm Red Team",
  1255. startx: null,
  1256. stary: null,
  1257. endx: null,
  1258. endy: null
  1259. }
  1260. ]
  1261.  
  1262. function draw_minimap() {
  1263. switch (gamemode) {
  1264. case "2tdm":
  1265. for (let i = 0; i < 3; i++) {
  1266. updateAndDrawElement(i);
  1267. }
  1268. break;
  1269. case "4tdm":
  1270. updateAndDrawElement(0);
  1271. for (let i = 3; i < minimap_elements.length; i++) { // Draw all 4tdm elements
  1272. updateAndDrawElement(i);
  1273. }
  1274. break;
  1275. }
  1276. if (script_list.minimap_leader_v1 || script_list.minimap_leader_v2) {
  1277. minimap_collision_check();
  1278. }
  1279. }
  1280.  
  1281. function updateAndDrawElement(index) {
  1282. // Update their real-time position
  1283. m_e_ctx_coords[index].startx = canvas.width - (minimap_elements[index].x * windowScaling());
  1284. m_e_ctx_coords[index].starty = canvas.height - (minimap_elements[index].y * windowScaling());
  1285. m_e_ctx_coords[index].endx = m_e_ctx_coords[index].startx + minimap_elements[index].width * windowScaling();
  1286. m_e_ctx_coords[index].endy = m_e_ctx_coords[index].starty + minimap_elements[index].height * windowScaling();
  1287.  
  1288. // Draw the element
  1289. ctx.beginPath();
  1290. ctx.rect(m_e_ctx_coords[index].startx, m_e_ctx_coords[index].starty, minimap_elements[index].width * windowScaling(), minimap_elements[index].height * windowScaling());
  1291. ctx.lineWidth = "1";
  1292. ctx.strokeStyle = minimap_elements[index].color;
  1293. ctx.stroke();
  1294. }
  1295.  
  1296. let position_on_minimap;
  1297.  
  1298. function minimap_collision_check() {
  1299. if (script_list.minimap_leader_v1 || script_list.minimap_leader_v2) {
  1300. let x = script_list.minimap_leader_v1 ? window.m_arrow.xl : window.M_X;
  1301. let y = script_list.minimap_leader_v1 ? window.m_arrow.yl : window.M_Y;
  1302.  
  1303. if (m_e_ctx_coords[0].startx < x &&
  1304. m_e_ctx_coords[0].starty < y &&
  1305. m_e_ctx_coords[0].endx > x &&
  1306. m_e_ctx_coords[0].endy > y) {
  1307.  
  1308. if (gamemode === "2tdm") {
  1309. if (checkWithinBase(1, x, y)) position_on_minimap = "blue base";
  1310. else if (checkWithinBase(2, x, y)) position_on_minimap = "red base";
  1311. else position_on_minimap = "not in the base";
  1312. } else if (gamemode === "4tdm") {
  1313. if (checkWithinBase(3, x, y)) position_on_minimap = "blue base";
  1314. else if (checkWithinBase(4, x, y)) position_on_minimap = "purple base";
  1315. else if (checkWithinBase(5, x, y)) position_on_minimap = "green base";
  1316. else if (checkWithinBase(6, x, y)) position_on_minimap = "red base";
  1317. else position_on_minimap = "not in the base";
  1318. }
  1319. } else {
  1320. position_on_minimap = "Warning! not on minimap";
  1321. }
  1322. }
  1323. }
  1324.  
  1325. function checkWithinBase(baseIndex, x, y) {
  1326. return m_e_ctx_coords[baseIndex].startx < x &&
  1327. m_e_ctx_coords[baseIndex].starty < y &&
  1328. m_e_ctx_coords[baseIndex].endx > x &&
  1329. m_e_ctx_coords[baseIndex].endy > y;
  1330. }
  1331.  
  1332. //let's try drawing a line to the leader
  1333.  
  1334. function apply_vector_on_minimap() {
  1335. if (script_list.minimap_leader_v1) {
  1336. let x = window.m_arrow.xl;
  1337. let y = window.m_arrow.yl;
  1338. let thetaRadians = angle_l * (Math.PI / 180);
  1339. let r = m_e_ctx_coords[0].endx - m_e_ctx_coords[0].startx;
  1340. let x2 = x + r * Math.cos(thetaRadians);
  1341. let y2 = y + r * Math.sin(thetaRadians);
  1342. ctx.beginPath();
  1343. ctx.moveTo(x, y);
  1344. ctx.lineTo(x2, y2);
  1345. ctx.stroke();
  1346. } else if (script_list.minimap_leader_v2) {
  1347. let x = window.M_X;
  1348. let y = window.M_Y;
  1349. let thetaRadians = angle_l * (Math.PI / 180);
  1350. let r = m_e_ctx_coords[0].endx - m_e_ctx_coords[0].startx;
  1351. let x2 = x + r * Math.cos(thetaRadians);
  1352. let y2 = y + r * Math.sin(thetaRadians);
  1353. ctx.beginPath();
  1354. ctx.moveTo(x, y);
  1355. ctx.lineTo(x2, y2);
  1356. ctx.stroke();
  1357. }
  1358. }
  1359.  
  1360.  
  1361. //drawing the limit of the server (needs rework)
  1362. function draw_server_border(a, b) {
  1363. ctx.beginPath();
  1364. ctx.rect(canvas.width / 2 - (a / 2 * scalingFactor), canvas.height / 2 - (b / 2 * scalingFactor), a * scalingFactor, b * scalingFactor);
  1365. ctx.strokeStyle = "red";
  1366. ctx.stroke();
  1367. }
  1368.  
  1369. const circle_gradients = [
  1370. "#FF0000", // Red
  1371. "#FF4D00", // Orange Red
  1372. "#FF8000", // Orange
  1373. "#FFB300", // Dark Goldenrod
  1374. "#FFD700", // Gold
  1375. "#FFEA00", // Yellow
  1376. "#D6FF00", // Light Yellow Green
  1377. "#A3FF00", // Yellow Green
  1378. "#6CFF00", // Lime Green
  1379. "#00FF4C", // Medium Spring Green
  1380. "#00FF9D", // Turquoise
  1381. "#00D6FF", // Sky Blue
  1382. "#006CFF", // Blue
  1383. "#0000FF" // Dark Blue
  1384. ];
  1385.  
  1386. function draw_crx_events() {
  1387. //you need either leader arrow or moveTo/lineTo script from h3llside for this part
  1388. if (script_list.moveToLineTo_debug) {
  1389. for (let i = 0; i < window.y_and_x.length; i++) {
  1390. ctx_arc(window.y_and_x[i][0], window.y_and_x[i][1], 10, 0, 2 * Math.PI, false, circle_gradients[i]);
  1391. ctx_text("white", "DarkRed", 6, 1.5 + "em Ubuntu", i, window.y_and_x[i][0], window.y_and_x[i][1]);
  1392. }
  1393. } else if (script_list.minimap_leader_v1) {
  1394. //ctx_arc(window.l_arrow.xm, window.l_arrow.ym, 15, 0, 2 * Math.PI, false, window.l_arrow.color);
  1395. //ctx_arc(window.m_arrow.xm, window.m_arrow.ym, 1, 0, 2 * Math.PI, false, "yellow");
  1396. ctx_arc(window.l_arrow.xl, window.l_arrow.yl, 5, 0, 2 * Math.PI, false, window.l_arrow.color);
  1397. ctx_arc(window.m_arrow.xl, window.m_arrow.yl, 1, 0, 2 * Math.PI, false, "yellow");
  1398. }
  1399. }
  1400.  
  1401. //tank aim lines
  1402. let TurretRatios = [
  1403. {
  1404. name: "Destroyer",
  1405. ratio: 95 / 71.4,
  1406. color: "red"
  1407. },
  1408. {
  1409. name: "Anni",
  1410. ratio: 95 / 96.6,
  1411. color: "darkred"
  1412. },
  1413. {
  1414. name: "Fighter",
  1415. ratio: 80 / 42,
  1416. color: "orange"
  1417. },
  1418. {
  1419. name: "Booster",
  1420. ratio: 70 / 42,
  1421. color: "green"
  1422. },
  1423. {
  1424. name: "Tank",
  1425. ratio: 95 / 42,
  1426. color: "yellow"
  1427. },
  1428. {
  1429. name: "Sniper",
  1430. ratio: 110 / 42,
  1431. color: "yellow"
  1432. },
  1433. {
  1434. name: "Ranger",
  1435. ratio: 120 / 42,
  1436. color: "orange"
  1437. },
  1438. {
  1439. name: "Hunter",
  1440. ratio: 95 / 56.7,
  1441. color: "orange"
  1442. },
  1443. {
  1444. name: "Predator",
  1445. ratio: 80 / 71.4,
  1446. color: "darkorange"
  1447. },
  1448. {
  1449. name: "Mega Trapper",
  1450. ratio: 60 / 54.6,
  1451. color: "red"
  1452. },
  1453. {
  1454. name: "Trapper",
  1455. ratio: 60 / 42,
  1456. color: "orange"
  1457. },
  1458. {
  1459. name: "Gunner Trapper",
  1460. ratio: 95 / 26.6,
  1461. color: "yellow"
  1462. },
  1463. {
  1464. name: "Predator",
  1465. ratio: 95 / 84.8,
  1466. color: "red"
  1467. },
  1468. {
  1469. name: "Gunner(small)",
  1470. ratio: 65 / 25.2,
  1471. color: "lightgreen"
  1472. },
  1473. {
  1474. name: "Gunner(big)",
  1475. ratio: 85 / 25.2,
  1476. color: "green"
  1477. },
  1478. {
  1479. name: "Spread1",
  1480. ratio: 89 / 29.4,
  1481. color: "orange"
  1482. },
  1483. {
  1484. name: "Spread2",
  1485. ratio: 83 / 29.4,
  1486. color: "orange"
  1487. },
  1488. {
  1489. name: "Spread3",
  1490. ratio: 71 / 29.4,
  1491. color: "orange"
  1492. },
  1493. {
  1494. name: "Spread4",
  1495. ratio: 65 / 29.4,
  1496. color: "orange"
  1497. },
  1498. //{name: "bullet", ratio: 1, color: "pink"},
  1499. ];
  1500.  
  1501. function drawTheThing(x, y, r, index) {
  1502. if (toggleButtons.Visual['Toggle Aim Lines']) {
  1503. if (TurretRatios[index].name != "bullet") {
  1504. ctx.strokeStyle = TurretRatios[index].color;
  1505. ctx.lineWidth = 5;
  1506.  
  1507. let extendedR = 300 * scalingFactor;
  1508.  
  1509. // Reverse the angle to switch the direction
  1510. const reversedAngle = -angle;
  1511.  
  1512. // Calculate the end point of the line
  1513. const endX = x + extendedR * Math.cos(reversedAngle);
  1514. const endY = y + extendedR * Math.sin(reversedAngle);
  1515.  
  1516. // Draw the line
  1517. ctx.beginPath();
  1518. ctx.moveTo(x, y);
  1519. ctx.lineTo(endX, endY);
  1520. ctx.stroke();
  1521.  
  1522. // Draw text at the end of the line
  1523. ctx.font = "20px Arial";
  1524. ctx.fillStyle = TurretRatios[index].color;
  1525. ctx.strokeStyle = "black";
  1526. ctx.strokeText(TurretRatios[index].name, endX, endY);
  1527. ctx.fillText(TurretRatios[index].name, endX, endY);
  1528. ctx.beginPath();
  1529. } else {
  1530. ctx.strokeStyle = TurretRatios[index].color;
  1531. ctx.lineWidth = 5;
  1532.  
  1533. // Draw text at the end of the line
  1534. ctx.font = "15px Arial";
  1535. ctx.fillStyle = TurretRatios[index].color;
  1536. ctx.strokeStyle = "black";
  1537. let tankRadiusesTrans = [];
  1538. for (let i = 1; i <= 45; i++) {
  1539. let value = Math.abs((48.589 * (1.01 ** (i - 1))) * Math.abs(scalingFactor).toFixed(4)).toFixed(3);
  1540. tankRadiusesTrans.push(value);
  1541. }
  1542.  
  1543. let r_abs = Math.abs(r).toFixed(3);
  1544. if (r_abs < tankRadiusesTrans[0]) {
  1545. ctx.beginPath();
  1546. ctx.strokeStyle = TurretRatios[index].color;
  1547. ctx.arc(x, y - r / 2, r * 2, 0, 2 * Math.PI);
  1548. ctx.stroke();
  1549. ctx.beginPath();
  1550. } else {
  1551.  
  1552. // Find the closest value in the array
  1553. let closestValue = tankRadiusesTrans.reduce((prev, curr) => {
  1554. return (Math.abs(curr - r_abs) < Math.abs(prev - r_abs) ? curr : prev);
  1555. });
  1556.  
  1557. // Find the index of the closest value
  1558. let closestIndex = tankRadiusesTrans.indexOf(closestValue);
  1559.  
  1560. if (closestIndex !== -1) {
  1561. let r_name = `Level ${closestIndex + 1}`;
  1562. ctx.strokeText(r_name, x, y + 50 * scalingFactor);
  1563. ctx.fillText(r_name, x, y + 50 * scalingFactor);
  1564. ctx.beginPath();
  1565. } else {
  1566.  
  1567. let r_name = `radius: ${Math.abs(r).toFixed(4)} 1: ${tankRadiusesTrans[0]} 2: ${tankRadiusesTrans[1]} 3: ${tankRadiusesTrans[2]}`;
  1568. ctx.strokeText(r_name, x, y);
  1569. ctx.fillText(r_name, x, y);
  1570. ctx.beginPath();
  1571. }
  1572. /*
  1573. ctx.strokeText(TurretRatios[index].name, x, y);
  1574. ctx.fillText(TurretRatios[index].name, x, y);
  1575. */
  1576. }
  1577. }
  1578. }
  1579. }
  1580.  
  1581. var angle, a, b, width;
  1582. let perm_cont = [];
  1583.  
  1584. CanvasRenderingContext2D.prototype.setTransform = new Proxy(CanvasRenderingContext2D.prototype.setTransform, {
  1585. apply(target, thisArgs, args) {
  1586. // Check if the ratio matches the specified conditions
  1587. for (let i = 0; i < TurretRatios.length; i++) {
  1588. if (Math.abs(args[0] / args[3]).toFixed(3) == (TurretRatios[i].ratio).toFixed(3)) {
  1589. if (TurretRatios[i].name === "bullet") {
  1590. if (args[0] != 1 && args[0] > 10 && args[0] < 100 && args[4] > 1 && args[5] > 1 && args[4] != args[5] &&
  1591. thisArgs.globalAlpha != 0.10000000149011612 && thisArgs.globalAlpha != 0.3499999940395355) {
  1592. if (!perm_cont.includes(thisArgs)) {
  1593. perm_cont.push(thisArgs);
  1594. //console.log(perm_cont);
  1595. }
  1596. angle = Math.atan2(args[2], args[3]) || 0;
  1597. width = Math.hypot(args[3], args[2]);
  1598. a = args[4] - Math.cos(angle + Math.PI / 2) * width / 2;
  1599. b = args[5] + Math.sin(angle + Math.PI / 2) * width / 2;
  1600. //console.log(b);
  1601. if (a > 0 && b > 0 && thisArgs.fillStyle != "#1B1B1B") { //OUTLINE COLOR
  1602. drawTheThing(a, b, Math.hypot(args[3], args[2]), i);
  1603. }
  1604. }
  1605. } else {
  1606. angle = Math.atan2(args[2], args[3]) || 0;
  1607. width = Math.hypot(args[3], args[2]);
  1608. a = args[4] - Math.cos(angle + Math.PI / 2) * width / 2;
  1609. b = args[5] + Math.sin(angle + Math.PI / 2) * width / 2;
  1610. drawTheThing(a, b, Math.hypot(args[3], args[2]), i);
  1611. }
  1612. }
  1613. }
  1614. return Reflect.apply(target, thisArgs, args);
  1615. }
  1616. });
  1617.  
  1618. setTimeout(() => {
  1619. let gui = () => {
  1620. if (state === "in game") {
  1621. if (toggleButtons.Visual['Toggle Minimap']) {
  1622. draw_minimap();
  1623. }
  1624. if (script_list.minimap_leader_v1 || script_list.minimap_leader_v2) {
  1625. if (toggleButtons.Addons['Toggle Leader Angle']) {
  1626. if (!script_list.minimap_leader_v1 && !script_list.minimap_leader_v2) {
  1627. input.inGameNotification("missing Leader & Minimap Arrow or Leader & Minimap Arrow(Mi300)");
  1628. }
  1629. if (!toggleButtons.Visual['Toggle Minimap']) {
  1630. input.inGameNotification("Enabled Minimap for it to work properly. To turn it off, go to Visual -> Minimap");
  1631. toggleButtons.Visual['Toggle Minimap'] = true;
  1632. } else {
  1633. calc_leader();
  1634. apply_vector_on_minimap();
  1635. }
  1636. }
  1637. }
  1638. if (script_list.set_transform_debug) {
  1639. ctx_arc(window.crx_container[2], window.crx_container[3], 50, 0, 2 * Math.PI, false, "yellow");
  1640. }
  1641. if (toggleButtons.Debug['Toggle Text']) {
  1642. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "canvas Lvl:" + currentLevel, canvas.width / 20 + 10, text_startingY + (textAdd * 0));
  1643. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "canvas tank: " + tanky, canvas.width / 20 + 10, text_startingY + (textAdd * 1));
  1644. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "radius: " + ripsaw_radius, canvas.width / 20 + 10, text_startingY + (textAdd * 2));
  1645. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "scaling Factor: " + scalingFactor, canvas.width / 20 + 10, text_startingY + (textAdd * 3));
  1646. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "diep Units: " + diepUnits, canvas.width / 20 + 10, text_startingY + (textAdd * 4));
  1647. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "Fov: " + FOV, canvas.width / 20 + 10, text_startingY + (textAdd * 5));
  1648. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "current Tick: " + currentTick, canvas.width / 20 + 10, text_startingY + (textAdd * 6));
  1649. ctx_text("white", "DarkRed", 3, 1 + "em Ubuntu", "vector: " + Math.floor(vector_l[0]) + ", " + Math.floor(vector_l[1]) + "angle: " + Math.floor(angle_l), canvas.width / 20 + 10, text_startingY + (textAdd * 7));
  1650. //ctx_text("white", "DarkRed", 6, 1.5 + "em Ubuntu", "realX: " + uwuX + "realY: " + uwuY + "newX: " + uwuX*windowScaling() + "newY: " + uwuY*windowScaling(), uwuX*2, uwuY*2);
  1651.  
  1652. //points at mouse
  1653. ctx_arc(uwuX * two, uwuY * two, 5, 0, 2 * Math.PI, false, "purple");
  1654. /*
  1655. circle_in_diepunits(uwuX*2/scalingFactor, uwuY*2/scalingFactor, 35, "pink");
  1656. circle_in_diepunits(uwuX*2/scalingFactor, uwuY*2/scalingFactor, 55, "yellow");
  1657. circle_in_diepunits(uwuX*2/scalingFactor, uwuY*2/scalingFactor, 75, "purple");
  1658. circle_in_diepunits(uwuX*2/scalingFactor, uwuY*2/scalingFactor, 200, "blue");
  1659. */
  1660.  
  1661. //coords at mouse
  1662. ctx_text("white", "DarkRed", 6, 1.5 + "em Ubuntu", "realX: " + uwuX * two + "realY: " + uwuY * two, uwuX * two, uwuY * two);
  1663. }
  1664.  
  1665. if (currentLevel != null && tanky != null) {
  1666. if (toggleButtons.Debug['Toggle Middle Circle']) {
  1667. ctx.beginPath();
  1668. ctx.moveTo(canvas.width / 2 + offsetX, canvas.height / 2 + offsetY);
  1669. ctx.lineTo(uwuX * two, uwuY * two);
  1670. ctx.stroke();
  1671. ctx_arc(canvas.width / 2 + offsetX, canvas.height / 2 + offsetY, ripsaw_radius, 0, 2 * Math.PI, false, "darkblue");
  1672. ctx_arc(canvas.width / 2 + offsetX, canvas.height / 2 + offsetY, ripsaw_radius * 0.9, 0, 2 * Math.PI, false, "lightblue");
  1673. }
  1674. if(toggleButtons.Debug['Toggle Arrow pos']){
  1675. window.arrowv2_debug = true;
  1676. }else{
  1677. window.arrowv2_debug = false;
  1678. }
  1679. if (toggleButtons.Debug['Toggle Upgrades']) {
  1680. draw_upgrade_grid();
  1681. }
  1682. //draw_server_border(4000, 2250);
  1683. draw_crx_events();
  1684. if (toggleButtons.Visual['Toggle Bullet Distance']) {
  1685. draw_cirle_radius_for_tank();
  1686. }
  1687. };
  1688. }
  1689. window.requestAnimationFrame(gui);
  1690. }
  1691. gui();
  1692. setTimeout(() => {
  1693. gui();
  1694. }, 5000);
  1695. }, 1000);
  1696.  
  1697. //game ticks finder
  1698. let clearRect_count = 0;
  1699. let fps;
  1700. CanvasRenderingContext2D.prototype.fillText = new Proxy(CanvasRenderingContext2D.prototype.fillText, {
  1701. apply(fillRect, ctx, [text, x, y, ...blah]) {
  1702. if (text.endsWith('FPS')) {
  1703. fps = text.split(' ')[0];
  1704. }
  1705. fillRect.call(ctx, text, x, y, ...blah);
  1706. }
  1707. });
  1708.  
  1709. // Tick tracking
  1710. let currentTick = 0;
  1711. const tickQueue = [];
  1712. const everyTickFunctions = [];
  1713.  
  1714. function runEveryTick(callback) {
  1715. everyTickFunctions.push(callback);
  1716. }
  1717.  
  1718. CanvasRenderingContext2D.prototype.clearRect = new Proxy(CanvasRenderingContext2D.prototype.clearRect, {
  1719. apply(target, thisArg, argumentsList) {
  1720. clearRect_count += 1;
  1721. currentTick = Math.floor(clearRect_count / 6);
  1722. processTickQueue();
  1723. everyTickFunctions.forEach(func => func(currentTick));
  1724. return target.apply(thisArg, argumentsList);
  1725. }
  1726. });
  1727.  
  1728. function scheduleAfterTicks(callback, ticksToWait) {
  1729. const executionTick = currentTick + ticksToWait;
  1730. tickQueue.push({
  1731. callback,
  1732. executionTick
  1733. });
  1734. }
  1735.  
  1736. function processTickQueue() {
  1737. while (tickQueue.length > 0 && tickQueue[0].executionTick <= currentTick) {
  1738. const item = tickQueue.shift();
  1739. item.callback();
  1740. }
  1741. }
  1742.  
  1743. // Function to run code for a specified number of ticks
  1744. function runForTicks(callback, totalTicks) {
  1745. const startingTick = currentTick;
  1746. let ticksPassed = 0;
  1747.  
  1748. function tickHandler() {
  1749. if (ticksPassed < totalTicks) {
  1750. callback(ticksPassed, currentTick);
  1751. ticksPassed++;
  1752. scheduleAfterTicks(tickHandler, 1);
  1753. }
  1754. }
  1755.  
  1756. tickHandler(); // Start the process
  1757. }
  1758.  
  1759. // Example usage:
  1760. function test() {
  1761. console.log("Starting test at tick:", currentTick);
  1762.  
  1763. scheduleAfterTicks(() => {
  1764. console.log("150 ticks have passed, current tick:", currentTick);
  1765. // Add your code here
  1766. }, 150);
  1767. }
  1768.  
  1769. function testLoop() {
  1770. console.log("Starting testLoop at tick:", currentTick);
  1771. runForTicks((ticksPassed, currentTick) => {
  1772. console.log(`Tick passed: ${ticksPassed}, Current tick: ${currentTick}`);
  1773. // Add any other code you want to run each tick
  1774. }, 50);
  1775. }
  1776.  
  1777. //cooldowns (unfinished)
  1778. let c_cd = "red";
  1779. let c_r = "green";
  1780. const cooldowns = [
  1781. {
  1782. Tank: "Destroyer",
  1783. cooldown0: 109,
  1784. cooldown1: 94,
  1785. cooldown2: 81,
  1786. cooldown3: 86
  1787. },
  1788. ]
  1789.  
  1790. //detect which slot was clicked
  1791. document.addEventListener('mousedown', checkPos)
  1792.  
  1793. function checkPos(e) {
  1794. console.log(currentTick);
  1795. console.log(boxes[selected_box]);
  1796. }
  1797.  
  1798.  
  1799. //warns you about annis, destroyers
  1800. /*
  1801. function drawTheThing(x,y,r) {
  1802. if(script_boolean){
  1803. let a = ctx.fillStyle;
  1804. ctx.fillStyle = "#FF000044";
  1805. ctx.beginPath();
  1806. ctx.arc(x,y,4*r,0,2*Math.PI);
  1807. ctx.fill();
  1808. ctx.fillStyle = "#FF000066";
  1809. ctx.beginPath();
  1810. ctx.arc(x,y,2*r,0,2*Math.PI);
  1811. ctx.fill();
  1812. ctx.beginPath();
  1813. }
  1814. }
  1815. var angle,a,b,width;
  1816. CanvasRenderingContext2D.prototype.setTransform = new Proxy(CanvasRenderingContext2D.prototype.setTransform, {
  1817. apply(target, thisArgs, args) {
  1818. //console.log(thisArgs)
  1819. if (Math.abs(args[0]/args[3]).toFixed(3) == (95/71.4).toFixed(3) || Math.abs(args[0]/args[3]).toFixed(3) == (95/96.6).toFixed(3)) {
  1820. angle = Math.atan2(args[2],args[3]) || 0;
  1821. width = Math.hypot(args[3], args[2]);
  1822. a = args[4]-Math.cos(angle+Math.PI/2)*width/2;
  1823. b = args[5]+Math.sin(angle+Math.PI/2)*width/2;
  1824. drawTheThing(a,b, Math.hypot(args[3],args[2]));
  1825. }
  1826. return Reflect.apply(target, thisArgs, args);
  1827. }
  1828. });
  1829. */
  1830.  
  1831. //physics for movement (UNFINISHED)
  1832. /*
  1833. //movement speed ingame stat
  1834. let m_s = [0, 1, 2, 3, 4, 5, 6, 7];
  1835.  
  1836. function accelarate(A_o){
  1837. //Accelaration
  1838. let sum = 0;
  1839. runForTicks((ticksPassed, currentTick) => {
  1840. console.log("sum is being calculated...");
  1841. sum += A_o * Math.pow(0.9, ticksPassed - 1);
  1842. offsetX = Math.floor(sum * scalingFactor);
  1843. console.log(offsetX);
  1844. }, 50);
  1845. //decelerate(sum);
  1846. }
  1847.  
  1848. function decelerate(sum){
  1849. //deceleration
  1850. let res = 0;
  1851. runForTicks((ticksPassed, currentTick) => {
  1852. console.log("res is being calculated...");
  1853. res = sum * Math.pow(0.9, ticksPassed);
  1854. offsetX = Math.floor(res * scalingFactor);
  1855. console.log(offsetX);
  1856. }, 50);
  1857. }
  1858. function calculate_speed(movement_speed_stat){
  1859. console.log("calculate_speed function called");
  1860. //use Accelaration for first 50 ticks, then deceleration until ticks hit 100, then stop moving
  1861.  
  1862. //calculating base value, we'll need this later
  1863. let a = (1.07**movement_speed_stat);
  1864. let b = (1.015**(currentLevel - 1));
  1865. let A_o = 2.55*(a/b);
  1866. accelarate(A_o);
  1867. }
  1868. */
  1869.  
  1870. //handle Key presses
  1871. let key_storage = [];
  1872.  
  1873. document.onkeydown = function(e) {
  1874. if (!key_storage.includes(e.key)) {
  1875. key_storage.push(e.key);
  1876. }
  1877. console.log(key_storage);
  1878. analyse_keys();
  1879. }
  1880.  
  1881. document.onkeyup = function(e) {
  1882. if (key_storage.includes(e.key)) {
  1883. key_storage.splice(key_storage.indexOf(e.key), 1);
  1884. }
  1885. console.log(key_storage);
  1886. analyse_keys();
  1887. }
  1888.  
  1889. function analyse_keys() {
  1890. if (key_storage.includes("j")) { //J
  1891. change_visibility();
  1892. } else if (key_storage.includes("e")) { //E
  1893. if (ingamescreen.classList.contains("screen") && ingamescreen.classList.contains("active")) {
  1894. f_s("fire");
  1895. } else {
  1896. auto_fire = false;
  1897. }
  1898. console.log(auto_fire);
  1899. } else if (key_storage.includes("c")) {
  1900. console.log(auto_spin);
  1901. if (ingamescreen.classList.contains("screen") && ingamescreen.classList.contains("active")) {
  1902. f_s("spin");
  1903. } else {
  1904. auto_spin = false;
  1905. }
  1906. console.log(auto_spin);
  1907. }
  1908. }
  1909. // Handle key presses for moving the center (UNFINISHED)
  1910.  
  1911. /*
  1912. function return_to_center(XorY, posOrNeg){
  1913. console.log("function called with: " + XorY + posOrNeg);
  1914. if(XorY === "x"){
  1915. if(posOrNeg === "pos"){
  1916. while(offsetX < 0){
  1917. offsetX += 0.5*scalingFactor;
  1918. }
  1919. }else if(posOrNeg === "neg"){
  1920. while(offsetX > 0){
  1921. offsetX -= 0.5*scalingFactor;
  1922. }
  1923. }else{
  1924. console.log("invalid posOrNeg at return_to_center();")
  1925. }
  1926. }else if(XorY === "y"){
  1927. if(posOrNeg === "pos"){
  1928. while(offsetY < 0){
  1929. offsetY += 0.5*scalingFactor;
  1930. }
  1931. }else if(posOrNeg === "neg"){
  1932. while(offsetY > 0){
  1933. offsetY -= 0.5*scalingFactor;
  1934. }
  1935. }else{
  1936. console.log("invalid posOrNeg at return_to_center();")
  1937. }
  1938. }else{
  1939. console.log("invalid XorY at return_to_center();");
  1940. }
  1941. }
  1942.  
  1943. document.onkeydown = function(e) {
  1944. switch (e.keyCode) {
  1945. case 87: // 'W' key
  1946. console.log("W");
  1947. if(offsetY >= -87.5*scalingFactor){
  1948. offsetY -= 12.5*scalingFactor;
  1949. }
  1950. break
  1951. case 83: // 'S' key
  1952. console.log("S");
  1953. if(offsetY <= 87.5*scalingFactor){
  1954. offsetY += 12.5*scalingFactor;
  1955. }
  1956. break;
  1957. case 68: // 'D' key
  1958. console.log("D");
  1959. if(offsetX <= 87.5*scalingFactor){
  1960. offsetX += 12.5*scalingFactor;
  1961. }
  1962. break
  1963. case 65: // 'A' key
  1964. console.log("A");
  1965. if(offsetX >= -87.5*scalingFactor){
  1966. offsetX -= 12.5*scalingFactor;
  1967. }
  1968. break
  1969. }
  1970. }
  1971.  
  1972. document.onkeyup = function(e) {
  1973. switch (e.keyCode) {
  1974. case 87: // 'W' key
  1975. console.log("W unpressed");
  1976. return_to_center("y", "pos");
  1977. break
  1978. case 83: // 'S' key
  1979. console.log("S unpressed");
  1980. return_to_center("y", "neg");
  1981. break;
  1982. case 68: // 'D' key
  1983. console.log("D unpressed");
  1984. return_to_center("x", "neg");
  1985. break
  1986. case 65:
  1987. console.log("A unpressed");
  1988. return_to_center("x", "pos");
  1989. }
  1990. }
  1991. */