General Thread for OM Code

Approved by Hollywood.

Hi, there!
This thread intends to collect the code required to play the approved Other Metas, including Pet Mods.

How to contribute?

You may provide a Github Gist, Pastebin, or link to a similar site, containing either the code itself required to implement the OM or the diffs involved in its implementation (so a link to a dedicated commit or pull request would be cool).
This is the way to go for Pet Mods code, as well as for OMs that dynamically change (e.g. Theorymon, OM Mashup, Pokémon Throwback, etc.) Pet Mods must only show their current version. Past versions of periodical OMs can be published though.

For small, simple (code-wise) OMs, you may just post it fully, using the format showcased below.

XY OMs

Metagamiate

config/formats.js
Code:
    {
        name: "Metagamiate",
        ruleset: ['Pokemon', 'Standard', 'Baton Pass Clause', 'Swagger Clause', 'Team Preview'],
        banlist: ['Gengarite', 'Kangaskhanite', 'Lucarionite', 'Soul Dew',
            'Arceus', 'Blaziken', 'Darkrai', 'Deoxys', 'Deoxys-Attack', 'Deoxys-Defense', 'Deoxys-Speed', 'Dialga', 'Genesect', 'Giratina',
            'Giratina-Origin', 'Groudon', 'Kyogre', 'Ho-Oh', 'Kyurem-White', 'Lugia', 'Mewtwo', 'Palkia', 'Rayquaza', 'Reshiram',
            'Shaymin-Sky', 'Kyurem-White', 'Xerneas', 'Yveltal', 'Zekrom'
        ],
        onModifyMove: function(move, pokemon) {
            if (move.type === 'Normal' && move.id !== 'hiddenpower' && !pokemon.hasAbility(['aerilate', 'pixilate', 'refrigerate'])) {
                var types = pokemon.getTypes();
                if (!types[0] || types[0] === '???') return;
                move.type = types[0];
                move.isMetagamiate = true;
            }
        },
        onBasePowerPriority: 9,
        onBasePower: function(basePower, attacker, defender, move) {
            if (!move.isMetagamiate) return;
            return this.chainModify([0x14CD, 0x1000]);
        }
    }


No Ability

config/formats.js

Code:
    {
        name: "No Ability",
        mod: 'noability',
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Ignore Illegal Abilities'],
        validateSet: function (pokemon) {
            pokemon.ability = 'None';
        }
    }
mods/noability/abilities.js

Code:
exports.BattleAbilities = {
    "None": {
        desc: "This Pokemon has no ability.",
        shortDesc: "This Pokemon has no ability.",
        id: "none",
        name: "None",
        rating: 1,
        num: 1
    }
};
mods/noability/scripts.js

Code:
exports.BattleScripts = {
    init: function() {
        for (var i in this.data.Pokedex) {
            // Needed because of forme changes
            this.modData('Pokedex', i).abilities['0'] = 'None';
        }
    }
};
mods/noability/formats-data.js

Code:
exports.BattleFormatsData = {
    blaziken: {
        inherit: true,
        tier: "OU"
    },
    slaking: {
        inherit: true,
        tier: "Uber"
    },
    regigigas: {
        inherit: true,
        tier: "Uber"
    },
    shayminsky: {
        inherit: true,
        tier: "OU"
    },
    genesect: {
        inherit: true,
        tier: "OU"
    },
    aegislash: {
        inherit: true,
        tier: "OU"
    },
    gengarmega: {
        inherit: true,
        tier: "OU"
    },
    kangaskhanmega: {
        inherit: true,
        tier: "OU"
    },
    lucariomega: {
        inherit: true,
        tier: "OU"
    }
};


Pacifistmons

config/formats.js

Code:
    {
        name: "PacifistMons",
        ruleset: ['Pokemon', 'Standard', 'Team Preview'],
        banlist: ['Heatran', 'Gengarite', 'Taunt', 'Magic Guard'],
        validateSet: function(set) {
            var problems = [];
            for (var i in set.moves) {
                var move = this.getMove(set.moves[i]);
                if (move.heal) problems.push(move.name + ' is banned as it is a healing move.');
                if (move.category !== 'Status') problems.push(move.name + ' is banned as it is an attacking move.');
            }
            return problems;
        }
    }


Protean Palace

config/formats.js

