Loading...

Top
PFQ Banner

This is PokéFarm Q, a free online Pokémon collectables game.

Already a user? New to PFQ?

Single post in Codes and things

Forum Index > PokéFarm > Journals > Codes and things >

Mirzam's AvatarMirzam
Mirzam's Avatar
User scripts I've written for myself & others: Update: I've added links to Greasy Fork, a user script hosting site. If you install via those links, you'll be able to receive any updates I push (especially to the variety eggs tournament script). If you have feedback on any of my scripts, I'd prefer a PM here over bug reports there.

50 sent on interactions page

Add a clickback link for up to 50 users in your sent but not reciprocated list. (Now part of the QoL) Install via Greasy Fork

Code

// ==UserScript== // @name Interaction Page 50 Sent // @namespace https://pokefarm.com/user/Tarashia // @version 1.0 // @description Show up to 50 users from sent interactions // @author Tarashia // @match https://pokefarm.com/interactions // @icon https://pokefarm.com/favicon.ico // @grant none // ==/UserScript== (function() { 'use strict'; var names = ""; var lists = document.getElementsByClassName('userlist'); var lastList = lists[lists.length-1]; if(lastList.parentElement.previousElementSibling.innerText == "Sent"){ var nameElements = lastList.childNodes; for(var i=0; i<nameElements.length; i++){ if(i>=50){ break; } if(i!=0){ names+=","; } var userUrl = nameElements[i].lastChild.href; var name = userUrl.split("/user/")[1]; names+=name; } var url = "https://pokefarm.com/users/"+names; var newP = document.createElement("p"); var newLink = document.createElement("a"); newLink.href = url; if(i>=50){ newLink.innerText = "Open top 50 users"; } else{ newLink.innerText = "Open all users"; } newP.appendChild(newLink); lastList.parentNode.insertBefore(newP,lastList); } })();

View summary links

On your private field page, open a popup that contains the summary links of all Pokemon in the current field, for easy summary visiting. (Now part of the QoL) Install via Greasy Fork

Code

// ==UserScript== // @name Field summary links // @namespace https://pokefarm.com/user/Tarashia // @version 1.0 // @description Show all summary links of Pokemon in fields // @author Tarashia // @match https://pokefarm.com/fields // @grant none // ==/UserScript== (function() { 'use strict'; var body = document.getElementsByTagName('body')[0]; var header = document.getElementsByTagName('h1')[0]; var core = document.getElementById('core'); var newBtn = document.createElement('button'); header.appendChild(newBtn); newBtn.innerText = 'View links'; newBtn.style= 'vertical-align:middle;margin-left: 10px;'; newBtn.onclick = function(){ var content = '<h3>Pokemon links</h3><table>'; var fieldmon = document.getElementsByClassName('fieldmon'); for(var i=0; i<fieldmon.length; i++){ if(i%4==0) { content += '<tr>'; } var pkmnID = fieldmon[i].getAttribute('data-id'); var small = fieldmon[i].children[1]; var imgSRC = small.getAttribute('src'); var pkmnName = small.getAttribute('alt'); content += '<td style="padding:5px;"><img src="'+imgSRC+'"> <a href="/summary/'+pkmnID+'">'+pkmnName+'</a></td>'; if(i%4==3) { content += '</tr>'; } } content += '</table>'; var dialog = document.createElement('div'); var dialogDiv1 = document.createElement('div'); var dialogDiv2 = document.createElement('div'); var dialogDiv3 = document.createElement('div'); var closeBtn = document.createElement('button'); closeBtn.setAttribute('type','button'); closeBtn.style = 'float:right;margin:8px;'; closeBtn.innerText = 'Close'; closeBtn.onclick = function() { dialog.remove(); core.classList.remove('scrolllock'); } dialog.classList.add('dialog'); dialog.appendChild(dialogDiv1); dialogDiv1.appendChild(dialogDiv2); dialogDiv2.appendChild(dialogDiv3); dialogDiv3.innerHTML = content; dialogDiv3.appendChild(closeBtn); body.prepend(dialog); core.classList.add('scrolllock'); }; })();

Hatch variety eggs tournament

Keep track of eggs during the hatch variety eggs tournament. Tracks lab & shelter eggs automatically - must manually add daycare, supplier, etc. The list of eggs is stored locally on your browser, so if you use multiple devices you'll need to export your data manually. Install via Greasy Fork

Code

