Codes and things
Forum Index > PokéFarm > Journals >
All of my posted code is fully free to use and modify. Some code may be based on other users' code - I will try to attribute that where possible.
Contents:
- [This post] TOC, Nature chart, temporary trackers
- Delta previewing
- Dex trading rules & details
- Field happiness gain/loss data
- BBCode/CSS I've written
- Userscripts I've written
- Google fonts guide
- Skin CSS snippets
Natures | |||||
---|---|---|---|---|---|
-A | -D | -SA | -SD | -S | |
+A | Hardy | Lonely | Adamant | Naughty | Brave |
+D | Bold | Docile | Impish | Lax | Relaxed |
+SA | Modest | Mild | Bashful | Rash | Quiet |
+SD | Calm | Gentle | Careful | Quirky | Sassy |
+S | Timid | Hasty | Jolly | Naive | Serious |
Lent out
[none]
When did this get 100 subs omg
Preview a specific delta
This demo uses CSS only to preview a delta species - all you need is the base Pokemon image, which can be found in the Wiki or your Pokedex, etc. The CSS image may be slightly blurry depending on your browser, and the shape isn't quite the same, but I am fairly pleased with how close I was able to get :)
(This code is based on other users' delta preview codes, unfortunately the links I had to their posts are mostly broken now)
Code
[sc=psychic-delta][img]/img/pkmn/u/7/n/w.png[/img][/sc]
[sc=dragon-delta][img]/img/pkmn/c/m/x.png[/img][/sc]
[style]
.delta-shadow(@color) {
margin: 5px;
filter:
drop-shadow(0px 1px 0px @color)
drop-shadow(-1px 0px 0px @color)
drop-shadow(1px 0px 0px @color)
drop-shadow(0px 0px 1px @color)
drop-shadow(0px -2px 1px @color);
}
.normal-delta img { .delta-shadow(rgb(168, 168, 120)); }
.fire-delta img { .delta-shadow(rgb(240, 128, 48)); }
.water-delta img { .delta-shadow(rgb(104, 144, 240)); }
.electric-delta img { .delta-shadow(rgb(248, 208, 48)); }
.grass-delta img { .delta-shadow(rgb(120, 200, 80)); }
.ice-delta img { .delta-shadow(rgb(152, 216, 216)); }
.fighting-delta img { .delta-shadow(rgb(192, 48, 40)); }
.poison-delta img { .delta-shadow(rgb(160, 64, 160)); }
.ground-delta img { .delta-shadow(rgb(224, 192, 104)); }
.flying-delta img { .delta-shadow(rgb(168, 144, 240)); }
.psychic-delta img { .delta-shadow(rgb(248, 88, 136)); }
.bug-delta img { .delta-shadow(rgb(168, 184, 32)); }
.rock-delta img { .delta-shadow(rgb(184, 160, 56)); }
.ghost-delta img { .delta-shadow(rgb(112, 88, 152)); }
.dragon-delta img { .delta-shadow(rgb(112, 56, 248)); }
.dark-delta img { .delta-shadow(rgb(112, 88, 72)); }
.steel-delta img { .delta-shadow(rgb(184, 184, 208)); }
.fairy-delta img { .delta-shadow(rgb(255, 101, 213)); }
[/style]
Preview all delta types for a single Pokemon
This demo uses the same base code as above, but previews all 18 types for a single Pokemon at once, while only needing to change a single line of code. Get the image code for the Pokemon you want to preview as above, then paste it into the @pkmn-img variable at the top of the code block. If you want to preview the deltas on a different color background, or a field image, set @background.
Code
[style]
/* https://pokefarm.wiki/Category:List_of_Pok%C3%A9mon */
@pkmn-img: '/img/pkmn/u/7/n/w.png';
/* change to a hex color code of choice, or url('image_link') */
@bg-color: transparent;
.delta-list {
display: flex;
flex-wrap: wrap;
text-align: center;
border-radius: 5px;
padding: 5px;
background: @bg-color;
>div {
padding: 5px;
}
.pkmn {
padding: 5px;
&:before {
content: url(@pkmn-img);
}
}
}
.delta-shadow(@color) {
margin: 5px;
filter:
drop-shadow(0px 1px 0px @color)
drop-shadow(-1px 0px 0px @color)
drop-shadow(1px 0px 0px @color)
drop-shadow(0px 0px 1px @color)
drop-shadow(0px -2px 1px @color);
}
.delta-list .normal .pkmn:before { .delta-shadow(rgb(168, 168, 120)); }
.delta-list .fire .pkmn:before { .delta-shadow(rgb(240, 128, 48)); }
.delta-list .water .pkmn:before { .delta-shadow(rgb(104, 144, 240)); }
.delta-list .electric .pkmn:before { .delta-shadow(rgb(248, 208, 48)); }
.delta-list .grass .pkmn:before { .delta-shadow(rgb(120, 200, 80)); }
.delta-list .ice .pkmn:before { .delta-shadow(rgb(152, 216, 216)); }
.delta-list .fighting .pkmn:before { .delta-shadow(rgb(192, 48, 40)); }
.delta-list .poison .pkmn:before { .delta-shadow(rgb(160, 64, 160)); }
.delta-list .ground .pkmn:before { .delta-shadow(rgb(224, 192, 104)); }
.delta-list .flying .pkmn:before { .delta-shadow(rgb(168, 144, 240)); }
.delta-list .psychic .pkmn:before { .delta-shadow(rgb(248, 88, 136)); }
.delta-list .bug .pkmn:before { .delta-shadow(rgb(168, 184, 32)); }
.delta-list .rock .pkmn:before { .delta-shadow(rgb(184, 160, 56)); }
.delta-list .ghost .pkmn:before { .delta-shadow(rgb(112, 88, 152)); }
.delta-list .dragon .pkmn:before { .delta-shadow(rgb(112, 56, 248)); }
.delta-list .dark .pkmn:before { .delta-shadow(rgb(112, 88, 72)); }
.delta-list .steel .pkmn:before { .delta-shadow(rgb(184, 184, 208)); }
.delta-list .fairy .pkmn:before { .delta-shadow(rgb(255, 101, 213)); }
[/style]
[sc=delta-list]
[sc=normal][sc=pkmn][/sc][sc=type][type=normal][/sc][/sc]
[sc=fire][sc=pkmn][/sc][sc=type][type=fire][/sc][/sc]
[sc=water][sc=pkmn][/sc][sc=type][type=water][/sc][/sc]
[sc=electric][sc=pkmn][/sc][sc=type][type=electric][/sc][/sc]
[sc=grass][sc=pkmn][/sc][sc=type][type=grass][/sc][/sc]
[sc=ice][sc=pkmn][/sc][sc=type][type=ice][/sc][/sc]
[sc=fighting][sc=pkmn][/sc][sc=type][type=fighting][/sc][/sc]
[sc=poison][sc=pkmn][/sc][sc=type][type=poison][/sc][/sc]
[sc=ground][sc=pkmn][/sc][sc=type][type=ground][/sc][/sc]
[sc=flying][sc=pkmn][/sc][sc=type][type=flying][/sc][/sc]
[sc=psychic][sc=pkmn][/sc][sc=type][type=psychic][/sc][/sc]
[sc=bug][sc=pkmn][/sc][sc=type][type=bug][/sc][/sc]
[sc=rock][sc=pkmn][/sc][sc=type][type=rock][/sc][/sc]
[sc=ghost][sc=pkmn][/sc][sc=type][type=ghost][/sc][/sc]
[sc=dragon][sc=pkmn][/sc][sc=type][type=dragon][/sc][/sc]
[sc=dark][sc=pkmn][/sc][sc=type][type=dark][/sc][/sc]
[sc=steel][sc=pkmn][/sc][sc=type][type=steel][/sc][/sc]
[sc=fairy][sc=pkmn][/sc][sc=type][type=fairy][/sc][/sc]
[/sc]
Dex trading rules & details
Cost: Each entry costs 3 gp or 3k credits. For most forme changing Pokemon, the base forme doesn't count, but all alternate formes do. Examples: Deoxys = 3 entries, Full Saiyan Line = 5 entries, Arceus/Silvally = 17 entries. Limits: I will only send up to 15 trades at a time - if you want more, please wait a few days, and message me again. Note that # of trades != # of entries. Deoxys is only one trade, and the Saiyan line is 3. A full set of Arceus/Silvally always counts as 3 trades, even if I can put the items on other Pokemon, just because there's so many items. Forme items: I have all the forme items for the Pokemon in my fields, including full plate/memory sets, and Ultranecrozium Z. Rules:- Please list what Pokemon you want clearly, as well as any alternate formes you need. Please do not link them or use display codes.
- You do not have to rush, but please send them back as soon as you can. I understand that not everyone has as many trade slots as I do!
- You may not send the Pokemon or items to others while you have them. Even if it will only take a moment.
- You may not evolve, mega evolve, or otherwise permanently change any Pokemon I send you. If you are unsure about how to get a specific forme, please ask before doing something risky.
Dex trade item tracking: (for my own reference, a single x0 likely just means it's currently equipped)
Plates
Flame Plate x1 |
Splash Plate x1 |
Zap Plate x1 |
Meadow Plate x1 |
Icicle Plate x1 |
Fist Plate x1 |
Toxic Plate x1 |
Earth Plate x1 |
Sky Plate x1 |
Mind Plate x1 |
Insect Plate x2 |
Stone Plate x1 |
Spooky Plate x1 |
Draco Plate x1 |
Dread Plate x1 |
Iron Plate x1 |
Pixie Plate x1 |
Memories
Fire Memory x1 |
Water Memory x0 |
Grass Memory x1 |
Electric Memory x1 |
Flying Memory x1 |
Ice Memory x1 |
Poison Memory x1 |
Fighting Memory x1 |
Bug Memory x1 |
Psychic Memory x1 |
Ghost Memory x1 |
Dark Memory x1 |
Rock Memory x1 |
Ground Memory x1 |
Steel Memory x1 |
Dragon Memory x1 |
Fairy Memory x1 |
Other items
Deoxys Meteorites:
Genesect Drives:
Meteorite Shard A x1 |
Meteorite Shard D x0 |
Meteorite Shard S x1 |
Burn Drive x0 |
Chill Drive x1 |
Douse Drive x1 |
Shock Drive x1 |
Happiness gain/loss in fields
My results:
Note: Gain/loss values are based on the 255 value, not the % value. 4 points is about 1.5%
To investigate: Delta typings
Discussion & Method
I've wondered for a while what the exact happiness gain/loss rates were for Pokemon in fields, especially for complex Pokemon like where one type matches the field and the other type either likes or dislikes the field. I've finally collected some data and would like to compare it to anyone else to see if I'm close or totally off-base here.
My numbers are based on the (unfortunately largely invisible) base happiness value, which is out of 255, rather than the more obvious visible % value since that's less accurate. I got those by using the set target feature, but that was still less accurate than I hoped, and I ended up doing some rounding/extrapolating.
My Pokemon examples are largely chosen randomly based on what I got from the shelter for testing. I used only fire/electric fields since I was able to find something for every case I could think of. (also I don't have all types of fields...)
Also don't get hung up on the type 1/2 numbers, it doesn't actually matter which one is the "real" type 1/2 for this, as far as I know anyway. (ex: Houndour is Dark/Fire, *not* Fire/Dark)
I left my Pokemon in the fields for 4 hours, but I think 3 might have been better for the math. (my Wooper was only in for 3 due to a mistake, and I got cleaner numbers off it)
Case | Rate | Example |
---|---|---|
Double type match | +8/hr | Apocalyptic Arcanine, double-typed deltas |
Type 1 match + type 2 super effective | +6/hr | Larvesta in Fire |
Type 1 match, neutral/no 2nd type | +4/hr | Growlithe or Houndour in Fire, Dratini in Dragon |
Both types super effective | +4/hr | Snom in Fire |
Type 1 match, type 2 not very effective | +2/hr | Turtonator in Fire |
Type 1 super effective, neutral/no 2nd type | +2/hr | Snorunt or Bulbasaur in Fire |
Both types neutral | 0/hr | Eevee or Zubat in Fire |
Type 1 super effective, type 2 not very effective | 0/hr | Anorith in Fire |
Type 1 not very effective, neutral/no 2nd type | -2/hr | Rockruff or Carvanha in Fire |
Both types not very effective | -4/hr | Relicanth in Fire |
Type 1 immune + any type 2 | -8/hr | Trapinch, Stunfisk, Wooper, Rhyhorn, Gible in Electric |
BBCode/CSS I've written for myself & others:
Not mine: Auto-update type race code
Show a pkmnpanel platform-style
Up to two icons are shown on the name bar, so for example my Charizard is from PF1 and is mega, but only shiny/male is shown. Everything customizable is at the top as variables: platform/name/berry bg colors, and show/hide options for the held item and berry button.
Future goals: Expand the name link to make the whole area clickable (padding? would need a new element to form the name bg, and need to ensure berry stays clickable). Add exp bar below name (decide if it shares colors with name/platform or gets its own vars). Prevent ready to evolve button from showing for owner.
Helix Fossil
Fossil
(: 0)
A fossil from a prehistoric Pokémon that once lived in the sea. It might be a piece of a seashell.
Unsellable
Likes:
Bitter food
27%
Gentle nature
Rare Bone
Treasure
(: 0)
A bone that is extremely valuable for Pokémon archaeology. It can be sold for a high price.
Sells for 5,000
Likes:
Any food
MAX
Quirky nature
Code
[pkmnpanel=3mc8] [pkmnpanel=Jg30] [pkmnpanel=kv3l9]
[style]
/* These default to the VIEWER's skin colors */
/* To customize them, just set hex color codes instead */
@platform-base: @col-bg1;
@platform-border: @col-border1;
@name-color: @col-fg1;
@name-background: @col-bg3;
@name-border: @col-border3;
@berry-background: @col-flavour-up;
@berry-border: @col-fg1;
/* Set to "block" to show, "none" to hide */
@display-item: block;
@display-berries: block;
.party {
display: inline-block;
&,>div {
padding: 0;
margin: 0;
background: transparent;
width: 120px !important;
height: 120px;
overflow: hidden;
border: none;
border-radius: 0;
box-shadow: none;
}
>div {
&::after {
display: none;
}
.pkmn {
margin: 0 10px;
float: unset;
&::before {
background-color: @platform-base;
border-color: @platform-border;
}
.helditem {
display: @display-item;
.itemsprite {
cursor: unset;
}
.tooltip_content {
display: none;
}
}
}
.name {
background-color: @name-background;
border: 1px solid @name-border;
border-radius: 5px;
margin-top: 1px;
height: 16px;
display: flex;
flex-wrap: nowrap;
a {
color: @name-color;
font-weight: normal;
margin: 0 2px;
width: 80px !important;
flex-grow: 99;
font-size: 12px;
}
img {
display: none;
}
img:nth-last-of-type(-n+2) {
display: inline;
margin: 0;
}
}
.action {
display: @display-berries;
position: absolute;
left: 88px;
top: 70px;
height: unset;
width: unset;
.berrybuttons[data-up="any"]>a[data-berry="aspear"],
.berrybuttons[data-up="sour"]>a[data-berry="aspear"],
.berrybuttons[data-up="spicy"]>a[data-berry="cheri"],
.berrybuttons[data-up="dry"]>a[data-berry="chesto"],
.berrybuttons[data-up="sweet"]>a[data-berry="pecha"],
.berrybuttons[data-up="bitter"]>a[data-berry="rawst"] {
display: inline-block;
}
.berrybuttons {
>a {
display: none;
width: 20px;
height: 20px;
line-height: 20px;
padding: 5px;
background-color: @berry-background;
border-radius: 20px;
>img {
vertical-align: top;
max-height: 20px;
max-width: 20px;
}
}
>a[data-berry="pecha"] img {
/* this berry is short */
margin-top: 1px;
}
}
&.working {
opacity: 0.5;
}
table, a[data-evolve] {
/* "thank you" message and evolve button */
display: none;
}
}
.expbar, .taste, .extra {
display: none;
}
}
>div:hover>.action a[data-berry]:after {
border-color: @berry-border;
}
}
[/style]
Short-form for signatures
[sc=platform-party][pkmnpanel=3mc8][/sc] [sc=platform-party][pkmnpanel=Jg30][/sc] [sc=platform-party][pkmnpanel=kv3l9][/sc]
[style]
/* These default to the VIEWER's skin colors */
/* To customize them, just set hex color codes instead */
@pparty-platform-base: @col-bg1;
@pparty-platform-border: @col-border1;
@pparty-name-color: @col-fg1;
@pparty-name-background: @col-bg3;
@pparty-name-border: @col-border3;
@pparty-berry-background: @col-flavour-up;
@pparty-berry-border: @col-fg1;
/* Set to "block" to show, "none" to hide */
@pparty-display-item: block;
@pparty-display-berries: block;
@import "skins/user/b/7/q/sharedcss/__extra";
[/style]
Compact pkmnpanel
Modify the pkmnpanel code to be a bit more compact, for narrow about mes and to fit on a single line in desktop mode.
Helix Fossil
Fossil
(: 0)
A fossil from a prehistoric Pokémon that once lived in the sea. It might be a piece of a seashell.
Unsellable
Likes:
Bitter food
27%
Gentle nature
Everstone
Special Evolution Item
(: 0)
A peculiar stone that prevents a Pokémon from evolving when held.
Sells for 250
Likes:
Sweet food
27%
Timid nature
Code
[pkmnpanel=3mc8][pkmnpanel=hynl1]
[style]
/* These default to the VIEWER's skin colors */
/* To customize them, just set hex color codes instead */
@pkmn-panel-bg: @col-bg3;
@pkmn-border-color: @col-border3;
@pkmn-text-color: @col-fg1;
@pkmn-link-color: @col-link1;
@pkmn-platform-color: @col-bg1;
@pkmn-platform-edge: @col-border1;
@pkmn-berry-color: @col-flavour-up;
@pkmn-xp-done: @col-bg1;
@pkmn-xp-remining: @col-bg3;
@pkmn-xp-text: @col-fg1;
@pkmn-xp-border: @col-border3;
.party {
display: inline-block;
margin: 10px;
width: unset !important;
color: @pkmn-text-color;
a {
color: @pkmn-link-color;
}
>div {
background: @pkmn-panel-bg;
border-color: @pkmn-border-color;
box-shadow: none;
width: 250px;
margin: 0;
overflow: hidden;
&:hover>.action a[data-berry]:after {
color: @pkmn-border-color;
}
>.pkmn:before {
background-color: @pkmn-platform-color;
border-color: @pkmn-platform-edge;
}
>.name a {
margin-bottom: 5px;
max-width: 140px;
}
>.expbar {
width: 140px;
height: 25px;
margin-top: 2px;
background-color: @pkmn-xp-remining;
border-color: @pkmn-xp-border;
color: @pkmn-xp-text;
>div {
border-color: @pkmn-xp-border;
background-color: @pkmn-xp-done;
}
}
>.extra {
>.happy {
display: none;
}
>.nature {
width: 165px;
margin-left: 5px;
}
}
>.action {
width: 140px;
height: 30px;
>.berrybuttons {
>a {
background-color: @pkmn-berry-color;
display: none;
width: 100%;
height: 30px;
padding: 3px;
box-sizing: border-box;
>img {
height: 25px;
vertical-align: top;
}
}
}
>.berrybuttons[data-up="any"]>a[data-berry="aspear"] {
display: inline-block;
border-radius: 20px;
}
>.berrybuttons[data-up="sour"]>a[data-berry="aspear"] {
display: inline-block;
}
>.berrybuttons[data-up="spicy"]>a[data-berry="cheri"] {
display: inline-block;
}
>.berrybuttons[data-up="dry"]>a[data-berry="chesto"] {
display: inline-block;
}
>.berrybuttons[data-up="sweet"]>a[data-berry="pecha"] {
display: inline-block;
}
>.berrybuttons[data-up="bitter"]>a[data-berry="rawst"] {
display: inline-block;
}
}
}
}
[/style]
Short-form for signatures
[sc=compact-party][pkmnpanel=3mc8][/sc] [sc=compact-party][pkmnpanel=hynl1][/sc]
[style]
/* These default to the VIEWER's skin colors */
/* To customize them, just set hex color codes instead */
@cparty-pkmn-panel-bg: @col-bg3;
@cparty-pkmn-border-color: @col-border3;
@cparty-pkmn-text-color: @col-fg1;
@cparty-pkmn-link-color: @col-link1;
@cparty-pkmn-platform-color: @col-bg1;
@cparty-pkmn-platform-edge: @col-border1;
@cparty-pkmn-berry-color: @col-flavour-up;
@cparty-pkmn-xp-done: @col-bg1;
@cparty-pkmn-xp-remining: @col-bg3;
@cparty-pkmn-xp-text: @col-fg1;
@cparty-pkmn-xp-border: @col-border3;
@import "skins/user/b/7/q/sharedcss/__extra";
[/style]
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.
(Not mine, but link for reference)
Change notification sound
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');
}
}
)();
How to use Google Fonts.
https://fonts.google.com/
Please choose your fonts carefully - decorative/artistic fonts should be used sparingly, as decoration, headers, etc. Never use cursive, decorative, or artistic fonts for large blocks of text. Keep in mind that this site has legibility guidelines in its rules.
I will be using this font as an example:
https://fonts.google.com/specimen/Righteous
- Click the "+ Select this style" button on the right side of the font preview area.
Screenshot
- A sidebar should open on the right, but if it doesn't click the square/+ icon in the very upper right of the page. (shown in upper right of screenshot above)
- Change from the "Review" to the "Embed" tab on the side bar. Under "Use on the web", change the radio button to "@import". Copy the URL only from the code - make sure to not grab either of the single quotes.
Screenshot
- Paste that link into a new browser window/tab. You should see some codes. Most English speakers should only need the /* latin */ block, but for other characters you may need latin-ext or perhaps even other alphabets (if available). You may need to scroll down to find it. Copy it.
Screenshot
- Include that code in your [style] tag, then use the [font=?] tag or font-family CSS property to apply it to the area you want it. If the font name has a space in it, you must put single or double quotes around it.
This is some sample text with the font tag.
Another example
This is a display box with the font as its header.Code
[font="Righteous"]This is some sample text with the font tag.[/font] [display=Another example]This is a display box with the font as its header.[/display] [style] .panel h3 { font-family: "Righteous"; } /* latin */ @font-face { font-family: 'Righteous'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/righteous/v9/1cXxaUPXBpj2rGoU7C9WiHGF.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } [/style]
CSS snippets for skins
Fast/compact party clicking
This is my version of the stacked/rapid party clicking mod. This is *not* compatible with the QoL party features.
You must be in compact mode for the code to take effect. (This way you can easily turn it off!) The code forces the compact check to appear even on mobile.
Screenshot
Code
/* Collapse party for quick clicking in compact mode */
.multi-compact #multiuser {
.fieldslink, .party .pkmn, .party .name, .party .working,
.berrybuttons .tooltip_content, .compact-view-toggle+label {
display: none !important;
}
#profilepage {
overflow: visible;
display: flex;
flex-direction: column;
align-items: center;
}
#partybox .party {
margin-top: 15px;
margin-bottom: 15px;
height: 50px;
position: relative;
/* Show party icons along side of click area */
> div[data-pid] .pkmn {
display: block !important;
}
> div:nth-of-type(1) .pkmn {
left: -50px;
top: -20px;
}
> div:nth-of-type(2) .pkmn {
left: -50px;
top: 30px;
}
> div:nth-of-type(3) .pkmn {
left: -50px;
top: 80px;
}
> div:nth-of-type(4) .pkmn {
left: 265px;
top: -20px;
}
> div:nth-of-type(5) .pkmn {
left: 265px;
top: 30px;
}
> div:nth-of-type(6) .pkmn {
left: 265px;
top: 80px;
}
> div {
position: absolute;
top: 0;
left: 0;
> .action {
float: none;
width: 100%;
height: 39px;
a, table {
width: 100%;
position: absolute;
left: 0;
top: 0;
}
a {
z-index: 98;
}
.berrybuttons[data-up='sour']>[data-berry='aspear'],
.berrybuttons[data-up='spicy']>[data-berry='cheri'],
.berrybuttons[data-up='dry']>[data-berry='chesto'],
.berrybuttons[data-up='sweet']>[data-berry='pecha'],
.berrybuttons[data-up='bitter']>[data-berry='rawst'] {
z-index: 99;
}
}
}
}
#partybox .mu_navlink.prev {
margin-left: 30px;
}
#partybox .mu_navlink.next {
margin-right: 30px;
}
/* Fix checkbox position */
.compact-view-toggle {
margin-left: 30px;
margin-top: 10px;
width: 50%;
text-align: left;
}
}
/* Force compact toggle to always appear */
.compact-view-toggle {
display: inline-block !important;
}
/* Fix a bug where the prev/next buttons are duplicated */
.prev+.next+.prev, .prev+.next+.prev+.next,
.compact-view-toggle+label+.compact-view-toggle,
.compact-view-toggle+label+.compact-view-toggle+label,
.compact-view-toggle+.compact-view-toggle {
display: none;
}
Enlarge field click zone
This code stacks all Pokemon in a field, then enlarges the click zone to fill the entire field area. The green/red background will still appear small, but the entire area will be clickable once a berry is selected. Great for touch screens!
This is *not* compatible with the QoL and other field stack/sort codes.
Code
/* Increase click zone when berry is selected */
#field_field>div.field>.fieldmon {
transition: none !important;
}
#field_berries.selected+#field_field>div.field>.fieldmon {
left: 0 !important;
top: 0 !important;
margin: 0 !important;
width: 60% !important;
height: 100% !important;
padding-left: 40% !important;
.small { display: none !important; }
.big { display: block !important; }
}
Change berry images
Changes the berry images in parties, fields, and summary pages, including the drag berry icon for the field click accessibility tool. Does *not* change the berries for pkmnpanels in forums & signatures... the code conflicted too much with the common pkmnpanel customizations people use.
Change the background-image URLs to customize. You shouldn't need to change anything else, the images will auto-resize, but try to choose appropriately sized images to prevent resize distortion.
This code was updated Jan 1 2024 to work better with holiday changes. Please feel free to contact me if you notice any problems. The new version cannot be used in the QoL CSS box without being compiled first, but should work fine in skins.
Pi day pie sprites on Wiki
Code
/* --- CHANGE ME --- */
/* big berries */
@sour-big: url("/img/pkmn/e/e/b.png");
@spicy-big: url("/img/pkmn/5/l/t.png");
@dry-big: url("/img/pkmn/b/g/x.png");
@sweet-big: url("/img/pkmn/6/v/3/l.png");
@bitter-big: url("/img/pkmn/4/w/v.png");
/* small berries */
@sour-small: url("/img/pkmn/f/h/l.png");
@spicy-small: url("/img/pkmn/v/m/7.png");
@dry-small: url("/img/pkmn/i/v/j.png");
@sweet-small: url("/img/pkmn/3/o/5/5.png");
@bitter-small: url("/img/pkmn/2/z/e.png");
/* --- do not change below this line --- */
/* small berries */
#profilepage .berrybuttons {
a[data-berry="aspear"] img,
a[data-berry="cheri"] img,
a[data-berry="chesto"] img,
a[data-berry="pecha"] img,
a[data-berry="rawst"] img {
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
height: 0;
padding-top: 24px;
width: 24px;
}
a[data-berry="aspear"] img {
background-image: @sour-small !important;
}
a[data-berry="cheri"] img {
background-image: @spicy-small !important;
}
a[data-berry="chesto"] img {
background-image: @dry-small !important;
}
a[data-berry="pecha"] img {
background-image: @sweet-small !important;
}
a[data-berry="rawst"] img {
background-image: @bitter-small !important;
}
}
/* big berries */
#partypage .berrybuttons,
#summarypage .berrybuttons,
#field_berries {
a[data-berry="aspear"] img,
a[data-berry="cheri"] img,
a[data-berry="chesto"] img,
a[data-berry="pecha"] img,
a[data-berry="rawst"] img {
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
height: 0;
padding-top: 52px;
width: 40px;
}
a[data-berry="aspear"] img {
background-image: @sour-big !important;
}
a[data-berry="cheri"] img {
background-image: @spicy-big !important;
}
a[data-berry="chesto"] img {
background-image: @dry-big !important;
}
a[data-berry="pecha"] img {
background-image: @sweet-big !important;
}
a[data-berry="rawst"] img {
background-image: @bitter-big !important;
}
}
/* field drag may not work during holidays */
.berrydragghost {
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
}
.berrydragghost[style*="/img/items/aspearberry.png"] {
background-image: @sour-small !important;
}
.berrydragghost[style*="/img/items/cheriberry.png"] {
background-image: @spicy-small !important;
}
.berrydragghost[style*="/img/items/chestoberry.png"] {
background-image: @dry-small !important;
}
.berrydragghost[style*="/img/items/pechaberry.png"] {
background-image: @sweet-small !important;
}
.berrydragghost[style*="/img/items/rawstberry.png"] {
background-image: @bitter-small !important;
}
Halloween candy image URLs
Big:
https://pfq-static.com/img/events/halloween/sour.candy.big.png
https://pfq-static.com/img/events/halloween/spicy.candy.big.png
https://pfq-static.com/img/events/halloween/dry.candy.big.png
https://pfq-static.com/img/events/halloween/sweet.candy.big.png
https://pfq-static.com/img/events/halloween/bitter.candy.big.png
Small:
https://pfq-static.com/img/events/halloween/sour.candy.png
https://pfq-static.com/img/events/halloween/spicy.candy.png
https://pfq-static.com/img/events/halloween/dry.candy.png
https://pfq-static.com/img/events/halloween/sweet.candy.png
https://pfq-static.com/img/events/halloween/bitter.candy.png
Christmas treat image URLs
Big:
https://pfq-static.com/img/events/christmas/sour.sweet.big.png
https://pfq-static.com/img/events/christmas/spicy.sweet.big.png
https://pfq-static.com/img/events/christmas/dry.sweet.big.png
https://pfq-static.com/img/events/christmas/sweet.sweet.big.png
https://pfq-static.com/img/events/christmas/bitter.sweet.big.png
Small:
https://pfq-static.com/img/events/christmas/sour.sweet.png
https://pfq-static.com/img/events/christmas/spicy.sweet.png
https://pfq-static.com/img/events/christmas/dry.sweet.png
https://pfq-static.com/img/events/christmas/sweet.sweet.png
https://pfq-static.com/img/events/christmas/bitter.sweet.png
Valentine's candy image URLs
Big:
https://pfq-static.com/img/events/valentine/sour.dessert.big.png
https://pfq-static.com/img/events/valentine/spicy.dessert.big.png
https://pfq-static.com/img/events/valentine/dry.dessert.big.png
https://pfq-static.com/img/events/valentine/sweet.dessert.big.png
https://pfq-static.com/img/events/valentine/bitter.dessert.big.png
Small:
https://pfq-static.com/img/events/valentine/sour.dessert.png
https://pfq-static.com/img/events/valentine/spicy.dessert.png
https://pfq-static.com/img/events/valentine/dry.dessert.png
https://pfq-static.com/img/events/valentine/sweet.dessert.png
https://pfq-static.com/img/events/valentine/bitter.dessert.png
Cannot post: Please log in to post