Code:
    {
        name: "Protean Palace",
        ruleset: ['Pokemon', 'Standard', 'Team Preview'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite'],
        onPrepareHit: function (source, target, move) {
            var type = move.type;
            if (type && type !== '???' && source.getTypes().join() !== type) {
                if (!source.setType(type)) return;
                this.add('-start', source, 'typechange', type);
            }
        }
    }


Same Type Stealth Rock

config/formats.js

Code:
    {
        name: "Same Type Stealth Rock",
        mod: 'stsr',
        ruleset: ['OU']
    }
mods/stsr/moves.js

Code:
exports.BattleMovedex = {
    stealthrock: {
        inherit: true,
        effect: {
            onStart: function (side, source) {
                this.add('-sidestart', side, 'move: Stealth Rock');
                this.effectData.type = source.getTypes()[0];
                this.add('-message', '(' + this.effectData.type + '-type)');
            },
            onSwitchIn: function (pokemon) {
                if (pokemon.hasAbility('voltabsorb') && this.effectData.type === 'Electric') {
                    pokemon.side.removeSideCondition('stealthrock');
                    this.add('-sideend', pokemon.side, 'move: Stealth Rock', '[of] ' + pokemon);
                } else if (pokemon.hasAbility('waterabsorb') && this.effectData.type === 'Water') {
                    pokemon.side.removeSideCondition('stealthrock');
                    this.add('-sideend', pokemon.side, 'move: Stealth Rock', '[of] ' + pokemon);
                } else if (pokemon.runImmunity(this.effectData.type)) {
                    var typeMod = this.getEffectiveness(this.effectData.type, pokemon);
                    var factor = 8;
                    if (typeMod === 1) factor = 4;
                    if (typeMod >= 2) factor = 2;
                    if (typeMod === -1) factor = 16;
                    if (typeMod <= -2) factor = 32;
                    var damage = this.damage(pokemon.maxhp / factor);
                }
            }
        }
    }
};


Wonkymons

config/formats.js

Code:
    {
        name: "Wonkymons",
        mod: 'wonkymons',
        ruleset: ['OU'],
        banlist: ['Tyranitar', 'Charizard', 'Mantyke']
    }
mods/wonkymons/pokedex.js

Pokedex file.




Old Gen OMs

Nothing to see here... (yet)

Nothing to see here... (yet)


Also, useful references:
 
Last edited:

Monte Cristo

Banned deucer.
when you make a thread like this- it's like asking me to get out of "retirement" (quitting)
https://github.com/Oiawesome/Final-OM-Serv
the commit history is fucked up and things because terminal wasn't being the nicest thing in the world at 6 am in the morn but it does have all the data in all the right places.

EDIT: Kalos 2 was privately disbanded so I never finished coding past beta 3- I'm sure I have the code for beta 3 somewhere- although I think the only copy of B3 is in my old broken desktop. So I guess you'll just have to put up w/ beta 2 for now! Not that anybody cares about Kalos 2 that is.
 
when you make a thread like this- it's like asking me to get out of "retirement" (quitting)
https://github.com/Oiawesome/Final-OM-Serv
the commit history is fucked up and things because terminal wasn't being the nicest thing in the world at 6 am in the morn but it does have all the data in all the right places.

EDIT: Kalos 2 was privately disbanded so I never finished coding past beta 3- I'm sure I have the code for beta 3 somewhere- although I think the only copy of B3 is in my old broken desktop. So I guess you'll just have to put up w/ beta 2 for now! Not that anybody cares about Kalos 2 that is.
But I care about K2...
;_;7 rip in peace
 

EV

Banned deucer.
If someone can teach me how to (again), I'd be glad to do the grunt work for changing the code for Wonkymons. I did it for Joim last time and then he hosted it in the lab, so I think I can do it again. I just need some help getting started.
 
I just wrote a script that is able to process a CSV file (which is one of the extensions supported by MS Excel and Google Docs) and generates a pokedex.js file readable by Pokémon Showdown.

By default, when it's ran using Node.js, it will read the pokedex.csv file in the same directory, and generate a file named pokedex.js.out, which you will need to rename and move to the appropriate path in its mod directory.

Any part of the Pokedex can be edited using this (no learnsets/tiers).

  • Create a spreadsheet (see valid format below), and save it as a CSV file. How to: In Google Sheets: File -> Download as -> Comma-separated values (.csv, current sheet). In Microsoft Excel: File -> Save as -> Save as type -> CSV (comma delimited) -> Save.
  • Download Node.js and install it.
  • Download the script to the path where your CSV file is (default pokedex.csv).
  • Open the command line. (In Windows / In OS X / If you are using Linux you'd better know.)
  • Navigate to the path where the script and CSV files are (In Windows / In OS X).
  • Type the following:
Code:
node pokedex-generator.js
It's done! Rename the file, which by default is originally named pokedex.js.out, and move it to the mod folder.


What's a valid format for the data?

Basically, you need a spreadsheet where the headers (the first row) say what kind of data each column contains.
If you don't need to edit a type of data for any Pokémon, you may just remove that column. If you don't need to edit a value for some Pokémon, you may leave the cell blank.
Furthermore, for any kind of data that can accept multiple subvalues, they should be separated by slashes (/).
Anyway, I guess it's better to see it by yourself.


First results of this script:

Wonkymons:
- Google Docs spreadsheet
- Downloaded as CSV
- Processed

UPDATE: Added details about usage and changed most links for clarity.
 
Last edited:

Monte Cristo

Banned deucer.
I just wrote a script that is able to process a CSV file (which is one of the extensions supported by MS Excel and Google Docs) and generates a pokedex.js file readable by Pokémon Showdown.

By default, when it's ran using Node.js, it will read the 'pokedex.csv' file in the same path, and generate a file named 'pokedex.js.out', which you will need to rename and move to the appropriate path in its mod directory.

Any part of the Pokedex can be edited using this (no learnsets/tiers).

First results of this script:

Wonkymons:
- Google Docs spreadsheet.
- Downloaded as CSV.
- Converted to a format readable by the script.
- Processed.
You've made a fucking ridiculous breakthrough for hardworking non programmers in the OM community with this script. Thank you lol. Its a shame I won't be here for this to be used in action!
 

Kit Kasai

Love colored magic
I just wrote a script that is able to process a CSV file (which is one of the extensions supported by MS Excel and Google Docs) and generates a pokedex.js file readable by Pokémon Showdown.

By default, when it's ran using Node.js, it will read the 'pokedex.csv' file in the same path, and generate a file named 'pokedex.js.out', which you will need to rename and move to the appropriate path in its mod directory.

Any part of the Pokedex can be edited using this (no learnsets/tiers).

First results of this script:

Wonkymons:
- Google Docs spreadsheet.
- Downloaded as CSV.
- Converted to a format readable by the script. (This step is magic. Hopefully you will write your spreadsheet having already a readable format.)
- Processed.
o-oh yeah? w-well I made a house out of legos today.

;______;
 

EV

Banned deucer.
I just wrote a script that is able to process a CSV file (which is one of the extensions supported by MS Excel and Google Docs) and generates a pokedex.js file readable by Pokémon Showdown.

By default, when it's ran using Node.js, it will read the 'pokedex.csv' file in the same path, and generate a file named 'pokedex.js.out', which you will need to rename and move to the appropriate path in its mod directory.

Any part of the Pokedex can be edited using this (no learnsets/tiers).

First results of this script:

Wonkymons:
- Google Docs spreadsheet.
- Downloaded as CSV.
- Converted to a format readable by the script. (This step is magic. Hopefully you will write your spreadsheet having already a readable format.)
- Processed.
This is really cool! What do I need to do now to get it playable?? :D
 

Monte Cristo

Banned deucer.
Sorry to bombard you with questions but will it work for pokemon who don't exist yet if the inhert = "true" part of the script is reworked? for metas such as Pop Culture Mons and Megas for All.

also turning the inherit off and writing the pokemon from scratch could work as a decent client side pokedex.js script, or are there other filters in check?
 
Sorry to bombard you with questions but will it work for pokemon who don't exist yet if the inhert = "true" part of the script is reworked? for metas such as Pop Culture Mons and Megas for All.

also turning the inherit off and writing the pokemon from scratch could work as a decent client side pokedex.js script, or are there other filters in check?
There is no problem if you keep the inherit flag there. It only has an effect if you use it in already existing Pokémon (though you may want to remove it for file size reasons).
Also yea, the client-side pokedex.js file is the same as server-side. You will need to add their formats-data and learnsets entries though.

UPDATE:
You may now remove the inherit flag by running
Code:
node pokedex-generator.js --new
 
Last edited:

Pikachuun

the entire waruda machine
Thread
config/formats.js
Code:
    {
        name: "Clockmons",
        section: "Other Metagames",

        mod: 'clockmons',
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite', 'Mawilite']
    },
{Note: Delete the comma if this is the last metagame in your list.
Replace Other Metagames with whatever you like if you don't want this in the Other Metagames section of your PS.}

mods/clockmons/statuses.js
Code:
exports.BattleStatuses = {
    raindance: {
        inherit: true,
        duration: 10,
        durationCallback: function (source, effect) {
            if (source && source.item === 'damprock') {
                return 13;
            }
            return 10;
        }
    },
    sunnyday: {
        inherit: true,
        duration: 10,
        durationCallback: function (source, effect) {
            if (source && source.item === 'heatrock') {
                return 13;
            }
            return 10;
        }
    },
    sandstorm: {
        inherit: true,
        duration: 10,
        durationCallback: function (source, effect) {
            if (source && source.item === 'smoothrock') {
                return 13;
            }
            return 10;
        }
    },
    hail: {
        inherit: true,
        duration: 10,
        durationCallback: function (source, effect) {
            if (source && source.item === 'icyrock') {
                return 13;
            }
            return 10;
        }
    }
};
clockmons/moves.js
 
Last edited:

Pikachuun

the entire waruda machine
Double Post but meh
config/formats.js
Code:
    {
        name: "Multitype Mansion",
        section: "Other Metagames",
      
        mod: 'multitype',
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause', 'Judgment Day'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite'],
        onSwitchInPriority: 101,
        onSwitchIn: function (pokemon) {
            var type = this.runEvent('Plate', pokemon);
            this.add('-message', type);
            if (!type || type === true) {
                type = pokemon.types;
            };
            pokemon.setType(type, true);
        }
    },
Same deal as always, get rid of the comma if this is your last format, and replace "Other Metagames" with whatever you want.
mods/multitype/scripts.js
Code:
exports.BattleScripts = {
    init: function() {
        for (var i in this.data.Learnsets) {
            if (this.modData('Learnsets', i).learnset.judgment) {
                this.modData('Learnsets', i).learnset.judgment = this.data.Learnsets[i].learnset.judgment && ['6L1'];
            } else {
                this.modData('Learnsets', i).learnset.judgment = ['6L1'];
            }
        }
    }
};
mods/multitype/rulesets.js
Code:
exports.BattleFormats = {
    judgmentday: {
        effectType: 'Banlist',
        name: 'Judgment Day',
        validateSet: function (set) {
            var item = this.getItem(set.item);
            var template = this.getTemplate(set.species);
            var problems = [];
            var moves = [];
            if (set.moves) {
                var hasMove = {};
                var judgmentCheck = false;
                for (var i = 0; i < set.moves.length; i++) {
                    var move = this.getMove(set.moves[i]);
                    var moveid = move.id;
                    if (moveid === 'judgment') {
                        judgmentCheck = true;
                    }
                }      
            }
            if (judgmentCheck && (!item || !item.onPlate)) {
                problems.push((set.name || set.species) + ' needs to hold a plate in order to use Judgment.');
            }
            return problems;
        }
    }
}
Done, tested, and confirmed.

Also, I would love for this to be stickied, The Eevee General
 
Last edited:
Thread
config/formats.js
Code:
{
    name: "Type Remix",
    section: "Other Metagames",

    mod: 'typeremix',
    ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause', 'Type Remix'],
    banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite', 'Mawilite']
}
team-validator.js
Code:
if (format.id === 'typeremix') {
    var megaTypes = [];
    for (var m = 0; m < template.otherFormes; m++){
    var otherFormeTemp = tools.getTemplate(template.otherFormes[m]);
    if (otherFormeTemp.isMega){
        for(var i = 0; i <otherFormeTemp.types; i++){megaTypes.push(otherFormeTemp.types[i]);}
    }
    }
    if (template.types.indexOf(tools.getMove(move).type) > -1 || (megaTypes && megaTypes.indexOf(tools.getMove(move).type) > -1)){
        var stabs = {
            "normal":{'extremespeed':1,'hypervoice':1,'recover':1,'rapidspin':1},
            "fighting":{'closecombat':1,'aurasphere':1,'bulkup':1,'drainpunch':1},
            "flying":{'bravebird':1,'hurricane':1,'roost':1,'acrobatics':1},
            "poison":{'poisonjab':1,'sludgebomb':1,'toxicspikes':1,'coil':1},
            "ground":{'earthquake':1,'hypervoice':1,'spikes':1,'bonemerang':1},
            "rock":{'stoneedge':1,'powergem':1,'stealthrock':1,'rockblast':1},
            "bug":{'megahorn':1,'bugbuzz':1,'quiverdance':1,'uturn':1},
            "ghost":{'shadowclaw':1,'shadowball':1,'destinybond':1,'nightshade':1},
            "steel":{'ironhead':1,'flashcannon':1,'autotomize':1,'gyroball':1},
            "fire":{'flareblitz':1,'fireblast':1,'willowisp':1,'flamecharge':1},
            "water":{'waterfall':1,'hydropump':1,'soak':1,'scald':1},
            "grass":{'woodhammer':1,'leafstorm':1,'leechseed':1,'gigadrain':1},
            "electric":{'wildcharge':1,'thunderbolt':1,'thunderwave':1,'voltswitch':1},
            "psychic":{'zenheadbutt':1,'psychic':1,'calmmind':1,'trickroom':1},
            "ice":{'iciclecrash':1,'icebeam':1,'haze':1,'iceshard':1},
            "dragon":{'outrage':1,'dracometeor':1,'dragondance':1,'dragonpulse':1},
            "dark":{'knockoff':1,'darkpulse':1,'nastyplot':1,'foulplay':1},
            "fairy":{'playrough':1,'moonblast':1,'moonlight':1,'drainingkiss':1}
        };
        var moveType = tools.getMove(move).type;
        if (stabs[moveType]){
            if (stabs[moveType][tools.getMove(move).id]) return false;
        }
    }
}
Due to the changes in Type RemiXY, this code has to be added after line ~584 (that contains "alreadyChecked[template.speciesid] = true;") and before the line ~587 (that contains "if (template.learnset)")
mods/typeremix/pokedex.js
Link
mods/typeremix/rulesets.js
Code:
exports.BattleFormats = {
    typeremix: {
        effectType: 'Banlist',
        name: 'Type Remix',
        validateSet: function (set) {
            var template = this.getTemplate(set.species);
            var lset = template.learnset;
            var countType = [];
            for (var i = 0; i < set.moves.length; i++){
                if (!lset[set.moves[i]]) countType[this.getMove(set.moves[i]).type]++;
            }
            for (var i in countType){
                if (countType[i].length > 1) return [(set.name || set.species) + "has more than 1 new "+i+"-type move."];
            }
        }
    }
}

EDIT: I am going to post all the metas I coded in this post until it runs out of character limit (does smogon forums have a character limit?)
Thread
config/formats.js
Code:
{
    name: "Ball Cup",
    section: "Other Metagames",

    mod: 'ballcup',
    ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause','Item Clause'],
    banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite', 'Mawilite']
},
mods/ballcup/items.js
Link
Thread
config/formats.js
Code:
{
        name: "Reliablemons",
        section: "Other Metagames",

        ruleset: ['Pokemon', 'Standard', 'Team Preview'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite'],
        onModifyMove: function(move, pokemon) {
            var moves = pokemon.moves;
            if (move.id === moves[0]) {
                var cheese = 0;
                var crackers = true;
            } else if (move.id === moves[1] && pokemon.typesData[1]) {
                var cheese = 1;
                var crackers = true;
            } else {
                var crackers = false;
            }
            if (crackers) {
                move.type = pokemon.typesData[cheese].type;
            }
        }
    },
Thread
config/formats.js
Code:
    {
        name: "Technician Tower",
        section: "Other Metagames",

        mod:'technichiantower',
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite', 'Mawilite','Heracronite', 'Technician'],
        validateSet: function(set) {
            for (var i in set.moves) {
                var move = this.getMove(string(set.moves[i]));
                if (move.basePower && move.basePower >= 90 && !(move.id in {'frustration':1,'return':1})) return ['The move ' + move.name + ' is banned because it has >90 Base Power.'];
                if (move.id === 'frustration' && set.happiness < 105) return ['The move Frustration is banned because Pokemon ' + (set.name || set.species) + ' has less than 105 happiness'];
                if (move.id === 'return' && set.happiness > 150) return ['The move Return is banned because Pokemon ' + (set.name || set.species) +  'has more than 150 happiness'];
                if (move.basePowerCallback) return ['The move ' + move.name + ' is banned because it has a variable BP'];
                if (move.basePower && move.basePower > 63 && set.ability in {'Pixilate':1,'Aerilate':1,'Refrigerate':1}) return ['The move ' + move.name + ' is banned for Pokemon with an -ate ability.']
            }
        },
        onBasePowerPriority: 8,
        onBasePower: function (basePower, attacker, defender, move) {
            if (basePower <= 60) {
                this.debug('Technician boost');
                return this.chainModify(1.5);
            }
        },
    },
mods/technichiantower/scripts.js
Code:
exports.BattleScripts = {
    init: function() {
        this.modData('Pokedex', 'scizormega').abilities['0'] = 'Swarm';
    }
}
Thread
config/formats.js
Code:
    {
        name: "Immunimons",
        section: "Other Metagames",

        ruleset: ['OU'],
        banlist: [],
        onTryHit: function (target, source, move) {
            if (target === source || move.type === '???' || move.id === 'struggle') return;
            if (target.hasType(move.type)) {
                this.add('-debug','immunimons immunity [' + move.id + ']');
                return null;
            }
        },
        onDamage: function (damage, target, source, effect) {
            if ((source.hasType('Rock') && effect.id === 'stealthrock') || (source.hasType('Ground') && effect.id === 'spikes')) {
                this.add('-debug','immunimons immunity [' + effect.id + ']');
                return false;
            }
        },
    },
Thread
config/formats.js
Code:
    {
        name: "Stat Preference",
        section: "XY Singles",

        mod: 'statpreference',
        ruleset: ['OU'],
        banlist: ['']
    },
mods/statpreference/scripts.js
Code:
exports.BattleScripts = {
    pokemon: {
        formeChange: function (template, dontRecalculateStats) {
            template = this.battle.getTemplate(template);

            if (!template.abilities) return false;
            this.illusion = null;
            this.template = template;
            this.types = template.types;
            this.typesData = [];
            for (var i = 0, l = this.types.length; i < l; i++) {
                this.typesData.push({
                    type: this.types[i],
                    suppressed: false,
                    isAdded: false
                });
            }

            if (!dontRecalculateStats) {
                for (var statName in this.stats) {
                    var stat = this.template.baseStats[statName];
                 
                    if (this.set.shiny) {
                        var newStat;
                        if (statName === 'atk') newStat = 'spa';
                        if (statName === 'def') newStat = 'spd';
                        if (statName === 'spa') newStat = 'atk';
                        if (statName === 'spd') newStat = 'def';
                        if (newStat) stat = this.template.baseStats[newStat];
                    }
                 
                    stat = Math.floor(Math.floor(2 * stat + this.set.ivs[statName] + Math.floor(this.set.evs[statName] / 4)) * this.level / 100 + 5);

                    // nature
                    var nature = this.battle.getNature(this.set.nature);
                    if (statName === nature.plus) stat *= 1.1;
                    if (statName === nature.minus) stat *= 0.9;
                    this.baseStats[statName] = this.stats[statName] = Math.floor(stat);
                }
                this.speed = this.stats.spe;
            }
            return true;
        }
    }
};
 
Last edited:

Pikachuun

the entire waruda machine
config/formats.js
Code:
   {
        name: "Atk-Def Equality",
        section: "Other Metagames",
       
        mod: 'atkdef',
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite']
    },
Does everyone know the drill yet? Yes? Good.
mods/atkdef/scripts.js
Code:
exports.BattleScripts = {
    init: function() {
        for (var i in this.data.Pokedex) {
            var atk = this.data.Pokedex[i].baseStats.atk;
            var def = this.data.Pokedex[i].baseStats.def;
            var spa = this.data.Pokedex[i].baseStats.spa;
            var spd = this.data.Pokedex[i].baseStats.spd;
            if (atk > def) {
                this.data.Pokedex[i].baseStats.def = atk;
            } else {
                this.data.Pokedex[i].baseStats.atk = def;
            }
            if (spa > spd) {
                this.data.Pokedex[i].baseStats.spd = spa;
            } else {
                this.data.Pokedex[i].baseStats.spa = spd;
            }
        }
    }
};
 

Pikachuun

the entire waruda machine
config/formats.js
Code:
    {
        name: "Gendermons",
        section: "Other Metagames",

        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite'],
        onModifyAtkPriority: 42,
        onModifyAtk: function (atk, pokemon) {
            if (pokemon.gender === 'M') {
                return this.chainModify(1.2);
            } else if (pokemon.gender === 'F') {
                return this.chainModify(.8);
            }
        },
        onModifyDefPriority: 42,
        onModifyDef: function (def, pokemon) {
            if (pokemon.gender === 'M') {
                return this.chainModify(1.2);
            } else if (pokemon.gender === 'F') {
                return this.chainModify(.8);
            }
        },
        onModifySpAPriority: 42,
        onModifySpA: function (spa, pokemon) {
            if (pokemon.gender === 'F') {
                return this.chainModify(1.2);
            } else if (pokemon.gender === 'M') {
                return this.chainModify(.8);
            }
        },
        onModifySpDPriority: 42,
        onModifySpD: function (spd, pokemon) {
            if (pokemon.gender === 'F') {
                return this.chainModify(1.2);
            } else if (pokemon.gender === 'M') {
                return this.chainModify(.8);
            }
        }
    },
You know the drill.
Can/Will the script do movepool edits?
Not to my knowledge, however that's quite easy to do by copy-pasting a line of code and modifying it accordingly anyway (I believe Multitype Mansion does this for every pokemon by using a for loop).

EDIT:
config/formats.js
Code:
    {
        name: "Noobmons",
        section: "Other Metagames",
    
        mod: 'noobmons',
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite']
    },
At this point everyone knows what to do o3o
mods/noobmons/typechart.js
Too long for a hide tag.
 
Last edited:
So I finally managed to push the required changes to main's repository, and I can share the code for Camomons and Type Control.

Camomons

config/formats.js

Code:
    {
        name: "Camomons",
        mod: 'camomons',
        ruleset: ['OU', 'Clean Nickname Clause']
    }
data/rulesets.js

Code:
cleannicknameclause: {
        effectType: 'Rule',
        onStart: function () {
            this.add('rule', "Clean Nickname Clause: only ASCII characters may be used to name Pokémon");
        },
        validateSet: function (pokemon) {
            if (!pokemon.name) return;
            pokemon.name = pokemon.name.replace(/[^\u0000-\u007F]/g, '');
        }
    }


mods/camomons/moves.js

Code:
exports.BattleMovedex = {
    sketch: {
        inherit: true,
        onHit: function (target, source) {
            var disallowedMoves = {chatter:1, sketch:1, struggle:1};
            if (source.transformed || !target.lastMove || disallowedMoves[target.lastMove] || source.moves.indexOf(target.lastMove) !== -1) return false;
            var moveslot = source.moves.indexOf('sketch');
            if (moveslot === -1) return false;
            var move = Tools.getMove(target.lastMove);
            var sketchedMove = {
                move: move.name,
                id: move.id,
                pp: move.pp,
                maxpp: move.pp,
                target: move.target,
                disabled: false,
                used: false
            };
            source.moveset[moveslot] = sketchedMove;
            source.baseMoveset[moveslot] = sketchedMove;
            source.moves[moveslot] = toId(move.name);
            if (moveslot < 2 && move.type !== 'Normal') {
                // Camomons-specific
                source.typesData[moveslot] = {
                    type: move.type,
                    suppressed: false,
                    isAdded: false
                };
            }
            this.add('-activate', source, 'move: Sketch', move.name);
        }
    },
    mimic: {
        inherit: true,
        onHit: function (target, source) {
            var disallowedMoves = {chatter:1, mimic:1, sketch:1, struggle:1, transform:1};
            if (source.transformed || !target.lastMove || disallowedMoves[target.lastMove] || source.moves.indexOf(target.lastMove) !== -1) return false;
            var moveslot = source.moves.indexOf('mimic');
            if (moveslot === -1) return false;
            var move = Tools.getMove(target.lastMove);
            source.moveset[moveslot] = {
                move: move.name,
                id: move.id,
                pp: move.pp,
                maxpp: move.pp,
                target: move.target,
                disabled: false,
                used: false
            };
            source.moves[moveslot] = toId(move.name);
            if (moveslot < 2 && move.type !== 'Normal') {
                // Camomons-specific
                source.typesData[moveslot] = {
                    type: move.type,
                    suppressed: false,
                    isAdded: false
                };
            }
            this.add('-start', source, 'Mimic', move.name);
        }
    }
};
mods/camomons/scripts.js


Code:
exports.BattleScripts = {
    pokemon: {
        formeChange: function (template, dontRecalculateStats) {
            template = this.battle.getTemplate(template);

            if (!template.abilities) return false;
            this.illusion = null;
            this.template = template;
            this.types = template.types;
            this.typesData = [];

            var typingMoves = [];
            for (var i=0, l=Math.min(this.moveset.length, 2); i<l; i++) {
                typingMoves.push(this.battle.getMove(this.moveset[i].id));
            }
            this.typesData = typingMoves.map('type').unique().map(function (type) {
                return {
                    type: type,
                    suppressed: false,
                    isAdded: false
                };
            });
            if (!dontRecalculateStats) {
                for (var statName in this.stats) {
                    var stat = this.template.baseStats[statName];
                    stat = Math.floor(Math.floor(2 * stat + this.set.ivs[statName] + Math.floor(this.set.evs[statName] / 4)) * this.level / 100 + 5);

                    // nature
                    var nature = this.battle.getNature(this.set.nature);
                    if (statName === nature.plus) stat *= 1.1;
                    if (statName === nature.minus) stat *= 0.9;
                    this.baseStats[statName] = this.stats[statName] = Math.floor(stat);
                }
                this.speed = this.stats.spe;
            }
            return true;
        }
    }
};

Type Control

config/formats.js

Code:
    {
        name: "Type Control",
        mod: 'typecontrol',
        ruleset: ['OU', 'Clean Nickname Clause']
    }
data/rulesets.js

Code:
cleannicknameclause: {
        effectType: 'Rule',
        onStart: function () {
            this.add('rule', "Clean Nickname Clause: only ASCII characters may be used to name Pokémon");
        },
        validateSet: function (pokemon) {
            if (!pokemon.name) return;
            pokemon.name = pokemon.name.replace(/[^\u0000-\u007F]/g, '');
        }
    }
mods/typecontrol/scripts.js

Code:
exports.BattleScripts = {
    pokemon: {
        formeChange: function (template, dontRecalculateStats) {
            template = this.battle.getTemplate(template);

            if (!template.abilities) return false;
            this.illusion = null;
            this.template = template;
            this.types = template.types;
            this.typesData = [];

            var battle = this.battle;
            var modTypes = this.name.split('/').slice(0, 2).map(toId).unique().map(function (type) {
                var id = type.charAt(0).toUpperCase() + type.slice(1);
                if (!battle.data.TypeChart.hasOwnProperty(id)) return;
                return id;
            }).compact();
            if (!modTypes.length) modTypes = template.types;

            this.typesData = modTypes.map(function (type) {
                return {
                    type: type,
                    suppressed: false,
                    isAdded: false
                };
            });
            if (!dontRecalculateStats) {
                for (var statName in this.stats) {
                    var stat = this.template.baseStats[statName];
                    stat = Math.floor(Math.floor(2 * stat + this.set.ivs[statName] + Math.floor(this.set.evs[statName] / 4)) * this.level / 100 + 5);

                    // nature
                    var nature = this.battle.getNature(this.set.nature);
                    if (statName === nature.plus) stat *= 1.1;
                    if (statName === nature.minus) stat *= 0.9;
                    this.baseStats[statName] = this.stats[statName] = Math.floor(stat);
                }
                this.speed = this.stats.spe;
            }
            return true;
        }
    }
};


Enjoy! Tagging Adrian Marin and mezomi because they have waited long enough.

IMPORTANT: If you want to host any of these two metagames, you will need the latest Pokémon Showdown version (as it is implied in the introduction).
 
Last edited:

Pikachuun

the entire waruda machine
Hey look at that slayer posted so I can make a new post for this now :D
config/formats.js
Code:
    {
        name: "Acid Rain",
        section: "Other Metagames",
   
        mod: 'acidrain',
        onBegin: function() {
            this.setWeather('raindance');
            delete this.weatherData.duration;
            this.add('-message', "Eh, close enough.");
        },
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite', 'Weather Ball', 'Castform']
    },
you get it by now
mods/acidrain
The code was too long for a hide-tag, so I put them all in a pastebin. File names are also indicated there too.
Just use Ctrl + F to find the js files (abilities, moves, typechart, statuses) and copy the code below it. I'll just presume you know what you doing when you copy-paste these.
 
Last edited:
Hey look at that slayer posted so I can make a new post for this now :D
config/formats.js
Code:
    {
        name: "Acid Rain",
        section: "Other Metagames",
  
        mod: 'acidrain',
        onBegin: function() {
            this.setWeather('sandstorm');
            delete this.weatherData.duration;
            this.add('-message', "What do you mean it says sandstorm instead of acid rain? DO YOU KNOW WHO YOU'RE DEALING WITH?!?");
        },
        ruleset: ['Pokemon', 'Standard', 'Team Preview', 'Swagger Clause', 'Baton Pass Clause'],
        banlist: ['Uber', 'Soul Dew', 'Gengarite', 'Kangaskhanite', 'Lucarionite', 'Weather Ball', 'Castform']
    },
you get it by now
mods/acidrain
The code was too long for a hide-tag, so I put them all in a pastebin. File names are also indicated there too.
Just use Ctrl + F to find the js files (abilities, moves, typechart, statuses) and copy the code below it. I'll just presume you know what you doing when you copy-paste these.
Why not use Rain Dance as the base weather instead and give it sandstorm-like effects? It would keep the rain animation that way.
 

Pikachuun

the entire waruda machine
Why not use Rain Dance as the base weather instead and give it sandstorm-like effects? It would keep the rain animation that way.
I tried that; it crashed when I attempted it. I can always try again when I get back to my computer and see if that works, though.

EDIT: Tested again, and it does work; I just had to delete something. I've edited the pastebin accordingly
 
Last edited:

Users Who Are Viewing This Thread (Users: 1, Guests: 0)

Top