13 Commits

Author SHA1 Message Date
kuroppoi
4628fee251 Restrict gender options if species is exclusively male, female or genderless 2023-07-12 19:29:24 +02:00
kuroppoi
a6ed715377 Update README.md 2023-07-12 19:20:47 +02:00
kuroppoi
4e56d2532f Update README.md 2023-07-12 19:19:12 +02:00
kuroppoi
eeb6048f54 Add Shaymin sky forme data 2023-07-12 16:29:49 +02:00
kuroppoi
875500d302 Display female encounter sprite if applicable 2023-07-12 16:28:04 +02:00
kuroppoi
1990519088 Change encounter defaults 2023-07-12 16:05:38 +02:00
kuroppoi
eb1605dbe7 Change how popup forms work so they don't rely on anchors 2023-07-11 23:27:50 +02:00
kuroppoi
d232de7307 Fix item form close button not working 2023-07-11 23:15:22 +02:00
kuroppoi
d57c7434a0 Display ability in dreamer summary 2023-07-11 04:20:37 +02:00
kuroppoi
022ee2f1e2 linguist-vendored test 2023-07-10 20:39:34 +02:00
kuroppoi
4f8a717ffb Use the first color index to determine foreground transparency 2023-07-10 16:57:39 +02:00
kuroppoi
a479c158db Fix bottleneck 2023-07-10 05:17:21 +02:00
kuroppoi
9a875cdf77 Apply background to Pokédex skins on read 2023-07-10 04:49:34 +02:00
11 changed files with 510 additions and 237 deletions

6
.gitattributes vendored
View File

@@ -1,6 +1,2 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
src/main/resources/dashboard/scripts/pokedata.js linguist-vendored

View File

