您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Adds in toggable options to have seasonal events infinitely run. Events can also run simultaneously with one another. Includes a custom event as well.
// ==UserScript== // @name [Pokeclicker] Infinite Seasonal Events // @namespace Pokeclicker Scripts // @author Ephenia // @description Adds in toggable options to have seasonal events infinitely run. Events can also run simultaneously with one another. Includes a custom event as well. // @copyright https://github.com/Ephenia // @license GPL-3.0 License // @version 1.3.3 // @homepageURL https://github.com/Ephenia/Pokeclicker-Scripts/ // @supportURL https://github.com/Ephenia/Pokeclicker-Scripts/issues // @match https://www.pokeclicker.com/ // @icon https://www.google.com/s2/favicons?domain=pokeclicker.com // @grant unsafeWindow // @run-at document-idle // ==/UserScript== var activeSeasonalEvents = {}; //Removed setTimeout, opted to make it load like the other scrips, also helps with notifications function initEvents() { const NUM_EVENTS = 10; const startDate = new Date(new Date().getFullYear(), -1); const endDate = new Date(new Date().getFullYear(), 10000); App.game.specialEvents.newEvent('Ephenia\'s Gift', 'Encounter Ribombee that roams across all regions.<br/>A special thanks for using my scripts!', startDate, () => { GameHelper.enumNumbers(GameConstants.Region).filter(i => i != GameConstants.Region.none).forEach(region => { RoamingPokemonList.add(region, 0, new RoamingPokemon('Ribombee')); // Currently adding in base subregions only }); }, endDate, () => { GameHelper.enumNumbers(GameConstants.Region).filter(i => i != GameConstants.Region.none).forEach(region => { RoamingPokemonList.remove(region, 0, 'Ribombee'); }); }, true ); //Testing loading events in init for (const event of App.game.specialEvents.events) { let eventActive = loadSetting(event.title, false); activeSeasonalEvents[event.title] = eventActive; } for (const event of App.game.specialEvents.events) { event.startTime = startDate; event.endTime = endDate; if (!event.hasStarted() && activeSeasonalEvents[event.title]) { event.start(); } } if (App.game.specialEvents.events.length != NUM_EVENTS) { Notifier.notify({ title: '[Outdated] Infinite Seasonal Events', message: `Please contact <a href="https://github.com/Ephenia/Pokeclicker-Scripts" target="_blank">Ephenia</a> so that this script can be updated!`, type: NotificationConstants.NotificationOption.danger, timeout: 1000000 }); } var eventLi = document.createElement('li'); eventLi.innerHTML = `<a class="dropdown-item" href="#eventModal" data-toggle="modal">Toggle Events</a>`; for (const node of document.querySelectorAll('#startMenu ul li')) { if (node.querySelector('a[href="#eventsModal"]')) { node.after(eventLi); break; } } var eventMod = document.createElement('div'); eventMod.setAttribute("class", "modal noselect fade show"); eventMod.setAttribute("id", "eventModal"); eventMod.setAttribute("tabindex", "-1"); eventMod.setAttribute("aria-labelledby", "eventModal"); eventMod.setAttribute("aria-labelledby", "eventModal"); eventMod.setAttribute("aria-modal", "true"); eventMod.setAttribute("role", "dialog"); eventMod.innerHTML = `<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg" role="document"> <div class="modal-content"> <div class="modal-header" style="justify-content: space-around;"> <h5 class="modal-title">Toggle Events</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> </div> </div>` document.getElementById('profileModal').before(eventMod); var modalBody = document.querySelector('[id=eventModal] div div [class=modal-body]') //Event order seems to change on startup so this loads them independent of order, also loads any new events without images for (const event of App.game.specialEvents.events) { let title = event.title; let description = event.description; switch(title){ case "Flying Pikachu": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/25.1.png"> <img src="assets/images/pokemon/21.01.png"> </div><hr>` break case "Mewtwo strikes back!": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/150.03.png"> <img src="assets/images/pokemon/1.01.png"> <img src="assets/images/pokemon/4.01.png"> <img src="assets/images/pokemon/7.01.png"> </div><hr>` break case "Halloween!": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/1.02.png"> <img src="assets/images/pokemon/25.12.png"> <img src="assets/images/pokemon/175.01.png"><br> <img src="assets/images/pokemon/92.png"> <img src="assets/images/pokemon/200.png"> <img src="assets/images/pokemon/353.png"> <img src="assets/images/pokemon/355.png"> </div><hr>` break case "Let's GO!": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/25.13.png"> <img src="assets/images/pokemon/133.02.png"> </div><hr>` break case "Merry Christmas!": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/143.02.png"> <img src="assets/images/pokemon/251.01.png"> <img src="assets/images/pokemon/446.01.png"> </div><hr>` break case "Hoopa Day": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <i>(Note that this event only adds a special joke questline and doesn't add Hoopa as an additional roamer. Hoopa is available without this event.)</i><br> <img src="assets/images/pokemon/720.png"> </div><hr>` break case "Lunar New Year": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/666.png"> <img src="assets/images/pokemon/666.19.png"><br> <img src="assets/images/pokemon/666.01.png"> <img src="assets/images/pokemon/666.02.png"> <img src="assets/images/pokemon/666.03.png"> <img src="assets/images/pokemon/666.04.png"> <img src="assets/images/pokemon/666.05.png"> <img src="assets/images/pokemon/666.06.png"> <img src="assets/images/pokemon/666.07.png"> <img src="assets/images/pokemon/666.08.png"> <img src="assets/images/pokemon/666.09.png"> <img src="assets/images/pokemon/666.1.png"> <img src="assets/images/pokemon/666.11.png"> <img src="assets/images/pokemon/666.12.png"> <img src="assets/images/pokemon/666.13.png"> <img src="assets/images/pokemon/666.14.png"> <img src="assets/images/pokemon/666.15.png"> <img src="assets/images/pokemon/666.16.png"> <img src="assets/images/pokemon/666.17.png"> <img src="assets/images/pokemon/666.18.png"> </div><hr>` break case "Easter": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/175.02.png"> </div><hr>` break case "Golden Week": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/1.03.png"> </div><hr>` break case "Ephenia's Gift": modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br> <img src="assets/images/pokemon/743.png"> </div><hr>` break default: modalBody.innerHTML += `<div id="event-${title}" class="event-select" data-value="${title}"><b>${title}</b><br>${description}<br><br>New event, Pokemon images coming soon, if not open an issue on github </div><hr>` } } for (const event of App.game.specialEvents.events) { if (activeSeasonalEvents[event.title]) { document.getElementById('event-'+event.title).style = "background-color: rgba(93, 226, 60, 0.5)"; } document.getElementById('event-'+event.title).addEventListener('click', toggleEvent); } addGlobalStyle('.event-select { cursor: pointer; }'); addGlobalStyle('.event-select:hover { background-color: rgba(48, 197, 255, 0.5); }'); } function toggleEvent() { var title = this.getAttribute('data-value'); activeSeasonalEvents[title] = !activeSeasonalEvents[title]; localStorage.setItem(title, activeSeasonalEvents[title]); if (activeSeasonalEvents[title]) { this.style = "background-color: rgba(93, 226, 60, 0.5)"; App.game.specialEvents.events.find((event) => (event.title === title)).start(); } else { this.style = ""; App.game.specialEvents.events.find((event) => (event.title === title)).end(); } } function loadSetting(key, defaultVal) { var val; try { val = JSON.parse(localStorage.getItem(key)); if (val == null || typeof val !== typeof defaultVal) { throw new Error; } } catch { val = defaultVal; localStorage.setItem(key, defaultVal); } return val; } function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } function loadEpheniaScript(scriptName, initFunction, priorityFunction) { function reportScriptError(scriptName, error) { console.error(`Error while initializing '${scriptName}' userscript:\n${error}`); Notifier.notify({ type: NotificationConstants.NotificationOption.warning, title: scriptName, 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.`, timeout: GameConstants.DAY, }); } const windowObject = !App.isUsingClient ? unsafeWindow : window; // Inject handlers if they don't exist yet if (windowObject.epheniaScriptInitializers === undefined) { windowObject.epheniaScriptInitializers = {}; const oldInit = Preload.hideSplashScreen; var hasInitialized = false; // Initializes scripts once enough of the game has loaded Preload.hideSplashScreen = function (...args) { var result = oldInit.apply(this, args); if (App.game && !hasInitialized) { // Initialize all attached userscripts Object.entries(windowObject.epheniaScriptInitializers).forEach(([scriptName, initFunction]) => { try { initFunction(); } catch (e) { reportScriptError(scriptName, e); } }); hasInitialized = true; } return result; } } // Prevent issues with duplicate script names if (windowObject.epheniaScriptInitializers[scriptName] !== undefined) { console.warn(`Duplicate '${scriptName}' userscripts found!`); Notifier.notify({ type: NotificationConstants.NotificationOption.warning, title: scriptName, message: `Duplicate '${scriptName}' userscripts detected. This could cause unpredictable behavior and is not recommended.`, timeout: GameConstants.DAY, }); let number = 2; while (windowObject.epheniaScriptInitializers[`${scriptName} ${number}`] !== undefined) { number++; } scriptName = `${scriptName} ${number}`; } // Add initializer for this particular script windowObject.epheniaScriptInitializers[scriptName] = initFunction; // Run any functions that need to execute before the game starts if (priorityFunction) { $(document).ready(() => { try { priorityFunction(); } catch (e) { reportScriptError(scriptName, e); // Remove main initialization function windowObject.epheniaScriptInitializers[scriptName] = () => null; } }); } } if (!App.isUsingClient || localStorage.getItem('infiniteseasonalevents') === 'true') { loadEpheniaScript('infiniteseasonalevents', initEvents); }