From b16c1527daf8bd23fb378dfdfb7b7b01aa7edb0e Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 23 Jan 2013 16:39:14 -0800 Subject: [PATCH] Populate with current state of client --- .gitignore | 2 + .htaccess | 45 + README.md | 37 +- action.php | 315 + backup/chartmaker.php | 405 + backup/closed.php | 16 + backup/pokedex.php | 53 + backup/replay.php | 274 + backup/sekritmkuser.php | 316 + backup/teambuilder.php | 81 + backup/test.php | 8 + cache.manifest | 11 + data/abilities.js | 2613 ++++++ data/aliases.js | 126 + data/formats-data.js | 4602 +++++++++ data/formats.js | 497 + data/graphics.js | 5985 ++++++++++++ data/items.js | 3107 ++++++ data/learnsets.js | 678 ++ data/meloettabg.png | Bin 0 -> 14070 bytes data/movedex.inc.php | 8454 +++++++++++++++++ data/moves.js | 12988 ++++++++++++++++++++++++++ data/pokedex-mini.js | 708 ++ data/pokedex.js | 713 ++ data/pokedex_numlookup.inc.php | 666 ++ data/protocol.txt | 172 + data/typechart.inc.php | 381 + data/typechart.js | 385 + favicon-128.png | Bin 0 -> 11401 bytes favicon-16.png | Bin 0 -> 1040 bytes favicon-32.png | Bin 0 -> 3322 bytes favicon-48.png | Bin 0 -> 4780 bytes favicon-notify.gif | Bin 0 -> 591 bytes favicon-notify.ico | Bin 0 -> 318 bytes favicon-notify2.ico | Bin 0 -> 318 bytes favicon.gif | 0 favicon.ico | Bin 0 -> 318 bytes fx/bg-beach.png | Bin 0 -> 14238 bytes fx/bg-beachshore.png | Bin 0 -> 11147 bytes fx/bg-city.png | Bin 0 -> 11662 bytes fx/bg-dampcave.png | Bin 0 -> 13188 bytes fx/bg-deepsea.png | Bin 0 -> 12435 bytes fx/bg-desert.png | Bin 0 -> 14319 bytes fx/bg-earthycave.png | Bin 0 -> 13953 bytes fx/bg-forest.png | Bin 0 -> 15916 bytes fx/bg-icecave.png | Bin 0 -> 18044 bytes fx/bg-meadow.png | Bin 0 -> 20556 bytes fx/bg-mountain.png | Bin 0 -> 17827 bytes fx/bg-river.png | Bin 0 -> 20160 bytes fx/bg-route.png | Bin 0 -> 20505 bytes fx/bg-thunderplains.png | Bin 0 -> 16621 bytes fx/bg-volcanocave.png | Bin 0 -> 17150 bytes fx/bg.jpg | Bin 0 -> 10529 bytes fx/bg.png | Bin 0 -> 73889 bytes fx/bottombite.png | Bin 0 -> 2822 bytes fx/caltrop.png | Bin 0 -> 5288 bytes fx/closebuttonsheet.png | Bin 0 -> 1375 bytes fx/electroball.png | Bin 0 -> 9165 bytes fx/energyball.png | Bin 0 -> 6629 bytes fx/faintleft.png | Bin 0 -> 1347 bytes fx/faintright.png | Bin 0 -> 1350 bytes fx/fireball.png | Bin 0 -> 2275 bytes fx/fist.png | Bin 0 -> 1109 bytes fx/foot.png | Bin 0 -> 1122 bytes fx/icicle.png | Bin 0 -> 2158 bytes fx/leftclaw.png | Bin 0 -> 1665 bytes fx/lightning.png | Bin 0 -> 16417 bytes fx/mute.png | Bin 0 -> 5164 bytes fx/poisoncaltrop.png | Bin 0 -> 6888 bytes fx/poisonwisp.png | Bin 0 -> 5136 bytes fx/pokeball.png | Bin 0 -> 2579 bytes fx/rightclaw.png | Bin 0 -> 1593 bytes fx/rock.png | Bin 0 -> 11012 bytes fx/rock1.png | Bin 0 -> 5071 bytes fx/rock2.png | Bin 0 -> 4884 bytes fx/rocks.png | Bin 0 -> 3592 bytes fx/shadowball.png | Bin 0 -> 6950 bytes fx/sound.png | Bin 0 -> 8037 bytes fx/switchleft.png | Bin 0 -> 1387 bytes fx/switchright.png | Bin 0 -> 1397 bytes fx/topbite.png | Bin 0 -> 2785 bytes fx/versus.png | Bin 0 -> 1220 bytes fx/waterwisp.png | Bin 0 -> 6341 bytes fx/weather-hail.png | Bin 0 -> 76719 bytes fx/weather-rain.png | Bin 0 -> 95359 bytes fx/weather-raindance.jpg | Bin 0 -> 52134 bytes fx/weather-raindance.png | Bin 0 -> 95359 bytes fx/weather-sandstorm.png | Bin 0 -> 114491 bytes fx/weather-sun.png | Bin 0 -> 33128 bytes fx/weather-sunnyday.jpg | Bin 0 -> 25518 bytes fx/weather-sunnyday.png | Bin 0 -> 38634 bytes fx/weather-trickroom.png | Bin 0 -> 20836 bytes fx/wisp.png | Bin 0 -> 5103 bytes index.php | 220 + js/autoresize.jquery.min.js | 97 + js/battle.js | 4770 ++++++++++ js/battledata.js | 604 ++ js/jquery-1.7.min.js | 4 + js/jquery-cookie.js | 96 + js/jquery.json-2.3.min.js | 23 + js/ladder.js | 79 + js/sim.js | 2939 ++++++ js/sockjs-0.3.min.js | 27 + js/soundmanager2.js | 5026 ++++++++++ js/teambuilder.js | 2254 +++++ js/utilichart.js | 562 ++ ladder.php | 108 + learnsets.js | 678 ++ lib/ntbb-ladder.lib.php | 419 + lib/ntbb-ladder.sql | 49 + notification.php | 71 + pokemonshowdown.png | Bin 0 -> 5854 bytes pokemonshowdownbeta.png | Bin 0 -> 5747 bytes robots.txt | 2 + showdown.crx | Bin 0 -> 19664 bytes showdown.webapp | 23 + style/battle.css | 753 ++ style/font-awesome.css | 307 + style/font/fontawesome-webfont.eot | Bin 0 -> 38708 bytes style/font/fontawesome-webfont.svg | 255 + style/font/fontawesome-webfont.ttf | Bin 0 -> 68476 bytes style/font/fontawesome-webfont.woff | Bin 0 -> 41752 bytes style/replayer.css | 508 + style/sim-types.css | 543 ++ style/sim.css | 1748 ++++ temp.html | 135 + 126 files changed, 65935 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 action.php create mode 100644 backup/chartmaker.php create mode 100644 backup/closed.php create mode 100644 backup/pokedex.php create mode 100644 backup/replay.php create mode 100644 backup/sekritmkuser.php create mode 100644 backup/teambuilder.php create mode 100644 backup/test.php create mode 100644 cache.manifest create mode 100644 data/abilities.js create mode 100644 data/aliases.js create mode 100644 data/formats-data.js create mode 100644 data/formats.js create mode 100644 data/graphics.js create mode 100644 data/items.js create mode 100644 data/learnsets.js create mode 100644 data/meloettabg.png create mode 100644 data/movedex.inc.php create mode 100644 data/moves.js create mode 100644 data/pokedex-mini.js create mode 100644 data/pokedex.js create mode 100644 data/pokedex_numlookup.inc.php create mode 100644 data/protocol.txt create mode 100644 data/typechart.inc.php create mode 100644 data/typechart.js create mode 100644 favicon-128.png create mode 100644 favicon-16.png create mode 100644 favicon-32.png create mode 100644 favicon-48.png create mode 100644 favicon-notify.gif create mode 100644 favicon-notify.ico create mode 100644 favicon-notify2.ico create mode 100644 favicon.gif create mode 100644 favicon.ico create mode 100755 fx/bg-beach.png create mode 100755 fx/bg-beachshore.png create mode 100755 fx/bg-city.png create mode 100755 fx/bg-dampcave.png create mode 100755 fx/bg-deepsea.png create mode 100755 fx/bg-desert.png create mode 100755 fx/bg-earthycave.png create mode 100755 fx/bg-forest.png create mode 100755 fx/bg-icecave.png create mode 100755 fx/bg-meadow.png create mode 100755 fx/bg-mountain.png create mode 100755 fx/bg-river.png create mode 100755 fx/bg-route.png create mode 100755 fx/bg-thunderplains.png create mode 100755 fx/bg-volcanocave.png create mode 100755 fx/bg.jpg create mode 100755 fx/bg.png create mode 100755 fx/bottombite.png create mode 100755 fx/caltrop.png create mode 100755 fx/closebuttonsheet.png create mode 100755 fx/electroball.png create mode 100755 fx/energyball.png create mode 100755 fx/faintleft.png create mode 100755 fx/faintright.png create mode 100755 fx/fireball.png create mode 100755 fx/fist.png create mode 100755 fx/foot.png create mode 100755 fx/icicle.png create mode 100755 fx/leftclaw.png create mode 100755 fx/lightning.png create mode 100755 fx/mute.png create mode 100755 fx/poisoncaltrop.png create mode 100755 fx/poisonwisp.png create mode 100755 fx/pokeball.png create mode 100755 fx/rightclaw.png create mode 100755 fx/rock.png create mode 100755 fx/rock1.png create mode 100755 fx/rock2.png create mode 100755 fx/rocks.png create mode 100755 fx/shadowball.png create mode 100755 fx/sound.png create mode 100755 fx/switchleft.png create mode 100755 fx/switchright.png create mode 100755 fx/topbite.png create mode 100755 fx/versus.png create mode 100755 fx/waterwisp.png create mode 100755 fx/weather-hail.png create mode 100755 fx/weather-rain.png create mode 100755 fx/weather-raindance.jpg create mode 100755 fx/weather-raindance.png create mode 100755 fx/weather-sandstorm.png create mode 100755 fx/weather-sun.png create mode 100755 fx/weather-sunnyday.jpg create mode 100755 fx/weather-sunnyday.png create mode 100755 fx/weather-trickroom.png create mode 100755 fx/wisp.png create mode 100644 index.php create mode 100644 js/autoresize.jquery.min.js create mode 100644 js/battle.js create mode 100644 js/battledata.js create mode 100644 js/jquery-1.7.min.js create mode 100644 js/jquery-cookie.js create mode 100644 js/jquery.json-2.3.min.js create mode 100644 js/ladder.js create mode 100644 js/sim.js create mode 100644 js/sockjs-0.3.min.js create mode 100644 js/soundmanager2.js create mode 100644 js/teambuilder.js create mode 100644 js/utilichart.js create mode 100644 ladder.php create mode 100644 learnsets.js create mode 100755 lib/ntbb-ladder.lib.php create mode 100644 lib/ntbb-ladder.sql create mode 100644 notification.php create mode 100644 pokemonshowdown.png create mode 100644 pokemonshowdownbeta.png create mode 100644 robots.txt create mode 100644 showdown.crx create mode 100644 showdown.webapp create mode 100644 style/battle.css create mode 100644 style/font-awesome.css create mode 100755 style/font/fontawesome-webfont.eot create mode 100755 style/font/fontawesome-webfont.svg create mode 100755 style/font/fontawesome-webfont.ttf create mode 100755 style/font/fontawesome-webfont.woff create mode 100644 style/replayer.css create mode 100644 style/sim-types.css create mode 100644 style/sim.css create mode 100644 temp.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..54eb290b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/sprites/ +/audio/ diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000000..ca309b3598 --- /dev/null +++ b/.htaccess @@ -0,0 +1,45 @@ +# -FrontPage- + +#IndexIgnore .htaccess */.??* *~ *# */HEADER* */README* */_vti* + + +order deny,allow +deny from all +allow from all + + +order deny,allow +deny from all + + +AddType text/plain .phps +AddType application/x-tgz .tgz +AddType application/x-chrome-extension .crx +AddType application/x-web-app-manifest+json .webapp + + +RewriteEngine on + +RewriteCond %{HTTP_HOST} ^www\.play\.pokemonshowdown\.com$ [NC] +RewriteRule ^(.*)$ http://play.pokemonshowdown.com/$1 [R=301,L] + +RewriteRule ^$ /lobby [R=301,L] +RewriteRule ^topsekritsim\.php$ /lobby [R=301,L] +RewriteRule ^topsekrit3\.php$ /lobby [R=301,L] +RewriteRule ^temporary508\.php$ /lobby [R=301,L] +RewriteRule ^temporary508\.php$ /lobby [R=301,L] +RewriteRule ^sim\.php$ /lobby [R=301,L] + +#RewriteRule ^([A-Za-z0-9-]*)$ closed.php [L,QSA] + +RewriteRule ^(teambuilder|ladder|lobby|battle)/?$ index.php [L,QSA] +RewriteRule ^(lobby|battle)-([A-Za-z0-9-]*)$ index.php [L,QSA] + +RewriteRule ^replay/battle-([A-Za-z0-9-]+)$ http://pokemonshowdown.com/replay/$1 [R=302,L] +RewriteRule ^replay/turn_(.+)\.png$ replay/turn-image.php?data=$1 [L,QSA] + +RewriteRule ^~~([^/]*)/?$ /~~$1/lobby [R=301,L] +RewriteRule ^~~([^/]*)/(teambuilder|ladder|lobby|battle)/?$ index.php?server=$1 [L,QSA] +RewriteRule ^~~([^/]*)/(lobby|battle)-([A-Za-z0-9-]*)$ index.php?server=$1 [L,QSA] + + diff --git a/README.md b/README.md index 2133342e78..dad7f6febd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,35 @@ -Pokemon-Showdown-Client -======================= +Pokemon Showdown Client +======================================================================== -The client for Pokemon Showdown \ No newline at end of file +This is a repository for some of the client code for Pokemon Showdown. + +This is what runs `play.pokemonshowdown.com`. + +WARNING: You probably want the [Pokemon Showdown server][1]. + + [1]: https://github.com/Zarel/Pokemon-Showdown + +Setup +------------------------------------------------------------------------ + +This repository is not "batteries included". It does NOT include everything +necessary to run a Pokemon Showdown client. + +In particular, it doesn't include a login/authentication server, nor does it +include the database abstraction library used by the ladder library (although +it's similar enough to `mysqli` that you can use that with minimal changes). + +It also doesn't include several resource files (namely, the `/audio/` and +`/sprites/` directories) for size reasons. + +In other words, this repository is incomplete and NOT intended for people +who wish to serve their own Pokemon Showdown client (you can, but it'll +require you to rewrite some things). Rather, it's intended for people who +wish to contribute and submit pull requests to Pokemon Showdown's client. + +License +------------------------------------------------------------------------ + +Pokemon Showdown's client is distributed under the terms of the [AGPLv3][2]. + + [2]: http://www.gnu.org/licenses/agpl-3.0.html diff --git a/action.php b/action.php new file mode 100644 index 0000000000..3be8ff7416 --- /dev/null +++ b/action.php @@ -0,0 +1,315 @@ + + +*/ + +error_reporting(E_ALL); + +include_once '../pokemonshowdown.com/lib/ntbb-session.lib.php'; +//include_once 'lib/ntbb-ladder.lib.php'; +include_once '../pokemonshowdown.com/config/servers.inc.php'; + +$reqs = array($_REQUEST); +$multiReqs = false; +if (@$_REQUEST['json']) { + $reqs = json_decode($_REQUEST['json'], true); + $multiReqs = true; +} + +$outArray = array(); + +foreach ($reqs as $reqData) { + + $reqData = array_merge($_REQUEST, $reqData); + if (!ctype_alnum(@$reqData['act'])) die('{"error":"invalid action"}'); + $out = array( + 'action' => @$reqData['act'] + ); + + // if ($_REQUEST['debug']) { + // var_export($reqData); + // } + + switch (@$reqData['act']) + { + case 'login': + if (!$_POST) die(); + $users->login($reqData['name'], $reqData['pass']); + unset($curuser['userdata']); + $out['curuser'] = $curuser; + $out['actionsuccess'] = !!$curuser; + if ($curuser && $reqData['servertoken']) + { + $out['sessiontoken'] = $users->getSessionToken($reqData['servertoken']) . '::' . $reqData['servertoken']; + } + $out['assertion'] = $users->getAssertion($curuser['userid']); + break; + case 'register': + $user = array(); + $user['username'] = @$_POST['username']; + if (strlen($users->userid($user['username'])) < 1) + { + $out['actionerror'] = 'Your username must contain at least one letter or number.'; + } + else if (strlen($user['username']) > 64) + { + $out['actionerror'] = 'Your username must be less than 64 characters long.'; + } + else if (strlen(@$_POST['password']) < 5) + { + $out['actionerror'] = 'Your password must be at least 5 characters long.'; + } + else if (@$_POST['password'] !== @$_POST['cpassword']) + { + $out['actionerror'] = 'Your passwords do not match.'; + } + else if (trim(strtolower(@$_POST['captcha'])) !== 'pikachu') + { + $out['actionerror'] = 'Please answer the anti-spam question given.'; + } + else if ($user = $users->addUser($user, $_POST['password'])) + { + $out['curuser'] = $user; + $out['assertion'] = $users->getAssertion($user['userid'], $user); + $out['actionsuccess'] = true; + if ($curuser && @$reqData['servertoken']) + { + $out['sessiontoken'] = $users->getSessionToken($reqData['servertoken']) . '::' . $reqData['servertoken']; + } + } + else + { + $out['actionerror'] = 'Your username is already taken.'; + } + break; + case 'upkeep': + unset($curuser['userdata']); + $out['curuser'] = $curuser; + if (empty($reqData['name'])) $userid = $curuser['userid']; + else $userid = $users->userid($reqData['name']); + $out['assertion'] = $users->getAssertion($userid); + break; + case 'checklogin': + // direct + die(!!$users->getUser($reqData['userid'])); + break; + case 'logout': + if (!$_POST) die(); + $users->logout(); + $out['curuser'] = $curuser; + $out['actionsuccess'] = true; + break; + case 'sekrit2q53mkuser': + $users->addUser(array('username'=>$reqData['user']), $reqData['pass']); + break; + case 'savedata': + if (!$_POST) die(); + $userdata = $curuser['userdata']; + $userdata['psclient'] = $reqData['userdata']; + $out['actionsuccess'] = $users->modifyUser($curuser, array( + 'userdata' => $userdata + )); + break; + case 'getsessiontoken': + // direct + die($users->getSessionToken($reqData['servertoken'])); + break; + case 'getassertion': + // direct + die($users->getAssertion(@$reqData['userid'])); + break; + case 'verifysessiontoken': + // direct + if (!$users->getUser(@$reqData['userid'])) + { + // ok + die('1'); + } + $user = $users->verifySessionToken(@$reqData['token'], @$reqData['servertoken']); + if (!$user) die(''); + if ($reqData['userid'] !== $user['userid']) die(''); + $serveruserdata = array( + 'userid' => $user['userid'], + 'username' => $user['username'], + 'group' => $user['group'] + // 'userserverdata' => @$user['userdata']['psserver'][@$reqData['servertoken']] + ); + header('Content-type: application/json'); + die(json_encode($serveruserdata)); + break; + case 'ladderupdate': + include_once 'lib/ntbb-ladder.lib.php'; + + $server = @$PokemonServers[@$reqData['serverid']]; + + //var_export($users->getUserData($reqData['p1'])); + if (!$server || $server['token'] !== md5($reqData['servertoken'])) + { + $out = 0; + break; + } + + $ladder = new NTBBLadder($server['id'], $reqData['format']); + $p1 = $users->getUserData($reqData['p1']); + $p2 = $users->getUserData($reqData['p2']); + + $ladder->updateRating($p1, $p2, floatval($reqData['score'])); + $out['actionsuccess'] = true; + $out['p1rating'] = $p1['rating']; + $out['p2rating'] = $p2['rating']; + unset($out['p1rating']['rpdata']); + unset($out['p2rating']['rpdata']); + break; + case 'prepreplay': + include_once 'lib/ntbb-ladder.lib.php'; + + $server = @$PokemonServers[@$reqData['serverid']]; + + //var_export($users->getUserData($reqData['p1'])); + if (!$server || $server['token'] !== md5($reqData['servertoken'])) + { + $out = 0; + break; + } + + if (@$reqData['serverid'] !== 'showdown') break; // let's not think about other servers yet + + $res = $db->query("SELECT * FROM `ntbb_replays` WHERE `id`='".$db->escape($reqData['id'])."','".$db->escape($reqData['loghash'])."'"); + $replay = $db->fetch_assoc($res); + + if ($replay && !$replay['loghash']) { + $out = !!$db->query("UPDATE `ntbb_replays` SET `loghash` = '".$db->escape($reqData['loghash'])."' WHERE `id`='".$db->escape($reqData['id'])."','".$db->escape($reqData['loghash'])."'"); + } else { + $out = !!$db->query("INSERT INTO `ntbb_replays` (`id`,`loghash`,`p1`,`p2`,`format`,`date`) VALUES ('".$db->escape($reqData['id'])."','".$db->escape($reqData['loghash'])."','".$db->escape($reqData['p1'])."','".$db->escape($reqData['p2'])."','".$db->escape($reqData['format'])."',".time().")"); + } + break; + case 'uploadreplay': + function stripNonAscii($str) { return preg_replace('/[^(\x20-\x7F)]+/','', $str); } + if (!$_POST['id']) die('ID needed'); + $id = $_POST['id']; + + $res = $db->query("SELECT * FROM `ntbb_replays` WHERE `id` = '".$db->escape($id)."'"); + + $replay = $db->fetch_assoc($res); + if (!$replay) die('not found'); + if (md5(stripNonAscii($_POST['log'])) !== $replay['loghash']) { + $_POST['log'] = str_replace("\r",'', $_POST['log']); + if (md5(stripNonAscii($_POST['log'])) !== $replay['loghash']) { + die('hash mismatch'); + } + } + + $db->query("UPDATE `ntbb_replays` SET `log` = '".$db->escape($_POST['log'])."', `loghash` = '' WHERE `id` = '".$db->escape($id)."'"); + + die('success'); + break; + case 'laddertest': + include_once 'lib/ntbb-ladder.lib.php'; + $ladder = new NTBBLadder('showdown', 'ou'); + + $p1 = array( + 'rating' => array( + 'r' => 1421.3542787803, + 'rd' => 201.04843020314, + 'sigma' => 0.059994925075002, + 'rptime' => 1341446400, + 'rpdata' => '[{"mu":0.63234332925469,"phi":0.27239037325046,"score":1},{"mu":1.7281504029414,"phi":0.43211783817514,"score":1},{"mu":0.93276078544053,"phi":0.99306537054533,"score":0},{"mu":-0.94051313144882,"phi":1.0099475282243,"score":1},{"mu":0.49643942459207,"phi":0.63523017522292,"score":1},{"mu":-1.0049237021831,"phi":0.3282791830483,"score":1},{"mu":1.5254097274879,"phi":0.87857256772749,"score":1},{"mu":0.66129185860516,"phi":0.8640590602575,"score":1},{"mu":-1.2436148187181,"phi":0.92373199886293,"score":1},{"mu":-0.64874832664816,"phi":0.55764845310102,"score":1},{"mu":-0.63452166982773,"phi":0.34511572273028,"score":1},{"mu":0.1021296183828,"phi":0.36117999082004,"score":1},{"mu":0.67700291340553,"phi":0.5099378019722,"score":1},{"mu":1.4314249415034,"phi":1.1022726006074,"score":1},{"mu":-0.6913699870422,"phi":1.4906684040673,"score":1},{"mu":-2.4139491282718,"phi":1.2766563943912,"score":1},{"mu":-0.54755058352569,"phi":0.19712357739302,"score":1},{"mu":1.6279574026323,"phi":0.20308162425787,"score":1},{"mu":1.6104933690428,"phi":0.20213766903132,"score":0},{"mu":0.81260576720117,"phi":0.14882872092356,"score":1},{"mu":-1.4771949264554,"phi":0.2576259670436,"score":1}]', + ), + ); + + $ladder->update($p1, false, true); + + var_export($p1); + + die(); + + break; + case 'ladderget': + include_once 'lib/ntbb-ladder.lib.php'; + + $server = $PokemonServers[$reqData['serverid']]; + if (!$server) die(''); + + $ladder = new NTBBLadder($server['id'], @$reqData['format']); + $user = $users->getUserData($reqData['user']); + $ladder->getAllRatings($user); + header('Content-type: application/json'); + die(json_encode($user['ratings'])); + break; + case 'ladderformatget': + include_once 'lib/ntbb-ladder.lib.php'; + + $server = $PokemonServers[$reqData['serverid']]; + if (!$server) die(''); + + $ladder = new NTBBLadder($server['id'], @$reqData['format']); + $user = $users->getUserData($reqData['user']); + $ladder->getRating($user); + if (!@$user['rating']) die(); + unset($user['rating']['serverid']); + unset($user['rating']['formatid']); + unset($user['rating']['rpdata']); + header('Content-type: application/json'); + die(json_encode($user['rating'])); + break; + case 'ladderformatgetmmr': + case 'mmr': + include_once 'lib/ntbb-ladder.lib.php'; + + $server = $PokemonServers[$reqData['serverid']]; + if (!$server) die(''); + + $ladder = new NTBBLadder($server['id'], @$reqData['format']); + $user = $users->getUserData($reqData['user']); + $ladder->getRating($user); + if (!@$user['rating']) { + $out = 1500; + } else { + $out = ($user['rating']['r']+$user['rating']['rpr'])/2; + } + break; + case 'laddertop': + include_once 'lib/ntbb-ladder.lib.php'; + + $server = $PokemonServers[$reqData['serverid']]; + + if (!$server) + { + die(''); + } + + $ladder = new NTBBLadder($server['id'], $reqData['format']); + $out = $ladder->getTop(); + break; + case 'glickotest': + include_once 'lib/ntbb-ladder.lib.php'; + + $ladder = new NTBBLadder('test', 'OU'); + + $p1 = $users->getUser('aeo1'); + $p2 = $users->getUser('aeo2'); + + $ladder->updateRating($p1, $p2, 1); + + var_export($p1); + die(); + break; + default: + break; + } + + if ($multiReqs) $outArray[] = $out; +} + +// json output +if ($multiReqs) { + header('Content-type: application/json'); + die(json_encode($outArray)); +} else { + header('Content-type: application/json'); + die(json_encode($out)); +} diff --git a/backup/chartmaker.php b/backup/chartmaker.php new file mode 100644 index 0000000000..a33b67f8d3 --- /dev/null +++ b/backup/chartmaker.php @@ -0,0 +1,405 @@ + "Shaymin-Sky", + "rotomh" => "Rotom-Heat", + "rotomw" => "Rotom-Wash", + "rotomf" => "Rotom-Frost", + "rotoms" => "Rotom-Fan", + "rotomc" => "Rotom-Mow", + "meloettas" => "Meloetta-Pirouette", + "meloettap" => "Meloetta-Pirouette", + "giratinao" => "Giratina-Origin", + "wormadamg" => "Wormadam-Sandy", + "wormadams" => "Wormadam-Trash", + "wormadamground" => "Wormadam-Sandy", + "wormadamsteel" => "Wormadam-Trash", + "deoxysa" => "Deoxys-Attack", + "deoxyss" => "Deoxys-Speed", + "deoxysd" => "Deoxys-Defense", + "deoxysdefence" => "Deoxys-Defense", + "basculinb" => "Basculin-Blue", + "darmanitanzenmode" => "Darmanitan-Zen", + "cherrimsunny" => "Cherrim-Sunshine", + "cherrims" => "Cherrim-Sunshine", + "castforms" => "Castform-Sunny", + "castformr" => "Castform-Rainy", + "castformh" => "Castform-Snowy", + "castformfire" => "Castform-Sunny", + "castformwater" => "Castform-Rainy", + "castformice" => "Castform-Snowy", + + // base formes + "nidoranfemale" => "Nidoran-F", + "nidoranmale" => "Nidoran-M", + "giratinaaltered" => "Giratina", + "giratinaa" => "Giratina", + "cherrimovercast" => "Cherrim", + "cherrimo" => "Cherrim", + "meloettaaria" => "Meloetta", + "meloettaa" => "Meloetta", + "basculinred" => "Basculin", + "basculinr" => "Basculin", + + // items + "cb" => "Choice Band", + "band" => "Choice Band", + "lefties" => "Leftovers", + "lo" => "Life Orb", + + // pokemon + "dnite" => "Dragonite", + "ttar" => "Tyranitar", + "rank" => "Reuniclus", + "ferry" => "Ferrothorn", + "forry" => "Forretress", + "luke" => "Lucario", + "poryz" => "Porygon-Z", + "pz" => "Porygon-Z", + "pory2" => "Porygon2", + "p2" => "Porygon2", + + // moves + "sd" => "Swords Dance", + "dd" => "Dragon Dance", + "hjk" => "Hi Jump Kick", + "cc" => "Close Combat", + "np" => "Nasty Plot", + "sr" => "Stealth Rock", + "tr" => "Trick Room", + "tbolt" => "Thunderbolt", + "wow" => "Will-O-Wisp", + "qd" => "Quiver Dance", + "tspikes" => "Toxic Spikes", + "twave" => "Thunder Wave", + "eq" => "Earthquake", + "cm" => "Calm Mind", + "se" => "Stone Edge", + + // Japanese names + "birijion" => "Virizion", + "terakion" => "Terrakion", + "agirudaa" => "Accelgor", + "randorosu" => "Landorus", + "urugamosu" => "Volcarona", + "erufuun" => "Whimsicott", + "doryuuzu" => "Excadrill", + "burungeru" => "Jellicent", + "nattorei" => "Ferrothorn", + "shandera" => "Chandelure", + "roobushin" => "Conkeldurr", + "ononokusu" => "Haxorus", + "sazandora" => "Hydreigon", + "chirachiino" => "Cinccino", + "kyuremu" => "Kyurem", + "jarooda" => "Serperior", + "zoroaaku" => "Zoroark", + "shinboraa" => "Sigilyph", + "barujiina" => "Mandibuzz", + "rankurusu" => "Reuniclus", + "borutorosu" => "Thundurus" + // there's no need to type out the other Japanese names + // I'll autogenerate them at some point +); + +if (isset($_REQUEST['1'])) +{ + + $file = file('data/pokedex.csv'); + + $BattlePokemon = array(); + $BattlePokemonByNumber = array(); + + $jp = false; + + $TableMaleOnly = array('32'=> 1,'33'=> 1,'34'=> 1,'106'=> 1,'107'=> 1,'128'=> 1,'236'=> 1,'237'=> 1,'313'=> 1,'381'=> 1,'414'=> 1,'475'=> 1,'538'=> 1,'539'=> 1,'627'=> 1,'628'=> 1,'641'=> 1,'642'=> 1,'645'=> 1,); + + $TableFemaleOnly = array('-2'=> 1,'29'=> 1,'30'=> 1,'31'=> 1,'113'=> 1,'115'=> 1,'124'=> 1,'238'=> 1,'241'=> 1,'242'=> 1,'314'=> 1,'380'=> 1,'413'=> 1,'416'=> 1,'440'=> 1,'478'=> 1,'488'=> 1,'548'=> 1,'549'=> 1,'629'=> 1,'630'=> 1,); + + $TableGenderless = array('-55'=> 1,'81'=> 1,'82'=> 1,'100'=> 1,'101'=> 1,'120'=> 1,'121'=> 1,'132'=> 1,'137'=> 1,'144'=> 1,'145'=> 1,'146'=> 1,'150'=> 1,'150'=> 1,'201'=> 1,'233'=> 1,'243'=> 1,'244'=> 1,'245'=> 1,'249'=> 1,'250'=> 1,'251'=> 1,'292'=> 1,'337'=> 1,'338'=> 1,'343'=> 1,'344'=> 1,'374'=> 1,'375'=> 1,'376'=> 1,'377'=> 1,'378'=> 1,'379'=> 1,'382'=> 1,'383'=> 1,'384'=> 1,'385'=> 1,'386'=> 1,'436'=> 1,'437'=> 1,'462'=> 1,'474'=> 1,'479'=> 1,'480'=> 1,'481'=> 1,'482'=> 1,'483'=> 1,'484'=> 1,'486'=> 1,'487'=> 1,'489'=> 1,'490'=> 1,'491'=> 1,'492'=> 1,'493'=> 1,'494'=> 1,'599'=> 1,'600'=> 1,'601'=> 1,'615'=> 1,'622'=> 1,'638'=> 1,'639'=> 1,'640'=> 1,'643'=> 1,'644'=> 1,'646'=> 1,'647'=> 1,'648'=> 1,'649'=> 1,); + + foreach ($file as $line) + { + $args = explode(',',$line); + + $negative = false; + if (substr($args[0],0,1) === '-') + { + $args[0] = substr($args[0],1); + $negative = true; + } + + if (!ctype_digit($args[0])) continue; + + while (substr($args[0],0,1)==='0') $args[0] = substr($args[0],1); + $num = intval($args[0]); + if ($negative) $num = -$num; + $species = $args[1]; + $speciesid = preg_replace('/[^a-z0-9]+/', '', strtolower($species)); + if ($BattlePokemon[$species] && $jp) continue; + $forme = ''; + $formeletter = ''; + $spriteid = $speciesid; + $basespecies = $species; + if ($loc = strrpos($species,'-') && $species !== 'Ho-Oh' && $species !== 'Ho-oh' && $species !== 'Porygon-Z') + { + $loc = strrpos($species,'-'); + $basespecies = substr($species, 0, $loc); + $forme = substr($species, $loc+1); + + $basespeciesid = preg_replace('/[^a-z0-9]+/', '', strtolower($basespecies)); + $formeid = preg_replace('/[^a-z0-9]+/', '', strtolower($forme)); + $spriteid = $basespeciesid.'-'.$formeid; + + $formeletter = substr($forme,0,1); + if ($speciesid === 'rotommow') $formeletter = 'C'; + if ($speciesid === 'rotomfan') $formeletter = 'S'; + if ($speciesid === 'wormadamsandy') $formeletter = 'G'; + if ($speciesid === 'wormadamtrash') $formeletter = 'S'; + if ($speciesid === 'castformsunny') $formeletter = 'F'; + if ($speciesid === 'castformrainy') $formeletter = 'W'; + if ($speciesid === 'castformsnowy') $formeletter = 'I'; + } + $types = array($args[2]); + if ($args[3]) $types[] = $args[3]; + $baseStats = array( + 'hp' => intval($args[4]), + 'atk' => intval($args[5]), + 'def' => intval($args[6]), + 'spa' => intval($args[7]), + 'spd' => intval($args[8]), + 'spe' => intval($args[9]), + ); + $abilities = array(0 => $args[29],1=>$args[30],'DW'=>$args[31]); + $BattlePokemon[$speciesid] = array( + 'name' => $species, + 'id' => $speciesid, + 'species' => $species, + 'speciesid' => $speciesid, + 'basespecies' => $basespecies, + 'forme' => $forme, + 'formeletter' => $formeletter, + 'spriteid' => $spriteid, + 'num' => $num, + 'types' => $types, + 'baseStats' => $baseStats, + 'abilities' => $abilities, + 'height' => $args[40+5], + 'heightm' => floatval(substr($args[40+5],0,-2)), + 'weight' => $args[41+5], + 'weightkg' => floatval(substr($args[41+5],0,-3)), + 'nfe' => false, + 'gender' => '', + 'prevo' => '', + //'jp' => $jp, + ); + + if ($TableMaleOnly[''.$num]) $BattlePokemon[$speciesid]['gender'] = 'M'; + if ($TableFemaleOnly[''.$num]) $BattlePokemon[$speciesid]['gender'] = 'F'; + if ($TableGenderless[''.$num]) $BattlePokemon[$speciesid]['gender'] = 'N'; + + if (!$BattlePokemonByNumber[$num]) $BattlePokemonByNumber[$num] = $speciesid; + if ($species === 'Genesect') + { + $jp = true; + break; + } + } + + persist_save('BattlePokemon', 'data/pokedex.inc.php'); + persist_save('BattlePokemonByNumber', 'data/pokedex_numlookup.inc.php'); + + echo 'next

