Dice Color RNG Predictor

Persistent RNG dice color predictor with dark purple UI

  1. // ==UserScript==
  2. // @name Dice Color RNG Predictor
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description Persistent RNG dice color predictor with dark purple UI
  6. // @author theo
  7. // @match https://www.online-dice.com/roll-color-dice/3/*
  8. // @include https://www.online-dice.com/*
  9. // @grant GM_addStyle
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @description join our discord https://discord.gg/MuUCebSYSD
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // Check if we've already injected the UI
  19. if (document.getElementById('dicePredictorContainer')) {
  20. return;
  21. }
  22.  
  23. // Dark purple UI styles
  24. const css = `
  25. #dicePredictorContainer {
  26. position: fixed;
  27. top: 20px;
  28. right: 20px;
  29. width: 320px;
  30. background-color: #2a0a3a;
  31. border: 2px solid #8a2be2;
  32. border-radius: 10px;
  33. padding: 15px;
  34. font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  35. color: #e6d5ff;
  36. z-index: 9999;
  37. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  38. }
  39.  
  40. #dicePredictorTitle {
  41. font-size: 18px;
  42. font-weight: bold;
  43. margin-bottom: 15px;
  44. text-align: center;
  45. color: #b388ff;
  46. border-bottom: 1px solid #8a2be2;
  47. padding-bottom: 8px;
  48. position: relative;
  49. }
  50.  
  51. .discord-icon {
  52. position: absolute;
  53. right: 0;
  54. top: 0;
  55. width: 24px;
  56. height: 24px;
  57. cursor: pointer;
  58. transition: transform 0.2s;
  59. }
  60.  
  61. .discord-icon:hover {
  62. transform: scale(1.1);
  63. }
  64.  
  65. /* [Rest of your existing CSS remains exactly the same] */
  66. `;
  67.  
  68. // Add styles to head
  69. GM_addStyle(css);
  70.  
  71. // Color definitions
  72. const COLORS = {
  73. 'red': '#ff5252',
  74. 'orange': '#ff9800',
  75. 'yellow': '#ffeb3b',
  76. 'green': '#0f9d58',
  77. 'blue': '#4285f4',
  78. 'purple': '#9c27b0'
  79. };
  80.  
  81. // Color names for display
  82. const COLOR_NAMES = {
  83. 'red': 'Red',
  84. 'orange': 'Orange',
  85. 'yellow': 'Yellow',
  86. 'green': 'Green',
  87. 'blue': 'Blue',
  88. 'purple': 'Purple'
  89. };
  90.  
  91. // Create container for our predictor
  92. function createUI() {
  93. const container = document.createElement('div');
  94. container.id = 'dicePredictorContainer';
  95. container.innerHTML = `
  96. <div id="dicePredictorTitle">
  97. Dice Color RNG Predictor
  98. <svg class="discord-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36">
  99. <path fill="#5865F2" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
  100. </svg>
  101. </div>
  102.  
  103. <div class="inputSection">
  104. <label class="inputLabel" for="dice1Color">First Dice Color:</label>
  105. <select class="colorSelect" id="dice1Color">
  106. ${Object.entries(COLORS).map(([value, color]) =>
  107. `<option value="${value}">${COLOR_NAMES[value]}</option>`
  108. ).join('')}
  109. </select>
  110.  
  111. <label class="inputLabel" for="dice2Color">Second Dice Color:</label>
  112. <select class="colorSelect" id="dice2Color">
  113. ${Object.entries(COLORS).map(([value, color]) =>
  114. `<option value="${value}">${COLOR_NAMES[value]}</option>`
  115. ).join('')}
  116. </select>
  117.  
  118. <label class="inputLabel" for="dice3Color">Third Dice Color:</label>
  119. <select class="colorSelect" id="dice3Color">
  120. ${Object.entries(COLORS).map(([value, color]) =>
  121. `<option value="${value}">${COLOR_NAMES[value]}</option>`
  122. ).join('')}
  123. </select>
  124.  
  125. <button id="predictButton">Generate Random Prediction</button>
  126. </div>
  127.  
  128. <div id="predictionResult">
  129. <div id="predictionText">Random prediction will appear here</div>
  130. <div id="nextColorPrediction">?</div>
  131. </div>
  132.  
  133. <div id="historyTitle">Prediction History</div>
  134. <div id="historyList"></div>
  135. `;
  136.  
  137. // Add to body
  138. document.body.appendChild(container);
  139.  
  140. // Add click handler for Discord icon
  141. document.querySelector('.discord-icon').addEventListener('click', () => {
  142. window.open('https://discord.gg/MuUCebSYSD', '_blank');
  143. });
  144.  
  145. // Load saved state
  146. loadState();
  147.  
  148. // Set up predict button
  149. document.getElementById('predictButton').addEventListener('click', makeRandomPrediction);
  150. }
  151.  
  152. // [Rest of your existing functions remain exactly the same]
  153. // Save current state
  154. function saveState() {
  155. const state = {
  156. dice1: document.getElementById('dice1Color').value,
  157. dice2: document.getElementById('dice2Color').value,
  158. dice3: document.getElementById('dice3Color').value,
  159. history: predictionHistory
  160. };
  161. GM_setValue('dicePredictorState', JSON.stringify(state));
  162. }
  163.  
  164. // Load saved state
  165. function loadState() {
  166. const savedState = GM_getValue('dicePredictorState');
  167. if (savedState) {
  168. try {
  169. const state = JSON.parse(savedState);
  170.  
  171. // Restore dropdown values
  172. document.getElementById('dice1Color').value = state.dice1;
  173. document.getElementById('dice2Color').value = state.dice2;
  174. document.getElementById('dice3Color').value = state.dice3;
  175.  
  176. // Restore history
  177. predictionHistory = state.history || [];
  178. updateHistoryDisplay();
  179. } catch (e) {
  180. console.error('Failed to load state:', e);
  181. }
  182. }
  183. }
  184.  
  185. // Track history of predictions
  186. let predictionHistory = [];
  187. const MAX_HISTORY = 15;
  188.  
  189. // Pure RNG prediction
  190. function makeRandomPrediction() {
  191. const color1 = document.getElementById('dice1Color').value;
  192. const color2 = document.getElementById('dice2Color').value;
  193. const color3 = document.getElementById('dice3Color').value;
  194.  
  195. const currentColors = [color1, color2, color3];
  196. const allColors = Object.keys(COLORS);
  197. const prediction = allColors[Math.floor(Math.random() * allColors.length)];
  198.  
  199. // Update prediction display
  200. const predictionElement = document.getElementById('nextColorPrediction');
  201. predictionElement.textContent = COLOR_NAMES[prediction];
  202. predictionElement.style.backgroundColor = COLORS[prediction];
  203. predictionElement.style.color = (prediction === 'yellow') ? '#000' : '#fff';
  204.  
  205. // Add to history
  206. const time = new Date().toLocaleTimeString();
  207. const historyEntry = {
  208. time: time,
  209. colors: currentColors,
  210. prediction: prediction
  211. };
  212.  
  213. predictionHistory.unshift(historyEntry);
  214. if (predictionHistory.length > MAX_HISTORY) {
  215. predictionHistory.pop();
  216. }
  217.  
  218. updateHistoryDisplay();
  219. saveState();
  220. }
  221.  
  222. // Update history display
  223. function updateHistoryDisplay() {
  224. const historyList = document.getElementById('historyList');
  225. if (!historyList) return;
  226.  
  227. historyList.innerHTML = '';
  228.  
  229. if (predictionHistory.length === 0) {
  230. historyList.innerHTML = '<div style="text-align: center; color: #ba55d3; padding: 10px;">No predictions yet</div>';
  231. return;
  232. }
  233.  
  234. predictionHistory.forEach((entry, index) => {
  235. const historyItem = document.createElement('div');
  236. historyItem.className = 'historyItem';
  237.  
  238. historyItem.innerHTML = `
  239. <div class="historyTime">${index + 1}. ${entry.time}</div>
  240. <div class="historyColors">
  241. ${entry.colors.map(color => `
  242. <div class="colorBox" style="background-color: ${COLORS[color]}; color: ${(color === 'yellow') ? '#000' : '#fff'}">
  243. ${COLOR_NAMES[color]}
  244. </div>
  245. `).join('')}
  246. </div>
  247. <div class="historyPrediction">
  248. <span>Prediction:</span>
  249. <div class="colorBox" style="background-color: ${COLORS[entry.prediction]}; color: ${(entry.prediction === 'yellow') ? '#000' : '#fff'}">
  250. ${COLOR_NAMES[entry.prediction]}
  251. </div>
  252. </div>
  253. `;
  254.  
  255. historyList.appendChild(historyItem);
  256. });
  257. }
  258.  
  259. // Initialize with random selections
  260. function randomizeInputs() {
  261. const colors = Object.keys(COLORS);
  262. document.getElementById('dice1Color').value = colors[Math.floor(Math.random() * colors.length)];
  263. document.getElementById('dice2Color').value = colors[Math.floor(Math.random() * colors.length)];
  264. document.getElementById('dice3Color').value = colors[Math.floor(Math.random() * colors.length)];
  265. }
  266.  
  267. // Create the UI
  268. createUI();
  269.  
  270. // Set up mutation observer to re-inject UI if removed
  271. const observer = new MutationObserver(function(mutations) {
  272. if (!document.getElementById('dicePredictorContainer')) {
  273. createUI();
  274. }
  275. });
  276.  
  277. observer.observe(document.body, {
  278. childList: true,
  279. subtree: true
  280. });
  281.  
  282. // Save state before page unload
  283. window.addEventListener('beforeunload', saveState);
  284. })();