From 70bf8eb5471e4b100a671eeb7fd94520c8a7c4b0 Mon Sep 17 00:00:00 2001 From: Kevin Lau Date: Tue, 3 Feb 2015 02:59:50 -0800 Subject: [PATCH] Seasonal: Implement February Seasonal: Han vs Hun Seasonal is based on Mulan, in honor of Chinese New Year. General Shang must defeat the Huns, but his new recruits are weak! Over time, however, they will get stronger over time by training (just like the movie, they train during I'll Make A Man Out Of You.) Singing will also make them train faster. The Han Chinese also have powerful rockets at their disposal (select Octazooka in battle). However, the rockets sometimes backfire on new recruits, but as they train the chance of backfire goes down. --- config/formats.js | 110 +++++++++++++++++++++++++++++++++++++++++++ data/scripts.js | 116 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) diff --git a/config/formats.js b/config/formats.js index 9b885ba4e4..e5448a62f0 100644 --- a/config/formats.js +++ b/config/formats.js @@ -353,6 +353,116 @@ exports.Formats = [ return problems; } }, + { + // Get it? They're Han Chinese! + name: "[Seasonal] Han vs Hun", + section: "OM of the Month", + + team: 'randomSeasonalMulan', + ruleset: ['HP Percentage Mod', 'Sleep Clause Mod', 'Cancel Mod'], + onBegin: function () { + this.add('message', "General Shang! The Huns are marching towards the Imperial City! Train your recruits quickly and make your stand!"); + this.seasonal.songCount = 0; + this.seasonal.song = [ + "Let's get down to business, to defeat the Huns!", "Did they send me daughters, when I asked for sons?", + "You're the saddest bunch I ever met.", "But you can bet, before we're through...", "Mister, I'll make a man out of you!", + "Tranquil as a forest, but on fire within.", "Once you find your center, you are sure to win!", + "You're a spineless, pale, pathetic lot, and you haven't got a clue.", "Somehow, I'll make a man out of you!", + "I'm never gonna catch my breath...", "Say goodbye to those who knew me...", "Boy, was I a fool in school for cutting gym...", + "This guy's got them scared to death!", "Hope he doesn't see right through me...", "Now I really wish I knew how to swim...", + "We must be swift as a coursing river!", "With all the force of a great typhoon!", "With all the strength of a raging fire!", + "Mysterious as the dark side of the moon!", "Time is racing towards us, 'til the Huns arrive.", + "Heed my every order, and you might survive!", "You're unsuited for the rage of war.", "So pack up, go home, you're through.", + "How could I make a man out of you?", "We must be swift as a coursing river!", "With all the force of a great typhoon!", + "With all the strength of a raging fire!", "Mysterious as the dark side of the moon!" + ]; + this.seasonal.verses = {4: true, 8: true, 14: true, 18: true, 23: true, 27: true}; + this.seasonal.morale = 0; + }, + onModifyMove: function (move) { + if (move.id === 'sing') { + move.name = "Train Recruits"; + move.accuracy = 100; + move.target = "self"; + move.onTryHit = function (target, source, move) { + if (this.seasonal.songCount < this.seasonal.song.length) { + this.add('-message', '"' + this.seasonal.song[this.seasonal.songCount] + '"'); + if (this.seasonal.verses[this.seasonal.songCount]) { + this.add('-message', "Because of the difficult training, the new recruits are more experienced!"); + if (this.seasonal.songCount === 27) { + this.add('-message', "The recruits are now fully trained!"); + } + if (source.name !== 'Li Shang' && source.name !== 'Mushu') { + var boosts = (this.seasonal.morale % 2 ? {def: 1, spd: 1} : {atk: 1, spa: 1}); + this.boost(boosts, source, source, move); + } + this.seasonal.morale++; + } + this.seasonal.songCount++; + } else { + this.add('-message', "The soldiers cannot be trained further!"); + } + return null; + }; + } else if (move.id === 'octazooka') { + move.name = "Fire Rocket"; + move.category = 'Physical'; + move.basePower = 180; + move.type = '???'; + move.accuracy = 90; + delete move.secondaries; + move.ignoreOffense = true; // Fireworks not affected by boosts from morale + move.onTry = function (source, target) { + // If the soldier is inexperienced, the rocket can explode in their face. 50% chance at 0 morale, 33% at 1, 17% at 2, 0% afterwards. + if (source.name !== 'Li Shang' && (this.random(6) > (this.seasonal.morale + 2))) { + this.add('-message', "But " + source.name + "'s inexperience caused the rocket to backfire!"); + this.damage(Math.ceil(source.maxhp / 8), source, source, "the explosion", true); + return null; + } + }; + } else if (move.id === 'sacredfire') { + // Sorry, Sacred Fire's burn chance is too good for this format, since mostly Physical attackers + delete move.secondaries; + } + }, + onSwitchIn: function (pokemon) { + this.seasonal.morale = this.seasonal.morale || 0; + if (pokemon.name in {'Mulan': 1, 'Yao': 1, 'Ling': 1, 'Chien-Po': 1}) { + var offense = Math.ceil(this.seasonal.morale / 2) - 1; + var defense = Math.floor(this.seasonal.morale / 2); + this.boost({atk: offense, spa: offense, def: defense, spd: defense}, pokemon, pokemon, this.getMove('sing')); + } + + // Make Mushu Dragon/Fire type. + if (pokemon.name === 'Mushu') { + pokemon.addType('Fire'); + this.add('-start', pokemon, 'typeadd', 'Fire', '[from] ' + pokemon); + } + }, + onResidual: function () { + if (this.seasonal.songCount < this.seasonal.song.length) { + this.add('-message', '"' + this.seasonal.song[this.seasonal.songCount] + '"'); + var pokemon = null; + if (this.seasonal.verses[this.seasonal.songCount]) { + this.add('-message', "Because of the difficult training, the new recruits are more experienced!"); + if (this.seasonal.songCount === 27) { + this.add('-message', "The recruits are now fully trained!"); + } + if (this.p1.active[0].name in {'Mulan': 1, 'Yao': 1, 'Ling': 1, 'Chien-Po': 1}) { + pokemon = this.p1.active[0]; + } else if (this.p2.active[0].name in {'Mulan': 1, 'Yao': 1, 'Ling': 1, 'Chien-Po': 1}) { + pokemon = this.p2.active[0]; + } + if (pokemon && pokemon.hp) { + var boosts = (this.seasonal.morale % 2 ? {def: 1, spd: 1} : {atk: 1, spa: 1}); + this.boost(boosts, pokemon, pokemon, this.getMove('sing')); + } + this.seasonal.morale++; + } + this.seasonal.songCount++; + } + } + }, { name: "CAP", section: "Other Metagames", diff --git a/data/scripts.js b/data/scripts.js index ef2584edb7..52ed0abd8d 100644 --- a/data/scripts.js +++ b/data/scripts.js @@ -2701,5 +2701,121 @@ exports.BattleScripts = { level: level, shiny: (Math.random() * (template.id === 'missingno' ? 4 : 1024) <= 1) }; + }, + randomSeasonalMulanTeam: function (side) { + var armySide = 'china'; + var team = []; + var pokemon = ''; + var template = {}; + var set = {}; + var megaCount = 0; + var pokemonLeft = 0; + + // If the other team has been chosen, we get its opposing force. + if (this.seasonal && this.seasonal.side) { + armySide = (this.seasonal.side === 'hun' ? 'china' : 'hun'); + } else { + // First team being generated, pick a armySide at random. + armySide = (Math.random() > 0.5 ? 'china' : 'hun'); + this.seasonal = {'side': armySide}; + } + + if (armySide === 'china') { + var chinese = [ + 'accelgor', 'bisharp', 'gallade', 'hitmonchan', 'hitmonlee', 'hitmontop', 'infernape', 'lucario', 'machoke', 'medicham', + 'medicham', 'mienshao', 'pangoro', 'sawk', 'scrafty', 'scizor', 'throh', 'ursaring', 'vigoroth', 'weavile', 'zangoose' + ].randomize(); + + var weakCount = {}; + + // Add the members of the army. + var names = ["Li Shang", "Mulan", "Yao", "Ling"]; + for (var i = 0; i < chinese.length && pokemonLeft < 4; i++) { + var mainWeakness = {}; + pokemon = chinese[i]; + template = this.getTemplate(pokemon); + + // We don't want too many Fighting or Flying weaknesses, since those moves will be common + // Hard limit it to two, since after factoring in Chien-Po we might have a lot of common weakness + var mainWeakness = {}; + if (Tools.getEffectiveness('Flying', template) > 0) mainWeakness['Flying'] = true; + if (Tools.getEffectiveness('Fighting', template) > 0) mainWeakness['Fighting'] = true; + if (mainWeakness['Fighting'] && weakCount['Fighting'] >= 2) continue; + else if (mainWeakness['Flying'] && weakCount['Flying'] >= 2) continue; + else { + for (var type in mainWeakness) { + if (type in weakCount) { + weakCount[type]++; + } else { + weakCount[type] = 1; + } + } + } + + set = this.randomSet(template, pokemonLeft, !!megaCount); + if (this.getItem(set.item).megaStone) megaCount++; + set.species = toId(set.name); + set.name = names[pokemonLeft]; + set.gender = (set.name === "Mulan" ? 'F' : 'M'); + set.moves[4] = 'sing'; + set.moves[5] = 'octazooka'; + team.push(set); + pokemonLeft++; + } + + // Chien Po is very large, so he samples from a different pool of Pokemon + pokemon = ['blastoise', 'snorlax', 'golem', 'lickilicky', 'poliwrath', 'hariyama', 'magmortar'][this.random(7)]; + template = this.getTemplate(pokemon); + set = this.randomSet(template, 4, !!megaCount); + if (this.getItem(set.item).megaStone) megaCount++; + set.species = toId(set.name); + set.name = "Chien-Po"; + set.gender = 'M'; + set.moves[4] = 'sing'; + set.moves[5] = 'octazooka'; + team.push(set); + + // Add Eddie Murphy-- I mean, Mushu, to the team as a Dragonair. + template = this.getTemplate('dragonair'); + template.randomBattleMoves = ['dragondance', 'outrage', 'aquatail', 'waterfall', 'fusionbolt', 'extremespeed', 'dracometeor', 'dragonascent']; + set = this.randomSet(template, 5); + set.species = toId(set.name); + set.name = "Mushu"; + set.gender = 'M'; + set.ability = "Turboblaze"; + set.moves[4] = 'sing'; + set.moves[5] = 'sacredfire'; + team.push(set); + } else { + var huns = [ + 'aggron', 'chesnaught', 'conkeldurr', 'drapion', 'electivire', 'emboar', 'exploud', 'feraligatr', 'granbull', + 'haxorus', 'machamp', 'nidoking', 'rhyperior', 'swampert', 'tyranitar' + ].randomize(); + + for (var i = 0; i < huns.length && pokemonLeft < 5; i++) { + pokemon = huns[pokemonLeft]; + template = this.getTemplate(pokemon); + set = this.randomSet(template, pokemonLeft, !!megaCount); + if (this.getItem(set.item).megaStone) megaCount++; + set.species = toId(set.name); + if (i === 0) { + set.name = "Shan Yu"; + } else { + set.name = "Hun " + template.species; + } + set.gender = 'M'; + team.push(set); + pokemonLeft++; + } + + // Add Hayabusa the falcon. + pokemon = ['fearow', 'pidgeot', 'staraptor', 'honchkrow', 'aerodactyl', 'archeops', 'braviary', 'noivern'][this.random(8)]; + template = this.getTemplate(pokemon); + set = this.randomSet(template, 5, !!megaCount); + set.species = toId(set.name); + set.name = "Hayabusa"; + team.push(set); + } + return team; } };