Skip to content

Commit

Permalink
Migrate js/battle.js to TypeScript
Browse files Browse the repository at this point in the history
This is only a first step and doesn't pass strictNullChecks.

I'm committing now because skipping straight to refactoring will be
easier than trying to make it pass strictNullChecks as-is.

TypeScript found at least a few bugs here, which is nice.
  • Loading branch information
Zarel committed May 17, 2018
1 parent 6933d5a commit 299f2af
Show file tree
Hide file tree
Showing 8 changed files with 1,634 additions and 1,542 deletions.
21 changes: 12 additions & 9 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"presets": [
"@babel/typescript"
],
"plugins": [
"@babel/plugin-transform-member-expression-literals",
"@babel/plugin-transform-property-literals",
"@babel/plugin-transform-typescript",
["@babel/plugin-transform-react-jsx", {"pragma": "Preact.h", "useBuiltIns": true}],

["@babel/plugin-proposal-class-properties", {"loose": true}],

["@babel/plugin-proposal-object-rest-spread", {"useBuiltIns": true}],

"@babel/plugin-transform-exponentiation-operator",

"@babel/plugin-transform-arrow-functions",
["@babel/plugin-transform-block-scoping", {"throwIfClosureRequired": true}],
["@babel/plugin-transform-classes", {"loose": true}],
Expand All @@ -16,10 +20,9 @@
"@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}]

"@babel/plugin-transform-member-expression-literals",
"@babel/plugin-transform-property-literals"
],
"ignore": [
"src/globals.d.ts"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ npm-debug.log
package-lock.json
/vendor/

/js/battle.js
/js/battledata.js
/js/battle-dex.js
/js/battle-dex-data.js
3 changes: 0 additions & 3 deletions data/graphics.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,6 @@ var BattleBackdrops = [
'bg-orassea.jpg',
'bg-skypillar.jpg'
];
var BattleStats = {
atk: 'Attack', def: 'Defense', spa: 'Special Attack', spd: 'Special Defense', spe: 'Speed', accuracy: 'accuracy', evasion: 'evasiveness', spc: 'Special'
};
var BattleItems = {
};
var BattleOtherAnims = {
Expand Down
2 changes: 1 addition & 1 deletion js/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2326,7 +2326,7 @@
order: 10007
},
'\u2605': {
name: "Player (\u2605)",
name: "Host (\u2605)",
type: 'normal',
order: 10008
},
Expand Down
26 changes: 25 additions & 1 deletion src/battle-dex-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* @license MIT
*/

type ID = string & {__isID: true};

const BattleNatures = {
Adamant: {
plus: 'atk',
Expand Down Expand Up @@ -134,6 +136,9 @@ const BattleStatNames = { // proper style
spd: 'SpD',
spe: 'Spe'
};
const BattleStats = {
atk: 'Attack', def: 'Defense', spa: 'Special Attack', spd: 'Special Defense', spe: 'Speed', accuracy: 'accuracy', evasion: 'evasiveness', spc: 'Special'
};

const baseSpeciesChart = [
'pikachu',
Expand Down Expand Up @@ -193,33 +198,52 @@ const baseSpeciesChart = [
];

type StatName = 'hp' | 'atk' | 'def' | 'spa' | 'spd' | 'spe';
type StatusName = 'par' | 'psn' | 'frz' | 'slp' | 'brn';
type BoostStatName = 'atk' | 'def' | 'spa' | 'spd' | 'spe' | 'evasion' | 'accuracy' | 'spc';
type GenderName = 'M' | 'F' | '';

interface Effect {
readonly id: string;
readonly id: ID;
readonly name: string;
readonly gen: number;
readonly effectType: 'Item' | 'Move' | 'Ability' | 'Template';
readonly exists: boolean;
}
interface Item extends Effect {
readonly effectType: 'Item';
readonly zMoveFrom?: string;
}
interface Move extends Effect {
readonly effectType: 'Move';
readonly type: string;
readonly category: string;
readonly isZ?: string;

// TODO: move to different interface
readonly anim: Function;
readonly residualAnim: Function;
readonly prepareAnim: Function;
readonly prepareMessage: Function;
}
interface Ability extends Effect {
readonly effectType: 'Ability';
}
interface Template extends Effect {
readonly effectType: 'Template';
readonly species: string;
readonly speciesid: ID;
readonly baseSpecies: string;
readonly forme: string;
readonly formeLetter: string;
readonly formeid: 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 weightkg: number;
readonly isNonstandard: boolean;
readonly isTotem?: boolean;
readonly isMega?: boolean;
}
59 changes: 37 additions & 22 deletions src/battle-dex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ function toId(text: any) {
} else if (text && text.userid) {
text = text.userid;
}
if (typeof text !== 'string' && typeof text !== 'number') return '';
return ('' + text).toLowerCase().replace(/[^a-z0-9]+/g, '');
if (typeof text !== 'string' && typeof text !== 'number') return '' as ID;
return ('' + text).toLowerCase().replace(/[^a-z0-9]+/g, '') as ID;
}

function toUserid(text: any) {
Expand All @@ -116,6 +116,17 @@ function toName(name: any) {
return name;
}

interface SpriteData {
w: number;
h: number;
y?: number;
url?: string;
pixelated?: boolean;
isBackSprite?: boolean;
cryurl?: string;
shiny?: boolean;
}

const Tools = {

resourcePrefix: (() => {
Expand Down Expand Up @@ -627,17 +638,17 @@ const Tools = {
if (!move.exists && id.substr(0, 11) === 'hiddenpower' && id.length > 11) {
let matches = /([a-z]*)([0-9]*)/.exec(id)!;
move = (window.BattleMovedex && window.BattleMovedex[matches[1]]) || {};
move = $.extend({}, move);
move = {...move};
move.basePower = matches[2];
}
if (!move.exists && id.substr(0, 6) === 'return' && id.length > 6) {
move = (window.BattleMovedex && window.BattleMovedex['return']) || {};
move = $.extend({}, move);
move = {...move};
move.basePower = id.slice(6);
}
if (!move.exists && id.substr(0, 11) === 'frustration' && id.length > 11) {
move = (window.BattleMovedex && window.BattleMovedex['frustration']) || {};
move = $.extend({}, move);
move = {...move};
move.basePower = id.slice(11);
}

Expand Down Expand Up @@ -669,7 +680,7 @@ const Tools = {

if (window.BattleMoveAnims) {
if (!move.anim) move.anim = BattleOtherAnims.attack.anim;
$.extend(move, BattleMoveAnims[move.id]);
Object.assign(move, BattleMoveAnims[move.id]);
}
}
return move;
Expand Down Expand Up @@ -839,7 +850,7 @@ const Tools = {

getType(type: any): Effect {
if (!type || typeof type === 'string') {
let id = toId(type);
let id = toId(type) as string;
id = id.substr(0, 1).toUpperCase() + id.substr(1);
type = (window.BattleTypeChart && window.BattleTypeChart[id]) || {};
if (type.damageTaken) type.exists = true;
Expand All @@ -865,10 +876,14 @@ const Tools = {
el.src = path + 'data/pokedex-mini-bw.js' + qs;
document.getElementsByTagName('body')[0].appendChild(el);
},
getSpriteData(pokemon: any, siden: number, options?: any) {
if (!options) options = {gen: 6};
getSpriteData(pokemon: Pokemon | Template | string, siden: number, options: {gen?: number, shiny?: boolean, gender?: GenderName, afd?: boolean, noScale?: boolean} = {gen: 6}) {
if (!options.gen) options.gen = 6;
pokemon = Tools.getTemplate(pokemon);
if (pokemon instanceof Pokemon) {
options.shiny = pokemon.shiny;
options.gender = pokemon.gender;
pokemon = pokemon.getSpecies();
}
const template = Tools.getTemplate(pokemon);
let spriteData = {
w: 96,
h: 96,
Expand All @@ -877,9 +892,9 @@ const Tools = {
pixelated: true,
isBackSprite: false,
cryurl: '',
shiny: pokemon.shiny
shiny: options.shiny
};
let name = pokemon.spriteid;
let name = template.spriteid;
let dir, facing;
if (siden) {
dir = '';
Expand All @@ -894,13 +909,13 @@ const Tools = {
let fieldGenNum = options.gen;
if (Tools.prefs('nopastgens')) fieldGenNum = 6;
if (Tools.prefs('bwgfx') && fieldGenNum >= 6) fieldGenNum = 5;
let genNum = Math.max(fieldGenNum, Math.min(pokemon.gen, 5));
let genNum = Math.max(fieldGenNum, Math.min(template.gen, 5));
let gen = ['', 'rby', 'gsc', 'rse', 'dpp', 'bw', 'xy', 'xy'][genNum];

let animationData = null;
let miscData = null;
let speciesid = pokemon.speciesid;
if (pokemon.isTotem) speciesid = toId(name);
let speciesid = template.speciesid;
if (template.isTotem) speciesid = toId(name);
if (gen === 'xy' && window.BattlePokemonSprites) {
animationData = BattlePokemonSprites[speciesid];
}
Expand All @@ -913,15 +928,15 @@ const Tools = {
if (!miscData) miscData = {};

if (miscData.num > 0) {
spriteData.cryurl = 'audio/cries/' + toId(pokemon.baseSpecies);
let formeid = pokemon.formeid;
if (pokemon.isMega || formeid && (formeid === '-sky' || formeid === '-therian' || formeid === '-primal' || formeid === '-eternal' || pokemon.baseSpecies === 'Kyurem' || formeid === '-super' || formeid === '-unbound' || formeid === '-midnight' || formeid === '-school' || pokemon.baseSpecies === 'Oricorio' || pokemon.baseSpecies === 'Zygarde')) {
spriteData.cryurl = 'audio/cries/' + toId(template.baseSpecies);
let formeid = template.formeid;
if (template.isMega || formeid && (formeid === '-sky' || formeid === '-therian' || formeid === '-primal' || formeid === '-eternal' || template.baseSpecies === 'Kyurem' || formeid === '-super' || formeid === '-unbound' || formeid === '-midnight' || formeid === '-school' || template.baseSpecies === 'Oricorio' || template.baseSpecies === 'Zygarde')) {
spriteData.cryurl += formeid;
}
spriteData.cryurl += (window.nodewebkit ? '.ogg' : '.mp3');
}

if (pokemon.shiny && options.gen > 1) dir += '-shiny';
if (options.shiny && options.gen > 1) dir += '-shiny';

// April Fool's 2014
if (window.Config && Config.server && Config.server.afd || options.afd) {
Expand All @@ -930,7 +945,7 @@ const Tools = {
return spriteData;
}

if (animationData[facing + 'f'] && pokemon.gender === 'F') facing += 'f';
if (animationData[facing + 'f'] && options.gender === 'F') facing += 'f';
let allowAnim = !Tools.prefs('noanim') && !Tools.prefs('nogif');
if (allowAnim && genNum >= 6) spriteData.pixelated = false;
if (allowAnim && animationData[facing] && genNum >= 5) {
Expand All @@ -948,7 +963,7 @@ const Tools = {

// Gender differences don't exist prior to Gen 4,
// so there are no sprites for it
if (genNum >= 4 && miscData['frontf'] && pokemon.gender === 'F') {
if (genNum >= 4 && miscData['frontf'] && options.gender === 'F') {
name += '-f';
}

Expand All @@ -972,7 +987,7 @@ const Tools = {
if (fieldGenNum === 5 && spriteData.isBackSprite) spriteData.y += 40;
if (genNum <= 2) spriteData.y += 2;
}
if (pokemon.isTotem && !options.noScale) {
if (template.isTotem && !options.noScale) {
spriteData.w *= 1.5;
spriteData.h *= 1.5;
spriteData.y += -11;
Expand Down
Loading

0 comments on commit 299f2af

Please sign in to comment.