Skip to content

Commit

Permalink
Move battledata.js to TypeScript
Browse files Browse the repository at this point in the history
This is the first step of moving the entire client over to
TypeScript + Preact!!!!

The main change here is that battledata.js has been split into three
files:
- `src/battle-dex.ts`
- `src/battle-dex-data.ts`
- `src/battle-dex-misc.js`

These are concatenated back into `battledata.js` in the client, so
third parties (and specifically, old replay files) should be
unaffected. Also, this makes sure that we don't have more than two
dependencies right now.

The compilation is done with Babel 7 beta, because no stable version
of Babel supports TypeScript. We're not using `tsc` because it can't
compile to ES3 and it doesn't support preserving line numbers.

`toRoomid` has been moved from client.js to battle-dex.ts.
  • Loading branch information
Zarel committed May 14, 2018
1 parent 3460343 commit a15ec64
Show file tree
Hide file tree
Showing 10 changed files with 632 additions and 477 deletions.
28 changes: 28 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"presets": [
"@babel/typescript"
],
"plugins": [
"@babel/plugin-transform-member-expression-literals",
"@babel/plugin-transform-property-literals",
"@babel/plugin-transform-arrow-functions",
["@babel/plugin-transform-block-scoping", {"throwIfClosureRequired": true}],
["@babel/plugin-transform-classes", {"loose": true}],
["@babel/plugin-transform-computed-properties", {"loose": true}],
"@babel/plugin-transform-destructuring",
["@babel/plugin-transform-for-of", {"assumeArray": true}],
"@babel/plugin-transform-literals",
"@babel/plugin-transform-parameters",
"@babel/plugin-transform-shorthand-properties",
["@babel/plugin-transform-spread", {"loose": true}],
["@babel/plugin-transform-template-literals", {"loose": true}],
"@babel/plugin-transform-exponentiation-operator",
["@babel/plugin-proposal-class-properties", {"loose": true}],
["@babel/plugin-proposal-object-rest-spread", {"useBuiltIns": true}],
["@babel/plugin-transform-react-jsx", {"pragma": "Preact.h", "useBuiltIns": true}]
],
"ignore": [
"src/globals.d.ts"
],
"retainLines": true
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ eslint-cache/
Thumbs.db
npm-debug.log
/vendor/

/js/battledata.js
/js/battle-dex.js
/js/battle-dex-data.js
39 changes: 30 additions & 9 deletions build-tools/update
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,53 @@
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const exec = require('child_process').exec;
const child_process = require('child_process');

const thisDir = __dirname;
const rootDir = path.resolve(thisDir, '..');
process.chdir(rootDir);

// update version
process.stdout.write("Updating version... ");
/*********************************************************
* Update version number
*********************************************************/

process.stdout.write("Updating version... ");

let version = require('../package.json').version;

let configBuf = fs.readFileSync(path.resolve(rootDir, 'config/config.js'), {encoding: 'utf8'});
let configBuf = fs.readFileSync('config/config.js', {encoding: 'utf8'});
configBuf = configBuf.replace(/\/\* version \*\/[^;\n]*;/, `/* version */ Config.version = ${JSON.stringify(version)};`);

fs.writeFileSync(path.resolve(rootDir, 'config/config.js'), configBuf);
fs.writeFileSync('config/config.js', configBuf);
console.log("DONE");

/*********************************************************
* Compile TS files
*********************************************************/

child_process.execSync(`node_modules/@babel/cli/bin/babel.js src --out-dir js --extensions '.ts,.tsx'`);

fs.writeFileSync(
'js/battledata.js',
fs.readFileSync('js/battle-dex.js') + '\n\n' +
fs.readFileSync('js/battle-dex-data.js') + '\n\n' +
fs.readFileSync('src/battle-dex-misc.js')
);

/*********************************************************
* Update cachebuster and News
*********************************************************/