'; + + var_export($BattlePokemon['necturna']); + +} +else if (isset($_REQUEST['2'])) +{ + include 'data/pokedex.inc.php'; + include 'data/pokedex_numlookup.inc.php'; + + // prevos + $file = file('data/po_evos.txt'); + foreach ($file as $line) + { + if (!$line) continue; + $args = explode(' ', $line); + + $poke = $BattlePokemonByNumber[intval($args[0])]; + + $args = array_splice($args,1); + + $BattlePokemon[$poke]['nfe'] = true; + foreach ($args as $arg) + { + $BattlePokemon[$BattlePokemonByNumber[intval($args[0])]]['prevo'] = $poke; + } + } + + persist_save('BattlePokemon', 'data/pokedex.inc.php'); + //file_put_contents('data/pokedex.js', 'exports.BattlePokedex = '.json_encode($BattlePokemon)); + + echo 'next

'; + + var_export($BattlePokemon['ivysaur']); +} +else if (isset($_REQUEST['3'])) +{ + include 'data/pokedex.inc.php'; + include 'data/typechart.inc.php'; + + $file = file('data/movesets.csv'); + + foreach ($file as $line) + { + $args = explode(',',$line); + if (!ctype_digit($args[3])) continue; + $species = $args[0]; + $speciesid = preg_replace('/[^a-z0-9]+/', '', strtolower($species)); + if ($BattleAliases[$speciesid]) + { + //echo $species." to ".$BattleAliases[$speciesid]." | "; + $species = $BattleAliases[$speciesid]; + $speciesid = preg_replace('/[^a-z0-9]+/', '', strtolower($species)); + } + if (!$speciesid) continue; + + if (!$BattlePokemon[$speciesid]['viablemoves']) $BattlePokemon[$speciesid]['viablemoves'] = array(); + + for ($i=10; $i<19; $i++) + { + $move = $args[$i]; + $moveid = preg_replace('/[^a-z0-9]+/', '', strtolower($move)); + + if (substr($moveid, 0, strlen('hiddenpower')) === 'hiddenpower') $moveid = 'hiddenpower'; + if ($moveid === 'none' || !$moveid) continue; + + $BattlePokemon[$speciesid]['viablemoves'][$moveid] = $move; + $BattlePokemon[$speciesid]['viable'] = true; + } + } + + file_put_contents('data/pokedex.js', 'exports.BattlePokedex = '.json_encode($BattlePokemon)); + + echo 'next

