mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-03-21 17:50:29 -05:00
Create test pages for sprites
Similar to styles/STYLING.html and styles/hpbartest.html, test pages prove to be more robust and convenient for testing than the unit tests (which are already broken). These pages are primarily intended to help with delivering #1369, but can be used to test improvements to sprites across the board.
This commit is contained in:
parent
730d1ffd1a
commit
d76cd108dd
|
|
@ -10,8 +10,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --config=.eslintrc.js --cache --cache-file=eslint-cache/base js/ data/ && eslint --config=build-tools/.eslintrc.js --cache --cache-file=eslint-cache/build build-tools/update build-tools/build-indexes && tslint --project .",
|
||||
"test": "npm run lint && tsc && node build && mocha test/*.test.js",
|
||||
"full-test": "npm run lint && tsc && node build indexes && mocha test/*.js",
|
||||
"test": "npm run lint && tsc && node build && mocha test/*.js",
|
||||
"fix": "eslint --config=.eslintrc.js --fix js/ && eslint --config=build-tools/.eslintrc.js --fix build-tools/update build-tools/build-indexes",
|
||||
"build": "node build",
|
||||
"build-full": "node build full"
|
||||
|
|
|
|||
316
sprites/gallery-test.html
Normal file
316
sprites/gallery-test.html
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Sprites</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Roboto", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
tr {
|
||||
min-height: 96px;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 5px solid black;
|
||||
}
|
||||
|
||||
.outline img {
|
||||
border: 1px solid black;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
img {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.picon {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
th {
|
||||
font-size: 2em;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 10px auto;
|
||||
padding: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
li {
|
||||
/* font-size: 13px; */
|
||||
display: inline-block;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
align-items: normal;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
border-style: none;
|
||||
box-sizing: content-box;
|
||||
cursor: pointer;
|
||||
display: inline;
|
||||
font: inherit;
|
||||
padding: 0;
|
||||
perspective-origin: 0 0;
|
||||
text-align: start;
|
||||
transform-origin: 0 0;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
exports = window;
|
||||
</script>
|
||||
<script src="../data/pokedex-mini.js"></script>
|
||||
<script src="../data/pokedex-mini-bw.js"></script>
|
||||
<script src="../data/teambuilder-tables.js"></script>
|
||||
<script src="../data/abilities.js"></script>
|
||||
<script src="../data/aliases.js"></script>
|
||||
<script src="../data/items.js"></script>
|
||||
<script src="../data/moves.js"></script>
|
||||
<script src="../data/pokedex.js"></script>
|
||||
<script src="../data/typechart.js"></script>
|
||||
<script src="../js/battle-dex-data.js"></script>
|
||||
<script src="../js/battle-dex.js"></script>
|
||||
<script src="../js/battle-scene-stub.js"></script>
|
||||
<script src="../data/text.js"></script>
|
||||
<script src="../js/battle-text-parser.js"></script>
|
||||
<script src="../js/battle.js"></script>
|
||||
<script>
|
||||
//#region VARIABLES
|
||||
const ROOT = document.getElementById('root');
|
||||
const PAGE_SIZE = 25;
|
||||
const GRAPHICS = {
|
||||
// 'gen1rg': 1,
|
||||
// 'gen1rb': 1,
|
||||
'gen1': 1,
|
||||
// 'gen2g': 2,
|
||||
// 'gen2s': 2,
|
||||
'gen2': 2,
|
||||
// 'gen3rs': 3,
|
||||
'gen3': 3,
|
||||
// 'gen3frlg': 3,
|
||||
// 'gen4dp': 4,
|
||||
'gen4': 4,
|
||||
'gen5': 5,
|
||||
'gen5ani': 5,
|
||||
'dex': 6,
|
||||
'ani': 6,
|
||||
};
|
||||
|
||||
var PAGE;
|
||||
var PAGES = 0;
|
||||
const SPECIES = [];
|
||||
let i = 0;
|
||||
for (let baseid in BattlePokedex) {
|
||||
if (baseid.endsWith('totem')) continue;
|
||||
const species = Dex.getSpecies(baseid);
|
||||
for (let formid of [''].concat(species.cosmeticFormes || [])) {
|
||||
let spriteid = species.spriteid;
|
||||
if (formid) spriteid += '-' + formid.slice(species.id.length);
|
||||
const id = toID(spriteid);
|
||||
SPECIES.push([id, species]);
|
||||
if (i++ % PAGE_SIZE === 0) PAGES++;
|
||||
}
|
||||
}
|
||||
|
||||
SPECIES.sort(([, a], [, b]) => {
|
||||
if (a.gen - b.gen) return a.gen - b.gen;
|
||||
return Math.abs(a.num) - Math.abs(b.num);
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region FUNCTIONS
|
||||
|
||||
function e(type, options) {
|
||||
const tag = document.createElement(type);
|
||||
if (!options) return tag;
|
||||
|
||||
if (typeof options === 'string' || typeof options === 'number') {
|
||||
tag.textContent = options;
|
||||
return tag;
|
||||
} else if (options instanceof Node) {
|
||||
tag.appendChild(options);
|
||||
return tag;
|
||||
}
|
||||
if (options.content) {
|
||||
if (typeof options.content === 'string' || typeof options.content === 'number') {
|
||||
tag.textContent = options.content;
|
||||
} else if (tag instanceof Node) {
|
||||
tag.appendChild(options.content);
|
||||
}
|
||||
}
|
||||
if (options.id) tag.setAttribute('id', options.id);
|
||||
if (options.class) tag.classList.add(options.class);
|
||||
return tag;
|
||||
}
|
||||
|
||||
function picons(spriteid) {
|
||||
const styles = new Set([
|
||||
Dex.getPokemonIcon({ id: spriteid }),
|
||||
Dex.getPokemonIcon({ id: spriteid, gender: 'F' }),
|
||||
Dex.getPokemonIcon({ id: spriteid }, true), // facingLeft
|
||||
]);
|
||||
|
||||
const icons = [];
|
||||
for (const style of styles) {
|
||||
const span = e('span', { class: 'picon' });
|
||||
span.style = style;
|
||||
icons.push(span);
|
||||
}
|
||||
|
||||
return icons;
|
||||
};
|
||||
|
||||
function sprites(graphics, spriteid, name, species) {
|
||||
const gen = GRAPHICS[graphics];
|
||||
const imgs = [];
|
||||
|
||||
if (graphics === 'dex') {
|
||||
// no gender or back sprites
|
||||
const data = Dex.getTeambuilderSpriteData({ species: name }, gen);
|
||||
for (const shiny of (gen > 1 ? ['', '-shiny'] : [''])) {
|
||||
const img = e('img');
|
||||
img.src = `${Dex.resourcePrefix}${data.spriteDir}${shiny}/${data.spriteid}.png`;
|
||||
if (gen < 5) img.style = 'image-rendering: pixelated;';
|
||||
imgs.push(img);
|
||||
}
|
||||
return imgs;
|
||||
}
|
||||
|
||||
withPrefs({ noanim: !graphics.endsWith('ani') }, () => {
|
||||
for (const shiny of (gen > 1 ? [false, true] : [false])) {
|
||||
for (const siden of [1, 0]) {
|
||||
for (const gender of (gen === 1 || species.gender ? [undefined] : ['M', 'F'])) {
|
||||
const data = Dex.getSpriteData(spriteid, siden, { gen, noScale: true, shiny, gender });
|
||||
const img = e('img');
|
||||
img.src = data.url;
|
||||
img.width = data.w;
|
||||
img.height = data.h;
|
||||
if (data.pixelated) img.style = 'image-rendering: pixelated;';
|
||||
imgs.push(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return imgs;
|
||||
};
|
||||
|
||||
function withPrefs(prefs, fn) {
|
||||
const saved = Dex.prefs;
|
||||
Dex.prefs = s => prefs[s];
|
||||
fn();
|
||||
Dex.prefs = saved;
|
||||
}
|
||||
|
||||
function renderRow(i) {
|
||||
const [spriteid, species] = SPECIES[i];
|
||||
const tr = e('tr')
|
||||
|
||||
const td = e('td');
|
||||
for (const icon of picons(spriteid)) {
|
||||
td.appendChild(icon);
|
||||
}
|
||||
tr.appendChild(td);
|
||||
|
||||
const name = species.id !== spriteid ? formeName(species, spriteid) : species.name;
|
||||
tr.appendChild(e('td', name));
|
||||
for (const graphics in GRAPHICS) {
|
||||
const td = e('td');
|
||||
for (const sprite of sprites(graphics, spriteid, name, species)) {
|
||||
td.appendChild(sprite);
|
||||
}
|
||||
tr.appendChild(td);
|
||||
}
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
function formeName(species, spriteid) {
|
||||
if (species.name === 'Toxtricity-Low-Key-Gmax') return species.name;
|
||||
let forme = spriteid.slice(species.id.length);
|
||||
forme = forme.charAt(0).toUpperCase() + forme.substr(1);
|
||||
return `${species.name}-${forme}`;
|
||||
}
|
||||
|
||||
function createNav(page) {
|
||||
const ul = e('ul');
|
||||
for (let i = 0; i < PAGES; i++) {
|
||||
const li = e('li');
|
||||
if (page === i) li.style = 'background-color: yellow;'
|
||||
const button = e('button', e(page === i ? 'b' : 'span', `${i + 1}`));
|
||||
button.addEventListener('click', () => displayPage(i));
|
||||
li.appendChild(button);
|
||||
ul.appendChild(li);
|
||||
}
|
||||
return ul;
|
||||
}
|
||||
|
||||
function displayPage(page) {
|
||||
PAGE = page;
|
||||
if (ROOT.firstChild) ROOT.removeChild(ROOT.firstChild);
|
||||
|
||||
const table = e('table')
|
||||
const tr = e('tr');
|
||||
tr.appendChild(e('th'));
|
||||
tr.appendChild(e('th'));
|
||||
for (const graphics in GRAPHICS) {
|
||||
tr.appendChild(e('th', graphics));
|
||||
}
|
||||
table.appendChild(tr);
|
||||
for (let i = page * PAGE_SIZE; i < Math.min(SPECIES.length, (page + 1) * PAGE_SIZE); i++) {
|
||||
const row = renderRow(i);
|
||||
table.appendChild(row);
|
||||
}
|
||||
|
||||
const div = e('div');
|
||||
div.appendChild(createNav(page));
|
||||
div.appendChild(table);
|
||||
div.appendChild(createNav(page));
|
||||
|
||||
ROOT.appendChild(div);
|
||||
window.scrollTo(0, 0);
|
||||
};
|
||||
|
||||
//#endregion
|
||||
//#region MAIN
|
||||
|
||||
displayPage(0);
|
||||
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.keyCode === 37 && PAGE !== 0) {
|
||||
displayPage(PAGE - 1);
|
||||
} else if (e.keyCode === 39 && PAGE !== PAGES) {
|
||||
displayPage(PAGE + 1);
|
||||
} else if (e.keyCode === 219) {
|
||||
ROOT.classList.toggle('outline');
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
790
sprites/scene-test.html
Normal file
790
sprites/scene-test.html
Normal file
|
|
@ -0,0 +1,790 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Sprites</title>
|
||||
<link rel="stylesheet" href="../style/battle.css" />
|
||||
<style>
|
||||
body {
|
||||
font-family: "Roboto", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
|
||||
max-width: 1365px;
|
||||
}
|
||||
|
||||
.picon {
|
||||
width: 40px;
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
float: left;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.dex {
|
||||
height: 85px;
|
||||
width: 115px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
fieldset legend {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
textarea {
|
||||
display: block;
|
||||
margin: 0px auto;
|
||||
width: 432px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.sprites {
|
||||
background-color: rgb(218, 229, 240);
|
||||
border-left: 2px groove threedface;
|
||||
height: 107px;
|
||||
width: 180px;
|
||||
float: right;
|
||||
margin: -14px -12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.pixelated {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
exports = window;
|
||||
</script>
|
||||
<script src="../data/pokedex-mini.js"></script>
|
||||
<script src="../data/pokedex-mini-bw.js"></script>
|
||||
<script src="../data/teambuilder-tables.js"></script>
|
||||
<script src="../data/abilities.js"></script>
|
||||
<script src="../data/aliases.js"></script>
|
||||
<script src="../data/items.js"></script>
|
||||
<script src="../data/moves.js"></script>
|
||||
<script src="../data/pokedex.js"></script>
|
||||
<script src="../data/typechart.js"></script>
|
||||
<script src="../js/battle-dex-data.js"></script>
|
||||
<script src="../js/battle-dex.js"></script>
|
||||
<script src="../js/battle-scene-stub.js"></script>
|
||||
<script src="../data/text.js"></script>
|
||||
<script src="../js/battle-text-parser.js"></script>
|
||||
<script src="../js/battle.js"></script>
|
||||
<script>
|
||||
//#region VARIABLES
|
||||
|
||||
const GRAPHIC_NAMES = {
|
||||
'Default': '',
|
||||
'Green': 'gen1rg',
|
||||
'Red/Blue': 'gen1rb',
|
||||
'Yellow': 'gen1',
|
||||
'Gold': 'gen2g',
|
||||
'Silver': 'gen2s',
|
||||
'Crystal': 'gen2',
|
||||
'Ruby/Sapphire': 'gen3rs',
|
||||
'FireRed/LeafGreen': 'gen3frlg',
|
||||
'Emerald': 'gen3',
|
||||
'Diamond/Pearl': 'gen4dp',
|
||||
'Platinum': 'gen4',
|
||||
'Black/White': 'gen5',
|
||||
'Black/White (Animated)': 'gen5ani',
|
||||
'Modern (Animated)': 'ani',
|
||||
};
|
||||
|
||||
const GRAPHICS = {
|
||||
// 'gen1rg': 1,
|
||||
// 'gen1rb': 1,
|
||||
'gen1': 1,
|
||||
// 'gen2g': 2,
|
||||
// 'gen2s': 2,
|
||||
'gen2': 2,
|
||||
// 'gen3rs': 3,
|
||||
'gen3': 3,
|
||||
// 'gen3frlg': 3,
|
||||
// 'gen4dp': 4,
|
||||
'gen4': 4,
|
||||
'gen5': 5,
|
||||
'gen5ani': 5,
|
||||
'ani': 6,
|
||||
};
|
||||
|
||||
var SETTINGS, SIDES, SCENE, STATE, BACKDROP;
|
||||
const ROOT = document.getElementById('root');
|
||||
|
||||
const SPECIES = [];
|
||||
for (let baseid in BattlePokedex) {
|
||||
const species = Dex.getSpecies(baseid);
|
||||
for (let formid of [''].concat(species.cosmeticFormes || [])) {
|
||||
let spriteid = species.spriteid;
|
||||
if (formid) spriteid += '-' + formid.slice(species.id.length);
|
||||
const id = toID(spriteid);
|
||||
SPECIES.push([formeName(species, id), species]);
|
||||
}
|
||||
}
|
||||
|
||||
SPECIES.sort(([, a], [, b]) => {
|
||||
if (a.gen - b.gen) return a.gen - b.gen;
|
||||
return Math.abs(a.num) - Math.abs(b.num);
|
||||
});
|
||||
|
||||
//#endregion
|
||||
//#region FUNCTIONS
|
||||
|
||||
function e(type, options) {
|
||||
const tag = document.createElement(type);
|
||||
if (!options) return tag;
|
||||
|
||||
if (typeof options === 'string' || typeof options === 'number') {
|
||||
tag.textContent = options;
|
||||
return tag;
|
||||
} else if (options instanceof Node) {
|
||||
tag.appendChild(options);
|
||||
return tag;
|
||||
}
|
||||
if (options.content) {
|
||||
if (typeof options.content === 'string' || typeof options.content === 'number') {
|
||||
tag.textContent = options.content;
|
||||
} else if (tag instanceof Node) {
|
||||
tag.appendChild(options.content);
|
||||
}
|
||||
}
|
||||
if (options.id) tag.setAttribute('id', options.id);
|
||||
if (options.class) tag.classList.add(options.class);
|
||||
return tag;
|
||||
}
|
||||
|
||||
function formeName(species, spriteid) {
|
||||
if (species.name === 'Toxtricity-Low-Key-Gmax') return species.name;
|
||||
let forme = spriteid.slice(species.id.length);
|
||||
if (!forme) return species.name;
|
||||
forme = forme.charAt(0).toUpperCase() + forme.substr(1);
|
||||
return `${species.name}-${forme}`;
|
||||
}
|
||||
|
||||
function selector(label, selected, generator) {
|
||||
label = e('label', label);
|
||||
const select = e('select');
|
||||
for (const [name, value] of generator()) {
|
||||
const option = e('option', name);
|
||||
option.value = value;
|
||||
select.appendChild(option);
|
||||
}
|
||||
select.value = selected;
|
||||
select.addEventListener('change', onChange);
|
||||
label.appendChild(select);
|
||||
return { div: e('div', label), select };
|
||||
}
|
||||
|
||||
function genSelector(selected) {
|
||||
return selector('Generation: ', selected, function* () {
|
||||
for (let gen = 1; gen <= 8; gen++) {
|
||||
yield [`${gen}`, gen];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function graphicsSelector(selected) {
|
||||
return selector('Graphics: ', selected, function* () {
|
||||
for (let name in GRAPHIC_NAMES) {
|
||||
const val = GRAPHIC_NAMES[name];
|
||||
if (!GRAPHICS[val]) continue;
|
||||
yield [name, val];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function pokemonSelector(selected) {
|
||||
return selector('Pokemon: ', selected, function* () {
|
||||
for (const [name,] of SPECIES) {
|
||||
yield [name, name];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkbox(label, name, checked) {
|
||||
label = e('label', label);
|
||||
const input = e('input');
|
||||
input.type = 'checkbox';
|
||||
input.name = name;
|
||||
if (checked) input.checked = 'checked';
|
||||
input.addEventListener('change', onChange);
|
||||
label.appendChild(input);
|
||||
return { div: e('div', label), input };
|
||||
}
|
||||
|
||||
function activeRadios() {
|
||||
const inputs = [];
|
||||
const div = e('div');
|
||||
div.textContent = 'Active: ';
|
||||
for (let active = 1; active <= 3; active++) {
|
||||
const input = e('input', {id: `radio${active}`});
|
||||
input.type = 'radio';
|
||||
input.name = 'active';
|
||||
input.value = active;
|
||||
input.addEventListener('change', onChange);
|
||||
if (active === 1) input.checked = true;
|
||||
inputs.push(input);
|
||||
const label = e('label', active);
|
||||
label.for =`radio${active}`;
|
||||
div.appendChild(input);
|
||||
div.appendChild(label);
|
||||
}
|
||||
return {inputs, div};
|
||||
}
|
||||
|
||||
function createSettingsControls(selected) {
|
||||
const fieldset = e('fieldset', e('legend', 'Settings'));
|
||||
|
||||
const fields = {
|
||||
gen: genSelector(selected.gen),
|
||||
graphics: graphicsSelector(selected.graphics),
|
||||
scale: checkbox('Scale: ', 'scale', selected.scale),
|
||||
oversize: checkbox('Oversize BW: ', 'oversize', selected.oversize),
|
||||
active: activeRadios(),
|
||||
};
|
||||
|
||||
const checkboxes = e('div');
|
||||
checkboxes.style.height = '21px';
|
||||
fields.scale.div.style.display = 'inline-block';
|
||||
fields.oversize.div.style.display = 'inline-block';
|
||||
fields.oversize.div.style.paddingLeft = '20px';
|
||||
checkboxes.appendChild(fields.scale.div);
|
||||
checkboxes.appendChild(fields.oversize.div);
|
||||
fields.active.div.style.height = '21px';
|
||||
|
||||
fieldset.appendChild(fields.gen.div);
|
||||
fieldset.appendChild(fields.graphics.div);
|
||||
fieldset.appendChild(checkboxes);
|
||||
fieldset.appendChild(fields.active.div);
|
||||
|
||||
fieldset.style.width = '240px';
|
||||
|
||||
return { fieldset, ...fields };
|
||||
}
|
||||
|
||||
function createSideControls(legend, selected) {
|
||||
const fieldset = e('fieldset', e('legend', legend));
|
||||
|
||||
const fields = {
|
||||
pokemon: pokemonSelector(selected.pokemon),
|
||||
female: checkbox('Female', 'female', selected.shiny),
|
||||
shiny: checkbox('Shiny', 'shiny', selected.shiny),
|
||||
dynamax: checkbox('Dynamax', 'dynamax', selected.dynamax),
|
||||
picon: e('div', { class: 'picon' }),
|
||||
dex: e('div', { class: 'dex' }),
|
||||
};
|
||||
|
||||
const controls = e('div');
|
||||
controls.style = 'float: left;';
|
||||
controls.appendChild(fields.pokemon.div);
|
||||
controls.appendChild(fields.female.div);
|
||||
controls.appendChild(fields.shiny.div);
|
||||
controls.appendChild(fields.dynamax.div);
|
||||
|
||||
const sprites = e('div', { class: 'sprites' });
|
||||
sprites.appendChild(fields.picon);
|
||||
sprites.appendChild(fields.dex);
|
||||
|
||||
fieldset.appendChild(controls);
|
||||
fieldset.appendChild(sprites);
|
||||
fieldset.style.width = '440px';
|
||||
|
||||
return { fieldset, ...fields };
|
||||
}
|
||||
|
||||
function toState() {
|
||||
const state = {
|
||||
gen: SETTINGS.gen.select.value,
|
||||
graphics: SETTINGS.graphics.select.value,
|
||||
scale: SETTINGS.scale.input.checked,
|
||||
oversize: SETTINGS.oversize.input.checked,
|
||||
active: SETTINGS.active.inputs.findIndex(input => input.checked) + 1,
|
||||
};
|
||||
for (const s in SIDES) {
|
||||
state[s] = {};
|
||||
state[s].pokemon = SIDES[s].pokemon.select.value;
|
||||
state[s].female = SIDES[s].female.input.checked;
|
||||
state[s].shiny = SIDES[s].shiny.input.checked;
|
||||
state[s].dynamax = SIDES[s].dynamax.input.checked;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function fromState(state) {
|
||||
if ('gen' in state) SETTINGS.gen.select.value = state.gen;
|
||||
if ('graphics' in state) SETTINGS.graphics.select.value = state.graphics;
|
||||
if ('scale' in state) SETTINGS.scale.input.checked = state.scale;
|
||||
if ('oversize' in state) SETTINGS.oversize.input.checked = state.oversize;
|
||||
if ('active' in state) null; // TODO
|
||||
for (const s in SIDES) {
|
||||
if (!state[s]) continue;
|
||||
if ('pokemon' in state[s]) SIDES[s].pokemon.select.value = state[s].pokemon
|
||||
if ('female' in state[s]) SIDES[s].female.input.checked = state[s].female;
|
||||
if ('shiny' in state[s]) SIDES[s].shiny.input.checked = state[s].shiny;
|
||||
if ('dynamax' in state[s]) SIDES[s].dynamax.input.checked = state[s].dynamax;
|
||||
}
|
||||
onChange();
|
||||
}
|
||||
|
||||
function onChange() {
|
||||
const gen = Number(SETTINGS.gen.select.value);
|
||||
|
||||
SETTINGS.oversize.input.disabled = !SETTINGS.graphics.select.value.startsWith('gen5');
|
||||
SETTINGS.active.inputs[1].disabled = gen < 3;
|
||||
SETTINGS.active.inputs[2].disabled = gen > 6 || gen < 5;
|
||||
for (const side in SIDES) {
|
||||
const species = Dex.getSpecies(SIDES[side].pokemon.select.value);
|
||||
if (gen === 1) {
|
||||
SIDES[side].female.input.disabled = true;
|
||||
} else if (species.gender) {
|
||||
SIDES[side].female.input.checked = SIDES[side].female.input.checked = species.gender === 'F';
|
||||
SIDES[side].female.input.disabled = true;
|
||||
} else {
|
||||
SIDES[side].female.input.disabled = false;
|
||||
}
|
||||
SIDES[side].shiny.input.disabled = gen === 1;
|
||||
SIDES[side].dynamax.input.disabled = gen !== 8;
|
||||
}
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
function changeBackdrop(backdrop, gen) {
|
||||
if (BACKDROP && BACKDROP.gen === gen) {
|
||||
backdrop.style = BACKDROP.style;
|
||||
return;
|
||||
}
|
||||
BACKDROP = gen;
|
||||
|
||||
const BattleBackdropsThree = [
|
||||
'bg-gen3.png',
|
||||
'bg-gen3-cave.png',
|
||||
'bg-gen3-ocean.png',
|
||||
'bg-gen3-sand.png',
|
||||
'bg-gen3-forest.png',
|
||||
'bg-gen3-arena.png',
|
||||
];
|
||||
const BattleBackdropsFour = [
|
||||
'bg-gen4.png',
|
||||
'bg-gen4-cave.png',
|
||||
'bg-gen4-snow.png',
|
||||
'bg-gen4-indoors.png',
|
||||
'bg-gen4-water.png',
|
||||
];
|
||||
const BattleBackdropsFive = [
|
||||
'bg-beach.png',
|
||||
'bg-beachshore.png',
|
||||
'bg-desert.png',
|
||||
'bg-meadow.png',
|
||||
'bg-thunderplains.png',
|
||||
'bg-city.png',
|
||||
'bg-earthycave.png',
|
||||
'bg-mountain.png',
|
||||
'bg-volcanocave.png',
|
||||
'bg-dampcave.png',
|
||||
'bg-forest.png',
|
||||
'bg-river.png',
|
||||
'bg-deepsea.png',
|
||||
'bg-icecave.png',
|
||||
'bg-route.png',
|
||||
];
|
||||
const BattleBackdrops = [
|
||||
'bg-aquacordetown.jpg',
|
||||
'bg-beach.jpg',
|
||||
'bg-city.jpg',
|
||||
'bg-dampcave.jpg',
|
||||
'bg-darkbeach.jpg',
|
||||
'bg-darkcity.jpg',
|
||||
'bg-darkmeadow.jpg',
|
||||
'bg-deepsea.jpg',
|
||||
'bg-desert.jpg',
|
||||
'bg-earthycave.jpg',
|
||||
'bg-elite4drake.jpg',
|
||||
'bg-forest.jpg',
|
||||
'bg-icecave.jpg',
|
||||
'bg-leaderwallace.jpg',
|
||||
'bg-library.jpg',
|
||||
'bg-meadow.jpg',
|
||||
'bg-orasdesert.jpg',
|
||||
'bg-orassea.jpg',
|
||||
'bg-skypillar.jpg',
|
||||
];
|
||||
|
||||
let bg;
|
||||
if (gen <= 1) bg = 'fx/bg-gen1.png';
|
||||
else if (gen <= 2) bg = 'fx/bg-gen2.png';
|
||||
else if (gen <= 3) bg = 'fx/' + sample(BattleBackdropsThree);
|
||||
else if (gen <= 4) bg = 'fx/' + sample(BattleBackdropsFour);
|
||||
else if (gen <= 5) bg = 'fx/' + sample(BattleBackdropsFive);
|
||||
else bg = 'sprites/gen6bgs/' + sample(BattleBackdrops);
|
||||
|
||||
const style = `background-image:url(${Dex.resourcePrefix}${bg});display:block;opacity:0.8`;
|
||||
backdrop.style = style;
|
||||
BACKDROP = {gen, style};
|
||||
}
|
||||
|
||||
function locToPos(loc, obj) {
|
||||
loc = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0,
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
...loc,
|
||||
};
|
||||
if (!loc.xscale && loc.xscale !== 0) loc.xscale = loc.scale;
|
||||
if (!loc.yscale && loc.yscale !== 0) loc.yscale = loc.scale;
|
||||
|
||||
let left = 210;
|
||||
let top = 245;
|
||||
let scale = (obj.gen === 5
|
||||
? 2.0 - ((loc.z) / 200)
|
||||
: 1.5 - 0.5 * ((loc.z) / 200));
|
||||
if (scale < .1) scale = .1;
|
||||
|
||||
left += (410 - 190) * ((loc.z) / 200);
|
||||
top += (135 - 245) * ((loc.z) / 200);
|
||||
left += Math.floor(loc.x * scale);
|
||||
top -= Math.floor(loc.y * scale /* - loc.x * scale / 4 */);
|
||||
let width = Math.floor(obj.w * scale * loc.xscale);
|
||||
let height = Math.floor(obj.h * scale * loc.yscale);
|
||||
let hoffset = Math.floor((obj.h - (obj.y || 0) * 2) * scale * loc.yscale);
|
||||
left -= Math.floor(width / 2);
|
||||
top -= Math.floor(hoffset / 2);
|
||||
|
||||
let pos = {
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
opacity: loc.opacity,
|
||||
};
|
||||
if (loc.display) pos.display = loc.display;
|
||||
return pos;
|
||||
}
|
||||
|
||||
function calculatePos(slot, z, gen, activeCount, pixelated, isBackSprite) {
|
||||
const moreActive = activeCount - 1;
|
||||
let statbarOffset = 0;
|
||||
let x = 0, y = 0;
|
||||
if (gen <= 4 && moreActive) {
|
||||
x = (slot - 0.52) * (isBackSprite ? -1 : 1) * -55;
|
||||
y = (isBackSprite ? -1 : 1) + 1;
|
||||
if (!isBackSprite) statbarOffset = 30 * slot;
|
||||
if (isBackSprite) statbarOffset = -28 * slot;
|
||||
} else {
|
||||
switch (moreActive) {
|
||||
case 0:
|
||||
x = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (pixelated) {
|
||||
x = (slot * -100 + 18) * (isBackSprite ? -1 : 1);
|
||||
} else {
|
||||
x = (slot * -75 + 18) * (isBackSprite ? -1 : 1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
x = (slot * -70 + 20) * (isBackSprite ? -1 : 1);
|
||||
break;
|
||||
}
|
||||
y = (slot * 10) * (isBackSprite ? -1 : 1);
|
||||
if (!isBackSprite) statbarOffset = 17 * slot;
|
||||
if (!isBackSprite && !moreActive && pixelated) statbarOffset = 15;
|
||||
if (isBackSprite) statbarOffset = -7 * slot;
|
||||
if (!isBackSprite && moreActive === 2) statbarOffset = 14 * slot - 10;
|
||||
}
|
||||
if (gen <= 2) {
|
||||
statbarOffset += isBackSprite ? 1 : 20;
|
||||
} else if (gen <= 3) {
|
||||
statbarOffset += isBackSprite ? 5 : 30;
|
||||
} else if (gen !== 5) {
|
||||
statbarOffset += isBackSprite ? 20 : 30;
|
||||
}
|
||||
|
||||
let pos = locToPos({x, y , z}, {w: 0, h: 96});
|
||||
pos.top += 40;
|
||||
|
||||
const statbarLeft = pos.left - 80;
|
||||
const statbarTop = pos.top - 73 - statbarOffset;
|
||||
|
||||
return {x, y, z, left: statbarLeft, top: statbarTop};
|
||||
}
|
||||
|
||||
function leftof(side, offset) {
|
||||
return (side === 'p1' ? -1 : 1) * offset;
|
||||
}
|
||||
|
||||
function getHPColor(pokemon) {
|
||||
let ratio = pokemon.hp / pokemon.maxhp;
|
||||
if (ratio > 0.5) return 'g';
|
||||
if (ratio > 0.2) return 'y';
|
||||
return 'r';
|
||||
}
|
||||
|
||||
function hpWidth(hp, maxhp, maxwidth) {
|
||||
// special case for low health...
|
||||
if (this.hp === 1 && this.maxhp > 45) return 1;
|
||||
let percentage = Math.ceil(100 * hp / maxhp);
|
||||
if ((percentage === 100) && (hp < maxhp)) {
|
||||
percentage = 99;
|
||||
}
|
||||
return percentage * maxwidth / 100;
|
||||
}
|
||||
|
||||
function displayHP(div, hp, maxhp, c) {
|
||||
let hpcolor = getHPColor({hp, maxhp});
|
||||
let w = hpWidth(hp, maxhp, 150);
|
||||
div.style = `width:${w}px;border-right-width:${w ? 1 : 0}px;`;
|
||||
if (hpcolor === 'y') div.classList.add(`${c}-yellow`);
|
||||
else if (hpcolor === 'r') div.classList.add(`${c}-yellow`, `${c}-red`);
|
||||
}
|
||||
|
||||
function renderStatbar(side, pokemon, gender) {
|
||||
const statbar = e('div');
|
||||
statbar.classList.add('statbar', (side === 'p2' ? 'lstatbar' : 'rstatbar'));
|
||||
statbar.style = 'display: block';
|
||||
|
||||
const strong = e('strong', pokemon);
|
||||
if (gender === 'M' || gender === 'F') {
|
||||
const img = e('img', {class: 'pixelated'});
|
||||
img.width = 7;
|
||||
img.height = 10;
|
||||
img.src = `${Dex.resourcePrefix}fx/gender-${gender.toLowerCase()}.png`;
|
||||
strong.textContent += ' ';
|
||||
strong.appendChild(img);
|
||||
}
|
||||
|
||||
let symbol = '';
|
||||
if (pokemon.indexOf('-Mega') >= 0) symbol = 'mega';
|
||||
else if (pokemon === 'Kyogre-Primal') symbol = 'alpha';
|
||||
else if (pokemon === 'Groudon-Primal') symbol = 'omega';
|
||||
if (symbol) {
|
||||
const img = e('img', {class: 'pixelated'});
|
||||
img.src = `${Dex.resourcePrefix}sprites/misc/${symbol}.png`;
|
||||
img.style = 'vertical-align:text-bottom;';
|
||||
strong.textContent += ' ';
|
||||
strong.appendChild(img);
|
||||
}
|
||||
|
||||
const maxhp = 100;
|
||||
const hp = Math.floor(Math.random() * (maxhp - 1)) + 0;
|
||||
const prevhp = Math.floor(Math.random() * (maxhp - hp + 1)) + hp;
|
||||
|
||||
const hpbar = e('div', {class: 'hpbar'});
|
||||
const hptext = e('div', {class: 'hptext', content: `${hpWidth(hp, maxhp, 100)}%`});
|
||||
hpbar.appendChild(hptext);
|
||||
hpbar.appendChild(e('div', {class: 'hptextborder'}));
|
||||
const prevhpDiv = e('div', {class: 'prevhp'});
|
||||
const hpDiv = e('div', {class: 'hp'});
|
||||
|
||||
displayHP(hpDiv, hp, maxhp, 'hp');
|
||||
displayHP(prevhpDiv, prevhp, maxhp, 'prevhp');
|
||||
|
||||
prevhpDiv.appendChild(hpDiv);
|
||||
hpbar.appendChild(prevhpDiv);
|
||||
hpbar.appendChild(e('div', {class: 'status'}));
|
||||
|
||||
statbar.appendChild(strong);
|
||||
statbar.appendChild(hpbar);
|
||||
return statbar;
|
||||
}
|
||||
|
||||
function getGender(gen, pokemon, female) {
|
||||
if (gen === 1) return undefined;
|
||||
const species = Dex.getSpecies(pokemon);
|
||||
if (species.gender) return species.gender;
|
||||
return female ? 'F' : 'M';
|
||||
}
|
||||
|
||||
function render() {
|
||||
const gen = Number(SETTINGS.gen.select.value);
|
||||
const graphicsGen = GRAPHICS[SETTINGS.graphics.select.value];
|
||||
|
||||
if (SCENE) ROOT.removeChild(SCENE);
|
||||
if (STATE) ROOT.removeChild(STATE);
|
||||
|
||||
SCENE = e('div', {class: 'battle'});
|
||||
const innerbattle = e('div', {class: 'innerbattle'});
|
||||
const backdrop = e('div', {class: 'backdrop'});
|
||||
const main = e('div');
|
||||
changeBackdrop(backdrop, gen);
|
||||
|
||||
innerbattle.appendChild(backdrop);
|
||||
innerbattle.appendChild(e('div', {class: 'leftbar'}));
|
||||
innerbattle.appendChild(e('div', {class: 'rightbar'}));
|
||||
innerbattle.appendChild(main);
|
||||
|
||||
const statbarsDiv = e('div');
|
||||
const spritesDiv = e('div');
|
||||
for (const side of ['p2', 'p1']) {
|
||||
const pokemon = SIDES[side].pokemon.select.value;
|
||||
const gender = getGender(gen, pokemon, SIDES[side].female.input.checked);
|
||||
const shiny = SIDES[side].shiny.input.checked;
|
||||
|
||||
SIDES[side].picon.style = Dex.getPokemonIcon(
|
||||
{id: pokemon, gender},
|
||||
side === 'p2' // facingLeft
|
||||
);
|
||||
SIDES[side].dex.style = getTeambuilderSprite({
|
||||
species: pokemon,
|
||||
shiny,
|
||||
}, graphicsGen);
|
||||
|
||||
const {statbars, sprites} = renderSide(gen, side, pokemon, shiny, gender);
|
||||
for (const statbar of statbars) statbarsDiv.appendChild(statbar);
|
||||
for (const sprite of sprites) spritesDiv.appendChild(sprite);
|
||||
}
|
||||
main.appendChild(spritesDiv);
|
||||
main.appendChild(statbarsDiv);
|
||||
|
||||
SCENE.style = 'position:relative;margin:50px auto;'
|
||||
SCENE.appendChild(innerbattle);
|
||||
|
||||
STATE = e('textarea');
|
||||
STATE.value = JSON.stringify(toState());
|
||||
STATE.addEventListener('change', () => fromState(JSON.parse(STATE.value)));
|
||||
|
||||
ROOT.appendChild(SCENE);
|
||||
ROOT.appendChild(STATE);
|
||||
}
|
||||
|
||||
function renderSide(gen, side, pokemon, shiny, gender) {
|
||||
const graphics = SETTINGS.graphics.select.value;
|
||||
const graphicsGen = GRAPHICS[SETTINGS.graphics.select.value];
|
||||
const active = SETTINGS.active.inputs.findIndex(input => input.checked) + 1;
|
||||
const siden = +(side === 'p2');
|
||||
const noScale = !SETTINGS.scale.input.checked;
|
||||
const dynamax = SIDES[side].dynamax.input.checked;
|
||||
const isBackSprite = side === 'p1';
|
||||
|
||||
const prefs = {
|
||||
noanim: !graphics.endsWith('ani'),
|
||||
nopastgens: graphicsGen > 5,
|
||||
};
|
||||
|
||||
const statbars = [];
|
||||
const sprites = [];
|
||||
for (let slot = 0; slot < active; slot++) {
|
||||
withPrefs(prefs, () => {
|
||||
const data = Dex.getSpriteData(pokemon, siden, { gen, noScale, shiny, gender, dynamax });
|
||||
const img = e('img');
|
||||
img.src = data.url;
|
||||
img.style.position = 'absolute';
|
||||
if (data.pixelated) img.classList.add('pixelated');
|
||||
|
||||
const {x, y, z, left, top} =
|
||||
calculatePos(slot, (siden ? 200 : 0), gen, active, data.pixelated, isBackSprite);
|
||||
|
||||
const css = locToPos({x, y, z, display: 'block'}, data);
|
||||
for (let k in css) img.style[k] = k === 'opacity' ? css[k] : `${css[k]}px`;
|
||||
|
||||
const statbar = renderStatbar(side, pokemon, gender);
|
||||
statbar.style.left = `${left}px`;
|
||||
statbar.style.top = `${top}px`;
|
||||
|
||||
statbars.push(statbar);
|
||||
sprites.push(img);
|
||||
});
|
||||
}
|
||||
|
||||
// God only knows why this particular z-ordering is desirable...
|
||||
if (siden) sprites.reverse();
|
||||
if (active === 2) {
|
||||
statbars.reverse();
|
||||
} else if (active === 3) {
|
||||
if (!siden) {
|
||||
statbars.reverse();
|
||||
[sprites[1], sprites[2]] = [sprites[2], sprites[1]];
|
||||
}
|
||||
}
|
||||
|
||||
return {statbars, sprites};
|
||||
}
|
||||
|
||||
function getTeambuilderSprite(pokemon, gen) {
|
||||
if (!pokemon) return '';
|
||||
const data = Dex.getTeambuilderSpriteData(pokemon, gen);
|
||||
const shiny = (data.shiny ? '-shiny' : '');
|
||||
return 'background-image:url(' + Dex.resourcePrefix + data.spriteDir + shiny + '/' + data.spriteid + '.png);background-position:' + (data.x) + 'px ' + (data.y - 15) + 'px;background-repeat:no-repeat';
|
||||
}
|
||||
|
||||
function withPrefs(prefs, fn) {
|
||||
const saved = Dex.prefs;
|
||||
Dex.prefs = s => prefs[s];
|
||||
fn();
|
||||
Dex.prefs = saved;
|
||||
}
|
||||
|
||||
function sample(arr) {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
function randomSelections() {
|
||||
const gen = sample([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
const graphics = sample(Object.keys(GRAPHICS));
|
||||
const oversize = graphics.startsWith('gen5') ? sample([true, false]) : false;
|
||||
const scale = sample([true, false]);
|
||||
const sides = { p1: {}, p2: {} };
|
||||
for (side in sides) {
|
||||
const [name, species] = sample(SPECIES);
|
||||
sides[side].pokemon = name;
|
||||
if (gen == 1) {
|
||||
sides[side].female = null;
|
||||
} else if (species.gender) {
|
||||
sides[side].female = species.gender === 'F' ? true : false;
|
||||
} else {
|
||||
sides[side].female = sample([true, false]);
|
||||
}
|
||||
sides[side].shiny = gen > 1 ? sample([true, false]) : false;
|
||||
sides[side].dynamax = gen === 8 ? sample([true, false]) : false;
|
||||
}
|
||||
return {
|
||||
gen,
|
||||
graphics,
|
||||
scale,
|
||||
oversize,
|
||||
...sides
|
||||
};
|
||||
}
|
||||
|
||||
function renderRandom() {
|
||||
if (ROOT.firstChild) ROOT.removeChild(ROOT.firstChild);
|
||||
const div = e('div');
|
||||
|
||||
const selected = randomSelections();
|
||||
SETTINGS = createSettingsControls(selected);
|
||||
SIDES = {
|
||||
p1: createSideControls('Player 1', selected.p1),
|
||||
p2: createSideControls('Player 2', selected.p2),
|
||||
};
|
||||
|
||||
div.appendChild(SETTINGS.fieldset);
|
||||
div.appendChild(SIDES.p1.fieldset);
|
||||
div.appendChild(SIDES.p2.fieldset);
|
||||
|
||||
const randomize = e('button', 'Randomize');
|
||||
randomize.addEventListener('click', () => renderRandom());
|
||||
randomize.style = 'padding: 10px; margin: 45px 25px';
|
||||
div.appendChild(randomize);
|
||||
|
||||
root.appendChild(div);
|
||||
onChange();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
//#region MAIN
|
||||
|
||||
renderRandom();
|
||||
|
||||
//#endregion
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -559,10 +559,16 @@ const Dex = new class implements ModdedDex {
|
|||
document.getElementsByTagName('body')[0].appendChild(el);
|
||||
}
|
||||
getSpriteData(pokemon: Pokemon | Species | string, siden: number, options: {
|
||||
gen?: number, shiny?: boolean, gender?: GenderName, afd?: boolean, noScale?: boolean, mod?: string,
|
||||
gen?: number,
|
||||
shiny?: boolean,
|
||||
gender?: GenderName,
|
||||
afd?: boolean,
|
||||
noScale?: boolean,
|
||||
mod?: string,
|
||||
dynamax?: boolean,
|
||||
} = {gen: 6}) {
|
||||
const mechanicsGen = options.gen || 6;
|
||||
let isDynamax = false;
|
||||
let isDynamax = !!options.dynamax;
|
||||
if (pokemon instanceof Pokemon) {
|
||||
if (pokemon.volatiles.transform) {
|
||||
options.shiny = pokemon.volatiles.transform[2];
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
const assert = require('assert').strict;
|
||||
|
||||
window = global;
|
||||
|
||||
window.BattleTeambuilderTable = require('../data/teambuilder-tables.js').BattleTeambuilderTable;
|
||||
window.BattleAbilities = require('../data/abilities.js').BattleAbilities;
|
||||
window.BattleItems = require('../data/items.js').BattleItems;
|
||||
window.BattleMovedex = require('../data/moves.js').BattleMovedex;
|
||||
window.BattlePokdex = require('../data/pokedex.js').BattlePokdex;
|
||||
window.BattleTypeChart = require('../data/typechart.js').BattleTypeChart;
|
||||
|
||||
require('../js/battle-dex-data.js');
|
||||
require('../js/battle-dex.js');
|
||||
require('../js/battle-scene-stub.js');
|
||||
global.BattleText = require('../data/text.js').BattleText;
|
||||
require('../js/battle-text-parser.js');
|
||||
require('../js/battle.js');
|
||||
|
||||
const withPrefs = (prefs, fn) => {
|
||||
const saved = Dex.prefs;
|
||||
Dex.prefs = s => prefs[s];
|
||||
fn();
|
||||
Dex.prefs = saved;
|
||||
};
|
||||
|
||||
const spriteData = override => {
|
||||
const url = Dex.resourcePrefix + 'sprites/' + (override.url || '');
|
||||
delete override.url;
|
||||
return Object.assign({
|
||||
gen: 6,
|
||||
w: 96,
|
||||
h: 96,
|
||||
y: 0,
|
||||
url,
|
||||
cryurl: '',
|
||||
shiny: undefined,
|
||||
}, override);
|
||||
};
|
||||
|
||||
describe('Dex', () => {
|
||||
it('getAbility', () => {
|
||||
assert.equal(Dex.getAbility('Sturdy').shortDesc, 'If this Pokemon is at full HP, it survives one hit with at least 1 HP. Immune to OHKO.');
|
||||
assert.equal(Dex.forGen(3).getAbility('s turdy').shortDesc, 'OHKO moves fail when used against this Pokemon.');
|
||||
});
|
||||
it('getItem', () => {
|
||||
assert(Dex.getItem('Aerodactylite').megaEvolves, 'Aerodactyl');
|
||||
});
|
||||
it('getMove', () => {
|
||||
assert(Dex.getMove('Draco Meteor').basePower, 130);
|
||||
assert(Dex.forGen(4).getMove('DracoMeteor').basePower, 140);
|
||||
assert(Dex.getMove('Crunch').category, 'Physical');
|
||||
assert(Dex.forGen(2).getMove('CRUNCH').category, 'Special');
|
||||
});
|
||||
it('getTemplate', () => {
|
||||
assert.equal(Dex.getTemplate('Alakazam').baseStats.spd, 95);
|
||||
assert.equal(Dex.forGen(3).getTemplate('Alakazam').baseStats.spd, 85);
|
||||
});
|
||||
it('getType', () => {
|
||||
assert(Dex.getType('Fairy').exists);
|
||||
assert(!Dex.forGen(1).getType('steel').exists);
|
||||
assert.equal(Dex.forGen(1).getType('Psychic').damageTaken['Ghost'], 3);
|
||||
assert.equal(Dex.getType('Psychic').damageTaken['Ghost'], 1);
|
||||
assert.equal(Dex.getType('Fire').damageTaken['Water'], 1);
|
||||
assert.equal(Dex.getType('Water').damageTaken['Fire'], 2);
|
||||
assert.equal(Dex.getType('Ground').damageTaken['Electric'], 3);
|
||||
});
|
||||
it('getSpriteData', () => {
|
||||
// TODO Transform
|
||||
// TODO Dynamax
|
||||
it('default prefs', () => {
|
||||
// withPrefs({}) or no withPrefs accomplishes the same, but this is explict
|
||||
withPrefs({nopastgens: false, bwgfx: false, noanim: false, nogif: false}, () => {
|
||||
assert.deepEqual(Dex.getSpriteData('pikachu', 0), spriteData({url: 'gen5-back/pikachu.png', pixelated: false, isBackSprite: true}));
|
||||
assert.deepEqual(Dex.getSpriteData('pikachu', 1, {gen: 4, shiny: true}), spriteData({url: 'gen4/pikachu-shiny.png', pixelated: true, isBackSprite: false}));
|
||||
});
|
||||
})
|
||||
// TODO oodles more
|
||||
});
|
||||
it('getTeambuilderSprite', () => {
|
||||
assert.equal(Dex.getTeambuilderSprite({species: 'foobar'}), 'background-image:url(https://play.pokemonshowdown.com/sprites/gen5/0.png);background-position:10px 5px;background-repeat:no-repeat');
|
||||
assert.equal(Dex.getTeambuilderSprite({species: 'pikachu'}), 'background-image:url(https://play.pokemonshowdown.com/sprites/dex/pikachu.png);background-position:-2px -3px;background-repeat:no-repeat');
|
||||
assert.equal(Dex.getTeambuilderSprite({species: 'pikachu'}, 1), 'background-image:url(https://play.pokemonshowdown.com/sprites/gen1/pikachu.png);background-position:10px 5px;background-repeat:no-repeat');
|
||||
assert.equal(Dex.getTeambuilderSprite({species: 'gyarados', shiny: true}, 3), 'background-image:url(https://play.pokemonshowdown.com/sprites/gen3-shiny/gyarados.png);background-position:10px 5px;background-repeat:no-repeat');
|
||||
});
|
||||
it('getTeambuilderSpriteData', () => {
|
||||
// Basic
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'foobar'}), {spriteDir: 'sprites/gen5', spriteid: '0', x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'pikachu'}), {spriteDir: 'sprites/dex', spriteid: 'pikachu', x: -2, y: -3});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'pikachu'}, 1), { spriteDir: 'sprites/gen1', spriteid: 'pikachu', x: 10, y: 5 });
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'gyarados', shiny: true}, 3), {spriteDir: 'sprites/gen3', spriteid: 'gyarados', shiny: true, x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'eiscue', spriteid: 'pikachu'}), {spriteDir: 'sprites/gen5', spriteid: 'pikachu', x: 10, y: 5});
|
||||
|
||||
// XY Dex
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'eiscue'}), {spriteDir: 'sprites/gen5', spriteid: 'eiscue', x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'melmetal'}, 7), {spriteDir: 'sprites/dex', spriteid: 'melmetal', x: -6, y: -7});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Araquanid-Totem'}), {spriteDir: 'sprites/dex', spriteid: 'araquanid', x: -6, y: -7});
|
||||
|
||||
// Special XY Offsets
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Arceus-Grass'}, 7), {spriteDir: 'sprites/dex', spriteid: 'arceus-grass', x: -2, y: 7});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Arceus-Electric'}, 4), {spriteDir: 'sprites/gen4', spriteid: 'arceus-electric', x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Garchomp'}), {spriteDir: 'sprites/dex', spriteid: 'garchomp', x: -2, y: 2});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Garchomp'}, 5), {spriteDir: 'sprites/gen5', spriteid: 'garchomp', x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Garchomp-Mega'}), {spriteDir: 'sprites/dex', spriteid: 'garchomp-mega', x: -2, y: 0});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Garchomp-Mega'}, 5), {spriteDir: 'sprites/gen5', spriteid: 'garchomp-mega', x: 10, y: 5});
|
||||
|
||||
// Rollup
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Garchomp'}, 1), {spriteDir: 'sprites/gen4', spriteid: 'garchomp', x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Froakie'}, 2), {spriteDir: 'sprites/gen5', spriteid: 'froakie', x: 10, y: 5});
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'Tyranitar'}, 1), {spriteDir: 'sprites/gen2', spriteid: 'tyranitar', x: 10, y: 5});
|
||||
|
||||
// No Past Gens
|
||||
withPrefs({nopastgens: true}, () => {
|
||||
assert.deepEqual(Dex.getTeambuilderSpriteData({species: 'pikachu'}, 1), {spriteDir: 'sprites/dex', spriteid: 'pikachu', x: -2, y: -3});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user