Heart Clicker Cheat Panel

Adds a modern cheat panel to the Heart Clicker game with draggable functionality and additional features

  1. // ==UserScript==
  2. // @name Heart Clicker Cheat Panel
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Adds a modern cheat panel to the Heart Clicker game with draggable functionality and additional features
  6. // @match https://heart-io.github.io/Heart/
  7. // @grant none
  8. // @run-at document-end
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Styles for the cheat panel and buttons
  15. const style = document.createElement('style');
  16. style.innerHTML = `
  17. #cheat-panel {
  18. position: absolute;
  19. top: 20px;
  20. left: 20px;
  21. background: #fff;
  22. border: 1px solid #333;
  23. padding: 15px;
  24. border-radius: 10px;
  25. width: 350px;
  26. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  27. z-index: 1000;
  28. }
  29. #cheat-panel h2 {
  30. margin: 0;
  31. font-size: 1.2em;
  32. color: #333;
  33. }
  34. .item {
  35. margin-bottom: 15px;
  36. }
  37. .item label {
  38. display: block;
  39. margin-bottom: 5px;
  40. font-weight: bold;
  41. }
  42. .item input, .item select, .item button {
  43. width: 100%;
  44. padding: 10px;
  45. margin-top: 5px;
  46. font-size: 1em;
  47. }
  48. #close-cheat-panel, #reopen-cheat-panel {
  49. background: #ff4d4d;
  50. color: #fff;
  51. border: none;
  52. border-radius: 5px;
  53. padding: 10px;
  54. cursor: pointer;
  55. font-size: 1em;
  56. }
  57. #reopen-cheat-panel {
  58. position: fixed;
  59. bottom: 20px;
  60. right: 20px;
  61. background: #4CAF50;
  62. }
  63. #warning-panel {
  64. position: fixed;
  65. top: 50%;
  66. left: 50%;
  67. transform: translate(-50%, -50%);
  68. background: rgba(0, 0, 0, 0.8);
  69. color: #fff;
  70. padding: 20px;
  71. border-radius: 10px;
  72. display: none;
  73. z-index: 1001;
  74. }
  75. #warning-panel button {
  76. margin: 5px;
  77. padding: 10px;
  78. font-size: 1em;
  79. }
  80. .bounce {
  81. animation: bounce 2s infinite;
  82. }
  83. @keyframes bounce {
  84. 0%, 20%, 50%, 80%, 100% {
  85. transform: translateY(0);
  86. }
  87. 40% {
  88. transform: translateY(-30px);
  89. }
  90. 60% {
  91. transform: translateY(-15px);
  92. }
  93. }
  94. `;
  95. document.head.appendChild(style);
  96.  
  97. // Create cheat panel HTML
  98. const panelHtml = `
  99. <div id="cheat-panel">
  100. <h2>Cheat Panel</h2>
  101. <div class="item">
  102. <label for="set-hearts">Set Hearts:</label>
  103. <input type="number" id="set-hearts" placeholder="Enter hearts" />
  104. <button id="apply-hearts">Apply</button>
  105. </div>
  106. <div class="item">
  107. <label for="heart-selection">Change Heart Character:</label>
  108. <select id="heart-selection">
  109. <!-- Dynamically filled with heart options -->
  110. </select>
  111. <button id="change-heart">Change</button>
  112. </div>
  113. <div class="item">
  114. <button id="unlock-admin">Unlock Admin Character</button>
  115. </div>
  116. <div class="item">
  117. <button id="realistic-mode">Realistic Mode</button>
  118. </div>
  119. <button id="close-cheat-panel">X</button>
  120. </div>
  121. <div id="warning-panel">
  122. <p>This might disturb you. Are you sure you want it realistic?</p>
  123. <button id="confirm-realistic">Yes</button>
  124. <button id="cancel-realistic">No</button>
  125. </div>
  126. <button id="reopen-cheat-panel">Show Cheat Panel</button>
  127. `;
  128. document.body.insertAdjacentHTML('beforeend', panelHtml);
  129.  
  130. // Initialize heart characters
  131. const heartCharacters = [
  132. { symbol: '💙', name: 'Blue Heart', cost: 100 },
  133. { symbol: '💚', name: 'Green Heart', cost: 150 },
  134. { symbol: '💛', name: 'Yellow Heart', cost: 200 },
  135. { symbol: '💜', name: 'Purple Heart', cost: 250 },
  136. { symbol: '🤍', name: 'White Heart', cost: 300 },
  137. { symbol: '🖤', name: 'Black Heart', cost: 350 },
  138. { symbol: '💖', name: 'Sparkling Heart', cost: 400 },
  139. { symbol: '💗', name: 'Growing Heart', cost: 450 },
  140. { symbol: '💝', name: 'Heart with Ribbon', cost: 500 },
  141. { symbol: '💘', name: 'Heart with Arrow', cost: 550 },
  142. { symbol: '❤️‍🔥', name: 'Heart on Fire', cost: 600 },
  143. { symbol: '💞', name: 'Revolving Hearts', cost: 650 },
  144. { symbol: '💕', name: 'Two Hearts', cost: 700 },
  145. { symbol: '💟', name: 'Heart Decoration', cost: 750 },
  146. { symbol: '❣️', name: 'Heavy Heart Exclamation', cost: 800 },
  147. { symbol: '❤️‍🩹', name: 'Heart with Bandage', cost: 850 }
  148. ];
  149.  
  150. // Populate heart selection
  151. const heartSelection = document.getElementById('heart-selection');
  152. heartCharacters.forEach(heart => {
  153. const option = document.createElement('option');
  154. option.value = heart.symbol;
  155. option.text = heart.name;
  156. heartSelection.add(option);
  157. });
  158.  
  159. let heartCount = parseInt(localStorage.getItem('heartCount')) || 0;
  160. let currentHeart = localStorage.getItem('currentHeart') || '❤️';
  161. let realisticMode = false;
  162.  
  163. function updateHeartCount() {
  164. const clicker = document.getElementById('clicker');
  165. if (clicker) {
  166. clicker.innerText = heartCount;
  167. }
  168. }
  169.  
  170. function saveGameState() {
  171. localStorage.setItem('heartCount', heartCount);
  172. localStorage.setItem('currentHeart', currentHeart);
  173. }
  174.  
  175. document.getElementById('apply-hearts').addEventListener('click', () => {
  176. const hearts = parseInt(document.getElementById('set-hearts').value);
  177. if (!isNaN(hearts) && hearts >= 0) {
  178. heartCount = hearts;
  179. updateHeartCount();
  180. saveGameState();
  181. } else {
  182. alert('Invalid heart count!');
  183. }
  184. });
  185.  
  186. document.getElementById('change-heart').addEventListener('click', () => {
  187. const selectedHeart = document.getElementById('heart-selection').value;
  188. currentHeart = selectedHeart;
  189. const clicker = document.getElementById('clicker');
  190. if (clicker) {
  191. clicker.innerHTML = `<img src="${currentHeart}" style="width: 50px; height: 50px;">`;
  192. updateHeartCount();
  193. saveGameState();
  194. }
  195. });
  196.  
  197. document.getElementById('unlock-admin').addEventListener('click', () => {
  198. currentHeart = 'https://i.ibb.co/txJkfHz/Untitled181-20240817233140.png'; // Admin Heart
  199. heartCount = 10000;
  200. const clicker = document.getElementById('clicker');
  201. if (clicker) {
  202. clicker.innerHTML = `<img src="${currentHeart}" style="width: 50px; height: 50px;">`;
  203. updateHeartCount();
  204. saveGameState();
  205. }
  206. });
  207.  
  208. document.getElementById('realistic-mode').addEventListener('click', () => {
  209. document.getElementById('warning-panel').style.display = 'block';
  210. });
  211.  
  212. document.getElementById('confirm-realistic').addEventListener('click', () => {
  213. realisticMode = true;
  214. currentHeart = 'https://i.ibb.co/xSVZBZq/IMG-7404.png'; // Realistic Heart
  215. const clicker = document.getElementById('clicker');
  216. if (clicker) {
  217. clicker.innerHTML = `<img src="${currentHeart}" style="width: 50px; height: 50px;">`;
  218. updateHeartCount();
  219. startRealisticMode();
  220. saveGameState();
  221. document.getElementById('warning-panel').style.display = 'none';
  222. }
  223. });
  224.  
  225. document.getElementById('cancel-realistic').addEventListener('click', () => {
  226. document.getElementById('warning-panel').style.display = 'none';
  227. });
  228.  
  229. function startRealisticMode() {
  230. setInterval(() => {
  231. if (realisticMode) {
  232. const clicker = document.getElementById('clicker');
  233. if (clicker) {
  234. clicker.classList.toggle('bounce');
  235. playHeartPumpSound();
  236. }
  237. }
  238. }, 2000);
  239. }
  240.  
  241. function playHeartPumpSound() {
  242. const audio = new Audio('https://www.soundjay.com/button/sounds/button-16.mp3'); // Replace with heart pump sound URL
  243. audio.play();
  244. }
  245.  
  246. // Draggable functionality
  247. function makeDraggable(element) {
  248. let offsetX, offsetY, isDragging = false;
  249.  
  250. element.addEventListener('mousedown', (e) => {
  251. isDragging = true;
  252. offsetX = e.clientX - parseInt(window.getComputedStyle(element).left);
  253. offsetY = e.clientY - parseInt(window.getComputedStyle(element).top);
  254. });
  255.  
  256. document.addEventListener('mousemove', (e) => {
  257. if (isDragging) {
  258. element.style.left = `${e.clientX - offsetX}px`;
  259. element.style.top = `${e.clientY - offsetY}px`;
  260. }
  261. });
  262.  
  263. document.addEventListener('mouseup', () => {
  264. isDragging = false;
  265. });
  266. }
  267.  
  268. makeDraggable(document.getElementById('cheat-panel'));
  269.  
  270. document.getElementById('close-cheat-panel').addEventListener('click', () => {
  271. document.getElementById('cheat-panel').style.display = 'none';
  272. document.getElementById('reopen-cheat-panel').style.display = 'block';
  273. });
  274.  
  275. document.getElementById('reopen-cheat-panel').addEventListener('click', () => {
  276. document.getElementById('cheat-panel').style.display = 'block';
  277. document.getElementById('reopen-cheat-panel').style.display = 'none';
  278. });
  279.  
  280. // Initialize
  281. updateHeartCount();
  282. })();