'; + var_export($BattlePokemon['weavile']); + +} +else if (isset($_REQUEST['4'])) +{ + include 'data/pokedex.inc.php'; + + $fp = fopen('data/pokedex-mini.js','w'); + fwrite($fp, "BattlePokemonSprites = {\n"); + +/* +$remap = array( + 'wormadam-ground' => 'wormadam-sandy', + 'wormadam-steel' => 'wormadam-trash', +); +foreach ($remap as $from => $to) +{ + rename('sprites/bwani/'.$from.'.gif', 'sprites/bwani/'.$to.'.gif'); + rename('sprites/bwani-shiny/'.$from.'.gif', 'sprites/bwani-shiny/'.$to.'.gif'); + rename('sprites/bwani-back/'.$from.'.gif', 'sprites/bwani-back/'.$to.'.gif'); + rename('sprites/bwani-back-shiny/'.$from.'.gif', 'sprites/bwani-back-shiny/'.$to.'.gif'); + rename('sprites/bwani/'.$from.'-f.gif', 'sprites/bwani/'.$to.'-f.gif'); + rename('sprites/bwani-shiny/'.$from.'-f.gif', 'sprites/bwani-shiny/'.$to.'-f.gif'); + rename('sprites/bwani-back/'.$from.'-f.gif', 'sprites/bwani-back/'.$to.'-f.gif'); + rename('sprites/bwani-back-shiny/'.$from.'-f.gif', 'sprites/bwani-back-shiny/'.$to.'-f.gif'); +} +die(); +*/ + + foreach($BattlePokemon as $poke) + { + if ($poke['jp']) break; + //$filename = str_pad(''.$poke['num'], 3, "0", STR_PAD_LEFT); + //if (!file_exists('sprites/ani-src/'.$filename.'.gif')) $filename = str_replace('_','-',$filename); + //if (substr($filename,0,2)==='0-') $filename = '-0'.substr($filename,2); + //if ($poke['forme']) $filename = $filename.'-'.strtolower($poke['forme']); + + $filename = $poke['spriteid']; + $size = @getimagesize('sprites/bwani/'.$filename.'.gif'); + if ($size) + { + if (!$BattlePokemon[$poke['speciesid']]['sprite']) $BattlePokemon[$poke['speciesid']]['sprite'] = array(); + + $BattlePokemon[$poke['speciesid']]['sprite']['ani'] = array( + 'w' => $size[0], + 'h' => $size[1] + ); + } + + $size = @getimagesize('sprites/bwani-back/'.$filename.'.gif'); + if ($size) + { + $BattlePokemon[$poke['speciesid']]['sprite']['backani'] = array( + 'w' => $size[0], + 'h' => $size[1] + ); + } + + $size = @getimagesize('sprites/bwani/'.$filename.'-f.gif'); + if ($size) + { + $BattlePokemon[$poke['speciesid']]['sprite']['anif'] = array( + 'w' => $size[0], + 'h' => $size[1] + ); + } + $size = @getimagesize('sprites/bwani-back/'.$filename.'-f.gif'); + if ($size) + { + $BattlePokemon[$poke['speciesid']]['sprite']['backanif'] = array( + 'w' => $size[0], + 'h' => $size[1] + ); + } + } + foreach($BattlePokemon as $poke) + { + if ($poke['sprite']['ani']) + { + fwrite($fp, " \"{$poke['speciesid']}\": {"); + if ($poke['num']) + { + fwrite($fp, "num:{$poke['num']}, "); + } + fwrite($fp, "front:{ani:{w: {$poke['sprite']['ani']['w']}, h: {$poke['sprite']['ani']['h']}}"); + if ($poke['sprite']['anif']) + { + fwrite($fp, ", anif:{w: {$poke['sprite']['anif']['w']}, h: {$poke['sprite']['anif']['h']}}"); + } + fwrite($fp, "}"); + if ($poke['sprite']['backani']) + { + fwrite($fp, ",back:{ani:{w: {$poke['sprite']['backani']['w']}, h: {$poke['sprite']['backani']['h']}}"); + if ($poke['sprite']['backanif']) + { + fwrite($fp, ", anif:{w: {$poke['sprite']['backanif']['w']}, h: {$poke['sprite']['backanif']['h']}}"); + } + fwrite($fp, "}"); + } + if ($poke['sprite']['f']) + { + fwrite($fp, ",f:1"); + } + fwrite($fp, "},\n"); + } + else if ($poke['num']) + { + fwrite($fp, " \"{$poke['speciesid']}\": {"); + fwrite($fp, "num:{$poke['num']}"); + fwrite($fp, "},\n"); + } + } + fwrite($fp, " done:null\n};\n"); + fclose($fp); + + var_export($BattlePokemon['bulbasaur']); +} diff --git a/backup/closed.php b/backup/closed.php new file mode 100644 index 0000000000..80878c85f8 --- /dev/null +++ b/backup/closed.php @@ -0,0 +1,16 @@ + + + + + +