// ==UserScript== // @name Variety eggs // @namespace TarashiaPFQ // @description Keep track of eggs during the hatch variety eggs tournament. Tracks lab & shelter eggs automatically - must manually add daycare, supplier, etc. // @version 1.3 // @license MIT // @match https://pokefarm.com/shelter // @match https://pokefarm.com/lab // @icon https://pokefarm.com/favicon.ico // @grant GM.getValue // @grant GM.setValue // ==/UserScript== (function() { // Change these to change how new/used/excluded eggs appear // Due to current style limitations, the used and exclude styles must also undo any of the above changes const newStyle = '{ filter: drop-shadow(0 0 10px yellow); }'; const usedStyle = '{ opacity: 0.3; filter: none !important; }'; const excludedStyle = '{ opacity: 1 !important; filter: none !important; }'; const wikiPage = 'https://pokefarm.wiki/index.php?title=Special:Search&search=Pokemon+Code+Compendium'; // Highlight used eggs var newStyleNode = document.createElement('style'); var usedStyleNode = document.createElement('style'); document.querySelector('body').append(newStyleNode); document.querySelector('body').append(usedStyleNode); const highlightEggs = () => { var addUsedStyle = ''; for(var i=0; i<usedEggs.length; i++) { if(addUsedStyle !== '') { addUsedStyle +=', '; } addUsedStyle += 'img[src*="'+usedEggs[i]+'"]'; } if(addUsedStyle !== '') { addUsedStyle += usedStyle; } var addExcludeStyle = ''; for(var i=0; i<excludedEggs.length; i++) { if(addExcludeStyle !== '') { addExcludeStyle +=', '; } addExcludeStyle += 'img[src*="'+excludedEggs[i]+'"]'; } if(addExcludeStyle !== '') { addExcludeStyle += excludedStyle; } usedStyleNode.innerText = addUsedStyle+' '+addExcludeStyle; } // Storage interface var usedEggs = []; var excludedEggs = []; const storeData = () => { GM.setValue('usedEggs', JSON.stringify(usedEggs)); GM.setValue('excludedEggs', JSON.stringify(excludedEggs)); } const fetchData = async () => { const storedUsedData = await GM.getValue('usedEggs'); if(storedUsedData) { try { usedEggs = JSON.parse(storedUsedData); } catch(e) { usedEggs = []; console.warn('Failed to parse stored used data:'); console.warn(storedUsedData); } } const storedExcludeData = await GM.getValue('excludedEggs'); if(storedExcludeData) { try { excludedEggs = JSON.parse(storedExcludeData); } catch(e) { excludedEggs = []; console.warn('Failed to parse stored excluded data:'); console.warn(storedExcludeData); } } highlightEggs(); } // Retrieve stored egg data fetchData(); // Store egg data const storeEgg = (imgSrc,exclude=false) => { const imgLoc = imgSrc.indexOf('/img/'); const pngLoc = imgSrc.indexOf('.png'); const eggID = imgSrc.substring(imgLoc,pngLoc+4); if(!exclude) { if(!usedEggs.includes(eggID)) { usedEggs.push(eggID); highlightEggs(); storeData(); } else { console.warn('Did not store repeat used egg: '+eggID); } } else { if(!excludedEggs.includes(eggID)) { excludedEggs.push(eggID); highlightEggs(); storeData(); } else { console.warn('Did not store repeat exclude egg: '+eggID); } } } // Clear stored data const clearData = () => { if(document.getElementById('clearUsedEggs').checked) { usedEggs = []; } else if(document.getElementById('clearExcludedEggs').checked) { excludedEggs = []; } else { usedEggs = []; excludedEggs = []; } highlightEggs(); storeData(); closeDialog(); } const confirmClear = () => { var content = '<p>Are you sure you want to clear your data?</p><p>You <b>cannot</b> undo this action.</p>'; content += '<div style="margin-bottom: 5px;"><input type="radio" id="clearUsedEggs" name="clearType" checked> <label for="clearUsedEggs">Used eggs only</label></div>'; content += '<div style="margin-bottom: 5px;"><input type="radio" id="clearExcludedEggs" name="clearType" > <label for="clearExcludedEggs">Excluded eggs only</label></div>'; content += '<div><input type="radio" id="clearAll" name="clearType"> <label for="clearAll">All data</label></div>'; dialogBox(content, clearData, 'Yes, clear data', 'Cancel'); } var buttonContainer = document.createElement('div'); buttonContainer.style = 'text-align: center;'; var clearButton = document.createElement('button'); clearButton.innerText = 'Clear data'; clearButton.onclick = confirmClear; buttonContainer.append(clearButton); // Manually add data const manualAdd = () => { var eggCode = document.getElementById('addExcludeCode').value; if(!eggCode.match('^[a-z0-9](\/[a-z0-9])+$')) { alert('Bad code format. Please try again.'); return; } if(document.getElementById('addUsedEgg').checked) { storeEgg('/img/pkmn/'+eggCode+'.png'); } else if(document.getElementById('addExcludedEgg').checked) { storeEgg('/img/pkmn/'+eggCode+'.png',true); } closeDialog(); } const addWindow = () => { var content = '<p>Enter an image code. Example: c/0/7</p>'; content += '<p><a href="'+wikiPage+'" target="_blank">Wiki page with all egg codes</a></p>'; content += '<div style="margin-bottom: 5px;"><input id="addExcludeCode" type="text" style="width: 100%;"></input></div>'; content += '<div style="margin-bottom: 5px;"><input type="radio" id="addUsedEgg" name="manualEntry" checked> <label for="addUsedEgg">Add used egg</label></div>'; content += '<div><input type="radio" id="addExcludedEgg" name="manualEntry"> <label for="addExcludedEgg">Exclude egg</label></div>'; dialogBox(content, manualAdd, 'Add egg', 'Cancel'); } var addButton = document.createElement('button'); addButton.innerText = 'Add/exclude egg'; addButton.onclick = addWindow; addButton.style = 'margin-left: 15px;'; buttonContainer.append(addButton); // Export & import data const updateData = () => { try { var importData = JSON.parse(atob(document.getElementById('importExportData').value)); } catch(e) { alert('Bad backup format. Please try again.'); return; } console.log(importData); if('usedEggs' in importData && 'excludedEggs' in importData) { usedEggs = importData.usedEggs; excludedEggs = importData.excludedEggs; highlightEggs(); storeData(); } else { alert('Bad backup format. Please try again.'); return; } closeDialog(); } const showData = () => { var content = '<p>Here is your current saved data.</p><p>You can back it up, or transfer it to another device.</p>'; var exportData = { usedEggs: usedEggs, excludedEggs: excludedEggs }; content += '<textarea id="importExportData" style="width: 100%;" rows="5">'+btoa(JSON.stringify(exportData))+'</textarea>'; dialogBox(content, updateData, 'Update egg list'); } var exportButton = document.createElement('button'); exportButton.innerText = 'Import/export data'; exportButton.onclick = showData; exportButton.style = 'margin-left: 15px;'; buttonContainer.append(exportButton); // Detect eggs adopted from lab const labWatch = () => { // buttons in the lab area start disabled, so must re-enable them clearButton.removeAttribute('disabled'); addButton.removeAttribute('disabled'); exportButton.removeAttribute('disabled'); const availableEggs = document.querySelectorAll('#egglist>div'); for(var i=0; i<availableEggs.length; i++) { if(availableEggs[i].innerText.includes('Egg adopted successfully!')) { storeEgg(availableEggs[i].children[1].src); } } } if(window.location == 'https://pokefarm.com/lab') { const labMO = new MutationObserver(labWatch); labMO.observe(document.querySelector('#egglist'), { childList: true, subtree: true }); document.querySelector('#eggsbox360').append(buttonContainer); newStyleNode.innerText = '#egglist img '+newStyle; } // Detect eggs adopted from shelter const shelterWatch = () => { const adoptionContainer = document.querySelector('#shelterarea .panel h3'); const eggContainer = document.querySelector('.adoptme .egg'); // if the adoption success panel is open, and it was an egg if(adoptionContainer && adoptionContainer.innerText == 'Adoption successful!' && eggContainer) { storeEgg(eggContainer.style['background-image']); } } if(window.location == 'https://pokefarm.com/shelter') { const shelterMO = new MutationObserver(shelterWatch); shelterMO.observe(document.querySelector('#shelterarea'), { childList: true }); try { const bgColor = window.getComputedStyle(document.querySelector('#sheltercommands')).getPropertyValue('background-color'); buttonContainer.style.backgroundColor = bgColor; } catch(e) { console.warn('Failed to set button container background'); console.warn(e); } buttonContainer.style.borderRadius = '0 0 6px 6px'; buttonContainer.style.paddingTop = '10px'; buttonContainer.style.paddingBottom = '5px'; document.querySelector('#shelter').append(buttonContainer); // Only highlight eggs newStyleNode.innerText = '#shelterarea div[data-stage="egg"] img '+newStyle; } // Create dialog box - action must be a function or null const dialogBox = (content, action, actionText, closeText='Close') => { var dialog = document.createElement('div'); dialog.classList = 'veDialog'; var dialogDiv1 = document.createElement('div'); var dialogDiv2 = document.createElement('div'); var dialogDiv3 = document.createElement('div'); var dialogContent = document.createElement('div'); var dialogFooter = document.createElement('div'); var closeBtn = document.createElement('button'); closeBtn.setAttribute('type','button'); closeBtn.style = 'float:right;margin:8px;'; closeBtn.innerText = closeText; closeBtn.onclick = function() { closeDialog(); } dialog.classList.add('dialog'); dialog.appendChild(dialogDiv1); dialogDiv1.appendChild(dialogDiv2); dialogDiv2.appendChild(dialogDiv3); dialogContent.innerHTML = content; dialogContent.style = 'padding: 10px;'; dialogDiv3.appendChild(dialogContent); dialogDiv3.appendChild(dialogFooter); dialogFooter.appendChild(closeBtn); if(action) { var actionBtn = document.createElement('button'); actionBtn.setAttribute('type','button'); actionBtn.style = 'float:right;margin:8px;'; actionBtn.innerText = actionText; actionBtn.onclick = action; dialogFooter.appendChild(actionBtn); } var body = document.getElementsByTagName('body')[0]; body.prepend(dialog); var core = document.getElementById('core'); core.classList.add('scrolllock'); return dialog; } const closeDialog = () => { var dialogs = document.getElementsByClassName('veDialog'); for(var i=0; i<dialogs.length; i++) { dialogs[i].remove(); } var core = document.getElementById('core'); core.classList.remove('scrolllock'); } } )();
(Not mine, but link for reference) Change notification sound
© PokéFarm 2009-2024 (Full details)Contact | Rules | Privacy | Reviews 4.6★Get shortlink for this page