function updateIndex() {
let indexContents = fs.readFileSync(path.resolve(rootDir, 'index.template.html'), {encoding: 'utf8'});
let indexContents = fs.readFileSync('index.template.html', {encoding: 'utf8'});

// add hashes to js and css files
process.stdout.write("Updating hashes... ");
indexContents = indexContents.replace(/(src|href)="\/(.*?)\?[a-z0-9]*?"/g, function (a, b, c) {
let hash = Math.random(); // just in case creating the hash fails
try {
const filename = c.replace('/play.pokemonshowdown.com/', '');
const fstr = fs.readFileSync(path.resolve(rootDir, filename), {encoding: 'utf8'});
const fstr = fs.readFileSync(filename, {encoding: 'utf8'});
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
} catch (e) {}

Expand All @@ -49,7 +70,7 @@ function updateIndex() {

// add news
process.stdout.write("Updating news... ");
exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) {
child_process.exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) {
let newsData = [0, '[failed to retrieve news]'];
if (!error && !stderr) {
try {
Expand All @@ -66,7 +87,7 @@ function updateIndex() {
console.log("DONE");

process.stdout.write("Writing new `index.html` file... ");
fs.writeFileSync(path.resolve(rootDir, 'index.html'), indexContents);
fs.writeFileSync('index.html', indexContents);
console.log("DONE");
});
}
Expand Down
6 changes: 0 additions & 6 deletions js/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,6 @@
});
}

// sanitize a room ID
// shouldn't actually do anything except against a malicious server
var toRoomid = this.toRoomid = function (roomid) {
return roomid.replace(/[^a-zA-Z0-9-]+/g, '').toLowerCase();
};

// support Safari 6 notifications
if (!window.Notification && window.webkitNotification) {
window.Notification = window.webkitNotification;
Expand Down
12 changes: 11 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@
"fix": "eslint --config=.eslintrc.js --fix js/*.js data/graphics.js && eslint --config=build-tools/.eslintrc.js --fix build-tools/update build-tools/build-indexes",
"testcafe": "build-tools/build-indexes && testcafe chrome test/"
},
"dependencies": {},
"dependencies": {
"@babel/cli": "^7.0.0-beta.46",
"@babel/core": "^7.0.0-beta.46",
"@babel/plugin-proposal-class-properties": "^7.0.0-beta.46",
"@babel/plugin-transform-member-expression-literals": "^7.0.0-beta.46",
"@babel/plugin-transform-property-literals": "^7.0.0-beta.46",
"@babel/plugin-transform-react-jsx": "^7.0.0-beta.46",
"@babel/preset-env": "^7.0.0-beta.46",
"@babel/preset-typescript": "^7.0.0-beta.46",
"@types/jquery": "^3.3.1"
},
"devDependencies": {
"@types/node": "^8.0.7",
"eslint": "^4.11.0",
Expand Down
225 changes: 225 additions & 0 deletions src/battle-dex-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/**
* Pokemon Showdown Dex Data
*
* A collection of data and definitions for src/battle-dex.ts.
*
* Larger data has their own files in data/, so this is just for small
* miscellaneous data that doesn't need its own file.
*
* @author Guangcong Luo <[email protected]>
* @license MIT
*/

const BattleNatures = {
Adamant: {
plus: 'atk',
minus: 'spa'
},
Bashful: {},
Bold: {
plus: 'def',
minus: 'atk'
},
Brave: {
plus: 'atk',
minus: 'spe'
},
Calm: {
plus: 'spd',
minus: 'atk'
},
Careful: {
plus: 'spd',
minus: 'spa'
},
Docile: {},
Gentle: {
plus: 'spd',
minus: 'def'
},
Hardy: {},
Hasty: {
plus: 'spe',
minus: 'def'
},
Impish: {
plus: 'def',
minus: 'spa'
},
Jolly: {
plus: 'spe',
minus: 'spa'
},
Lax: {
plus: 'def',
minus: 'spd'
},
Lonely: {
plus: 'atk',
minus: 'def'
},
Mild: {
plus: 'spa',
minus: 'def'
},
Modest: {
plus: 'spa',
minus: 'atk'
},
Naive: {
plus: 'spe',
minus: 'spd'
},
Naughty: {
plus: 'atk',
minus: 'spd'
},
Quiet: {
plus: 'spa',
minus: 'spe'
},
Quirky: {},
Rash: {
plus: 'spa',
minus: 'spd'
},
Relaxed: {
plus: 'def',
minus: 'spe'
},
Sassy: {
plus: 'spd',
minus: 'spe'
},
Serious: {},
Timid: {
plus: 'spe',
minus: 'atk'
}
};
const BattleStatIDs = {
HP: 'hp',
hp: 'hp',
Atk: 'atk',
atk: 'atk',
Def: 'def',
def: 'def',
SpA: 'spa',
SAtk: 'spa',
SpAtk: 'spa',
spa: 'spa',
spc: 'spa',
Spc: 'spa',
SpD: 'spd',
SDef: 'spd',
SpDef: 'spd',
spd: 'spd',
Spe: 'spe',
Spd: 'spe',
spe: 'spe'
};
const BattlePOStatNames = { // only used for interacting with PO
hp: 'HP',
atk: 'Atk',
def: 'Def',
spa: 'SAtk',
spd: 'SDef',
spe: 'Spd'
};
const BattleStatNames = { // proper style
hp: 'HP',
atk: 'Atk',
def: 'Def',
spa: 'SpA',
spd: 'SpD',
spe: 'Spe'
};

const baseSpeciesChart = [
'pikachu',
'pichu',
'unown',
'castform',
'deoxys',
'burmy',
'wormadam',
'cherrim',
'shellos',
'gastrodon',
'rotom',
'giratina',
'shaymin',
'arceus',
'basculin',
'darmanitan',
'deerling',
'sawsbuck',
'tornadus',
'thundurus',
'landorus',
'kyurem',
'keldeo',
'meloetta',
'genesect',
'vivillon',
'flabebe',
'floette',
'florges',
'furfrou',
'aegislash',
'pumpkaboo',
'gourgeist',
'meowstic',
'hoopa',
'zygarde',
'lycanroc',
'wishiwashi',
'minior',
'mimikyu',
'greninja',
'oricorio',
'silvally',
'necrozma',

// alola totems
'raticate',
'marowak',
'kommoo',

// mega evolutions
'charizard',
'mewtwo'
// others are hardcoded by ending with 'mega'
];

type StatName = 'hp' | 'atk' | 'def' | 'spa' | 'spd' | 'spe';
interface Effect {
readonly id: string;
readonly name: string;
readonly gen: number;
readonly effectType: 'Item' | 'Move' | 'Ability' | 'Template';
readonly exists: boolean;
}
interface Item extends Effect {
readonly effectType: 'Item';
}
interface Move extends Effect {
readonly effectType: 'Move';
readonly type: string;
readonly category: string;
}
interface Ability extends Effect {
readonly effectType: 'Ability';
}
interface Template extends Effect {
readonly effectType: 'Template';
readonly species: string;
readonly baseSpecies: string;
readonly spriteid: string;
readonly types: string[];
readonly abilities: {0: string, 1?: string, H?: string, S?: string};
readonly baseStats: {hp: number, atk: number, def: number, spa: number, spd: number, spe: number}
readonly unreleasedHidden: boolean;
readonly tier: string;
readonly isNonstandard: boolean;
}
Loading

0 comments on commit a15ec64

Please sign in to comment.