+ Thank you for your interest in the Pokemon Showdown beta! +

+

+ The server is down at the moment. We hope to bring it back up soon. +

+

+ —aeo +

+ + diff --git a/backup/pokedex.php b/backup/pokedex.php new file mode 100644 index 0000000000..18bc371412 --- /dev/null +++ b/backup/pokedex.php @@ -0,0 +1,53 @@ + + + + + Showdown! + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + + \ No newline at end of file diff --git a/backup/replay.php b/backup/replay.php new file mode 100644 index 0000000000..c7ef25cb99 --- /dev/null +++ b/backup/replay.php @@ -0,0 +1,274 @@ + '01', 'february' => '02', 'march' => '03', 'april' => '04', 'may' => '05', 'june' => '06', 'july' => '07', 'august' => '08', 'september' => '09', 'october' => '10', 'november' => '11', 'december' => '12'); + if (substr($name, -5) === '.html') $name = substr($name,0,-5); + if (substr($name, -4) === '.htm') $name = substr($name,0,-4); + if (preg_match('/^(.*)\-\-([0-9]+) ([A-Z][a-z]+) ([0-9]+) at ([0-9]+)h([0-9]+)$/', $name, $matches)) + { + $name = trim($matches[1]).'--'.$matches[4].'-'.$monthTable[strtolower($matches[3])].'-'.$matches[2]; + } + $name = str_replace(' ','-',$name); + + $name = preg_replace('/[^A-Za-z0-9-]+/', '', $name); + return $name; +} + + +if ($_REQUEST['name']) +{ + $replay =& $REPLAYS[$_REQUEST['name']]; + if (!$replay) + { + $replay['id'] = $_REQUEST['name']; + } +?> + + + + + + + + + Viewing Pokemon replay: <?php echo htmlentities($_REQUEST['name']); ?> + + + + + + + + + + + + + + + +
+
+
+
+ +
+
+
+
+ Speed: +
+
+
+ Color scheme: +
+
+
+ Music: +
+
+
+
+ + + THIS REPLAY IS PRIVATE - make sure you have the owner\'s permission to share
'; ?> + +
+ + [Original replay | Convert again] [Upload your own replay] [Report bugs to the Smogon thread] +
+changed
'; + if ($_POST['highlight']) $replay['highlight'] = true; + else unset($replay['highlight']); + if ($_POST['notes']) $replay['notes'] = $_POST['notes']; + else unset($replay['notes']); + if ($_POST['link']) $replay['link'] = $_POST['link']; + else unset($replay['link']); + persist_save('REPLAYS'); + } +?> +
+ id="highlight" />
+ notes
+ link
+ +
+ + + + + +

404 Not Found

\ No newline at end of file diff --git a/backup/sekritmkuser.php b/backup/sekritmkuser.php new file mode 100644 index 0000000000..90b0e954b4 --- /dev/null +++ b/backup/sekritmkuser.php @@ -0,0 +1,316 @@ + '5', // Arcticblast + 'hse54rgs56ed' => '5', // Aquaaaa + 'gse54rgs84e' => '5', // Tournesol + 'h5s46e5rth' => '+10', // DragonTamerChris + '7jsw34hs3e4' => '5', // AfroThunderRule + 's3e46s3e4hb64s' => '5', // MissingNO + 's34s34b63es4' => '5', // StevoDuhHero + '23h6bst3wv4534rf' => '5', // GL1TCH + 'svg346v3gs346' => '5', // SaMaLo + '78d45bd34gbd' => '5', // The Hall Monitor, Shawn Parks? + 'hws4b6s34vse34' => '5', // Ash Caughtem + 'sv534b3w4nsy5' => '+10', // Arceus Ex Machina + '5bs35ys3456s' => '5', // Metamaster + '4s3b4ys34bt3s4' => '5', // WARP + 'sg34sb3e4t34' => '5', // loldongs + '5bwh35yg34g3' => '5', // ==public + 'h2489yguah3kjr2aj3' => '5', // steamroll + 'sv34s3b4tyb43' => '5', // Dabrikishaw + 's3v4ysb4ey54ny' => '5', // Keai + 'db45yd4bhe4e5' => '5', // FlarePod + '5bsh45yb4shty' => '5', // Perish Song + 'ha3sw4gt63sh4y' => '5', // JoshBundy + 'af234a34fa34' => '5', // Joeyboy + 'af45af24a2' => '5', // SoulWind + 's34ctseysees' => '5', // Dalek + '4gvsf4sc454' => '5', // MuriloMarques + '5gsy54hdu6u' => '5', // Ducinator + 'a2f3523af2' => '5', // H-C + 'naysevtdbsw' => '5', // Texas Cloverleaf + 'y4a3v64ahs4bt' => '5', // weeheehoo + 'av35syvyn5' => '5', // dragonboy52 + 'snb5yv4u56nsu' => '5', // romojuice + '87b67biyudb6t' => '5', // Aqualouis + '87obt7u6rv56du' => '5', // Neblim + '7u6tfyi7bnt8' => '5', // Acklow + '3wf5twd3t4q34t' => '5', // rtc3 + '87tb7niuyuy' => '5', // Trollmonchan + '4q3t4wy54w' => '5', // Pidge + 'h7e4d5gydrt33' => '5', // Skippy11 + 'w7hs35gse5ys54' => '5', // Auraknight + 'syb5yseyse4cy3' => '5', // shnen + 'sy35vse4cy5se4ty' => '5', // Evan Falco + 'sy4s4ts4t34ts' => '5', // daoze555 + 's34t5y46ehu54' => '5', // Phi + 'g5yd45vysc45y4' => '5', // Pocket Cucco + 's3g4ts43g6t3s' => '5', // Ice-eyes + '3b4ya3v4vt3ac4t3' => '5', // Darmanitan14 + 'ac34ta3v4t3b4' => '5', // Mostwanted + 'vsye5cyc4ca43' => '5', // Xaqwais + 'a34t3tavt4sv4' => '5', // Zapteryx + 'ys35yv45cy3s4' => '5', // KPrime + 'yvs34yvsey5' => '+10', // Omicron + 'bs345ybs54y' => '5', // SiDoesGood + 's34ybsv4453s4y' => '5', // Fireworks + 'kk34h4532' => '+10', // AccidentalGreed + 't3s4cy5s34t' => '5', // iDerp + 's3y4s4t34' => '5', // Chieliee + '7a3g46a3f46a23' => '+10', // NixHex + '59hv83sh49s' => '5', // SkaterTrainer + '40atj34iuj' => '+10', // Rising_Dusk + '3gay5w4s5y3' => '5', // tophway + '43fy453s4y3s4' => '5', // Mysterious Trainer + 'ast34t3a4t34t' => '5', // wotw + 'as34ts34t34' => '5', // PurePwnage + 's43tsy5s34y' => '+10', // macle + 's34y54s34ioi' => '5', // ShinyAzelf + 'w53y453wy5w35w' => '5', // Steven Snype + 'tw34tq3ww4y35w' => '5', // Patronus + 'ywf35y35ywy5' => '5', // New World Order + 'wy435yw4433w54y' => '5', // chase + 'w93g4qg34t35y' => '5', // DFMatt + '5wy35yw34y34' => '5', // Wynaut? + 'g6w3y5e45vyw' => '5', // Manxer + 'tw343f4tw34t3w34' => '5', // theangryscientist + 'wft34tw34t3w4' => '5', // demasiorus + 't3w4tfq34ft34t' => '5', // tomtom5858 + 'q23tq2334tw34' => '9', // jumpluff + '3wg5yw345tw34' => '3', // drevan + 'w3t5w34ytw34tw3' => '9', // Delta2777 + 'wt34wvt34w34t3w5' => '9', // Honko + '8o7btinoiuh' => '4', // King N + '87bonuihuhu' => '5', // Iceydude168 + 'bi87f6856i7' => '5', // Mewcario2546 + 'w983s4ht3kl' => '5', // Bromishi + '4t34ya3t434t' => '5', // Breludicolo + 'aefawegary34a' => '5', // Karpman + 'y3s4ys34y34y' => '5', // YoshiLover + 'ba35y3462363' => '5', // Maniak + 'yn985o3u4t3a44' => '9', // ethereal + '4ty59uhisoijeo' => '+10', // Surgo + 'a34tcc34t34t' => '5', // Woodchuck + 'f34tw34yc34344t' => '5', // thepkmnmaster + 'va4yw34gw3s5fy3' => '5', // Pwnemon + 't34tq24trq23r2q' => '5', // Neb555 + 'tac4t3c4tc34t' => '5', // YAYtears + 'ah4ya34bay34va34' => '5', // RitterCat + 'a43vta34vcta34cta3' => '5', // MaestroXXVI + 'av4ta3v4tca34tva34' => '5', // doominic77 + 'sb4y3v4t34c343' => '5', // pokemon0078 + 'a4vtsnby34by3sb4' => '5', // Engineer Pikachu + 'sn45ybs5evyse5y' => '+10', // tennisace + 'vdrtyv5syv4s5yv' => '5', // SteelEdges + 'usj45sbe54b54' => '9', // bojangles + '34bsy5ysbrtye' => '5', // mcculla28 + '7bt7niguygnu7' => '5', // Kiorein + '875bee5edn7ftfu' => '5', // dkurt89 + 'qb34tvw3ct43w34' => '5', // Darkamber8828 + 'a34tgv234c24tc2' => '10', // Calm Pokemaster, jayjinde + 'a34t3c4twt5ty34w' => '+10', // kyledove + 'bysy45vy3c4y3' => '+10', // John + 'y3b5yyyyvs4v3es' => '9', // Theorymon + McMeghan + 'y4ns45byvsu45' => '9', // aldaron + '5un46hbsv45y45v45' => '+10', // iss + 's4j56unb4v5s45c4y' => '9', // Wild Eep + 's45y45y45ws345' => '5', // Thepain + 's45by455ysc5cy45' => '5', // Birkal + 's3h5yv4vs5ys35yc4' => '25', // hotdogturtle + 'sye5yb4s5ys45y45' => '5', // Kingclown50 + 'sje5nuby45ub4s5v4' => '5', // Lickmybergers + 'b5s45vy4s5cs54' => '5', // Lesser Smaug + 'bu56s345vy35cy34w' => '5', // Limi + '65345yvurjnsfvcs' => '+10', // ifm + '4nu6bs4v5y4s45ys45' => '5', // ToF + 'yb54sv4y5s45y45' => '5', // Weebos + 'bo87n87ym8979huyi' => '5', // itsme + '796rbn6fiuyghuyig' => '5', // Diploman + '875brfn6tuyguiyguy' => '5', // Balchmorn + 'uw6fj5e6e4y98m98m' => '5', // Charmander + '876tkguyihuhouyg6r' => '+10', // Lamppost + '86bd7nf8mg7yighuygmt' => '9', // Hugendugen + '57dbnf68mg7nf76f6mtft' => '5', // comatt + 'x64eb5dn75rf6mg7' => '5', // Guyguypants + 'n987whtuhi3galt' => '5', // kmuffinman + '94ntay3i48yuthkia' => '5', // huggye + '7s346ys4y3s4tfs34' => '5', // Metric + '897tb67dntuyiuguyhu' => '5', // Improbable + 'awv4taw4etcaw4c3' => '5', // kwando1313 + 'hbas4yvs4tc3s434y' => '5', // Tiffanyy + '4s3h54ys4ye5ys5y4s5' => '5', // SuperPokenerd + '54se5ybse4geysegs' => '+10', // Hob + '74hf9283h4f234f2' => '5', // Ace Emerald + 'f23h498j203034' => '5', // verbatim + '983j443j4oifji234' => '5', // Amarillo + '4y234u89f234234' => '5', // HoiPolloi + 'fh49832joj2i3ji23' => '5', // FinnTheWastelander + 'ag4v6aw3c53c2535' => '+10', // Violatic + 'ahg43a34a3f5a23d2a3' => '9', // Stormclouds + 'a35b6ay63s4vy4' => '+10', // whatevs + 'va3v5a3c5ag5b3' => '+10', // MS + '7b4s43v6s4v436s4' => '10', // public #2 + 'avg23v5ta3c5a23ca23' => '10', // stone cold + '6sv34sv34swh36es' => '10', // Amarillo + 'gs46e5r4g65se4r6g5e4' => '5', // Rjwegz + 'h4se6t54jd6fgh54jf6g5h' => '+10', // Zurich + 'kf45g6h564jr6dt546j' => '5', // Wiz + 'jd64j6rt4565dhr456t' => '5', // Gerard + 'd4r6t5h4dr65t4hd6r' => '5', // zek4040 + 'k47s96er4thy654sdr' => '5', // KorKonT + 'hja56es4r5h4sd6fgj' => '5', // Salemsectra + 'hjdr46t54hd65r46t' => '5', // lol6789 + 'k4d65r4t6hs54ere' => '5', // Thorns + 'h4ser65th65se4r5h4s' => '5', // ungulateman + 'j46dr5t4hj6s54er6g5s4er' => '5', // Yllnath + '3kjs45ude4yhbs34' => '5', // Purple Cant + 'aj3y5hse5yse4gys' => '5', // Jealous + 'kmus45dhur5njd4r' => '5', // Fishkiller nomore + 'umkdr56ud45hud4r5' => '5', // zombachu + 'u6kd45s34j75d' => '5', // Deity + '7d4k568dr454' => '+10', // Jibaku + 't4s73a4s634b3' => '5', // Kingtrace + 'jg10294u89jflsa' => '5', // Soarin + 'les45jsd45jn4w' => '5', // Sparky + 'jw457eh457je45' => '+10', // Aerrow + 'e4jm57he457ke45' => '+10', // LonelyNess + '7k54r7j5685rmk68' => '+10', // ginganinja + '8kr567568r568jrt' => '5', // JRank + '4g9ha834gkjalw4th2a' => '+10', // Ditto + '9gh8a3w94iotajw4h' => '+Obvious', // Obvious + 't043t23t43w5yl3jo2' => '10', // Macchiateau + 'vyb9w3u4ntca23t24y' => '+10', // DHR + 'yhv2934iocsotj35c3' => '+10', // Red Alert + 'yvjn3w402348ut938420' => '25', // Moonlapse + '8hv59yw3jisu4thjk3s' => '5', // PBOB + '9tg83hw49tjiw34jt3' => '5', // Zarox + '23y54he4jw354yw34' => '5', // DGBsLeaderKamina + 'ihj045w98j393tg4w34' => '5', // Marre + 'yj3984jt9w34jito3' => '+10', // Serei + 'yi93iwj9t3ui4jiow34t3' => '5', // Tpyo + '98wh39ur3igthu3' => '5', // elipSEverity + '8249tghusiwkjfowiofja' => '10', // Drielme + 'b783qh4tyuhw4skuth43' => '5', // Okuu + 'yn8vw37y47tw3uy4tg3' => '+10', // Kyoukusho + 'hj3895jswhy34tw34h6w3' => '5', // Floating + '7jnw3bg6e7v57e4fv5345' => '5', // gameshrk90 + 'e7hd357nur56nuje46be745' => '5', // aegyo + 'y43bn7syv34yta3v4yta3' => '5', // LibraSnakes13 + 'yab4vta4caw4vt34a' => '5', // LightBlue + 'ynab34ta34tca3w4a2' => '5', // unreconstructed + 'sc4t34tby3v53c3s4t3' => '5', // 494 + 'b3s4ys34ct34t23t23' => '5', // Rowchee + 'hj6e4yt45etsgsj56hy4e5' => '5', // DTC's + 'lkjuydrtghndry' => '5', // DTC's + '4hw6juye46sjsu45y4' => '5', // DTC's + '7h5tw34twh45wjte45yw45' => '5', // Pharen + 'nue45estyhw45yw45wy' => '10', // techniloom + 'sigjeorij34oigoa3' => '10', // hawnt + 'nijw3oi4jcqo3ij4xtq2' => '5', // Gary + 'nuwijb394icjtqi924jxt' => '5', // Leader Jasmine + '9g8i3o2jfi23ij4oif' => '5', // + 'fu0923ojfwiij32oi3ji3' => 'xax', // ethereal + 'hf923huikfhi3u4f' => '+10', // Deck_Knight + 'gjh839j4ji3u4jt324g' => '5', // phoopes + 'jtn459w82u948r2q3' => '5', // bashy + 'hn59j34iut3jw4t2' => '5', // Coyote-Stark + 'ifwjoaijegoiawjef' => '5', // PUB + 'hj9358gaoiwjiofwaerwae' => '5', // rku + 'gh3578wh34iufgkj3i4t' => '5', // srk1214 + 'hg28948thgiuwkh54gt3' => '1', // outlaw4 + 'g3ijh982j3ir2q3' => '5', // Hello2 + 'h4829a23rjk23jr3' => '1', // + 'j4w6su5eytghs34y53hwy5t5@$' => '50', // giveaway + 'h8f72h38uhkf234f343' => '5', // bashybushman + '3gh984ahwit32hoir3j2' => '5', // xpsp2 + 'ajwoeifja2839toj2ijar' => '5', // iRawrDragonite + '8934jg2iuh4gk2j3lk2j3r' => '5', // prankster + '28394thgu4ijhkjnk2t3' => '5', // sean + 'h27398guh4iukwjakjwnf' => '5', // welch + '8q9c3hugjo2awejl23' => '+5', // stoopidphukr + '93823wt940gc8joal23jxt' => '+5', // Kalashnikov + 'jaoi3928gj9aoi32lj23' => '+10', // Noire + '289thag3ikwejtl2kaj23' => '1', // some guy + '2t492oajl3jt23t2q2tq' => '5', // stoopidphukr again + 'j938w4tkj3lyj4oi3josy4' => '5', // brenner + 'y9034w934uyjwi3k4tw34t234' => '+10', // Marty + 'j7qn3ub4sv3y45c3s4ct3w4' => '5', // supercoolsnorlax + 'yj09384utoiwj34iotj3wo4iot34' => '5', // elemental +); + +if (!$_REQUEST['key']) die('

Enter a beta key:

'); + +if (!$keys[$_REQUEST['key']]) die('

Your beta key is invalid

'); + +$key = $_REQUEST['key']; +$user = $keys[$_REQUEST['key']]; + +$voice = false; +if (substr($user,0,1) === '+') +{ + $voice = true; + $user = substr($user,1); +} + +$maxusecount = 1; + +if (ctype_digit($user)) +{ + $maxusecount = intval($user); + $user = ''; +} + +include 'lib/ntbb-session.lib.php'; + +$usecount = $users->keyCount($key); + +if ($usecount >= $maxusecount) die('This key has already been used its maximum number of times ('.$usecount.' times).'); +if ($usecount > 0) $voice = false; + +$pass = @$_POST['pass']; +$pass2 = @$_POST['pass2']; + +if ($pass && $pass === $pass2) +{ + if (!$user) $user = $_REQUEST['user']; + if (!$user) die('Username not specified. Click Back and try again.'); + if ($users->addUser(array('username'=>$user, 'signupkey'=>$key), $pass)) + { + if ($voice) + { + if ($users->modifyUser($curuser, array('group' => 3))) + { + die('User created and voiced. You may now proceed to PS.'); + } + else + { + die('User created, but voicing FAILED: '.$error); + } + } + die('User created. You may now proceed to PS.'); + } + else + { + die('There\'s already a user with this name (you probably already created an account).'); + } +} +else if ($pass || $pass2) +{ + die('Passwords don\'t match. Click Back and try again.'); +} +?> +
+

