[Pokeclicker] Simple Weather Changer

Adds a button to select the weather for the current region, also freezes all weather

  1. // ==UserScript==
  2. // @name [Pokeclicker] Simple Weather Changer
  3. // @namespace Pokeclicker Scripts
  4. // @author KarmaAlex (Credit: Ephenia, Optimatum)
  5. // @description Adds a button to select the weather for the current region, also freezes all weather
  6. // @copyright https://github.com/Ephenia
  7. // @license GPL-3.0 License
  8. // @version 1.4.3
  9.  
  10. // @homepageURL https://github.com/Ephenia/Pokeclicker-Scripts/
  11. // @supportURL https://github.com/Ephenia/Pokeclicker-Scripts/issues
  12.  
  13. // @match https://www.pokeclicker.com/
  14. // @icon https://www.google.com/s2/favicons?domain=pokeclicker.com
  15. // @grant unsafeWindow
  16. // @run-at document-idle
  17. // ==/UserScript==
  18.  
  19. var weatherChangerWeather;
  20.  
  21. function initWeatherChange() {
  22. // Load selected weather
  23. weatherChangerWeather = parseInt(localStorage.getItem('weatherChangerWeather'));
  24. if (isNaN(weatherChangerWeather)) {
  25. weatherChangerWeather = -1;
  26. }
  27.  
  28. // Make selectbox
  29. const weatherSelect = document.createElement('select');
  30. weatherSelect.innerHTML = '<option value="-1">Default Weather</option>\n' + GameHelper.enumSelectOption(WeatherType).map((w) => `<option value="${w.value}">${w.name}</option>`).join('\n');
  31. weatherSelect.id = 'change-weather-select';
  32. weatherSelect.value = weatherChangerWeather;
  33. document.querySelector('#townMap button[data-bind*="DayCycle.color"').before(weatherSelect);
  34.  
  35. document.getElementById('change-weather-select').addEventListener('change', (event) => { changeWeather(event); });
  36. addGlobalStyle('#change-weather-select { position: absolute; right: 100px; top: 10px; width: auto; height: 20px; font-size: 9px; }');
  37.  
  38. overrideGenerateWeather();
  39. Weather.generateWeather(new Date());
  40. }
  41.  
  42. function changeWeather(event) {
  43. weatherChangerWeather = +event.target.value;
  44. Weather.generateWeather(new Date());
  45. localStorage.setItem('weatherChangerWeather', weatherChangerWeather);
  46. }
  47.  
  48. function overrideGenerateWeather() {
  49. const oldGenerateWeather = Weather.generateWeather;
  50. Weather.generateWeather = function(...args) {
  51. if (weatherChangerWeather >= 0) {
  52. Weather.regionalWeather.forEach((weather) => weather(weatherChangerWeather));
  53. } else {
  54. return oldGenerateWeather.apply(this, args);
  55. }
  56. }
  57. }
  58.  
  59. function addGlobalStyle(css) {
  60. var head, style;
  61. head = document.getElementsByTagName('head')[0];
  62. if (!head) { return; }
  63. style = document.createElement('style');
  64. style.type = 'text/css';
  65. style.innerHTML = css;
  66. head.appendChild(style);
  67. }
  68.  
  69. function loadEpheniaScript(scriptName, initFunction, priorityFunction) {
  70. function reportScriptError(scriptName, error) {
  71. console.error(`Error while initializing '${scriptName}' userscript:\n${error}`);
  72. Notifier.notify({
  73. type: NotificationConstants.NotificationOption.warning,
  74. title: scriptName,
  75. message: `The '${scriptName}' userscript crashed while loading. Check for updates or disable the script, then restart the game.\n\nReport script issues to the script developer, not to the Pokéclicker team.`,
  76. timeout: GameConstants.DAY,
  77. });
  78. }
  79. const windowObject = !App.isUsingClient ? unsafeWindow : window;
  80. // Inject handlers if they don't exist yet
  81. if (windowObject.epheniaScriptInitializers === undefined) {
  82. windowObject.epheniaScriptInitializers = {};
  83. const oldInit = Preload.hideSplashScreen;
  84. var hasInitialized = false;
  85.  
  86. // Initializes scripts once enough of the game has loaded
  87. Preload.hideSplashScreen = function (...args) {
  88. var result = oldInit.apply(this, args);
  89. if (App.game && !hasInitialized) {
  90. // Initialize all attached userscripts
  91. Object.entries(windowObject.epheniaScriptInitializers).forEach(([scriptName, initFunction]) => {
  92. try {
  93. initFunction();
  94. } catch (e) {
  95. reportScriptError(scriptName, e);
  96. }
  97. });
  98. hasInitialized = true;
  99. }
  100. return result;
  101. }
  102. }
  103.  
  104. // Prevent issues with duplicate script names
  105. if (windowObject.epheniaScriptInitializers[scriptName] !== undefined) {
  106. console.warn(`Duplicate '${scriptName}' userscripts found!`);
  107. Notifier.notify({
  108. type: NotificationConstants.NotificationOption.warning,
  109. title: scriptName,
  110. message: `Duplicate '${scriptName}' userscripts detected. This could cause unpredictable behavior and is not recommended.`,
  111. timeout: GameConstants.DAY,
  112. });
  113. let number = 2;
  114. while (windowObject.epheniaScriptInitializers[`${scriptName} ${number}`] !== undefined) {
  115. number++;
  116. }
  117. scriptName = `${scriptName} ${number}`;
  118. }
  119. // Add initializer for this particular script
  120. windowObject.epheniaScriptInitializers[scriptName] = initFunction;
  121. // Run any functions that need to execute before the game starts
  122. if (priorityFunction) {
  123. $(document).ready(() => {
  124. try {
  125. priorityFunction();
  126. } catch (e) {
  127. reportScriptError(scriptName, e);
  128. // Remove main initialization function
  129. windowObject.epheniaScriptInitializers[scriptName] = () => null;
  130. }
  131. });
  132. }
  133. }
  134.  
  135. if (!App.isUsingClient || localStorage.getItem('simpleweatherchanger') === 'true') {
  136. loadEpheniaScript('simpleweatherchanger', initWeatherChange);
  137. }