@@ -1,5 +1,6 @@
# Entralinked
[![build](https://github.com/kuroppoi/entralinked/actions/workflows/dist-upload-artifact.yml/badge.svg)](https://github.com/kuroppoi/entralinked/actions)
[![release](https://img.shields.io/github/v/release/kuroppoi/entralinked?labelColor=30373D&label=Release&logoColor=959DA5&logo=github)](https://github.com/kuroppoi/entralinked/releases/latest)
Entralinked is a standalone Game Sync emulator developed for use with Pokémon Black & White and its sequels.\
Its purpose is to serve as a simple utility for downloading Pokémon, Items, C-Gear skins, Pokédex skins, Musicals\
@@ -28,5 +29,5 @@ Entralinked has a built-in DNS server.\
In order for your game to connect, you must configure the DNS settings of your DS.\
By default, Entralinked is configured to automatically use the local host of the system.\
This approach is not always accurate, however, and you may need to manually configure it in `config.json`.\
If you receive error code `60000` when trying to connect, erase the Nintendo WFC Configuration of your DS and try again.\
After tucking in a Pokémon, navigate to `http://localhost/dashboard/profile.html` in a web browser to configure Game Sync settings.
If you receive error code `60000` when trying to connect, erase the WFC Configuration of your DS and try again.\
After tucking in a Pokémon, navigate to http://localhost/dashboard/profile.html to configure Game Sync settings.

View File

@@ -7,17 +7,18 @@ import com.fasterxml.jackson.annotation.JsonProperty;
* Record containing information about a Pokémon
*/
public record PkmnInfo(
@JsonProperty(required = true) int personality,
@JsonProperty(required = true) int species,
@JsonProperty(required = true) int heldItem,
@JsonProperty(required = true) int trainerId,
@JsonProperty(required = true) int trainerSecretId,
@JsonProperty(required = true) int level,
@JsonProperty(required = true) int form,
@JsonProperty(required = true) PkmnNature nature,
@JsonProperty(required = true) PkmnGender gender,
@JsonProperty(required = true) String nickname,
@JsonProperty(required = true) String trainerName) {
@JsonProperty(required = true) String nickname,
@JsonProperty(required = true) String trainerName,
@JsonProperty(required = true) PkmnNature nature,
@JsonProperty(required = true) PkmnGender gender,
@JsonProperty(required = true) int species,
@JsonProperty(required = true) int personality,
@JsonProperty(required = true) int trainerId,
@JsonProperty(required = true) int trainerSecretId,
@JsonProperty(required = true) int level,
@JsonProperty(required = false) int form,
@JsonProperty(required = false) int ability,
@JsonProperty(required = false) int heldItem) {
@JsonIgnore
public boolean isShiny() {

View File

@@ -58,7 +58,7 @@ public class PkmnInfoReader {
// Read Pokémon data
int species = buffer.getShortLE(8);
int item = buffer.getShortLE(10) & 0xFFFF;
int heldItem = buffer.getShortLE(10) & 0xFFFF;
int trainerId = buffer.getShortLE(12) & 0xFFFF;
int trainerSecretId = buffer.getShortLE(14) & 0xFFFF;
int level = buffer.getByte(140);
@@ -78,14 +78,14 @@ public class PkmnInfoReader {
// Loosely verify data
if(species < 1 || species > 649) throw new IOException("Invalid species");
if(item < 0 || item > 638) throw new IOException("Invalid held item");
if(heldItem < 0 || heldItem > 638) throw new IOException("Invalid held item");
if(ability < 1 || ability > 164) throw new IOException("Invalid ability");
if(level < 1 || level > 100) throw new IOException("Level is out of range");
if(nature == null) throw new IOException("Invalid nature");
// Create record
PkmnInfo info = new PkmnInfo(personality, species, item, trainerId, trainerSecretId, level, form, nature, gender, nickname, trainerName);
return info;
return new PkmnInfo(nickname, trainerName, nature, gender, species, personality,
trainerId, trainerSecretId, level, form, ability, heldItem);
}
private static void decryptData(ByteBuf buffer, int offset, int length, int seed) throws IOException {

View File

@@ -4,6 +4,9 @@ import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Utility class for reading tiled images (C-Gear & Pokédex skin data) into a usable {@link BufferedImage}.
*/
@@ -15,44 +18,72 @@ public class TiledImageReader {
public static final int COLOR_PALETTE_SIZE = 16;
public static final int SCREEN_WIDTH = 256;
public static final int SCREEN_HEIGHT = 192;
public static final int SCREEN_TILE_COUNT = SCREEN_WIDTH * SCREEN_HEIGHT / TILE_SIZE;
public static final int SCREEN_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT;
public static final int SCREEN_TILE_COUNT = SCREEN_SIZE / TILE_SIZE;
private static final byte[] dexBackgroundColorIndices = new byte[SCREEN_SIZE];
private static final Logger logger = LogManager.getLogger();
static {
// Load Pokédex skin background color indices
try(InputStream inputStream = TiledImageReader.class.getResourceAsStream("/zukan.bin")) {
int currentIndex = 0;
int valueAmount = -1;
int value = -1;
// Read until end of stream
while((valueAmount = inputStream.read()) != -1 && (value = inputStream.read()) != -1) {
for(int i = 0; i < valueAmount; i++) {
dexBackgroundColorIndices[currentIndex++] = (byte)(value & 63);
}
}
} catch(IOException e) {
logger.error("Could not load Pokédex background data", e);
}
}
/**
* Calls {@link #readTiledImage(InputStream, int, boolean)} with a tile count of 255.
* Reads a C-Gear skin from the specified {@link InputStream}.
*
* @param normalizeIndices Should be {@code true} if the provided C-Gear skin data is from the original Black & White.
* @return A {@link BufferedImage} representing the read C-Gear skin data.
*/
public static BufferedImage readCGearSkin(InputStream inputStream, boolean normalizeIndices) throws IOException {
return readTiledImage(inputStream, 255, normalizeIndices);
return readTiledImage(inputStream, 255, 0, null, normalizeIndices);
}
/**
* Calls {@link #readTiledImage(InputStream, int, boolean)} with a tile count of 768 and index normalization disabled.
* Reads a Pokédex skin from the specified {@link InputStream}.
* If the skin in question is an overlay, the Pokédex background will be applied to the resulting image automatically.
*
* @return A {@link BufferedImage} representing the read Pokédex skin data.
*/
public static BufferedImage readDexSkin(InputStream inputStream) throws IOException {
return readTiledImage(inputStream, 768, false);
return readTiledImage(inputStream, 768, 64, dexBackgroundColorIndices, false);
}
/**
* Reads tiled image data from the provided {@link InputStream} and returns a {@link BufferedImage} representing the read image data.
*
* @param tileCount The number of tiles to be read. This should be equal to the maximum number of tiles for this image.
* @param backgroundColorCount The number of background colors this image has.
* @param backgroundColorIndices The background color indices of the background image. If {@code null}, no background will be used.
* @param normalizedIndices Indicates that tile indices are not linear (Black & White C-Gear skins) and should be normalized.
* @return A {@link BufferedImage} representing the read image data.
*/
public static BufferedImage readTiledImage(InputStream inputStream, int tileCount, boolean normalizeIndices) throws IOException {
public static BufferedImage readTiledImage(InputStream inputStream, int tileCount, int backgroundColorCount,
byte[] backgroundColorIndices, boolean normalizeIndices) throws IOException {
BufferedImage image = new BufferedImage(SCREEN_WIDTH, SCREEN_HEIGHT, BufferedImage.TYPE_INT_RGB); // Result image
int[] tileData = new int[tileCount * TILE_SIZE];
int[] tileIndices = new int[tileCount]; // Tile index lookup table
int[] colorPalette = new int[COLOR_PALETTE_SIZE];
int[] backgroundColorPalette = new int[backgroundColorCount];
// Read tile data.
for(int i = 0; i < tileCount; i++) {
for(int j = 0; j < TILE_SIZE / 2; j++) {
int paletteIndices = inputStream.read(); // Contains color palette indices for 2 adjacent pixels.
byte[] rawTileData = inputStream.readNBytes(TILE_SIZE / 2);
for(int j = 0; j < rawTileData.length; j++) {
int paletteIndices = rawTileData[j]; // Contains color palette indices for 2 adjacent pixels.
tileData[i * TILE_SIZE + j * 2] = paletteIndices & (COLOR_PALETTE_SIZE - 1);
tileData[i * TILE_SIZE + j * 2 + 1] = (paletteIndices >> 4) & (COLOR_PALETTE_SIZE - 1);
}
@@ -61,17 +92,18 @@ public class TiledImageReader {
tileIndices[i] = normalizeIndices ? i + i / 17 * 15 + 0xA0A0 : i;
}
// Read color data.
// Read foreground color data.
// In cases where background colors are present, pixels that use the *first* foreground color
// will be replaced by the background color at that pixel's location.
for(int i = 0; i < COLOR_PALETTE_SIZE; i++) {
colorPalette[i] = convertColor(inputStream.read() | inputStream.read() << 8);
}
// Read background color data.
// Pokédex skins contain room for 240 extra colors, 64 of which are defined and appear to be used as the
// 'background' colors in cases where the skin is only an overlay that is displayed on top of the 'true' Pokédex.
for(int i = 0; i < COLOR_PALETTE_SIZE; i++) {
int color = inputStream.read() | inputStream.read() << 8;
// Convert BGR555 to RGB888
int red = (color & 0x1F) << 3;
int green = ((color & 0x3E0) >> 5) << 3;
int blue = ((color & 0x7C00) >> 10) << 3;
colorPalette[i] = (red << 16) | (green << 8) | blue;
for(int i = 0; i < backgroundColorCount; i++) {
backgroundColorPalette[i] = convertColor(inputStream.read() | inputStream.read() << 8);
}
// Map tiles to the resulting image.
@@ -107,10 +139,18 @@ public class TiledImageReader {
case 12 -> TILE_SIZE - j - 1; // Flip horizontally & vertically
default -> j; // Don't flip
};
// Finally, set the pixel!
int pixelX = x + j % TILE_WIDTH;
int pixelY = y + j / TILE_WIDTH;
int paletteIndex = tileData[tileIndex * TILE_SIZE + tilePixelIndex];
image.setRGB(x + j % TILE_WIDTH, y + j / TILE_WIDTH, colorPalette[paletteIndex]);
// If a background is present and the foreground color index of this pixel is 0, use the background color instead.
// The background color index is determined by the pixel location.
int color = backgroundColorIndices == null || paletteIndex > 0 ? colorPalette[paletteIndex]
: backgroundColorPalette[backgroundColorIndices[pixelY * SCREEN_WIDTH + pixelX]];
// Finally, set the pixel!
image.setRGB(pixelX, pixelY, color);
}
}
} else {
@@ -120,11 +160,28 @@ public class TiledImageReader {
int y = i * TILE_WIDTH / SCREEN_WIDTH * TILE_WIDTH;
for(int j = 0; j < TILE_SIZE; j++) {
image.setRGB(x + j % TILE_WIDTH, y + j / TILE_WIDTH, colorPalette[tileData[i * TILE_SIZE + j]]);
int pixelX = x + j % TILE_WIDTH;
int pixelY = y + j / TILE_WIDTH;
int paletteIndex = tileData[i * TILE_SIZE + j];
int color = backgroundColorIndices == null || paletteIndex > 0 ? colorPalette[paletteIndex]
: backgroundColorPalette[backgroundColorIndices[pixelY * SCREEN_WIDTH + pixelX]];
image.setRGB(pixelX, pixelY, color);
}
}
}
return image;
}
/**
* Converts the input BGR555 color value to an RGB888 color value.
*
* @return The RGB888 color value.
*/
private static int convertColor(int color) {
int red = (color & 0x1F) << 3;
int green = ((color & 0x3E0) >> 5) << 3;
int blue = ((color & 0x7C00) >> 10) << 3;
return (red << 16) | (green << 8) | blue;
}
}

View File

@@ -21,24 +21,26 @@
<tr>
<th>Species</th>
<td id="dreamer-species"></td>
<th>Nature</th>
<td id="dreamer-nature"></td>
<th>Ability</th>
<td id="dreamer-ability"></td>
</tr>
<tr>
<th>Name</th>
<td id="dreamer-name"></td>
<th>Gender</th>
<td id="dreamer-gender"></td>
<th>Nature</th>
<td id="dreamer-nature"></td>
</tr>
<tr>
<th>Trainer</th>
<td id="dreamer-trainer"></td>
<th>Level</th>
<td id="dreamer-level"></td>
<th>Gender</th>
<td id="dreamer-gender"></td>
</tr>
<tr>
<th>Trainer ID</th>
<td id="dreamer-trainer-id"></td>
<th>Level</th>
<td id="dreamer-level"></td>
</tr>
</table>
</div>
@@ -48,18 +50,18 @@
<div>
<table id="encounter-table" class="encounter-image-table">
<tr>
<td><a id="encounter0" href="#configureEncounter" onclick="configureEncounter(0)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter1" href="#configureEncounter" onclick="configureEncounter(1)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter2" href="#configureEncounter" onclick="configureEncounter(2)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter3" href="#configureEncounter" onclick="configureEncounter(3)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter4" href="#configureEncounter" onclick="configureEncounter(4)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td id="encounter0" onclick="configureEncounter(0)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter1" onclick="configureEncounter(1)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter2" onclick="configureEncounter(2)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter3" onclick="configureEncounter(3)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter4" onclick="configureEncounter(4)"><image src="/sprites/pokemon/normal/0.png"/></td>
</tr>
<tr>
<td><a id="encounter5" href="#configureEncounter" onclick="configureEncounter(5)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter6" href="#configureEncounter" onclick="configureEncounter(6)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter7" href="#configureEncounter" onclick="configureEncounter(7)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter8" href="#configureEncounter" onclick="configureEncounter(8)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td><a id="encounter9" href="#configureEncounter" onclick="configureEncounter(9)"><image src="/sprites/pokemon/normal/0.png"/></a></td>
<td id="encounter5" onclick="configureEncounter(5)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter6" onclick="configureEncounter(6)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter7" onclick="configureEncounter(7)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter8" onclick="configureEncounter(8)"><image src="/sprites/pokemon/normal/0.png"/></td>
<td id="encounter9" onclick="configureEncounter(9)"><image src="/sprites/pokemon/normal/0.png"/></td>
</tr>
</table>
</div>
@@ -70,20 +72,20 @@
<div>
<table id="visitor-table" class="visitor-table">
<tr>
<td><a id="visitor0" href="#configureVisitor" onclick="configureVisitor(0)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor1" href="#configureVisitor" onclick="configureVisitor(1)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor2" href="#configureVisitor" onclick="configureVisitor(2)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor3" href="#configureVisitor" onclick="configureVisitor(3)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor4" href="#configureVisitor" onclick="configureVisitor(4)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor5" href="#configureVisitor" onclick="configureVisitor(5)"><image src="/sprites/trainers/none.png"/></a></td>
<td id="visitor0" onclick="configureVisitor(0)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor1" onclick="configureVisitor(1)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor2" onclick="configureVisitor(2)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor3" onclick="configureVisitor(3)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor4" onclick="configureVisitor(4)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor5" onclick="configureVisitor(5)"><image src="/sprites/trainers/none.png"/></td>
</tr>
<tr>
<td><a id="visitor6" href="#configureVisitor" onclick="configureVisitor(6)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor7" href="#configureVisitor" onclick="configureVisitor(7)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor8" href="#configureVisitor" onclick="configureVisitor(8)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor9" href="#configureVisitor" onclick="configureVisitor(9)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor10" href="#configureVisitor" onclick="configureVisitor(10)"><image src="/sprites/trainers/none.png"/></a></td>
<td><a id="visitor11" href="#configureVisitor" onclick="configureVisitor(11)"><image src="/sprites/trainers/none.png"/></a></td>
<td id="visitor6" onclick="configureVisitor(6)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor7" onclick="configureVisitor(7)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor8" onclick="configureVisitor(8)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor9" onclick="configureVisitor(9)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor10" onclick="configureVisitor(10)"><image src="/sprites/trainers/none.png"/></td>
<td id="visitor11" onclick="configureVisitor(11)"><image src="/sprites/trainers/none.png"/></td>
</tr>
</table>
</div>
@@ -94,28 +96,28 @@
<div>
<table id="item-table" class="item-table">
<tr>
<td><a id="item0" href="#configureItem" onclick="configureItem(0)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item1" href="#configureItem" onclick="configureItem(1)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item2" href="#configureItem" onclick="configureItem(2)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item3" href="#configureItem" onclick="configureItem(3)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item4" href="#configureItem" onclick="configureItem(4)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item5" href="#configureItem" onclick="configureItem(5)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item6" href="#configureItem" onclick="configureItem(6)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item7" href="#configureItem" onclick="configureItem(7)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item8" href="#configureItem" onclick="configureItem(8)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item9" href="#configureItem" onclick="configureItem(9)"><image src="/sprites/items/0.png"/></a></td>
<td id="item0" onclick="configureItem(0)"><image src="/sprites/items/0.png"/></td>
<td id="item1" onclick="configureItem(1)"><image src="/sprites/items/0.png"/></td>
<td id="item2" onclick="configureItem(2)"><image src="/sprites/items/0.png"/></td>
<td id="item3" onclick="configureItem(3)"><image src="/sprites/items/0.png"/></td>
<td id="item4" onclick="configureItem(4)"><image src="/sprites/items/0.png"/></td>
<td id="item5" onclick="configureItem(5)"><image src="/sprites/items/0.png"/></td>
<td id="item6" onclick="configureItem(6)"><image src="/sprites/items/0.png"/></td>
<td id="item7" onclick="configureItem(7)"><image src="/sprites/items/0.png"/></td>
<td id="item8" onclick="configureItem(8)"><image src="/sprites/items/0.png"/></td>
<td id="item9" onclick="configureItem(9)"><image src="/sprites/items/0.png"/></td>
</tr>
<tr>
<td><a id="item10" href="#configureItem" onclick="configureItem(10)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item11" href="#configureItem" onclick="configureItem(11)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item12" href="#configureItem" onclick="configureItem(12)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item13" href="#configureItem" onclick="configureItem(13)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item14" href="#configureItem" onclick="configureItem(14)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item15" href="#configureItem" onclick="configureItem(15)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item16" href="#configureItem" onclick="configureItem(16)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item17" href="#configureItem" onclick="configureItem(17)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item18" href="#configureItem" onclick="configureItem(18)"><image src="/sprites/items/0.png"/></a></td>
<td><a id="item19" href="#configureItem" onclick="configureItem(19)"><image src="/sprites/items/0.png"/></a></td>
<td id="item10" onclick="configureItem(10)"><image src="/sprites/items/0.png"/></td>
<td id="item11" onclick="configureItem(11)"><image src="/sprites/items/0.png"/></td>
<td id="item12" onclick="configureItem(12)"><image src="/sprites/items/0.png"/></td>
<td id="item13" onclick="configureItem(13)"><image src="/sprites/items/0.png"/></td>
<td id="item14" onclick="configureItem(14)"><image src="/sprites/items/0.png"/></td>
<td id="item15" onclick="configureItem(15)"><image src="/sprites/items/0.png"/></td>
<td id="item16" onclick="configureItem(16)"><image src="/sprites/items/0.png"/></td>
<td id="item17" onclick="configureItem(17)"><image src="/sprites/items/0.png"/></td>
<td id="item18" onclick="configureItem(18)"><image src="/sprites/items/0.png"/></td>
<td id="item19" onclick="configureItem(19)"><image src="/sprites/items/0.png"/></td>
</tr>
</table>
</div>
@@ -157,7 +159,7 @@
</div>
</div>
<!-- Entree Forest Encounter Configuration Form -->
<div id="configureEncounter" class="popup">
<div id="encounter-config" class="popup">
<div class="content">
<button class="close-button" onclick="closeEncounterForm()">X</button>
<form id="encounter-form">
@@ -198,9 +200,9 @@
</div>
</div>
<!-- Item Configuration Form -->
<div id="configureItem" class="popup">
<div id="item-config" class="popup">
<div class="content">
<button class="close-button" onclick="closeEncounterForm()">X</button>
<button class="close-button" onclick="closeItemForm()">X</button>
<form id="item-form">
<label for="item-form-id">Item</label>
<select id="item-form-id" name="id" value="1">
@@ -214,7 +216,7 @@
</div>
</div>
<!-- Join Avenue Visitor Configuration Form -->
<div id="configureVisitor" class="popup">
<div id="visitor-config" class="popup">
<div class="content">
<button class="close-button" onclick="closeVisitorForm()">X</button>
<form id="visitor-form">

View File

@@ -1,7 +1,9 @@
const POKE_SPECIES_MAP = {};
const POKE_SPECIES_LIST = [];
const POKE_MOVE_MAP = {};
const POKE_MOVE_LIST = [];
const SPECIES_MAP = {};
const SPECIES_LIST = [];
const MOVE_MAP = {};
const MOVE_LIST = [];
const ABILITY_MAP = {};
const ABILITY_LIST = [];
const ITEM_MAP = {};
const ITEM_LIST = [];
const REGION_MAP = {};
@@ -38,12 +40,12 @@ const REGION_LIST = [];
{id: 26, name: "Raichu", downloadable: true},
{id: 27, name: "Sandshrew", downloadable: true},
{id: 28, name: "Sandslash", downloadable: true},
{id: 29, name: "Nidoran♀", downloadable: true},
{id: 30, name: "Nidorina", downloadable: true},
{id: 31, name: "Nidoqueen", downloadable: true},
{id: 32, name: "Nidoran♂", downloadable: true},
{id: 33, name: "Nidorino", downloadable: true},
{id: 34, name: "Nidoking", downloadable: true},
{id: 29, name: "Nidoran♀", downloadable: true, gender: "female"},
{id: 30, name: "Nidorina", downloadable: true, gender: "female"},
{id: 31, name: "Nidoqueen", downloadable: true, gender: "female"},
{id: 32, name: "Nidoran♂", downloadable: true, gender: "male"},
{id: 33, name: "Nidorino", downloadable: true, gender: "male"},
{id: 34, name: "Nidoking", downloadable: true, gender: "male"},
{id: 35, name: "Clefairy", downloadable: true},
{id: 36, name: "Clefable", downloadable: true},
{id: 37, name: "Vulpix", downloadable: true},
@@ -90,8 +92,8 @@ const REGION_LIST = [];
{id: 78, name: "Rapidash", downloadable: true},
{id: 79, name: "Slowpoke", downloadable: true},
{id: 80, name: "Slowbro", downloadable: true},
{id: 81, name: "Magnemite", downloadable: true},
{id: 82, name: "Magneton", downloadable: true},
{id: 81, name: "Magnemite", downloadable: true, gender: "unknown"},
{id: 82, name: "Magneton", downloadable: true, gender: "unknown"},
{id: 83, name: "Farfetch'd", downloadable: true},
{id: 84, name: "Doduo", downloadable: true},
{id: 85, name: "Dodrio", downloadable: true},
@@ -109,58 +111,58 @@ const REGION_LIST = [];
{id: 97, name: "Hypno", downloadable: true},
{id: 98, name: "Krabby", downloadable: true},
{id: 99, name: "Kingler", downloadable: true},
{id: 100, name: "Voltorb", downloadable: true},
{id: 101, name: "Electrode", downloadable: true},
{id: 100, name: "Voltorb", downloadable: true, gender: "unknown"},
{id: 101, name: "Electrode", downloadable: true, gender: "unknown"},
{id: 102, name: "Exeggcute", downloadable: true},
{id: 103, name: "Exeggutor", downloadable: true},
{id: 104, name: "Cubone", downloadable: true},
{id: 105, name: "Marowak", downloadable: true},
{id: 106, name: "Hitmonlee", downloadable: true},
{id: 107, name: "Hitmonchan", downloadable: true},
{id: 106, name: "Hitmonlee", downloadable: true, gender: "male"},
{id: 107, name: "Hitmonchan", downloadable: true, gender: "male"},
{id: 108, name: "Lickitung", downloadable: true},
{id: 109, name: "Koffing", downloadable: true},
{id: 110, name: "Weezing", downloadable: true},
{id: 111, name: "Rhyhorn", downloadable: true},
{id: 112, name: "Rhydon", downloadable: true},
{id: 113, name: "Chansey", downloadable: true},
{id: 113, name: "Chansey", downloadable: true, gender: "female"},
{id: 114, name: "Tangela", downloadable: true},
{id: 115, name: "Kangaskhan", downloadable: true},
{id: 115, name: "Kangaskhan", downloadable: true, gender: "female"},
{id: 116, name: "Horsea", downloadable: true},
{id: 117, name: "Seadra", downloadable: true},
{id: 118, name: "Goldeen", downloadable: true},
{id: 119, name: "Seaking", downloadable: true},
{id: 120, name: "Staryu", downloadable: true},
{id: 121, name: "Starmie", downloadable: true},
{id: 120, name: "Staryu", downloadable: true, gender: "unknown"},
{id: 121, name: "Starmie", downloadable: true, gender: "unknown"},
{id: 122, name: "Mr. Mime", downloadable: true},
{id: 123, name: "Scyther", downloadable: true},
{id: 124, name: "Jynx", downloadable: true},
{id: 124, name: "Jynx", downloadable: true, gender: "female"},
{id: 125, name: "Electabuzz", downloadable: true},
{id: 126, name: "Magmar", downloadable: true},
{id: 127, name: "Pinsir", downloadable: true},
{id: 128, name: "Tauros", downloadable: true},
{id: 128, name: "Tauros", downloadable: true, gender: "male"},
{id: 129, name: "Magikarp", downloadable: true},
{id: 130, name: "Gyarados", downloadable: true},
{id: 131, name: "Lapras", downloadable: true},
{id: 132, name: "Ditto", downloadable: true},
{id: 132, name: "Ditto", downloadable: true, gender: "unknown"},
{id: 133, name: "Eevee", downloadable: true},
{id: 134, name: "Vaporeon", downloadable: true},
{id: 135, name: "Jolteon", downloadable: true},
{id: 136, name: "Flareon", downloadable: true},
{id: 137, name: "Porygon", downloadable: true},
{id: 137, name: "Porygon", downloadable: true, gender: "unknown"},
{id: 138, name: "Omanyte", downloadable: true},
{id: 139, name: "Omastar", downloadable: true},
{id: 140, name: "Kabuto", downloadable: true},
{id: 141, name: "Kabutops", downloadable: true},
{id: 142, name: "Aerodactyl", downloadable: true},
{id: 143, name: "Snorlax", downloadable: true},
{id: 144, name: "Articuno", downloadable: true},
{id: 145, name: "Zapdos", downloadable: true},
{id: 146, name: "Moltres", downloadable: true},
{id: 144, name: "Articuno", downloadable: true, gender: "unknown"},
{id: 145, name: "Zapdos", downloadable: true, gender: "unknown"},
{id: 146, name: "Moltres", downloadable: true, gender: "unknown"},
{id: 147, name: "Dratini", downloadable: true},
{id: 148, name: "Dragonair", downloadable: true},
{id: 149, name: "Dragonite", downloadable: true},
{id: 150, name: "Mewtwo", downloadable: true},
{id: 151, name: "Mew", downloadable: true},
{id: 150, name: "Mewtwo", downloadable: true, gender: "unknown"},
{id: 151, name: "Mew", downloadable: true, gender: "unknown"},
{id: 152, name: "Chikorita", downloadable: true},
{id: 153, name: "Bayleef", downloadable: true},
{id: 154, name: "Meganium", downloadable: true},
@@ -210,7 +212,7 @@ const REGION_LIST = [];
{id: 198, name: "Murkrow", downloadable: true},
{id: 199, name: "Slowking", downloadable: true},
{id: 200, name: "Misdreavus", downloadable: true},
{id: 201, name: "Unown", downloadable: true, forms: [
{id: 201, name: "Unown", downloadable: true, gender: "unknown", forms: [
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P","Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "!", "?"]},
{id: 202, name: "Wobbuffet", downloadable: true},
@@ -244,25 +246,25 @@ const REGION_LIST = [];
{id: 230, name: "Kingdra", downloadable: true},
{id: 231, name: "Phanpy", downloadable: true},
{id: 232, name: "Donphan", downloadable: true},
{id: 233, name: "Porygon2", downloadable: true},
{id: 233, name: "Porygon2", downloadable: true, gender: "unknown"},
{id: 234, name: "Stantler", downloadable: true},
{id: 235, name: "Smeargle", downloadable: true},
{id: 236, name: "Tyrogue", downloadable: true},
{id: 237, name: "Hitmontop", downloadable: true},
{id: 236, name: "Tyrogue", downloadable: true, gender: "male"},
{id: 237, name: "Hitmontop", downloadable: true, gender: "male"},
{id: 238, name: "Smoochum", downloadable: true},
{id: 239, name: "Elekid", downloadable: true},
{id: 240, name: "Magby", downloadable: true},
{id: 241, name: "Miltank", downloadable: true},
{id: 242, name: "Blissey", downloadable: true},
{id: 243, name: "Raikou", downloadable: true},
{id: 244, name: "Entei", downloadable: true},
{id: 245, name: "Suicune", downloadable: true},
{id: 241, name: "Miltank", downloadable: true, gender: "female"},
{id: 242, name: "Blissey", downloadable: true, gender: "female"},
{id: 243, name: "Raikou", downloadable: true, gender: "unknown"},
{id: 244, name: "Entei", downloadable: true, gender: "unknown"},
{id: 245, name: "Suicune", downloadable: true, gender: "unknown"},
{id: 246, name: "Larvitar", downloadable: true},
{id: 247, name: "Pupitar", downloadable: true},
{id: 248, name: "Tyranitar", downloadable: true},
{id: 249, name: "Lugia", downloadable: true},
{id: 250, name: "Ho-Oh", downloadable: true},
{id: 251, name: "Celebi", downloadable: true},
{id: 249, name: "Lugia", downloadable: true, gender: "unknown"},
{id: 250, name: "Ho-Oh", downloadable: true, gender: "unknown"},
{id: 251, name: "Celebi", downloadable: true, gender: "unknown"},
{id: 252, name: "Treecko", downloadable: true},
{id: 253, name: "Grovyle", downloadable: true},
{id: 254, name: "Sceptile", downloadable: true},
@@ -303,7 +305,7 @@ const REGION_LIST = [];
{id: 289, name: "Slaking", downloadable: true},
{id: 290, name: "Nincada", downloadable: true},
{id: 291, name: "Ninjask", downloadable: true},
{id: 292, name: "Shedinja", downloadable: true},
{id: 292, name: "Shedinja", downloadable: true, gender: "unknown"},
{id: 293, name: "Whismur", downloadable: true},
{id: 294, name: "Loudred", downloadable: true},
{id: 295, name: "Exploud", downloadable: true},
@@ -324,8 +326,8 @@ const REGION_LIST = [];
{id: 310, name: "Manectric", downloadable: true},
{id: 311, name: "Plusle", downloadable: true},
{id: 312, name: "Minun", downloadable: true},
{id: 313, name: "Volbeat", downloadable: true},
{id: 314, name: "Illumise", downloadable: true},
{id: 313, name: "Volbeat", downloadable: true, gender: "male"},
{id: 314, name: "Illumise", downloadable: true, gender: "female"},
{id: 315, name: "Roselia", downloadable: true},
{id: 316, name: "Gulpin", downloadable: true},
{id: 317, name: "Swalot", downloadable: true},
@@ -348,14 +350,14 @@ const REGION_LIST = [];
{id: 334, name: "Altaria", downloadable: true},
{id: 335, name: "Zangoose", downloadable: true},
{id: 336, name: "Seviper", downloadable: true},
{id: 337, name: "Lunatone", downloadable: true},
{id: 338, name: "Solrock", downloadable: true},
{id: 337, name: "Lunatone", downloadable: true, gender: "unknown"},
{id: 338, name: "Solrock", downloadable: true, gender: "unknown"},
{id: 339, name: "Barboach", downloadable: true},
{id: 340, name: "Whiscash", downloadable: true},
{id: 341, name: "Corphish", downloadable: true},
{id: 342, name: "Crawdaunt", downloadable: true},
{id: 343, name: "Baltoy", downloadable: true},
{id: 344, name: "Claydol", downloadable: true},
{id: 343, name: "Baltoy", downloadable: true, gender: "unknown"},
{id: 344, name: "Claydol", downloadable: true, gender: "unknown"},
{id: 345, name: "Lileep", downloadable: true},
{id: 346, name: "Cradily", downloadable: true},
{id: 347, name: "Anorith", downloadable: true},
@@ -385,19 +387,19 @@ const REGION_LIST = [];
{id: 371, name: "Bagon", downloadable: true},
{id: 372, name: "Shelgon", downloadable: true},
{id: 373, name: "Salamence", downloadable: true},
{id: 374, name: "Beldum", downloadable: true},
{id: 375, name: "Metang", downloadable: true},
{id: 376, name: "Metagross", downloadable: true},
{id: 377, name: "Regirock", downloadable: true},
{id: 378, name: "Regice", downloadable: true},
{id: 379, name: "Registeel", downloadable: true},
{id: 380, name: "Latias", downloadable: true},
{id: 381, name: "Latios", downloadable: true},
{id: 382, name: "Kyogre", downloadable: true},
{id: 383, name: "Groudon", downloadable: true},
{id: 384, name: "Rayquaza", downloadable: true},
{id: 385, name: "Jirachi", downloadable: true},
{id: 386, name: "Deoxys", downloadable: true, forms: ["Normal", "Attack", "Defense", "Speed"]},
{id: 374, name: "Beldum", downloadable: true, gender: "unknown"},
{id: 375, name: "Metang", downloadable: true, gender: "unknown"},
{id: 376, name: "Metagross", downloadable: true, gender: "unknown"},
{id: 377, name: "Regirock", downloadable: true, gender: "unknown"},
{id: 378, name: "Regice", downloadable: true, gender: "unknown"},
{id: 379, name: "Registeel", downloadable: true, gender: "unknown"},
{id: 380, name: "Latias", downloadable: true, gender: "female"},
{id: 381, name: "Latios", downloadable: true, gender: "male"},
{id: 382, name: "Kyogre", downloadable: true, gender: "unknown"},
{id: 383, name: "Groudon", downloadable: true, gender: "unknown"},
{id: 384, name: "Rayquaza", downloadable: true, gender: "unknown"},
{id: 385, name: "Jirachi", downloadable: true, gender: "unknown"},
{id: 386, name: "Deoxys", downloadable: true, gender: "unknown", forms: ["Normal", "Attack", "Defense", "Speed"]},
{id: 387, name: "Turtwig", downloadable: true},
{id: 388, name: "Grotle", downloadable: true},
{id: 389, name: "Torterra", downloadable: true},
@@ -424,10 +426,10 @@ const REGION_LIST = [];
{id: 410, name: "Shieldon", downloadable: true},
{id: 411, name: "Bastiodon", downloadable: true},
{id: 412, name: "Burmy", downloadable: true, forms: ["Plant Cloak", "Sandy Cloak", "Trash Cloak"]},
{id: 413, name: "Wormadam", downloadable: true, forms: ["Plant Cloak", "Sandy Cloak", "Trash Cloak"]},
{id: 414, name: "Mothim", downloadable: true},
{id: 413, name: "Wormadam", downloadable: true, gender: "female", forms: ["Plant Cloak", "Sandy Cloak", "Trash Cloak"]},
{id: 414, name: "Mothim", downloadable: true, gender: "male"},
{id: 415, name: "Combee", downloadable: true},
{id: 416, name: "Vespiquen", downloadable: true},
{id: 416, name: "Vespiquen", downloadable: true, gender: "female"},
{id: 417, name: "Pachirisu", downloadable: true},
{id: 418, name: "Buizel", downloadable: true},
{id: 419, name: "Floatzel", downloadable: true},
@@ -447,8 +449,8 @@ const REGION_LIST = [];
{id: 433, name: "Chingling", downloadable: true},
{id: 434, name: "Stunky", downloadable: true},
{id: 435, name: "Skuntank", downloadable: true},
{id: 436, name: "Bronzor", downloadable: true},
{id: 437, name: "Bronzong", downloadable: true},
{id: 436, name: "Bronzor", downloadable: true, gender: "unknown"},
{id: 437, name: "Bronzong", downloadable: true, gender: "unknown"},
{id: 438, name: "Bonsly", downloadable: true},
{id: 439, name: "Mime Jr.", downloadable: true},
{id: 440, name: "Happiny", downloadable: true},
@@ -473,7 +475,7 @@ const REGION_LIST = [];
{id: 459, name: "Snover", downloadable: true},
{id: 460, name: "Abomasnow", downloadable: true},
{id: 461, name: "Weavile", downloadable: true},
{id: 462, name: "Magnezone", downloadable: true},
{id: 462, name: "Magnezone", downloadable: true, gender: "unknown"},
{id: 463, name: "Lickilicky", downloadable: true},
{id: 464, name: "Rhyperior", downloadable: true},
{id: 465, name: "Tangrowth", downloadable: true},
@@ -485,29 +487,29 @@ const REGION_LIST = [];
{id: 471, name: "Glaceon", downloadable: true},
{id: 472, name: "Gliscor", downloadable: true},
{id: 473, name: "Mamoswine", downloadable: true},
{id: 474, name: "Porygon-Z", downloadable: true},
{id: 475, name: "Gallade", downloadable: true},
{id: 474, name: "Porygon-Z", downloadable: true, gender: "unknown"},
{id: 475, name: "Gallade", downloadable: true, gender: "male"},
{id: 476, name: "Probopass", downloadable: true},
{id: 477, name: "Dusknoir", downloadable: true},
{id: 478, name: "Froslass", downloadable: true},
{id: 479, name: "Rotom", downloadable: true, forms: ["Normal", "Heat", "Wash", "Frost", "Fan", "Mow"]},
{id: 480, name: "Uxie", downloadable: true},
{id: 481, name: "Mesprit", downloadable: true},
{id: 482, name: "Azelf", downloadable: true},
{id: 483, name: "Dialga", downloadable: true},
{id: 484, name: "Palkia", downloadable: true},
{id: 478, name: "Froslass", downloadable: true, gender: "female"},
{id: 479, name: "Rotom", downloadable: true, gender: "unknown", forms: ["Normal", "Heat", "Wash", "Frost", "Fan", "Mow"]},
{id: 480, name: "Uxie", downloadable: true, gender: "unknown"},
{id: 481, name: "Mesprit", downloadable: true, gender: "unknown"},
{id: 482, name: "Azelf", downloadable: true, gender: "unknown"},
{id: 483, name: "Dialga", downloadable: true, gender: "unknown"},
{id: 484, name: "Palkia", downloadable: true, gender: "unknown"},
{id: 485, name: "Heatran", downloadable: true},
{id: 486, name: "Regigigas", downloadable: true},
{id: 487, name: "Giratina", downloadable: true, forms: ["Altered", "Origin"]},
{id: 488, name: "Cresselia", downloadable: true},
{id: 489, name: "Phione", downloadable: true},
{id: 490, name: "Manaphy", downloadable: true},
{id: 491, name: "Darkrai", downloadable: true},
{id: 492, name: "Shaymin", downloadable: true},
{id: 493, name: "Arceus", downloadable: true, forms: [
"Normal", "Fighting", "Flying", "Poison", "Ground", "Rock", "Bug", "Ghost", "Steel",
"Fire", "Water", "Grass", "Electric", "Psychic", "Ice", "Dragon", "Dark"]},
{id: 494, name: "Victini", downloadable: true},
{id: 486, name: "Regigigas", downloadable: true, gender: "unknown"},
{id: 487, name: "Giratina", downloadable: true, gender: "unknown", forms: ["Altered", "Origin"]},
{id: 488, name: "Cresselia", downloadable: true, gender: "female"},
{id: 489, name: "Phione", downloadable: true, gender: "unknown"},
{id: 490, name: "Manaphy", downloadable: true, gender: "unknown"},
{id: 491, name: "Darkrai", downloadable: true, gender: "unknown"},
{id: 492, name: "Shaymin", downloadable: true, gender: "unknown", forms: ["Land", "Sky"]},
{id: 493, name: "Arceus", downloadable: true, gender: "unknown", forms: [
"Normal", "Fighting", "Flying", "Poison", "Ground", "Rock", "Bug", "Ghost",
"Steel", "Fire", "Water", "Grass", "Electric", "Psychic", "Ice", "Dragon", "Dark"]},
{id: 494, name: "Victini", downloadable: true, gender: "unknown"},
{id: 495, name: "Snivy", downloadable: false},
{id: 496, name: "Servine", downloadable: false},
{id: 497, name: "Serperior", downloadable: false},
@@ -551,8 +553,8 @@ const REGION_LIST = [];
{id: 535, name: "Tympole", downloadable: true},
{id: 536, name: "Palpitoad", downloadable: false},
{id: 537, name: "Seismitoad", downloadable: false},
{id: 538, name: "Throh", downloadable: true},
{id: 539, name: "Sawk", downloadable: true},
{id: 538, name: "Throh", downloadable: true, gender: "male"},
{id: 539, name: "Sawk", downloadable: true, gender: "male"},
{id: 540, name: "Sewaddle", downloadable: false},
{id: 541, name: "Swadloon", downloadable: false},
{id: 542, name: "Leavanny", downloadable: true},
@@ -561,8 +563,8 @@ const REGION_LIST = [];
{id: 545, name: "Scolipede", downloadable: true},
{id: 546, name: "Cottonee", downloadable: true},
{id: 547, name: "Whimsicott", downloadable: false},
{id: 548, name: "Petilil", downloadable: true},
{id: 549, name: "Lilligant", downloadable: false},
{id: 548, name: "Petilil", downloadable: true, gender: "female"},
{id: 549, name: "Lilligant", downloadable: false, gender: "female"},
{id: 550, name: "Basculin", downloadable: true, forms: ["Red-striped", "Blue-striped"]},
{id: 551, name: "Sandile", downloadable: false},
{id: 552, name: "Krokorok", downloadable: false},
@@ -612,9 +614,9 @@ const REGION_LIST = [];
{id: 596, name: "Galvantula", downloadable: true},
{id: 597, name: "Ferroseed", downloadable: false},
{id: 598, name: "Ferrothorn", downloadable: false},
{id: 599, name: "Klink", downloadable: false},
{id: 600, name: "Klang", downloadable: true},
{id: 601, name: "Klinklang", downloadable: false},
{id: 599, name: "Klink", downloadable: false, gender: "unknown"},
{id: 600, name: "Klang", downloadable: true, gender: "unknown"},
{id: 601, name: "Klinklang", downloadable: false, gender: "unknown"},
{id: 602, name: "Tynamo", downloadable: false},
{id: 603, name: "Eelektrik", downloadable: false},
{id: 604, name: "Eelektross", downloadable: false},
@@ -628,22 +630,22 @@ const REGION_LIST = [];
{id: 612, name: "Haxorus", downloadable: false},
{id: 613, name: "Cubchoo", downloadable: true},
{id: 614, name: "Beartic", downloadable: false},
{id: 615, name: "Cryogonal", downloadable: false},
{id: 615, name: "Cryogonal", downloadable: false, gender: "unknown"},
{id: 616, name: "Shelmet", downloadable: true},
{id: 617, name: "Accelgor", downloadable: false},
{id: 618, name: "Stunfisk", downloadable: true},
{id: 619, name: "Mienfoo", downloadable: true},
{id: 620, name: "Mienshao", downloadable: false},
{id: 621, name: "Druddigon", downloadable: true},
{id: 622, name: "Golett", downloadable: true},
{id: 623, name: "Golurk", downloadable: false},
{id: 622, name: "Golett", downloadable: true, gender: "unknown"},
{id: 623, name: "Golurk", downloadable: false, gender: "unknown"},
{id: 624, name: "Pawniard", downloadable: true},
{id: 625, name: "Bisharp", downloadable: false},
{id: 626, name: "Bouffalant", downloadable: true},
{id: 627, name: "Rufflet", downloadable: false},
{id: 628, name: "Braviary", downloadable: true},
{id: 629, name: "Vullaby", downloadable: false},
{id: 630, name: "Mandibuzz", downloadable: true},
{id: 627, name: "Rufflet", downloadable: false, gender: "male"},
{id: 628, name: "Braviary", downloadable: true, gender: "male"},
{id: 629, name: "Vullaby", downloadable: false, gender: "female"},
{id: 630, name: "Mandibuzz", downloadable: true, gender: "female"},
{id: 631, name: "Heatmor", downloadable: true},
{id: 632, name: "Durant", downloadable: true},
{id: 633, name: "Deino", downloadable: false},
@@ -651,18 +653,18 @@ const REGION_LIST = [];
{id: 635, name: "Hydreigon", downloadable: false},
{id: 636, name: "Larvesta", downloadable: false},
{id: 637, name: "Volcarona", downloadable: false},
{id: 638, name: "Cobalion", downloadable: false},
{id: 639, name: "Terrakion", downloadable: false},
{id: 640, name: "Virizion", downloadable: false},
{id: 641, name: "Tornadus", downloadable: false, forms: ["Incarnate", "Therian"]},
{id: 642, name: "Thundurus", downloadable: false, forms: ["Incarnate", "Therian"]},
{id: 643, name: "Reshiram", downloadable: false},
{id: 644, name: "Zekrom", downloadable: false},
{id: 645, name: "Landorus", downloadable: false, forms: ["Incarnate", "Therian"]},
{id: 646, name: "Kyurem", downloadable: false, forms: ["Normal", "White", "Black"]},
{id: 647, name: "Keldeo", downloadable: false, forms: ["Ordinary", "Resolute"]},
{id: 648, name: "Meloetta", downloadable: false, forms: ["Aria", "Pirouette"]},
{id: 649, name: "Genesect", downloadable: false, forms: ["Normal", "Douse", "Shock", "Burn", "Chill"]}
{id: 638, name: "Cobalion", downloadable: false, gender: "unknown"},
{id: 639, name: "Terrakion", downloadable: false, gender: "unknown"},
{id: 640, name: "Virizion", downloadable: false, gender: "unknown"},
{id: 641, name: "Tornadus", downloadable: false, gender: "male", forms: ["Incarnate", "Therian"]},
{id: 642, name: "Thundurus", downloadable: false, gender: "male", forms: ["Incarnate", "Therian"]},
{id: 643, name: "Reshiram", downloadable: false, gender: "unknown"},
{id: 644, name: "Zekrom", downloadable: false, gender: "unknown"},
{id: 645, name: "Landorus", downloadable: false, gender: "male", forms: ["Incarnate", "Therian"]},
{id: 646, name: "Kyurem", downloadable: false, gender: "unknown", forms: ["Normal", "White", "Black"]},
{id: 647, name: "Keldeo", downloadable: false, gender: "unknown", forms: ["Ordinary", "Resolute"]},
{id: 648, name: "Meloetta", downloadable: false, gender: "unknown", forms: ["Aria", "Pirouette"]},
{id: 649, name: "Genesect", downloadable: false, gender: "unknown", forms: ["Normal", "Douse", "Shock", "Burn", "Chill"]}
];
// Moves
@@ -1228,6 +1230,174 @@ const REGION_LIST = [];
{id: 559, name: "Fusion Bolt"}
];
// Abilities
let abilities = [
{id: 1, name: "Stench"},
{id: 2, name: "Drizzle"},
{id: 3, name: "Speed Boost"},
{id: 4, name: "Battle Armor"},
{id: 5, name: "Sturdy"},
{id: 6, name: "Damp"},
{id: 7, name: "Limber"},
{id: 8, name: "Sand Veil"},
{id: 9, name: "Static"},
{id: 10, name: "Volt Absorb"},
{id: 11, name: "Water Absorb"},
{id: 12, name: "Oblivious"},
{id: 13, name: "Cloud Nine"},
{id: 14, name: "Compound Eyes"},
{id: 15, name: "Insomnia"},
{id: 16, name: "Color Change"},
{id: 17, name: "Immunity"},
{id: 18, name: "Flash Fire"},
{id: 19, name: "Shield Dust"},
{id: 20, name: "Own Tempo"},
{id: 21, name: "Suction Cups"},
{id: 22, name: "Intimidate"},
{id: 23, name: "Shadow Tag"},
{id: 24, name: "Rough Skin"},
{id: 25, name: "Wonder Guard"},
{id: 26, name: "Levitate"},
{id: 27, name: "Effect Spore"},
{id: 28, name: "Synchronize"},
{id: 29, name: "Clear Body"},
{id: 30, name: "Natural Cure"},
{id: 31, name: "Lightning Rod"},
{id: 32, name: "Serene Grace"},
{id: 33, name: "Swift Swim"},
{id: 34, name: "Chlorophyll"},
{id: 35, name: "Illuminate"},
{id: 36, name: "Trace"},
{id: 37, name: "Huge Power"},
{id: 38, name: "Poison Point"},
{id: 39, name: "Inner Focus"},
{id: 40, name: "Magma Armor"},
{id: 41, name: "Water Veil"},
{id: 42, name: "Magnet Pull"},
{id: 43, name: "Soundproof"},
{id: 44, name: "Rain Dish"},
{id: 45, name: "Sand Stream"},
{id: 46, name: "Pressure"},
{id: 47, name: "Thick Fat"},
{id: 48, name: "Early Bird"},
{id: 49, name: "Flame Body"},
{id: 50, name: "Run Away"},
{id: 51, name: "Keen Eye"},
{id: 52, name: "Hyper Cutter"},
{id: 53, name: "Pickup"},
{id: 54, name: "Truant"},
{id: 55, name: "Hustle"},
{id: 56, name: "Cute Charm"},
{id: 57, name: "Plus"},
{id: 58, name: "Minus"},
{id: 59, name: "Forecast"},
{id: 60, name: "Sticky Hold"},
{id: 61, name: "Shed Skin"},
{id: 62, name: "Guts"},
{id: 63, name: "Marvel Scale"},
{id: 64, name: "Liquid Ooze"},
{id: 65, name: "Overgrow"},
{id: 66, name: "Blaze"},
{id: 67, name: "Torrent"},
{id: 68, name: "Swarm"},
{id: 69, name: "Rock Head"},
{id: 70, name: "Drought"},
{id: 71, name: "Arena Trap"},
{id: 72, name: "Vital Spirit"},
{id: 73, name: "White Smoke"},
{id: 74, name: "Pure Power"},
{id: 75, name: "Shell Armor"},
{id: 76, name: "Air Lock"},
{id: 77, name: "Tangled Feet"},
{id: 78, name: "Motor Drive"},
{id: 79, name: "Rivalry"},
{id: 80, name: "Steadfast"},
{id: 81, name: "Snow Cloak"},
{id: 82, name: "Gluttony"},
{id: 83, name: "Anger Point"},
{id: 84, name: "Unburden"},
{id: 85, name: "Heatproof"},
{id: 86, name: "Simple"},
{id: 87, name: "Dry Skin"},
{id: 88, name: "Download"},
{id: 89, name: "Iron Fist"},
{id: 90, name: "Poison Heal"},
{id: 91, name: "Adaptability"},
{id: 92, name: "Skill Link"},
{id: 93, name: "Hydration"},
{id: 94, name: "Solar Power"},
{id: 95, name: "Quick Feet"},
{id: 96, name: "Normalize"},
{id: 97, name: "Sniper"},
{id: 98, name: "Magic Guard"},
{id: 99, name: "No Guard"},
{id: 100, name: "Stall"},
{id: 101, name: "Technician"},
{id: 102, name: "Leaf Guard"},
{id: 103, name: "Klutz"},
{id: 104, name: "Mold Breaker"},
{id: 105, name: "Super Luck"},
{id: 106, name: "Aftermath"},
{id: 107, name: "Anticipation"},
{id: 108, name: "Forewarn"},
{id: 109, name: "Unaware"},
{id: 110, name: "Tinted Lens"},
{id: 111, name: "Filter"},
{id: 112, name: "Slow Start"},
{id: 113, name: "Scrappy"},
{id: 114, name: "Storm Drain"},
{id: 115, name: "Ice Body"},
{id: 116, name: "Solid Rock"},
{id: 117, name: "Snow Warning"},
{id: 118, name: "Honey Gather"},
{id: 119, name: "Frisk"},
{id: 120, name: "Reckless"},
{id: 121, name: "Multitype"},
{id: 122, name: "Flower Gift"},
{id: 123, name: "Bad Dreams"},
{id: 124, name: "Pickpocket"},
{id: 125, name: "Sheer Force"},
{id: 126, name: "Contrary"},
{id: 127, name: "Unnerve"},
{id: 128, name: "Defiant"},
{id: 129, name: "Defeatist"},
{id: 130, name: "Cursed Body"},
{id: 131, name: "Healer"},
{id: 132, name: "Friend Guard"},
{id: 133, name: "Weak Armor"},
{id: 134, name: "Heavy Metal"},
{id: 135, name: "Light Metal"},
{id: 136, name: "Multiscale"},
{id: 137, name: "Toxic Boost"},
{id: 138, name: "Flare Boost"},
{id: 139, name: "Harvest"},
{id: 140, name: "Telepathy"},
{id: 141, name: "Moody"},
{id: 142, name: "Overcoat"},
{id: 143, name: "Poison Touch"},
{id: 144, name: "Regenerator"},
{id: 145, name: "Big Pecks"},
{id: 146, name: "Sand Rush"},
{id: 147, name: "Wonder Skin"},
{id: 148, name: "Analytic"},
{id: 149, name: "Illusion"},
{id: 150, name: "Imposter"},
{id: 151, name: "Infiltrator"},
{id: 152, name: "Mummy"},
{id: 153, name: "Moxie"},
{id: 154, name: "Justified"},
{id: 155, name: "Rattled"},
{id: 156, name: "Magic Bounce"},
{id: 157, name: "Sap Sipper"},
{id: 158, name: "Prankster"},
{id: 159, name: "Sand Force"},
{id: 160, name: "Iron Barbs"},
{id: 161, name: "Zen Mode"},
{id: 162, name: "Victory Star"},
{id: 163, name: "Turboblaze"},
{id: 164, name: "Teravolt"}
];
// Items
let items = [
{id: 1, name: "Master Ball"},
@@ -2390,14 +2560,20 @@ const REGION_LIST = [];
// Index data
for(let i in species) {
let entry = species[i];
POKE_SPECIES_MAP[entry.id] = entry;
POKE_SPECIES_LIST[i] = entry;
SPECIES_MAP[entry.id] = entry;
SPECIES_LIST[i] = entry;
}
for(let i in moves) {
let move = moves[i];
POKE_MOVE_MAP[move.id] = move;
POKE_MOVE_LIST[i] = move;
MOVE_MAP[move.id] = move;
MOVE_LIST[i] = move;
}
for(let i in abilities) {
let ability = abilities[i];
ABILITY_MAP[ability.id] = ability;
ABILITY_LIST[i] = ability;
}
for(let i in items) {

View File

@@ -3,6 +3,7 @@ const ELEMENT_GAME_SUMMARY = document.getElementById("game-summary");
const ELEMENT_DREAMER_SPRITE = document.getElementById("dreamer-sprite");
const ELEMENT_DREAMER_SPECIES = document.getElementById("dreamer-species");
const ELEMENT_DREAMER_ABILITY = document.getElementById("dreamer-ability");
const ELEMENT_DREAMER_NATURE = document.getElementById("dreamer-nature");
const ELEMENT_DREAMER_NAME = document.getElementById("dreamer-name");
const ELEMENT_DREAMER_GENDER = document.getElementById("dreamer-gender");
@@ -10,15 +11,18 @@ const ELEMENT_DREAMER_TRAINER = document.getElementById("dreamer-trainer");
const ELEMENT_DREAMER_TRAINER_ID = document.getElementById("dreamer-trainer-id");
const ELEMENT_DREAMER_LEVEL = document.getElementById("dreamer-level");
const ELEMENT_ENCOUNTER_CONFIG = document.getElementById("encounter-config");
const ELEMENT_ENCOUNTER_SPECIES = document.getElementById("encounter-form-species");
const ELEMENT_ENCOUNTER_MOVE = document.getElementById("encounter-form-move");
const ELEMENT_ENCOUNTER_FORM = document.getElementById("encounter-form-form");
const ELEMENT_ENCOUNTER_GENDER = document.getElementById("encounter-form-gender");
const ELEMENT_ENCOUNTER_ANIMATION = document.getElementById("encounter-form-animation");
const ELEMENT_ITEM_CONFIG = document.getElementById("item-config");
const ELEMENT_ITEM_ID = document.getElementById("item-form-id");
const ELEMENT_ITEM_QUANTITY = document.getElementById("item-form-quantity");
const ELEMENT_VISITOR_CONFIG = document.getElementById("visitor-config");
const ELEMENT_VISITOR_NAME = document.getElementById("visitor-form-name");
const ELEMENT_VISITOR_TYPE = document.getElementById("visitor-form-type");
const ELEMENT_VISITOR_SHOP_TYPE = document.getElementById("visitor-form-shop-type");
@@ -59,7 +63,8 @@ var profile = {
if(response.dreamerInfo) {
let dreamerInfo = response.dreamerInfo;
ELEMENT_DREAMER_SPRITE.innerHTML = "<image src='" + response.dreamerSprite + "'/>";
ELEMENT_DREAMER_SPECIES.innerHTML = POKE_SPECIES_LIST[dreamerInfo.species - 1].name;
ELEMENT_DREAMER_SPECIES.innerHTML = SPECIES_MAP[dreamerInfo.species] ? (SPECIES_MAP[dreamerInfo.species].name) : "N/A";
ELEMENT_DREAMER_ABILITY.innerHTML = ABILITY_MAP[dreamerInfo.ability] ? ABILITY_MAP[dreamerInfo.ability].name : "N/A";
ELEMENT_DREAMER_NATURE.innerHTML = stringToWord(dreamerInfo.nature);
ELEMENT_DREAMER_NAME.innerHTML = dreamerInfo.nickname;
ELEMENT_DREAMER_GENDER.innerHTML = stringToWord(dreamerInfo.gender);
@@ -103,8 +108,8 @@ var profile = {
});
// Sort data lists alphabetically
let sortedSpecies = [...POKE_SPECIES_LIST].sort((a, b) => a.name.localeCompare(b.name));
let sortedMoves = [...POKE_MOVE_LIST].sort((a, b) => a.name.localeCompare(b.name));
let sortedSpecies = [...SPECIES_LIST].sort((a, b) => a.name.localeCompare(b.name));
let sortedMoves = [...MOVE_LIST].sort((a, b) => a.name.localeCompare(b.name));
let sortedItems = [...ITEM_LIST].sort((a, b) => a.name.localeCompare(b.name));
// Add species data
@@ -138,10 +143,10 @@ var profile = {
ELEMENT_VISITOR_REGION.options[ELEMENT_VISITOR_REGION.options.length] = new Option(region.name, region.id);
}
// Event listener for changing the form selector contents when species changes
// Event listener for changing the form & gender selector contents when species changes
ELEMENT_ENCOUNTER_SPECIES.addEventListener("change", function() {
updateEncounterFormOptions();
ELEMENT_ENCOUNTER_FORM.value = 0;
ELEMENT_ENCOUNTER_FORM.value = updateEncounterFormOptions();
ELEMENT_ENCOUNTER_GENDER.value = updateEncounterGenderOptions();
});
// Same thing, but for Join Avenue visitor region & subregion
@@ -156,7 +161,7 @@ var profile = {
function updateEncounterFormOptions() {
clearSelectOptions(ELEMENT_ENCOUNTER_FORM);
let species = POKE_SPECIES_MAP[ELEMENT_ENCOUNTER_SPECIES.value];
let species = SPECIES_MAP[ELEMENT_ENCOUNTER_SPECIES.value];
// Update special form options
if(species.forms) {
@@ -166,17 +171,47 @@ function updateEncounterFormOptions() {
} else {
ELEMENT_ENCOUNTER_FORM.options[ELEMENT_ENCOUNTER_FORM.options.length] = new Option("N/A", 0);
}
return 0;
}
function updateEncounterGenderOptions() {
clearSelectOptions(ELEMENT_ENCOUNTER_GENDER);
let species = SPECIES_MAP[ELEMENT_ENCOUNTER_SPECIES.value];
// Update gender options
if(species.gender) {
console.log(species.gender);
switch(species.gender) {
case "male":
ELEMENT_ENCOUNTER_GENDER.options[0] = new Option("Male", "MALE");
return "MALE";
case "female":
ELEMENT_ENCOUNTER_GENDER.options[0] = new Option("Female", "FEMALE");
return "FEMALE";
case "unknown":
ELEMENT_ENCOUNTER_GENDER.options[0] = new Option("N/A", "GENDERLESS");
return "GENDERLESS";
}
}
ELEMENT_ENCOUNTER_GENDER.options[0] = new Option("Male", "MALE");
ELEMENT_ENCOUNTER_GENDER.options[1] = new Option("Female", "FEMALE");
ELEMENT_ENCOUNTER_GENDER.options[2] = new Option("Random", "GENDERLESS");
return "GENDERLESS";
}
function configureEncounter(index) {
encounterTableIndex = Math.min(10, Math.min(index, profile.encounters.length));
let encounter = profile.encounters[encounterTableIndex];
ELEMENT_ENCOUNTER_SPECIES.value = encounter ? encounter.species : 1;
updateEncounterFormOptions();
ELEMENT_ENCOUNTER_SPECIES.value = encounter ? encounter.species : 493;
let form = updateEncounterFormOptions();
let gender = updateEncounterGenderOptions();
ELEMENT_ENCOUNTER_MOVE.value = encounter ? encounter.move : 0;
ELEMENT_ENCOUNTER_FORM.value = encounter ? encounter.form : 0;
ELEMENT_ENCOUNTER_GENDER.value = encounter ? encounter.gender : "GENDERLESS";
ELEMENT_ENCOUNTER_ANIMATION.value = encounter ? encounter.animation : "WALK_AROUND";
ELEMENT_ENCOUNTER_FORM.value = encounter ? encounter.form : form;
ELEMENT_ENCOUNTER_GENDER.value = encounter ? encounter.gender : gender;
ELEMENT_ENCOUNTER_ANIMATION.value = encounter ? encounter.animation : "LOOK_AROUND";
ELEMENT_ENCOUNTER_CONFIG.style.display = "block";
}
function saveEncounter() {
@@ -223,13 +258,20 @@ function updateEncounterCell(index) {
if(encounterData) {
spriteImage = spriteBase + encounterData.species + ".png";
// Use unique form sprite if it exists
if(encounterData.form > 0) {
// Use unique form sprite if it exists
let formSpriteImage = spriteBase + encounterData.species + "-" + encounterData.form + ".png";
if(checkURL(formSpriteImage)){
spriteImage = formSpriteImage;
}
} else if(encounterData.gender == "FEMALE") {
// Otherwise, use female sprite if it exists
let femaleSpriteImage = spriteBase + "female/" + encounterData.species + ".png";
if(checkURL(femaleSpriteImage)){
spriteImage = femaleSpriteImage;
}
}
}
@@ -238,7 +280,7 @@ function updateEncounterCell(index) {
function closeEncounterForm() {
encounterTableIndex = -1;
window.location.href = "#";
ELEMENT_ENCOUNTER_CONFIG.style.display = "none";
}
/**
@@ -278,6 +320,7 @@ function configureVisitor(index) {
ELEMENT_VISITOR_SUBREGION.value = visitor ? visitor.stateProvinceCode : 0;
ELEMENT_VISITOR_PERSONALITY.value = visitor ? visitor.personality : 0;
ELEMENT_VISITOR_DREAMER.value = visitor ? visitor.dreamerSpecies : 1;
ELEMENT_VISITOR_CONFIG.style.display = "block";
}
function saveVisitor() {
@@ -355,7 +398,7 @@ function updateVisitorCell(index) {
function closeVisitorForm() {
visitorTableIndex = -1;
window.location.href = "#";
ELEMENT_VISITOR_CONFIG.style.display = "none";
}
/**
@@ -367,6 +410,7 @@ function configureItem(index) {
let item = profile.items[itemTableIndex];
ELEMENT_ITEM_ID.value = item ? item.id : 1;
ELEMENT_ITEM_QUANTITY.value = item ? item.quantity : 1;
ELEMENT_ITEM_CONFIG.style.display = "block";
}
function saveItem() {
@@ -422,7 +466,7 @@ function updateItemCell(index) {
function closeItemForm() {
itemTableIndex = -1;
window.location.href = "#";
ELEMENT_ITEM_CONFIG.style.display = "none";
}
/**

View File

@@ -100,20 +100,13 @@ a:link, a:visited {
}
.popup {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
opacity: 0;
transition: opacity 200ms;
visibility: hidden;
}
.popup:target {
opacity: 1;
visibility: visible;
}
.popup .close-button {
@@ -147,6 +140,7 @@ a:link, a:visited {
width: 96px;
height: 96px;
text-align: center;
cursor: pointer;
}
.item-table {
@@ -163,6 +157,7 @@ a:link, a:visited {
width: 48px;
height: 48px;
text-align: center;
cursor: pointer;
}
.item-table td a {
@@ -185,6 +180,7 @@ a:link, a:visited {
width: 80px;
height: 80px;
text-align: center;
cursor: pointer;
}
.big-button {

Binary file not shown.