Beta key:

+ +

VOICE - the first use of this beta key will automatically voice your account after creation. 1) { ?> Subsequent usages (i.e. when your friends register) will create regular (unvoiced) accounts.

+ +

This key can be used more time(s)

+ 1) { ?> +

Give this link to your friends. This key can be used times total: for you and friends.

+ +

Username: ' ?>

+

Password:

+

Password (confirm):

+

+
diff --git a/backup/teambuilder.php b/backup/teambuilder.php new file mode 100644 index 0000000000..b93fddcde1 --- /dev/null +++ b/backup/teambuilder.php @@ -0,0 +1,81 @@ + + + + + Showdown Teambuilder + + + + + + + + +
+

Pokemon Showdown! (beta)

+
+
+
+
+ Teambuilder +
+
+
+
Loading...
+
+ If this message isn't going away, try refreshing.
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backup/test.php b/backup/test.php new file mode 100644 index 0000000000..0ab75fef22 --- /dev/null +++ b/backup/test.php @@ -0,0 +1,8 @@ + + +
+Your name: +Lastname: +
+ + \ No newline at end of file diff --git a/cache.manifest b/cache.manifest new file mode 100644 index 0000000000..f13ec3f49c --- /dev/null +++ b/cache.manifest @@ -0,0 +1,11 @@ +CACHE MANIFEST +# 2011-02-02 + +# Explicitly cached 'master entries'. +CACHE: +sim.css +js/ +data/ + +# Resources that require the user to be online. +NETWORK: diff --git a/data/abilities.js b/data/abilities.js new file mode 100644 index 0000000000..7ca02a45bb --- /dev/null +++ b/data/abilities.js @@ -0,0 +1,2613 @@ +/* + +Ratings and how they work: + +-2: Extremely detrimental + The sort of ability that relegates Pokemon with Uber-level BSTs + into NU. + ex. Slow Start, Truant + +-1: Detrimental + An ability that does more harm than good. + ex. Defeatist, Klutz + + 0: Useless + An ability with no net effect on a Pokemon during a battle. + ex. Pickup, Illuminate + + 1: Ineffective + An ability that has a minimal effect. Should never be chosen over + any other ability. + ex. Pressure, Damp + + 2: Situationally useful + An ability that can be useful in certain situations. + ex. Blaze, Insomnia + + 3: Useful + An ability that is generally useful. + ex. Volt Absorb, Iron Fist + + 4: Very useful + One of the most popular abilities. The difference between 3 and 4 + can be ambiguous. + ex. Technician, Intimidate + + 5: Essential + The sort of ability that defines metagames. + ex. Drizzle, Magnet Pull + +*/ + +exports.BattleAbilities = { + "adaptability": { + desc: "This Pokemon's attacks that receive STAB (Same Type Attack Bonus) are increased from 50% to 100%.", + shortDesc: "This Pokemon's same-type attack bonus (STAB) is increased from 1.5x to 2x.", + onModifyMove: function(move) { + move.stab = 2; + }, + id: "adaptability", + name: "Adaptability", + rating: 3.5, + num: 91 + }, + "aftermath": { + desc: "If a contact move knocks out this Pokemon, the opponent receives damage equal to one-fourth of its max HP.", + shortDesc: "If this Pokemon is KOed with a contact move, that move's user loses 1/4 its max HP.", + id: "aftermath", + name: "Aftermath", + onFaint: function(target, source, effect) { + if (effect && effect.effectType === 'Move' && effect.isContact && source) { + this.damage(source.maxhp/4, source, target); + } + }, + rating: 3, + num: 106 + }, + "airlock": { + desc: "While this Pokemon is active, all weather conditions and their effects are disabled.", + shortDesc: "While this Pokemon is active, all weather conditions and their effects are disabled.", + onAnyModifyPokemon: function(pokemon) { + pokemon.ignore['WeatherTarget'] = true; + }, + id: "airlock", + name: "Air Lock", + rating: 3, + num: 76 + }, + "analytic": { + desc: "If the user moves last, the power of that move is increased by 30%.", + shortDesc: "This Pokemon's attacks do 1.3x damage if it is the last to move in a turn.", + onBasePower: function(basePower, attacker, defender, move) { + if (!this.willMove(defender)) { + this.debug('Analytic boost'); + return basePower * 1.3; + } + }, + id: "analytic", + name: "Analytic", + rating: 1, + num: 148 + }, + "angerpoint": { + desc: "If this Pokemon, or its Substitute, is struck by a Critical Hit, its Attack is boosted to six stages.", + shortDesc: "If this Pokemon (not a Substitute) is hit by a critical hit, its Attack is boosted by 12.", + onCriticalHit: function(target) { + if (!target.volatiles['substitute']) { + target.setBoost({atk: 6}); + this.add('-setboost',target,'atk',12,'[from] ability: Anger Point'); + } + }, + id: "angerpoint", + name: "Anger Point", + rating: 2, + num: 83 + }, + "anticipation": { + desc: "A warning is displayed if an opposing Pokemon has the moves Fissure, Guillotine, Horn Drill, Sheer Cold, or any attacking move from a type that is considered super effective against this Pokemon (including Counter, Mirror Coat, and Metal Burst). Hidden Power, Judgment, Natural Gift and Weather Ball are considered Normal-type moves.", + shortDesc: "On switch-in, this Pokemon shudders if any foe has a super effective or OHKO move.", + onStart: function(pokemon) { + var targets = pokemon.side.foe.active; + for (var i=0; i 0 || move.ohko)) { + this.add('-activate', pokemon, 'Anticipation'); + return; + } + } + } + }, + id: "anticipation", + name: "Anticipation", + rating: 1, + num: 107 + }, + "arenatrap": { + desc: "When this Pokemon enters the field, its opponents cannot switch or flee the battle unless they are part Flying-type, have the Levitate ability, are holding Shed Shell, or they use the moves Baton Pass or U-Turn. Flying-type and Levitate Pokemon cannot escape if they are holding Iron Ball or Gravity is in effect. Levitate Pokemon also cannot escape if their ability is disabled through other means, such as Skill Swap or Gastro Acid.", + shortDesc: "Prevents foes from switching out normally unless they have immunity to Ground.", + onFoeModifyPokemon: function(pokemon) { + if (pokemon.runImmunity('Ground', false)) { + pokemon.trapped = true; + } + }, + id: "arenatrap", + name: "Arena Trap", + rating: 5, + num: 71 + }, + "baddreams": { + desc: "If asleep, each of this Pokemon's opponents receives damage equal to one-eighth of its max HP.", + shortDesc: "Causes sleeping adjacent foes to lose 1/8 of their max HP at the end of each turn.", + onResidualOrder: 26, + onResidualSubOrder: 1, + onResidual: function(pokemon) { + for (var i=0; i= totalspd) { + this.boost({spa:1}); + } else { + this.boost({atk:1}); + } + }, + id: "download", + name: "Download", + rating: 4, + num: 88 + }, + "drizzle": { + desc: "When this Pokemon enters the battlefield, it causes a permanent Rain Dance that can only be stopped by Air Lock, Cloud Nine or another weather condition.", + shortDesc: "On switch-in, this Pokemon summons Rain Dance until another weather replaces it.", + onStart: function(source) { + this.setWeather('raindance'); + this.weatherData.duration = 0; + }, + id: "drizzle", + name: "Drizzle", + rating: 5, + num: 2 + }, + "drought": { + desc: "When this Pokemon enters the battlefield, it causes a permanent Sunny Day that can only be stopped by Air Lock, Cloud Nine or another weather condition.", + shortDesc: "On switch-in, this Pokemon summons Sunny Day until another weather replaces it.", + onStart: function(source) { + this.setWeather('sunnyday'); + this.weatherData.duration = 0; + }, + id: "drought", + name: "Drought", + rating: 5, + num: 70 + }, + "dryskin": { + desc: "This Pokemon absorbs Water attacks and gains a weakness to Fire attacks. If Sunny Day is in effect, this Pokemon takes damage. If Rain Dance is in effect, this Pokemon recovers health.", + shortDesc: "This Pokemon is healed 1/4 by Water, 1/8 by Rain; is hurt 1.25x by Fire, 1/8 by Sun.", + onImmunity: function(type, pokemon) { + if (type === 'Water') { + this.heal(pokemon.maxhp/4); + return null; + } + }, + onFoeBasePower: function(basePower, attacker, defender, move) { + if (move.type === 'Fire') { + return basePower * 5/4; + } + }, + onWeather: function(target, source, effect) { + if (effect.id === 'raindance') { + this.heal(target.maxhp/8); + } else if (effect.id === 'sunnyday') { + this.damage(target.maxhp/8); + } + }, + id: "dryskin", + name: "Dry Skin", + rating: 3, + num: 87 + }, + "earlybird": { + desc: "This Pokemon will remain asleep for half as long as it normally would; this includes both opponent-induced sleep and user-induced sleep via Rest.", + shortDesc: "This Pokemon's sleep status lasts half as long as usual, self-induced or not.", + id: "earlybird", + name: "Early Bird", + isHalfSleep: true, + rating: 2.5, + num: 48 + }, + "effectspore": { + desc: "If an opponent directly attacks this Pokemon, there is a 30% chance that the opponent will become either poisoned, paralyzed or put to sleep. There is an equal chance to inflict each status.", + shortDesc: "30% chance of poisoning, paralyzing, or causing sleep on Pokemon making contact.", + onAfterDamage: function(damage, target, source, move) { + if (move && move.isContact && !source.status) { + var r = this.random(100); + if (r < 11) source.setStatus('slp'); + else if (r < 21) source.setStatus('par'); + else if (r < 30) source.setStatus('psn'); + } + }, + id: "effectspore", + name: "Effect Spore", + rating: 2, + num: 27 + }, + "filter": { + desc: "This Pokemon receives one-fourth reduced damage from Super Effective attacks.", + shortDesc: "This Pokemon receives 3/4 damage from super effective attacks.", + onFoeBasePower: function(basePower, attacker, defender, move) { + if (this.getEffectiveness(move.type, defender) > 0) { + this.debug('Filter neutralize'); + return basePower * 3/4; + } + }, + id: "filter", + name: "Filter", + rating: 3, + num: 111 + }, + "flamebody": { + desc: "If an opponent directly attacks this Pokemon, there is a 30% chance that the opponent will become burned.", + shortDesc: "30% chance of burning a Pokemon making contact with this Pokemon.", + onAfterDamage: function(damage, target, source, move) { + if (move && move.isContact) { + if (this.random(10) < 3) { + source.trySetStatus('brn', target, move); + } + } + }, + id: "flamebody", + name: "Flame Body", + rating: 2, + num: 49 + }, + "flareboost": { + desc: "When the user with this ability is burned, its Special Attack is raised by 50%.", + shortDesc: "When this Pokemon is burned, its special attacks do 1.5x damage.", + onModifyStats: function(stats, pokemon) { + if (pokemon.status === 'brn') { + stats.spa *= 1.5; + } + }, + id: "flareboost", + name: "Flare Boost", + rating: 3, + num: 138 + }, + "flashfire": { + desc: "This Pokemon is immune to all Fire-type attacks; additionally, its own Fire-type attacks receive a 50% boost if a Fire-type move hits this Pokemon. Multiple boosts do not occur if this Pokemon is hit with multiple Fire-type attacks.", + shortDesc: "This Pokemon's Fire attacks do 1.5x damage if hit by one Fire move; Fire immunity.", + onImmunity: function(type, pokemon) { + if (type === 'Fire') { + pokemon.addVolatile('flashfire'); + return null; + } + }, + effect: { + noCopy: true, // doesn't get copied by Baton Pass + onStart: function(target) { + this.add('-start',target,'ability: Flash Fire'); + }, + onBasePower: function(basePower, attacker, defender, move) { + if (move.type === 'Fire') { + this.debug('Flash Fire boost'); + return basePower * 1.5; + } + } + }, + id: "flashfire", + name: "Flash Fire", + rating: 3, + num: 18 + }, + "flowergift": { + desc: "If this Pokemon is active while Sunny Day is in effect, its Attack and Special Defense stats (as well as its partner's stats in double battles) receive a 50% boost.", + shortDesc: "If user is Cherrim and Sunny Day is active, it and allies' Attack and Sp. Def are 1.5x.", + onStart: function(pokemon) { + delete this.effectData.forme; + }, + onModifyStats: function(stats, pokemon) { + if (this.weather === 'sunnyday') { + stats.atk *= 1.5; + stats.spd *= 1.5; + if (pokemon.isActive && pokemon.speciesid === 'cherrim' && this.effectData.forme !== 'Sunny') { + this.effectData.forme = 'Sunny'; + this.add('-formechange', pokemon, 'Cherrim-Sunny'); + this.add('-message', pokemon.name+' transformed! (placeholder)'); + } + } else if (pokemon.isActive && pokemon.speciesid === 'cherrim' && this.effectData.forme) { + delete this.effectData.forme; + this.add('-formechange', pokemon, 'Cherrim'); + this.add('-message', pokemon.name+' transformed! (placeholder)'); + } + }, + id: "flowergift", + name: "Flower Gift", + rating: 3, + num: 122 + }, + "forecast": { + desc: "This Pokemon's type changes according to the current weather conditions: it becomes Fire-type during Sunny Day, Water-type during Rain Dance, Ice-type during Hail and remains its regular type otherwise.", + shortDesc: "Castform's type changes to the current weather condition's type, except Sandstorm.", + onModifyPokemon: function(pokemon) { + if (pokemon.baseTemplate.species !== 'Castform' || pokemon.transformed) return; + var forme = null; + switch (this.weather) { + case 'sunnyday': + if (pokemon.template.speciesid !== 'castformsunny') forme = 'Castform-Sunny'; + break; + case 'raindance': + if (pokemon.template.speciesid !== 'castformrainy') forme = 'Castform-Rainy'; + break; + case 'hail': + if (pokemon.template.speciesid !== 'castformsnowy') forme = 'Castform-Snowy'; + break; + default: + if (pokemon.template.speciesid !== 'castform') forme = 'Castform'; + break; + } + if (pokemon.isActive && forme) { + pokemon.transformInto(forme); + pokemon.transformed = false; + this.add('-formechange', pokemon, forme); + this.add('-message', pokemon.name+' transformed! (placeholder)'); + } + }, + id: "forecast", + name: "Forecast", + rating: 4, + num: 59 + }, + "forewarn": { + desc: "The move with the highest Base Power in the opponent's moveset is revealed.", + shortDesc: "On switch-in, this Pokemon is alerted to the foes' move with the highest base power.", + onStart: function(pokemon) { + var targets = pokemon.side.foe.active; + var warnMoves = []; + var warnBp = 1; + for (var i=0; i warnBp) { + warnMoves = [[move, targets[i]]]; + warnBp = bp; + } else if (bp == warnBp) { + warnMoves.push([move, targets[i]]); + } + } + } + if (!warnMoves.length) return; + var warnMove = warnMoves[this.random(warnMoves.length)]; + this.add('-activate', pokemon, 'ability: Forewarn', warnMove[0]); + }, + id: "forewarn", + name: "Forewarn", + rating: 1, + num: 108 + }, + "friendguard": { + desc: "Reduces the damage received from an ally in a double or triple battle.", + shortDesc: "This Pokemon's allies receive 3/4 damage from other Pokemon's attacks.", + id: "friendguard", + name: "Friend Guard", + rating: 0, + num: 132 + }, + "frisk": { + desc: "When this Pokemon enters the field, it identifies the opponent's held item; in double battles, the held item of an unrevealed, randomly selected opponent is identified.", + shortDesc: "On switch-in, this Pokemon identifies a random foe's held item.", + onStart: function(pokemon) { + var target = pokemon.side.foe.randomActive(); + if (target && target.item) { + this.add('-item', target, target.getItem().name, '[from] ability: Frisk', '[of] '+pokemon); + } + }, + id: "frisk", + name: "Frisk", + rating: 1.5, + num: 119 + }, + "gluttony": { + desc: "This Pokemon consumes its held berry when its health reaches 50% max HP or lower.", + shortDesc: "When this Pokemon has 1/2 or less of its max HP, it uses certain Berries early.", + id: "gluttony", + name: "Gluttony", + rating: 1.5, + num: 82 + }, + "guts": { + desc: "When this Pokemon is poisoned (including Toxic), burned, paralyzed or asleep (including self-induced Rest), its Attack stat receives a 50% boost; the burn status' Attack drop is also ignored.", + shortDesc: "If this Pokemon is statused, its Attack is 1.5x; burn's Attack drop is ignored.", + onModifyStats: function(stats, pokemon) { + if (pokemon.status) { + stats.atk *= 1.5; + } + }, + id: "guts", + name: "Guts", + rating: 4, + num: 62 + }, + "harvest": { + desc: "When the user uses a held Berry, it is restored at the end of the turn.", + shortDesc: "50% chance this Pokemon's Berry is restored at the end of each turn. 100% in Sun.", + id: "harvest", + name: "Harvest", + onResidualOrder: 26, + onResidualSubOrder: 1, + onResidual: function(pokemon) { + if ((this.weather === 'sunnyday') || (this.random(2) === 0)) { + if (!pokemon.item && this.getItem(pokemon.lastItem).isBerry) { + pokemon.setItem(pokemon.lastItem); + this.add("-item", pokemon, pokemon.item, '[from] ability: Harvest'); + } + } + }, + rating: 4, + num: 139 + }, + "healer": { + desc: "Has a 30% chance of curing an adjacent ally's status ailment at the end of each turn in Double and Triple Battles.", + shortDesc: "30% chance of curing an adjacent ally's status at the end of each turn.", + id: "healer", + name: "Healer", + onResidualOrder: 5, + onResidualSubOrder: 1, + rating: 0, + num: 131 + }, + "heatproof": { + desc: "This Pokemon receives half damage from both Fire-type attacks and residual burn damage.", + shortDesc: "This Pokemon receives half damage from Fire-type attacks and burn damage.", + onSourceBasePower: function(basePower, attacker, defender, move) { + if (move.type === 'Fire') { + return basePower / 2; + } + }, + onDamage: function(damage, attacker, defender, effect) { + if (effect && effect.id === 'brn') { + return damage / 2; + } + }, + id: "heatproof", + name: "Heatproof", + rating: 2.5, + num: 85 + }, + "heavymetal": { + desc: "The user's weight is doubled. This increases user's base power of Heavy Slam and Heat Crash, as well as damage taken from the opponent's Low Kick and Grass Knot, due to these moves being calculated by the target's weight.", + shortDesc: "This Pokemon's weight is doubled.", + onModifyPokemon: function(pokemon) { + pokemon.weightkg *= 2; + }, + id: "heavymetal", + name: "Heavy Metal", + rating: 0, + num: 134 + }, + "honeygather": { + desc: "If it is not already holding an item, this Pokemon may find and be holding Honey after a battle.", + shortDesc: "No competitive use.", + id: "honeygather", + name: "Honey Gather", + rating: 0, + num: 118 + }, + "hugepower": { + desc: "This Pokemon's Attack stat is doubled. Therefore, if this Pokemon's Attack stat on the status screen is 200, it effectively has an Attack stat of 400; which is then subject to the full range of stat boosts and reductions.", + shortDesc: "This Pokemon's Attack is doubled.", + onModifyStats: function(stats) { + stats.atk *= 2; + }, + id: "hugepower", + name: "Huge Power", + rating: 5, + num: 37 + }, + "hustle": { + desc: "This Pokemon's Attack receives a 50% boost but its Physical attacks receive a 20% drop in Accuracy. For example, a 100% accurate move would become an 80% accurate move. The accuracy of moves that never miss, such as Aerial Ace, remains unaffected.", + shortDesc: "This Pokemon's Attack is 1.5x and Accuracy of its physical attacks is 0.8x.", + onModifyStats: function(stats) { + stats.atk *= 1.5; + }, + onModifyMove: function(move) { + if (move.category === 'Physical' && typeof move.accuracy === 'number') { + move.accuracy *= 0.8; + } + }, + id: "hustle", + name: "Hustle", + rating: 3, + num: 55 + }, + "hydration": { + desc: "If this Pokemon is active while Rain Dance is in effect, it recovers from poison, paralysis, burn, sleep and freeze at the end of the turn.", + shortDesc: "This Pokemon has its status cured at the end of each turn if Rain Dance is active.", + onResidualOrder: 5, + onResidualSubOrder: 1, + onResidual: function(pokemon) { + if (pokemon.status && this.weather === 'raindance') { + this.debug('hydration'); + pokemon.cureStatus(); + } + }, + id: "hydration", + name: "Hydration", + rating: 4, + num: 93 + }, + "hypercutter": { + desc: "Opponents cannot reduce this Pokemon's Attack stat; they can, however, modify stat changes with Power Swap or Heart Swap and inflict a stat boost with Swagger. This ability does not prevent self-inflicted stat reductions.", + shortDesc: "Prevents other Pokemon from lowering this Pokemon's Attack.", + onBoost: function(boost, target, source) { + if (source && target === source) return; + if (boost['atk'] && boost['atk'] < 0) { + boost['atk'] = 0; + this.add("-message", target.name+"'s Attack was not lowered! (placeholder)"); + } + }, + id: "hypercutter", + name: "Hyper Cutter", + rating: 2, + num: 52 + }, + "icebody": { + desc: "If active while Hail is in effect, this Pokemon recovers one-sixteenth of its max HP after each turn. If a non-Ice-type Pokemon receives this ability through Skill Swap, Role Play or the Trace ability, it will not take damage from Hail.", + shortDesc: "If Hail is active, this Pokemon heals 1/16 of its max HP each turn; immunity to Hail.", + onWeather: function(target, source, effect) { + if (effect.id === 'hail') { + this.heal(target.maxhp/16); + } + }, + onImmunity: function(type, pokemon) { + if (type === 'hail') return false; + }, + id: "icebody", + name: "Ice Body", + rating: 3, + num: 115 + }, + "illuminate": { + desc: "When this Pokemon is in the first slot of the player's party, it doubles the rate of wild encounters.", + shortDesc: "No competitive use.", + id: "illuminate", + name: "Illuminate", + rating: 0, + num: 35 + }, + "illusion": { + desc: "Illusion will change the appearance of the Pokemon to a different species. This is dependent on the last Pokemon in the player's party. Along with the species itself, Illusion is broken when the user is damaged, but is not broken by Substitute, weather conditions, status ailments, or entry hazards. Illusion will replicate the type of Poke Ball, the species name, and the gender of the Pokemon it is masquerading as.", + shortDesc: "This Pokemon appears as the last Pokemon in the party until it takes direct damage.", + onBeforeSwitchIn: function(pokemon) { + if (!pokemon.volatiles['illusion']) { + var i; + for (i=pokemon.side.pokemon.length-1; i>pokemon.position; i--) { + if (!pokemon.side.pokemon[i]) continue; + if (!pokemon.side.pokemon[i].fainted) break; + } + pokemon.illusion = pokemon.side.pokemon[i]; + } + }, + onDamage: function(damage, pokemon, source, effect) { + if (effect && effect.effectType === 'Move') { + this.debug('illusion cleared'); + //pokemon.addVolatile('illusion'); + pokemon.setAbility(''); + pokemon.illusion = null; + this.add('replace', pokemon, pokemon.getDetails()); + } + }, + id: "illusion", + name: "Illusion", + rating: 4.5, + num: 149 + }, + "immunity": { + desc: "This Pokemon cannot become poisoned nor Toxic poisoned.", + shortDesc: "This Pokemon cannot be poisoned. Gaining this Ability while poisoned cures it.", + onImmunity: function(type) { + if (type === 'psn') return false; + }, + id: "immunity", + name: "Immunity", + rating: 1, + num: 17 + }, + "imposter": { + desc: "As soon as the user comes into battle, it Transforms into its opponent, copying the opponent's stats exactly, with the exception of HP. Imposter copies all stat changes on the target originating from moves and abilities such as Swords Dance and Intimidate, but not from items such as Choice Specs. Imposter will not Transform the user if the opponent is an Illusion or if the opponent is behind a Substitute.", + shortDesc: "On switch-in, this Pokemon copies the foe it's facing; stats, moves, types, Ability.", + onStart: function(pokemon) { + var target = pokemon.side.foe.randomActive(); + if (target && pokemon.transformInto(target)) { + this.add('-transform', pokemon, target); + } + }, + id: "imposter", + name: "Imposter", + rating: 5, + num: 150 + }, + "infiltrator": { + desc: "Ignores Reflect, Light Screen and Safeguard under effect on the target.", + shortDesc: "This Pokemon's moves ignore the foe's Reflect, Light Screen, Safeguard, and Mist.", + // Implemented in the corresponding effects. + id: "infiltrator", + name: "Infiltrator", + rating: 1, + num: 151 + }, + "innerfocus": { + desc: "This Pokemon cannot be made to flinch.", + shortDesc: "This Pokemon cannot be made to flinch.", + onFlinch: false, + id: "innerfocus", + name: "Inner Focus", + rating: 1, + num: 39 + }, + "insomnia": { + desc: "This Pokemon cannot be put to sleep; this includes both opponent-induced sleep as well as user-induced sleep via Rest.", + shortDesc: "This Pokemon cannot fall asleep. Gaining this Ability while asleep cures it.", + onImmunity: function(type, pokemon) { + if (type === 'slp') return false; + }, + id: "insomnia", + name: "Insomnia", + rating: 2, + num: 15 + }, + "intimidate": { + desc: "When this Pokemon enters the field, the Attack stat of each of its opponents lowers by one stage.", + shortDesc: "On switch-in, this Pokemon lowers adjacent foes' Attack by 1.", + onStart: function(pokemon) { + var foeactive = pokemon.side.foe.active; + for (var i=0; i