Compare commits
11 Commits
16063863d5
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32b031f734 | ||
|
|
212fdcd74f | ||
|
|
355903c1ff | ||
|
|
adf8708710 | ||
|
|
58e3c1c734 | ||
|
|
aff99a507c | ||
|
|
cc78d15068 | ||
| dd61d27d98 | |||
|
|
874dcfe450 | ||
|
|
269ad43957 | ||
|
|
74b304de1e |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -117,4 +117,5 @@ Thumbs.db
|
||||
*.dmg
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
*.log
|
||||
.specstory/
|
||||
|
||||
@@ -8,7 +8,7 @@ project(PokemonBattleSimulator
|
||||
)
|
||||
|
||||
# Set C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
|
||||
218
POKEMON_TABLE_README.md
Normal file
218
POKEMON_TABLE_README.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# Pokemon Table Implementation
|
||||
|
||||
This document describes the high-performance Pokemon data table implementation for the Pokemon Battle Simulator.
|
||||
|
||||
## Overview
|
||||
|
||||
The Pokemon Table is a high-performance data structure that provides O(1) lookup access to all Pokemon species data. It loads Pokemon data from JSON files and stores them in memory for fast runtime access.
|
||||
|
||||
## Features
|
||||
|
||||
- **O(1) ID-based lookup**: Access any Pokemon by its ID in constant time
|
||||
- **O(1) Name-based lookup**: Access any Pokemon by its name using a hash map
|
||||
- **Automatic data loading**: Loads all Pokemon data from JSON files at startup
|
||||
- **Memory efficient**: Uses contiguous memory storage for optimal cache performance
|
||||
- **Type safety**: Strongly typed with comprehensive error handling
|
||||
- **Validation**: Built-in data validation to ensure integrity
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Classes
|
||||
|
||||
#### `PokemonTable`
|
||||
The main class that manages the Pokemon data table.
|
||||
|
||||
**Key Methods:**
|
||||
- `loadFromDataDirectory()`: Loads Pokemon data from the standard data directory
|
||||
- `loadFromFiles()`: Loads Pokemon data from specific JSON files
|
||||
- `getPokemon(uint16_t id)`: O(1) lookup by Pokemon ID
|
||||
- `getPokemonByName(std::string_view name)`: O(1) lookup by Pokemon name
|
||||
- `hasPokemon(uint16_t id)`: Check if a Pokemon ID exists
|
||||
- `size()`: Get the total number of loaded Pokemon
|
||||
- `validate()`: Validate the integrity of loaded data
|
||||
|
||||
#### `PokemonSpecies`
|
||||
Struct containing all the data for a single Pokemon species.
|
||||
|
||||
**Fields:**
|
||||
- `id`: Pokemon ID (1-based)
|
||||
- `name`: Pokemon name
|
||||
- `base_stats`: Base stats (HP, Attack, Defense, SpAttack, SpDefense, Speed)
|
||||
- `types`: Primary and secondary types
|
||||
|
||||
### Global Access
|
||||
|
||||
The implementation provides a global Pokemon table instance for convenient access:
|
||||
|
||||
```cpp
|
||||
#include "core/pokemon_table.h"
|
||||
|
||||
// Initialize the global table (call once at startup)
|
||||
bool success = PokEng::initializePokemonTable();
|
||||
|
||||
// Use the global table
|
||||
const auto* bulbasaur = PokEng::g_pokemonTable->getPokemon(1);
|
||||
const auto* charizard = PokEng::g_pokemonTable->getPokemonByName("charizard");
|
||||
|
||||
// Clean up (call at shutdown)
|
||||
PokEng::shutdownPokemonTable();
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
### Benchmarks
|
||||
|
||||
Based on the example program, the Pokemon table demonstrates excellent performance:
|
||||
|
||||
- **Initialization**: ~89ms to load 1025 Pokemon species
|
||||
- **ID Lookups**: ~33,333 lookups per millisecond (100,000 lookups in 3ms)
|
||||
- **Memory Usage**: Minimal memory footprint with contiguous storage
|
||||
|
||||
### Storage Strategy
|
||||
|
||||
The table uses a hybrid storage approach for optimal performance:
|
||||
|
||||
1. **Vector storage**: Pokemon species are stored in a `std::vector<PokemonSpecies>` indexed by ID
|
||||
2. **Hash map**: Name-to-ID mapping using `std::unordered_map` for fast name lookups
|
||||
3. **Index 0 unused**: Vector index 0 is unused, so Pokemon with ID 1 is at index 1
|
||||
|
||||
This approach provides:
|
||||
- O(1) ID lookups via direct vector indexing
|
||||
- O(1) average case name lookups via hash table
|
||||
- Excellent cache locality for ID-based access patterns
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```cpp
|
||||
#include "core/pokemon_table.h"
|
||||
|
||||
int main() {
|
||||
// Initialize the Pokemon table
|
||||
if (!PokEng::initializePokemonTable()) {
|
||||
std::cerr << "Failed to load Pokemon data!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Look up Pokemon by ID
|
||||
const auto* pikachu = PokEng::g_pokemonTable->getPokemon(25);
|
||||
if (pikachu) {
|
||||
std::cout << "Pikachu's speed: " << pikachu->base_stats.speed << std::endl;
|
||||
std::cout << "Pikachu's type: " << PokEng::TypeUtils::typeToString(pikachu->types.getPrimary()) << std::endl;
|
||||
}
|
||||
|
||||
// Look up Pokemon by name
|
||||
const auto* charizard = PokEng::g_pokemonTable->getPokemonByName("charizard");
|
||||
if (charizard) {
|
||||
std::cout << "Charizard ID: " << charizard->id << std::endl;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
PokEng::shutdownPokemonTable();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Advanced Usage
|
||||
|
||||
```cpp
|
||||
// Check if Pokemon exists
|
||||
if (PokEng::g_pokemonTable->hasPokemon(150)) {
|
||||
const auto* mewtwo = PokEng::g_pokemonTable->getPokemon(150);
|
||||
// Use mewtwo data...
|
||||
}
|
||||
|
||||
// Iterate through all Pokemon
|
||||
for (uint16_t id = 1; id <= PokEng::g_pokemonTable->getMaxId(); ++id) {
|
||||
const auto* pokemon = PokEng::g_pokemonTable->getPokemon(id);
|
||||
if (pokemon) {
|
||||
// Process pokemon...
|
||||
}
|
||||
}
|
||||
|
||||
// Get all Pokemon at once (for bulk operations)
|
||||
const auto& allPokemon = PokEng::g_pokemonTable->getAllPokemon();
|
||||
for (const auto& pokemon : allPokemon) {
|
||||
if (pokemon.id != 0) { // Skip empty entries
|
||||
// Process pokemon...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Data Loading
|
||||
|
||||
The Pokemon table automatically loads data from JSON files in the `data/pokemon/` directory:
|
||||
|
||||
- `generation-i.json` through `generation-ix.json`
|
||||
- Each file contains Pokemon from a specific generation
|
||||
- Data is validated during loading
|
||||
|
||||
### JSON Format
|
||||
|
||||
Each Pokemon entry in the JSON files has the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"name": "bulbasaur",
|
||||
"height": 7,
|
||||
"weight": 69,
|
||||
"base_experience": 64,
|
||||
"types": ["grass", "poison"],
|
||||
"stats": {
|
||||
"hp": 45,
|
||||
"attack": 49,
|
||||
"defense": 49,
|
||||
"special-attack": 65,
|
||||
"special-defense": 65,
|
||||
"speed": 45
|
||||
},
|
||||
"abilities": [...],
|
||||
"species": {...}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The implementation includes comprehensive error handling:
|
||||
|
||||
- **File loading errors**: Graceful handling of missing or corrupted JSON files
|
||||
- **JSON parsing errors**: Detailed error messages for malformed JSON
|
||||
- **Data validation**: Built-in validation to ensure data integrity
|
||||
- **Memory safety**: Proper resource management with RAII
|
||||
|
||||
## Testing
|
||||
|
||||
The implementation includes comprehensive unit tests covering:
|
||||
|
||||
- Data loading and initialization
|
||||
- ID-based and name-based lookups
|
||||
- Error handling for invalid inputs
|
||||
- Performance validation
|
||||
- Data integrity validation
|
||||
|
||||
Run tests with:
|
||||
```bash
|
||||
cd build
|
||||
make test
|
||||
```
|
||||
|
||||
## Integration
|
||||
|
||||
The Pokemon table is designed to integrate seamlessly with other components:
|
||||
|
||||
- **Pokemon creation**: Use table data to create Pokemon instances
|
||||
- **Battle calculations**: Fast access to base stats and types
|
||||
- **Type effectiveness**: Integration with type system for damage calculations
|
||||
- **Stat calculations**: Base stats for battle stat computations
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements for the Pokemon table:
|
||||
|
||||
1. **Lazy loading**: Load Pokemon data on-demand to reduce startup time
|
||||
2. **Compressed storage**: Use compression to reduce memory footprint
|
||||
3. **Multi-threading**: Parallel loading of Pokemon data
|
||||
4. **Caching**: Implement LRU cache for frequently accessed Pokemon
|
||||
5. **Serialization**: Save/load compiled Pokemon data for faster startup
|
||||
2
Prompts/6-pokemonTable
Normal file
2
Prompts/6-pokemonTable
Normal file
@@ -0,0 +1,2 @@
|
||||
This repo is the start of a highly performant pokemon battle simulator.
|
||||
I want you to implement a pokemon data table that contains all PokemonSpecies. So we can easily access any pokemon using it's ID during runtime.
|
||||
@@ -29,7 +29,7 @@ A high-performance C++ library for simulating Pokemon battles from Generation 1
|
||||
|
||||
## Build Requirements
|
||||
|
||||
- C++17 or later
|
||||
- C++20 or later
|
||||
- CMake 3.15+
|
||||
- Python 3.8+ (for tooling)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ cmake/
|
||||
- **Profile**: Special build for performance profiling
|
||||
|
||||
### Compiler Support
|
||||
- **GCC 9+**: Primary compiler with full C++17 support
|
||||
- **GCC 9+**: Primary compiler with full C++20 support
|
||||
- **Clang 10+**: Alternative compiler with excellent diagnostics
|
||||
- **MSVC 2019+**: Windows support with Visual Studio
|
||||
- **Cross-compilation**: Support for different target architectures
|
||||
|
||||
@@ -6,7 +6,11 @@ function(set_project_warnings)
|
||||
add_compile_options(
|
||||
/W4
|
||||
/permissive-
|
||||
/std:c++20 # Explicitly enable C++20 standard
|
||||
$<$<BOOL:${WARNINGS_AS_ERRORS}>:/WX>
|
||||
# Disable specific warnings that are too strict
|
||||
/wd4244 # conversion from 'int' to 'char', possible loss of data
|
||||
/wd4996 # 'fopen': This function or variable may be unsafe
|
||||
)
|
||||
else()
|
||||
add_compile_options(
|
||||
|
||||
30688
data/all_moves.json
Normal file
30688
data/all_moves.json
Normal file
File diff suppressed because it is too large
Load Diff
5777
data/moves/generation-i.json
Normal file
5777
data/moves/generation-i.json
Normal file
File diff suppressed because it is too large
Load Diff
8787
data/moves/generation-ii.json
Normal file
8787
data/moves/generation-ii.json
Normal file
File diff suppressed because it is too large
Load Diff
12680
data/moves/generation-iii.json
Normal file
12680
data/moves/generation-iii.json
Normal file
File diff suppressed because it is too large
Load Diff
16635
data/moves/generation-iv.json
Normal file
16635
data/moves/generation-iv.json
Normal file
File diff suppressed because it is too large
Load Diff
30688
data/moves/generation-ix.json
Normal file
30688
data/moves/generation-ix.json
Normal file
File diff suppressed because it is too large
Load Diff
19855
data/moves/generation-v.json
Normal file
19855
data/moves/generation-v.json
Normal file
File diff suppressed because it is too large
Load Diff
22025
data/moves/generation-vi.json
Normal file
22025
data/moves/generation-vi.json
Normal file
File diff suppressed because it is too large
Load Diff
26260
data/moves/generation-vii.json
Normal file
26260
data/moves/generation-vii.json
Normal file
File diff suppressed because it is too large
Load Diff
29584
data/moves/generation-viii.json
Normal file
29584
data/moves/generation-viii.json
Normal file
File diff suppressed because it is too large
Load Diff
6121
data/pokemon/generation-i.json
Normal file
6121
data/pokemon/generation-i.json
Normal file
File diff suppressed because it is too large
Load Diff
4056
data/pokemon/generation-ii.json
Normal file
4056
data/pokemon/generation-ii.json
Normal file
File diff suppressed because it is too large
Load Diff
5258
data/pokemon/generation-iii.json
Normal file
5258
data/pokemon/generation-iii.json
Normal file
File diff suppressed because it is too large
Load Diff
4169
data/pokemon/generation-iv.json
Normal file
4169
data/pokemon/generation-iv.json
Normal file
File diff suppressed because it is too large
Load Diff
4574
data/pokemon/generation-ix.json
Normal file
4574
data/pokemon/generation-ix.json
Normal file
File diff suppressed because it is too large
Load Diff
6258
data/pokemon/generation-v.json
Normal file
6258
data/pokemon/generation-v.json
Normal file
File diff suppressed because it is too large
Load Diff
2802
data/pokemon/generation-vi.json
Normal file
2802
data/pokemon/generation-vi.json
Normal file
File diff suppressed because it is too large
Load Diff
3288
data/pokemon/generation-vii.json
Normal file
3288
data/pokemon/generation-vii.json
Normal file
File diff suppressed because it is too large
Load Diff
3768
data/pokemon/generation-viii.json
Normal file
3768
data/pokemon/generation-viii.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,221 +0,0 @@
|
||||
{
|
||||
"2": {
|
||||
"id": 2,
|
||||
"name": "ivysaur",
|
||||
"types": [
|
||||
"grass",
|
||||
"poison"
|
||||
],
|
||||
"base_stats": {
|
||||
"hp": 60,
|
||||
"attack": 62,
|
||||
"defense": 63,
|
||||
"special_attack": 80,
|
||||
"special_defense": 80,
|
||||
"speed": 60
|
||||
},
|
||||
"abilities": [
|
||||
"overgrow",
|
||||
"chlorophyll"
|
||||
],
|
||||
"moves": [
|
||||
14,
|
||||
15,
|
||||
20,
|
||||
22,
|
||||
29,
|
||||
33,
|
||||
34,
|
||||
36,
|
||||
38,
|
||||
45,
|
||||
46,
|
||||
70,
|
||||
72,
|
||||
73,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
92,
|
||||
99,
|
||||
102,
|
||||
104,
|
||||
111,
|
||||
113,
|
||||
115,
|
||||
117,
|
||||
133,
|
||||
148,
|
||||
156,
|
||||
164,
|
||||
173,
|
||||
174,
|
||||
182,
|
||||
188,
|
||||
189,
|
||||
200,
|
||||
202,
|
||||
203,
|
||||
204,
|
||||
206,
|
||||
207,
|
||||
210,
|
||||
213,
|
||||
214,
|
||||
216,
|
||||
218,
|
||||
219,
|
||||
230,
|
||||
235,
|
||||
237,
|
||||
241,
|
||||
249,
|
||||
263,
|
||||
267,
|
||||
270,
|
||||
275,
|
||||
282,
|
||||
290,
|
||||
311,
|
||||
331,
|
||||
345,
|
||||
363,
|
||||
388,
|
||||
402,
|
||||
412,
|
||||
437,
|
||||
438,
|
||||
445,
|
||||
447,
|
||||
474,
|
||||
491,
|
||||
496,
|
||||
497,
|
||||
520,
|
||||
526,
|
||||
580,
|
||||
590,
|
||||
803,
|
||||
851,
|
||||
885
|
||||
],
|
||||
"weight": 130,
|
||||
"height": 10,
|
||||
"base_experience": 142
|
||||
},
|
||||
"1": {
|
||||
"id": 1,
|
||||
"name": "bulbasaur",
|
||||
"types": [
|
||||
"grass",
|
||||
"poison"
|
||||
],
|
||||
"base_stats": {
|
||||
"hp": 45,
|
||||
"attack": 49,
|
||||
"defense": 49,
|
||||
"special_attack": 65,
|
||||
"special_defense": 65,
|
||||
"speed": 45
|
||||
},
|
||||
"abilities": [
|
||||
"overgrow",
|
||||
"chlorophyll"
|
||||
],
|
||||
"moves": [
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
20,
|
||||
22,
|
||||
29,
|
||||
33,
|
||||
34,
|
||||
36,
|
||||
38,
|
||||
45,
|
||||
70,
|
||||
72,
|
||||
73,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
92,
|
||||
99,
|
||||
102,
|
||||
104,
|
||||
111,
|
||||
113,
|
||||
115,
|
||||
117,
|
||||
124,
|
||||
130,
|
||||
133,
|
||||
148,
|
||||
156,
|
||||
164,
|
||||
173,
|
||||
174,
|
||||
182,
|
||||
188,
|
||||
189,
|
||||
200,
|
||||
202,
|
||||
203,
|
||||
204,
|
||||
206,
|
||||
207,
|
||||
210,
|
||||
213,
|
||||
214,
|
||||
216,
|
||||
218,
|
||||
219,
|
||||
230,
|
||||
235,
|
||||
237,
|
||||
241,
|
||||
249,
|
||||
263,
|
||||
267,
|
||||
270,
|
||||
275,
|
||||
282,
|
||||
290,
|
||||
311,
|
||||
320,
|
||||
331,
|
||||
345,
|
||||
363,
|
||||
388,
|
||||
402,
|
||||
412,
|
||||
437,
|
||||
438,
|
||||
445,
|
||||
447,
|
||||
474,
|
||||
491,
|
||||
496,
|
||||
497,
|
||||
520,
|
||||
526,
|
||||
580,
|
||||
590,
|
||||
803,
|
||||
851,
|
||||
885
|
||||
],
|
||||
"weight": 69,
|
||||
"height": 7,
|
||||
"base_experience": 64
|
||||
}
|
||||
}
|
||||
@@ -1,412 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0
|
||||
}
|
||||
]
|
||||
@@ -1,494 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-i"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 1.0,
|
||||
"generation": "generation-i"
|
||||
}
|
||||
]
|
||||
@@ -1,650 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ii"
|
||||
}
|
||||
]
|
||||
@@ -1,650 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iii"
|
||||
}
|
||||
]
|
||||
@@ -1,650 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-iv"
|
||||
}
|
||||
]
|
||||
@@ -1,722 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-ix"
|
||||
}
|
||||
]
|
||||
@@ -1,662 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-v"
|
||||
}
|
||||
]
|
||||
@@ -1,722 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vi"
|
||||
}
|
||||
]
|
||||
@@ -1,722 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-vii"
|
||||
}
|
||||
]
|
||||
@@ -1,722 +0,0 @@
|
||||
[
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "normal",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "electric",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "grass",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ice",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fighting",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "poison",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ground",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "flying",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "psychic",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "bug",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "flying",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "bug",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "ground",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "rock",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "ghost",
|
||||
"defending_type": "normal",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dragon",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "ghost",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "psychic",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "dark",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "rock",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "ice",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fairy",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "water",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "steel",
|
||||
"defending_type": "electric",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fighting",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dragon",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "dark",
|
||||
"damage_factor": 2.0,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "poison",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "steel",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
},
|
||||
{
|
||||
"attacking_type": "fairy",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 0.5,
|
||||
"generation": "generation-viii"
|
||||
}
|
||||
]
|
||||
479
data/types/generation-i.json
Normal file
479
data/types/generation-i.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-ii.json
Normal file
479
data/types/generation-ii.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-iii.json
Normal file
479
data/types/generation-iii.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-iv.json
Normal file
479
data/types/generation-iv.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-ix.json
Normal file
479
data/types/generation-ix.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-v.json
Normal file
479
data/types/generation-v.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-vi.json
Normal file
479
data/types/generation-vi.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-vii.json
Normal file
479
data/types/generation-vii.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
479
data/types/generation-viii.json
Normal file
479
data/types/generation-viii.json
Normal file
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"normal": {
|
||||
"double_damage_from": [
|
||||
"fighting"
|
||||
],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"fighting": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"normal",
|
||||
"rock",
|
||||
"steel",
|
||||
"ice",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"rock",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"psychic",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ghost"
|
||||
]
|
||||
},
|
||||
"flying": {
|
||||
"double_damage_from": [
|
||||
"rock",
|
||||
"electric",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"poison": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"psychic"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"poison",
|
||||
"bug",
|
||||
"grass",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"ground",
|
||||
"rock",
|
||||
"ghost"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"steel"
|
||||
]
|
||||
},
|
||||
"ground": {
|
||||
"double_damage_from": [
|
||||
"water",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"poison",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"rock"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"bug",
|
||||
"grass"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"electric"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"rock": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel",
|
||||
"water",
|
||||
"grass"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"poison",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"bug": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"grass",
|
||||
"psychic",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"grass"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"flying",
|
||||
"poison",
|
||||
"ghost",
|
||||
"steel",
|
||||
"fire",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"ghost": {
|
||||
"double_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"poison",
|
||||
"bug"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"dark"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"normal",
|
||||
"fighting"
|
||||
],
|
||||
"no_damage_to": [
|
||||
"normal"
|
||||
]
|
||||
},
|
||||
"steel": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"ground",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"rock",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"normal",
|
||||
"flying",
|
||||
"rock",
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"psychic",
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"electric"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"poison"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fire": {
|
||||
"double_damage_from": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"bug",
|
||||
"steel",
|
||||
"grass",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"ice",
|
||||
"fairy"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"rock",
|
||||
"fire",
|
||||
"water",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"water": {
|
||||
"double_damage_from": [
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"fire"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"water",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"grass": {
|
||||
"double_damage_from": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"fire",
|
||||
"ice"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ground",
|
||||
"rock",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ground",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"flying",
|
||||
"poison",
|
||||
"bug",
|
||||
"steel",
|
||||
"fire",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"electric": {
|
||||
"double_damage_from": [
|
||||
"ground"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"water"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"flying",
|
||||
"steel",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"grass",
|
||||
"electric",
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"ground"
|
||||
]
|
||||
},
|
||||
"psychic": {
|
||||
"double_damage_from": [
|
||||
"bug",
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"poison"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"dark"
|
||||
]
|
||||
},
|
||||
"ice": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"rock",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"flying",
|
||||
"ground",
|
||||
"grass",
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ice"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel",
|
||||
"fire",
|
||||
"water",
|
||||
"ice"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"dragon": {
|
||||
"double_damage_from": [
|
||||
"ice",
|
||||
"dragon",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"dragon"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fire",
|
||||
"water",
|
||||
"grass",
|
||||
"electric"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"steel"
|
||||
],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": [
|
||||
"fairy"
|
||||
]
|
||||
},
|
||||
"dark": {
|
||||
"double_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"fairy"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"ghost",
|
||||
"psychic"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"ghost",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"fighting",
|
||||
"dark",
|
||||
"fairy"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"psychic"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"fairy": {
|
||||
"double_damage_from": [
|
||||
"poison",
|
||||
"steel"
|
||||
],
|
||||
"double_damage_to": [
|
||||
"fighting",
|
||||
"dragon",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_from": [
|
||||
"fighting",
|
||||
"bug",
|
||||
"dark"
|
||||
],
|
||||
"half_damage_to": [
|
||||
"poison",
|
||||
"steel",
|
||||
"fire"
|
||||
],
|
||||
"no_damage_from": [
|
||||
"dragon"
|
||||
],
|
||||
"no_damage_to": []
|
||||
},
|
||||
"stellar": {
|
||||
"double_damage_from": [],
|
||||
"double_damage_to": [],
|
||||
"half_damage_from": [],
|
||||
"half_damage_to": [],
|
||||
"no_damage_from": [],
|
||||
"no_damage_to": []
|
||||
}
|
||||
}
|
||||
@@ -1,311 +0,0 @@
|
||||
# Pokemon Type System Implementation
|
||||
|
||||
This document describes the high-performance Pokemon type system implementation for the Pokemon Battle Simulator.
|
||||
|
||||
## Overview
|
||||
|
||||
The type system provides:
|
||||
- **High-performance type effectiveness calculations** using integer arithmetic only
|
||||
- **Multi-generation support** without runtime generation checks
|
||||
- **Dual-type Pokemon support** with proper damage multiplier calculations
|
||||
- **JSON-based type chart loading** from the provided data files
|
||||
- **Comprehensive testing and benchmarking** for performance validation
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Performance Optimizations
|
||||
|
||||
- **Integer-only arithmetic**: Uses integer multipliers (0, 1, 2, 4, 8, 16) representing (0x, 0.25x, 0.5x, 1x, 2x, 4x) damage
|
||||
- **Compile-time generation selection**: Template-based generation support eliminates runtime checks
|
||||
- **Cache-friendly type chart storage**: 2D array layout optimized for CPU cache performance
|
||||
- **Minimal memory allocations**: Static storage for type charts loaded at startup
|
||||
|
||||
### 2. Type System Architecture
|
||||
|
||||
#### Core Components
|
||||
|
||||
- **`Type` enum**: All 19 Pokemon types (Generation 1-9)
|
||||
- **`TypeMultiplier` enum**: Integer damage multipliers
|
||||
- **`Generation` enum**: Pokemon game generations
|
||||
- **`PokemonTypes` class**: Represents single/dual-type Pokemon
|
||||
- **`TypeUtils` class**: Core type system functionality
|
||||
- **`TypeChartTraits` template**: Generation-specific type chart access
|
||||
|
||||
#### Type Multipliers
|
||||
|
||||
```cpp
|
||||
enum class TypeMultiplier : uint8_t {
|
||||
ZERO = 0, // 0x damage (immune)
|
||||
QUARTER = 1, // 0.25x damage
|
||||
HALF = 2, // 0.5x damage
|
||||
NEUTRAL = 4, // 1x damage (neutral)
|
||||
DOUBLE = 8, // 2x damage
|
||||
QUADRUPLE = 16 // 4x damage
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Usage Examples
|
||||
|
||||
#### Basic Type Effectiveness
|
||||
|
||||
```cpp
|
||||
using namespace PokEng;
|
||||
|
||||
// Calculate damage with type effectiveness
|
||||
uint32_t damage = calculateTypeDamage<Generation::I>(
|
||||
100, // Base damage
|
||||
Type::WATER, // Attack type
|
||||
Type::FIRE // Defender type
|
||||
);
|
||||
// Result: 200 (Water is super effective against Fire)
|
||||
```
|
||||
|
||||
#### Dual-Type Pokemon
|
||||
|
||||
```cpp
|
||||
// Electric attack on Water/Flying Pokemon
|
||||
uint32_t damage = calculateTypeDamage<Generation::I>(
|
||||
100, // Base damage
|
||||
Type::ELECTRIC, // Attack type
|
||||
Type::WATER, // Primary defender type
|
||||
Type::FLYING // Secondary defender type
|
||||
);
|
||||
// Result: 400 (Electric is super effective against both types)
|
||||
```
|
||||
|
||||
#### Pokemon with Types
|
||||
|
||||
```cpp
|
||||
// Create Pokemon with types
|
||||
Pokemon charizard("Charizard", 150, Type::FIRE, Type::FLYING);
|
||||
Pokemon blastoise("Blastoise", 150, Type::WATER);
|
||||
|
||||
// Calculate damage using Pokemon methods
|
||||
uint32_t damage = charizard.calculateDamageTaken<Generation::I>(
|
||||
100, // Base damage
|
||||
Type::WATER // Attack type
|
||||
);
|
||||
// Result: 200 (Water is super effective against Fire)
|
||||
```
|
||||
|
||||
### 4. Generation Support
|
||||
|
||||
The system supports all Pokemon generations through compile-time templates:
|
||||
|
||||
```cpp
|
||||
// Generation 1 type effectiveness
|
||||
auto gen1Damage = calculateTypeDamage<Generation::I>(100, Type::FIRE, Type::WATER);
|
||||
|
||||
// Generation 8 type effectiveness
|
||||
auto gen8Damage = calculateTypeDamage<Generation::VIII>(100, Type::FIRE, Type::WATER);
|
||||
```
|
||||
|
||||
Each generation has its own type chart loaded from the corresponding JSON file.
|
||||
|
||||
### 5. Type Chart Loading
|
||||
|
||||
Type charts are loaded from JSON files at program startup:
|
||||
|
||||
- `data/type_effectiveness_generation-i.json` → Generation 1
|
||||
- `data/type_effectiveness_generation-ii.json` → Generation 2
|
||||
- ... and so on through Generation 9
|
||||
|
||||
The loading process:
|
||||
1. Parses JSON using RapidJSON
|
||||
2. Converts float multipliers to integer TypeMultiplier values
|
||||
3. Stores in optimized 2D array format
|
||||
4. Provides O(1) lookup performance
|
||||
|
||||
## Performance Characteristics
|
||||
|
||||
### Benchmarks
|
||||
|
||||
The implementation includes comprehensive benchmarks:
|
||||
|
||||
```bash
|
||||
# Run type system benchmarks
|
||||
./build/benchmarks/benchmarks
|
||||
|
||||
# Run specific benchmark
|
||||
./build/benchmarks/benchmarks --benchmark_filter=TypeSystemBenchmark
|
||||
```
|
||||
|
||||
Key benchmark results (example):
|
||||
- **Type effectiveness lookup**: ~1-2 nanoseconds
|
||||
- **Damage multiplier calculation**: ~2-3 nanoseconds
|
||||
- **Full damage calculation**: ~3-5 nanoseconds
|
||||
- **Batch processing**: Sub-microsecond for realistic scenarios
|
||||
|
||||
### Memory Layout
|
||||
|
||||
- Type charts: ~3KB per generation (19x19 types)
|
||||
- Total memory: ~27KB for all 9 generations
|
||||
- Cache-friendly access pattern: Row-major order for optimal CPU cache usage
|
||||
|
||||
## Testing
|
||||
|
||||
### Unit Tests
|
||||
|
||||
Comprehensive unit test coverage:
|
||||
|
||||
```bash
|
||||
# Run type system tests
|
||||
./build/tests/unit/core/test_types
|
||||
|
||||
# Run all tests
|
||||
./build/tests/test_all.sh
|
||||
```
|
||||
|
||||
Test categories:
|
||||
- **Type string conversion**: Valid/invalid conversions
|
||||
- **Type effectiveness**: Known type matchups
|
||||
- **Damage calculations**: Single/dual-type scenarios
|
||||
- **Edge cases**: Immunity, invalid inputs
|
||||
- **Generation differences**: Cross-generation behavior
|
||||
- **Performance**: Speed validation
|
||||
|
||||
### Example Output
|
||||
|
||||
```cpp
|
||||
// Test: Water attack on Fire type
|
||||
uint32_t damage = calculateTypeDamage<Generation::I>(100, Type::WATER, Type::FIRE);
|
||||
ASSERT_EQ(damage, 200); // Water is super effective (2x) against Fire
|
||||
|
||||
// Test: Dual-type Electric attack on Water/Flying
|
||||
uint32_t dualDamage = calculateTypeDamage<Generation::I>(100, Type::ELECTRIC, Type::WATER, Type::FLYING);
|
||||
ASSERT_EQ(dualDamage, 400); // Electric is super effective (2x) against both types = 4x total
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### Core Functions
|
||||
|
||||
#### `calculateTypeDamage`
|
||||
|
||||
```cpp
|
||||
template <Generation Gen = Generation::I>
|
||||
uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, const PokemonTypes& defenderTypes);
|
||||
|
||||
template <Generation Gen = Generation::I>
|
||||
uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, Type defenderType);
|
||||
|
||||
template <Generation Gen = Generation::I>
|
||||
uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, Type defenderType1, Type defenderType2);
|
||||
```
|
||||
|
||||
#### `TypeUtils` Methods
|
||||
|
||||
```cpp
|
||||
static std::optional<Type> stringToType(std::string_view typeStr);
|
||||
static std::string_view typeToString(Type type);
|
||||
static TypeMultiplier getTypeEffectiveness(Type attackType, Type defendType);
|
||||
static uint32_t calculateDamageMultiplier(Type attackType, const PokemonTypes& defenderTypes);
|
||||
```
|
||||
|
||||
### Type Enums
|
||||
|
||||
#### `Type`
|
||||
|
||||
```cpp
|
||||
enum class Type : uint8_t {
|
||||
NONE = 0, NORMAL, FIRE, WATER, ELECTRIC, GRASS, ICE, FIGHTING,
|
||||
POISON, GROUND, FLYING, PSYCHIC, BUG, ROCK, GHOST, DRAGON,
|
||||
DARK, STEEL, FAIRY, TYPE_COUNT
|
||||
};
|
||||
```
|
||||
|
||||
#### `Generation`
|
||||
|
||||
```cpp
|
||||
enum class Generation : uint8_t {
|
||||
I = 1, II = 2, III = 3, IV = 4,
|
||||
V = 5, VI = 6, VII = 7, VIII = 8,
|
||||
IX = 9
|
||||
};
|
||||
```
|
||||
|
||||
## Building and Running
|
||||
|
||||
### Dependencies
|
||||
|
||||
- C++17 compatible compiler
|
||||
- RapidJSON (header-only, included in `thirdParty/rapidjson`)
|
||||
- CMake 3.15+
|
||||
- Google Test (for unit tests)
|
||||
- Google Benchmark (for performance tests)
|
||||
|
||||
### Build Commands
|
||||
|
||||
```bash
|
||||
# Configure
|
||||
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
# Build
|
||||
cmake --build build --config Release
|
||||
|
||||
# Run tests
|
||||
cd build && ctest --output-on-failure
|
||||
|
||||
# Run benchmarks
|
||||
./benchmarks/benchmarks
|
||||
|
||||
# Run example
|
||||
./examples/type_system_example
|
||||
```
|
||||
|
||||
### Integration
|
||||
|
||||
To use the type system in your code:
|
||||
|
||||
```cpp
|
||||
#include "types.h"
|
||||
|
||||
// Use the high-level API
|
||||
uint32_t damage = PokEng::calculateTypeDamage(
|
||||
100, Type::FIRE, Type::GRASS
|
||||
);
|
||||
```
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### Integer-Only Arithmetic
|
||||
|
||||
- **Rationale**: Floating-point operations are slower and introduce precision issues
|
||||
- **Solution**: Use integer multipliers with division by 4 for final damage calculation
|
||||
- **Benefit**: 2-3x performance improvement over float-based calculations
|
||||
|
||||
### Template-Based Generations
|
||||
|
||||
- **Rationale**: Runtime generation checks would add overhead
|
||||
- **Solution**: Compile-time generation selection via templates
|
||||
- **Benefit**: Zero runtime overhead for generation selection
|
||||
|
||||
### Static Type Charts
|
||||
|
||||
- **Rationale**: Type effectiveness rarely changes during program execution
|
||||
- **Solution**: Load once at startup, store in static arrays
|
||||
- **Benefit**: Optimal cache performance for repeated lookups
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements:
|
||||
1. **SIMD optimizations** for batch damage calculations
|
||||
2. **Memory-mapped file loading** for reduced startup time
|
||||
3. **Type combination caching** for frequently used type pairs
|
||||
4. **Custom type chart support** for ROM hacks/modifications
|
||||
5. **Advanced effectiveness rules** (e.g., Freeze Dry, Flying Press)
|
||||
|
||||
## Contributing
|
||||
|
||||
When extending the type system:
|
||||
1. Add new types to the `Type` enum
|
||||
2. Update string conversion mappings
|
||||
3. Add new JSON data files for type effectiveness
|
||||
4. Update template instantiations
|
||||
5. Add comprehensive unit tests
|
||||
6. Add performance benchmarks
|
||||
7. Update documentation
|
||||
|
||||
## License
|
||||
|
||||
This implementation is part of the Pokemon Battle Simulator project. See LICENSE file for details.
|
||||
108
examples/pokemon_table_example.cpp
Normal file
108
examples/pokemon_table_example.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "core/pokemon_table.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
using namespace PokEng;
|
||||
|
||||
int main() {
|
||||
std::cout << "Pokemon Table Example" << std::endl;
|
||||
std::cout << "====================" << std::endl;
|
||||
|
||||
// Initialize the global Pokemon table
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (!initializePokemonTable()) {
|
||||
std::cerr << "Failed to initialize Pokemon table!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
|
||||
std::cout << "Pokemon table initialized in " << duration.count() << "ms" << std::endl;
|
||||
std::cout << "Total Pokemon loaded: " << g_pokemonTable->size() << std::endl;
|
||||
std::cout << "Max Pokemon ID: " << g_pokemonTable->getMaxId() << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Demonstrate fast ID-based lookup
|
||||
std::cout << "Fast ID-based lookups:" << std::endl;
|
||||
std::cout << "--------------------" << std::endl;
|
||||
|
||||
const uint16_t testIds[] = {1, 25, 150, 493, 807, 905}; // Bulbasaur, Pikachu, Mewtwo, Arceus, Zeraora, Enamorus
|
||||
|
||||
for (uint16_t id : testIds) {
|
||||
const auto* pokemon = g_pokemonTable->getPokemon(id);
|
||||
if (pokemon) {
|
||||
std::cout << "#" << std::setw(3) << std::setfill('0') << pokemon->id << " "
|
||||
<< std::setw(15) << std::left << pokemon->name << " | "
|
||||
<< "HP: " << std::setw(3) << static_cast<int>(pokemon->base_stats.hp) << " | "
|
||||
<< "Atk: " << std::setw(3) << static_cast<int>(pokemon->base_stats.attack) << " | "
|
||||
<< "Def: " << std::setw(3) << static_cast<int>(pokemon->base_stats.defense) << " | "
|
||||
<< "SpA: " << std::setw(3) << static_cast<int>(pokemon->base_stats.sp_attack) << " | "
|
||||
<< "SpD: " << std::setw(3) << static_cast<int>(pokemon->base_stats.sp_defense) << " | "
|
||||
<< "Spe: " << std::setw(3) << static_cast<int>(pokemon->base_stats.speed) << " | "
|
||||
<< "Type: " << TypeUtils::typeToString(pokemon->types.getPrimary());
|
||||
if (pokemon->types.hasSecondary()) {
|
||||
std::cout << "/" << TypeUtils::typeToString(pokemon->types.getSecondary());
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
// Demonstrate name-based lookup
|
||||
std::cout << "Name-based lookups:" << std::endl;
|
||||
std::cout << "------------------" << std::endl;
|
||||
|
||||
const std::string testNames[] = {"charizard", "gengar", "snorlax", "dragonite", "mew"};
|
||||
|
||||
for (const auto& name : testNames) {
|
||||
const auto* pokemon = g_pokemonTable->getPokemonByName(name);
|
||||
if (pokemon) {
|
||||
std::cout << "#" << std::setw(3) << std::setfill('0') << pokemon->id << " "
|
||||
<< std::setw(12) << std::left << pokemon->name << " | "
|
||||
<< "Total: " << std::setw(3) << (pokemon->base_stats.hp +
|
||||
pokemon->base_stats.attack +
|
||||
pokemon->base_stats.defense +
|
||||
pokemon->base_stats.sp_attack +
|
||||
pokemon->base_stats.sp_defense +
|
||||
pokemon->base_stats.speed)
|
||||
<< std::endl;
|
||||
} else {
|
||||
std::cout << "Pokemon '" << name << "' not found" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
// Performance test for ID lookups
|
||||
std::cout << "Performance test (100,000 ID lookups):" << std::endl;
|
||||
std::cout << "--------------------------------------" << std::endl;
|
||||
|
||||
start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
volatile size_t checksum = 0; // Prevent optimization
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
uint16_t randomId = (i % g_pokemonTable->getMaxId()) + 1;
|
||||
const auto* pokemon = g_pokemonTable->getPokemon(randomId);
|
||||
if (pokemon) {
|
||||
checksum += pokemon->base_stats.hp;
|
||||
}
|
||||
}
|
||||
|
||||
end = std::chrono::high_resolution_clock::now();
|
||||
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
|
||||
std::cout << "Time: " << duration.count() << "ms (" << (100000.0 / duration.count()) << " lookups/ms)" << std::endl;
|
||||
std::cout << "Checksum: " << checksum << std::endl;
|
||||
|
||||
// Cleanup
|
||||
shutdownPokemonTable();
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Example completed successfully!" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
// Type System Example
|
||||
// Demonstrates how to use the high-performance Pokemon type system
|
||||
|
||||
#include "pokemon_battle_sim.h"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace PokEng;
|
||||
|
||||
int main() {
|
||||
std::cout << "=== Pokemon Type System Example ===\n\n";
|
||||
|
||||
// Example 1: Basic type effectiveness lookup
|
||||
std::cout << "1. Basic Type Effectiveness Examples:\n";
|
||||
std::cout << "-----------------------------------\n";
|
||||
|
||||
// Water attack on Fire type (super effective)
|
||||
uint32_t damage1 = calculateTypeDamage<Generation::I>(100, Type::WATER, Type::FIRE);
|
||||
std::cout << "Water attack on Fire Pokemon: " << damage1 << " damage (expected: 200)\n";
|
||||
|
||||
// Fire attack on Water type (not very effective)
|
||||
uint32_t damage2 = calculateTypeDamage<Generation::I>(100, Type::FIRE, Type::WATER);
|
||||
std::cout << "Fire attack on Water Pokemon: " << damage2 << " damage (expected: 50)\n";
|
||||
|
||||
// Normal attack on Ghost type (immune)
|
||||
uint32_t damage3 = calculateTypeDamage<Generation::I>(100, Type::NORMAL, Type::GHOST);
|
||||
std::cout << "Normal attack on Ghost Pokemon: " << damage3 << " damage (expected: 0)\n";
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
// Example 2: Dual-type Pokemon
|
||||
std::cout << "2. Dual-Type Pokemon Examples:\n";
|
||||
std::cout << "-----------------------------\n";
|
||||
|
||||
// Electric attack on Water/Flying (super effective against both)
|
||||
uint32_t damage4 = calculateTypeDamage<Generation::I>(100, Type::ELECTRIC, Type::WATER, Type::FLYING);
|
||||
std::cout << "Electric attack on Water/Flying Pokemon: " << damage4 << " damage (4x effective)\n";
|
||||
|
||||
// Grass attack on Water/Flying (mixed effectiveness)
|
||||
uint32_t damage5 = calculateTypeDamage<Generation::I>(100, Type::GRASS, Type::WATER, Type::FLYING);
|
||||
std::cout << "Grass attack on Water/Flying Pokemon: " << damage5 << " damage (neutral effectiveness)\n";
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
// Example 3: Pokemon with types
|
||||
std::cout << "3. Pokemon with Type Support:\n";
|
||||
std::cout << "-----------------------------\n";
|
||||
|
||||
// Create some Pokemon with different types
|
||||
Pokemon charizard(6, 150, Type::FIRE, Type::FLYING);
|
||||
Pokemon blastoise(9, 150, Type::WATER);
|
||||
Pokemon venusaur(3, 150, Type::GRASS, Type::POISON);
|
||||
|
||||
std::cout << charizard.getId() << " (Fire/Flying) has "
|
||||
<< TypeUtils::typeToString(charizard.getTypes().getPrimary()) << "/"
|
||||
<< TypeUtils::typeToString(charizard.getTypes().getSecondary()) << " types\n";
|
||||
|
||||
std::cout << blastoise.getId() << " (Water) has "
|
||||
<< TypeUtils::typeToString(blastoise.getTypes().getPrimary()) << " type\n";
|
||||
|
||||
std::cout << venusaur.getId() << " (Grass/Poison) has "
|
||||
<< TypeUtils::typeToString(venusaur.getTypes().getPrimary()) << "/"
|
||||
<< TypeUtils::typeToString(venusaur.getTypes().getSecondary()) << " types\n";
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
// Example 4: Damage calculation using Pokemon methods
|
||||
std::cout << "4. Damage Calculations Using Pokemon Methods:\n";
|
||||
std::cout << "--------------------------------------------\n";
|
||||
|
||||
uint32_t fireDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::FIRE);
|
||||
std::cout << "Charizard takes " << fireDamage << " damage from Fire attack (expected: 50)\n";
|
||||
|
||||
uint32_t waterDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::WATER);
|
||||
std::cout << "Charizard takes " << waterDamage << " damage from Water attack (expected: 200)\n";
|
||||
|
||||
uint32_t electricDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::ELECTRIC);
|
||||
std::cout << "Charizard takes " << electricDamage << " damage from Electric attack (expected: 200)\n";
|
||||
|
||||
uint32_t groundDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::GROUND);
|
||||
std::cout << "Charizard takes " << groundDamage << " damage from Ground attack (expected: 0 - immune)\n";
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
// Example 5: Different generations
|
||||
std::cout << "5. Generation Differences:\n";
|
||||
std::cout << "-------------------------\n";
|
||||
|
||||
// Steel type was introduced in Gen 2, so Steel moves don't exist in Gen 1
|
||||
uint32_t gen1Damage = calculateTypeDamage<Generation::I>(100, Type::NORMAL, Type::STEEL);
|
||||
uint32_t gen8Damage = calculateTypeDamage<Generation::VIII>(100, Type::NORMAL, Type::STEEL);
|
||||
|
||||
std::cout << "Normal attack on Steel in Generation 1: " << gen1Damage << " damage\n";
|
||||
std::cout << "Normal attack on Steel in Generation 8: " << gen8Damage << " damage\n";
|
||||
std::cout << "(Note: Steel type behavior may differ across generations)\n";
|
||||
|
||||
std::cout << "\n";
|
||||
|
||||
// Example 6: Type string conversion
|
||||
std::cout << "6. Type String Conversion:\n";
|
||||
std::cout << "-------------------------\n";
|
||||
|
||||
std::vector<Type> typesToTest = {Type::FIRE, Type::WATER, Type::GRASS, Type::ELECTRIC, Type::FAIRY};
|
||||
|
||||
for (Type type : typesToTest) {
|
||||
std::string_view typeName = TypeUtils::typeToString(type);
|
||||
auto convertedBack = TypeUtils::stringToType(typeName);
|
||||
|
||||
std::cout << "Type: " << typeName << " -> "
|
||||
<< (convertedBack ? TypeUtils::typeToString(*convertedBack) : "ERROR")
|
||||
<< " (conversion " << (convertedBack ? "successful" : "failed") << ")\n";
|
||||
}
|
||||
|
||||
std::cout << "\n=== Example Complete ===\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef BATTLE_H
|
||||
#define BATTLE_H
|
||||
|
||||
#include "pokemon.h"
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// High-level type system functions for easy use
|
||||
template <Generation Gen = Generation::I>
|
||||
inline uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, const PokemonTypes& defenderTypes) {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, defenderTypes);
|
||||
}
|
||||
|
||||
template <Generation Gen = Generation::I>
|
||||
inline uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, Type defenderType) {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, PokemonTypes(defenderType));
|
||||
}
|
||||
|
||||
template <Generation Gen = Generation::I>
|
||||
inline uint32_t calculateTypeDamage(uint32_t baseDamage, Type attackType, Type defenderType1, Type defenderType2) {
|
||||
return calculateDamage<Gen>(baseDamage, attackType, PokemonTypes(defenderType1, defenderType2));
|
||||
}
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif
|
||||
@@ -18,6 +18,89 @@ VIII = 8,
|
||||
IX = 9
|
||||
};
|
||||
|
||||
// Stat indices for nature calculations
|
||||
enum class StatIndex : uint8_t {
|
||||
HP = 0,
|
||||
ATTACK = 1,
|
||||
DEFENSE = 2,
|
||||
SP_ATTACK = 3,
|
||||
SP_DEFENSE = 4,
|
||||
SPEED = 5
|
||||
};
|
||||
|
||||
// Pokemon Nature - encoded as 8 bits: upper 4 bits = positive stat, lower 4 bits = negative stat
|
||||
// Stat encoding: 0=HP/None, 1=Attack, 2=Defense, 3=SpAttack, 4=SpDefense, 5=Speed
|
||||
struct Nature {
|
||||
private:
|
||||
uint8_t m_encoded; // Upper 4 bits: positive stat, Lower 4 bits: negative stat
|
||||
|
||||
public:
|
||||
// Constructor from encoded value
|
||||
constexpr explicit Nature(uint8_t encoded = 0) : m_encoded(encoded) {}
|
||||
|
||||
// Constructor from positive and negative stats
|
||||
constexpr Nature(StatIndex positive, StatIndex negative)
|
||||
: m_encoded((static_cast<uint8_t>(positive) << 4) | static_cast<uint8_t>(negative)) {}
|
||||
|
||||
// Get the stat that is increased by this nature
|
||||
constexpr StatIndex getPositiveStat() const {
|
||||
return static_cast<StatIndex>((m_encoded >> 4) & 0xF);
|
||||
}
|
||||
|
||||
// Get the stat that is decreased by this nature
|
||||
constexpr StatIndex getNegativeStat() const {
|
||||
return static_cast<StatIndex>(m_encoded & 0xF);
|
||||
}
|
||||
|
||||
// Check if nature is neutral (same positive and negative stat)
|
||||
constexpr bool isNeutral() const {
|
||||
return getPositiveStat() == getNegativeStat();
|
||||
}
|
||||
|
||||
constexpr uint8_t getMultiplier10(StatIndex stat) const {
|
||||
return static_cast<uint8_t>(10u + (getPositiveStat() == stat) - (getNegativeStat() == stat));
|
||||
}
|
||||
|
||||
// Get encoded value
|
||||
constexpr uint8_t getEncoded() const { return m_encoded; }
|
||||
|
||||
// Comparison operators
|
||||
constexpr bool operator==(const Nature& other) const { return m_encoded == other.m_encoded; }
|
||||
constexpr bool operator!=(const Nature& other) const { return m_encoded != other.m_encoded; }
|
||||
|
||||
// Predefined nature constants
|
||||
static constexpr Nature HARDY() { return Nature(StatIndex::ATTACK, StatIndex::ATTACK); }
|
||||
static constexpr Nature DOCILE() { return Nature(StatIndex::DEFENSE, StatIndex::DEFENSE); }
|
||||
static constexpr Nature BASHFUL() { return Nature(StatIndex::SP_ATTACK, StatIndex::SP_ATTACK); }
|
||||
static constexpr Nature QUIRKY() { return Nature(StatIndex::SP_DEFENSE, StatIndex::SP_DEFENSE); }
|
||||
static constexpr Nature SERIOUS() { return Nature(StatIndex::SPEED, StatIndex::SPEED); }
|
||||
|
||||
static constexpr Nature LONELY() { return Nature(StatIndex::ATTACK, StatIndex::DEFENSE); }
|
||||
static constexpr Nature ADAMANT() { return Nature(StatIndex::ATTACK, StatIndex::SP_ATTACK); }
|
||||
static constexpr Nature NAUGHTY() { return Nature(StatIndex::ATTACK, StatIndex::SP_DEFENSE); }
|
||||
static constexpr Nature BRAVE() { return Nature(StatIndex::ATTACK, StatIndex::SPEED); }
|
||||
|
||||
static constexpr Nature BOLD() { return Nature(StatIndex::DEFENSE, StatIndex::ATTACK); }
|
||||
static constexpr Nature IMPISH() { return Nature(StatIndex::DEFENSE, StatIndex::SP_ATTACK); }
|
||||
static constexpr Nature LAX() { return Nature(StatIndex::DEFENSE, StatIndex::SP_DEFENSE); }
|
||||
static constexpr Nature RELAXED() { return Nature(StatIndex::DEFENSE, StatIndex::SPEED); }
|
||||
|
||||
static constexpr Nature MODEST() { return Nature(StatIndex::SP_ATTACK, StatIndex::ATTACK); }
|
||||
static constexpr Nature MILD() { return Nature(StatIndex::SP_ATTACK, StatIndex::DEFENSE); }
|
||||
static constexpr Nature RASH() { return Nature(StatIndex::SP_ATTACK, StatIndex::SP_DEFENSE); }
|
||||
static constexpr Nature QUIET() { return Nature(StatIndex::SP_ATTACK, StatIndex::SPEED); }
|
||||
|
||||
static constexpr Nature CALM() { return Nature(StatIndex::SP_DEFENSE, StatIndex::ATTACK); }
|
||||
static constexpr Nature GENTLE() { return Nature(StatIndex::SP_DEFENSE, StatIndex::DEFENSE); }
|
||||
static constexpr Nature CAREFUL() { return Nature(StatIndex::SP_DEFENSE, StatIndex::SP_ATTACK); }
|
||||
static constexpr Nature SASSY() { return Nature(StatIndex::SP_DEFENSE, StatIndex::SPEED); }
|
||||
|
||||
static constexpr Nature TIMID() { return Nature(StatIndex::SPEED, StatIndex::ATTACK); }
|
||||
static constexpr Nature HASTY() { return Nature(StatIndex::SPEED, StatIndex::DEFENSE); }
|
||||
static constexpr Nature JOLLY() { return Nature(StatIndex::SPEED, StatIndex::SP_ATTACK); }
|
||||
static constexpr Nature NAIVE() { return Nature(StatIndex::SPEED, StatIndex::SP_DEFENSE); }
|
||||
};
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
|
||||
|
||||
@@ -2,37 +2,99 @@
|
||||
#define POKEMON_H
|
||||
|
||||
#include "config.h"
|
||||
#include "stats.h"
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Pokemon species data structure
|
||||
struct PokemonSpecies {
|
||||
PokemonSpecies() = default;
|
||||
|
||||
class Pokemon {
|
||||
public:
|
||||
Pokemon() = default;
|
||||
~Pokemon() = default;
|
||||
|
||||
Pokemon(uint16_t id) : m_id(id) {}
|
||||
Pokemon(uint16_t id, uint16_t health) : m_id(id), m_health(health) {}
|
||||
Pokemon(uint16_t id, uint16_t health, Type primaryType) : m_id(id), m_health(health), m_types(primaryType) {}
|
||||
Pokemon(uint16_t id, uint16_t health, Type primaryType, Type secondaryType) : m_id(id), m_health(health), m_types(primaryType, secondaryType) {}
|
||||
|
||||
std::string name;
|
||||
uint16_t id;
|
||||
BaseStats base_stats;
|
||||
PokemonTypes types;
|
||||
};
|
||||
|
||||
// Pokemon Archetype - contains information on how a pokemon will be instantiated
|
||||
class PokemonArchetype {
|
||||
public:
|
||||
PokemonArchetype() = default;
|
||||
PokemonArchetype(uint16_t species_id, uint8_t level = 50,
|
||||
Nature nature = Nature::HARDY(),
|
||||
const IndividualValues& ivs = IndividualValues(),
|
||||
const EffortValues& evs = EffortValues(),
|
||||
uint32_t exp = 0)
|
||||
: m_species_id(species_id), m_level(level), m_nature(nature),
|
||||
m_ivs(ivs), m_evs(evs), m_exp(exp) {}
|
||||
|
||||
// Getters
|
||||
uint16_t getId() const { return m_id; }
|
||||
uint16_t getHealth() const { return m_health; }
|
||||
PokemonTypes getTypes() const { return m_types; }
|
||||
uint16_t getSpeciesId() const { return m_species_id; }
|
||||
uint8_t getLevel() const { return m_level; }
|
||||
Nature getNature() const { return m_nature; }
|
||||
const IndividualValues& getIVs() const { return m_ivs; }
|
||||
const EffortValues& getEVs() const { return m_evs; }
|
||||
uint32_t getExp() const { return m_exp; }
|
||||
|
||||
// Setters
|
||||
void setSpeciesId(uint16_t species_id) { m_species_id = species_id; }
|
||||
void setLevel(uint8_t level) { m_level = (level > 100) ? 100 : level; }
|
||||
void setNature(Nature nature) { m_nature = nature; }
|
||||
void setIVs(const IndividualValues& ivs) { m_ivs = ivs; }
|
||||
void setEVs(const EffortValues& evs) { if (evs.isValid()) m_evs = evs; }
|
||||
void setExp(uint32_t exp) { m_exp = exp; }
|
||||
|
||||
// Calculate battle stats for different generations
|
||||
template<Generation Gen>
|
||||
BattleStats calculateBattleStats() const;
|
||||
|
||||
private:
|
||||
uint16_t m_species_id = 0;
|
||||
uint8_t m_level = 50;
|
||||
Nature m_nature = Nature::HARDY();
|
||||
IndividualValues m_ivs;
|
||||
EffortValues m_evs;
|
||||
uint32_t m_exp = 0; // For Gen I & II stat calculations
|
||||
};
|
||||
|
||||
// Pokemon Instance - only contains data needed for battle
|
||||
class PokemonInstance {
|
||||
public:
|
||||
PokemonInstance() = default;
|
||||
PokemonInstance(uint16_t species_id, const BattleStats& stats,
|
||||
const PokemonTypes& types, uint8_t friendship = 0)
|
||||
: m_species_id(species_id), m_battle_stats(stats), m_types(types),
|
||||
m_current_hp(stats.hp), m_friendship(friendship) {}
|
||||
|
||||
// Create from archetype
|
||||
template<Generation Gen>
|
||||
static PokemonInstance fromArchetype(const PokemonArchetype& archetype, uint8_t friendship = 0);
|
||||
|
||||
// Getters
|
||||
uint16_t getSpeciesId() const { return m_species_id; }
|
||||
uint16_t getCurrentHP() const { return m_current_hp; }
|
||||
uint16_t getMaxHP() const { return m_battle_stats.hp; }
|
||||
const BattleStats& getBattleStats() const { return m_battle_stats; }
|
||||
const PokemonTypes& getTypes() const { return m_types; }
|
||||
Type getPrimaryType() const { return m_types.getPrimary(); }
|
||||
Type getSecondaryType() const { return m_types.getSecondary(); }
|
||||
|
||||
uint8_t getFriendship() const { return m_friendship; }
|
||||
|
||||
// Battle stat getters
|
||||
uint16_t getAttack() const { return m_battle_stats.attack; }
|
||||
uint16_t getDefense() const { return m_battle_stats.defense; }
|
||||
uint16_t getSpAttack() const { return m_battle_stats.sp_attack; }
|
||||
uint16_t getSpDefense() const { return m_battle_stats.sp_defense; }
|
||||
uint16_t getSpeed() const { return m_battle_stats.speed; }
|
||||
|
||||
// Setters
|
||||
void setHealth(uint16_t health) { m_health = health; }
|
||||
void setTypes(Type primary) { m_types.setPrimary(primary); m_types.setSecondary(Type::NONE); }
|
||||
void setTypes(Type primary, Type secondary) { m_types.setPrimary(primary); m_types.setSecondary(secondary); }
|
||||
void SetPokemonTypes(PokemonTypes types) { m_types = types; }
|
||||
|
||||
public:
|
||||
void setCurrentHP(uint16_t hp) {
|
||||
m_current_hp = (hp > m_battle_stats.hp) ? m_battle_stats.hp : hp;
|
||||
}
|
||||
void setFriendship(uint8_t friendship) { m_friendship = friendship; }
|
||||
|
||||
// Type-based operations
|
||||
template <Generation Gen = Generation::I>
|
||||
uint32_t calculateDamageTaken(uint32_t baseDamage, Type attackType) const {
|
||||
@@ -40,11 +102,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t m_id;
|
||||
uint16_t m_health;
|
||||
uint16_t m_species_id = 0;
|
||||
BattleStats m_battle_stats;
|
||||
PokemonTypes m_types;
|
||||
uint16_t m_current_hp = 0;
|
||||
uint8_t m_friendship = 0;
|
||||
};
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif
|
||||
#endif // POKEMON_H
|
||||
|
||||
209
include/core/pokemon_table.h
Normal file
209
include/core/pokemon_table.h
Normal file
@@ -0,0 +1,209 @@
|
||||
#ifndef POKEMON_TABLE_H
|
||||
#define POKEMON_TABLE_H
|
||||
|
||||
#include "pokemon.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Forward declaration
|
||||
struct PokemonSpecies;
|
||||
|
||||
/**
|
||||
* @brief A high-performance Pokemon data table that provides O(1) lookup by ID
|
||||
*
|
||||
* This class loads all Pokemon species data from JSON files and stores them
|
||||
* in a way that allows for extremely fast runtime access by Pokemon ID.
|
||||
* The table is designed to be loaded once at startup and then used throughout
|
||||
* the application's lifetime.
|
||||
*/
|
||||
class PokemonTable {
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* Creates an empty Pokemon table. Use loadFromDataDirectory() or
|
||||
* loadFromFiles() to populate the table with data.
|
||||
*/
|
||||
PokemonTable() = default;
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~PokemonTable() = default;
|
||||
|
||||
// Delete copy operations to prevent accidental copies
|
||||
PokemonTable(const PokemonTable&) = delete;
|
||||
PokemonTable& operator=(const PokemonTable&) = delete;
|
||||
|
||||
// Allow move operations
|
||||
PokemonTable(PokemonTable&&) = default;
|
||||
PokemonTable& operator=(PokemonTable&&) = default;
|
||||
|
||||
/**
|
||||
* @brief Load Pokemon data from the standard data directory
|
||||
*
|
||||
* This method loads all Pokemon data from the JSON files in the
|
||||
* data/pokemon/ directory, parsing all generations.
|
||||
*
|
||||
* @return true if loading was successful, false otherwise
|
||||
*/
|
||||
bool loadFromDataDirectory();
|
||||
|
||||
/**
|
||||
* @brief Load Pokemon data from specific JSON files
|
||||
*
|
||||
* @param filePaths Vector of paths to JSON files containing Pokemon data
|
||||
* @return true if loading was successful, false otherwise
|
||||
*/
|
||||
bool loadFromFiles(const std::vector<std::string>& filePaths);
|
||||
|
||||
/**
|
||||
* @brief Get a Pokemon species by its ID
|
||||
*
|
||||
* This is the primary lookup method and provides O(1) access time.
|
||||
*
|
||||
* @param id The Pokemon ID (1-based, e.g., 1 = Bulbasaur)
|
||||
* @return Pointer to the PokemonSpecies if found, nullptr otherwise
|
||||
*/
|
||||
const PokemonSpecies* getPokemon(uint16_t id) const;
|
||||
|
||||
/**
|
||||
* @brief Get a Pokemon species by its name
|
||||
*
|
||||
* This method provides O(1) access time using an internal hash map.
|
||||
*
|
||||
* @param name The Pokemon name (case-sensitive)
|
||||
* @return Pointer to the PokemonSpecies if found, nullptr otherwise
|
||||
*/
|
||||
const PokemonSpecies* getPokemonByName(std::string_view name) const;
|
||||
|
||||
/**
|
||||
* @brief Check if a Pokemon ID exists in the table
|
||||
*
|
||||
* @param id The Pokemon ID to check
|
||||
* @return true if the Pokemon exists, false otherwise
|
||||
*/
|
||||
bool hasPokemon(uint16_t id) const;
|
||||
|
||||
/**
|
||||
* @brief Get the total number of Pokemon species in the table
|
||||
*
|
||||
* @return The number of Pokemon species loaded
|
||||
*/
|
||||
size_t size() const;
|
||||
|
||||
/**
|
||||
* @brief Check if the table is empty
|
||||
*
|
||||
* @return true if no Pokemon data has been loaded, false otherwise
|
||||
*/
|
||||
bool empty() const;
|
||||
|
||||
/**
|
||||
* @brief Get the highest Pokemon ID in the table
|
||||
*
|
||||
* @return The maximum Pokemon ID, or 0 if the table is empty
|
||||
*/
|
||||
uint16_t getMaxId() const;
|
||||
|
||||
/**
|
||||
* @brief Clear all data from the table
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* @brief Get all Pokemon species (for iteration)
|
||||
*
|
||||
* @return A const reference to the internal vector of Pokemon species
|
||||
*/
|
||||
const std::vector<PokemonSpecies>& getAllPokemon() const;
|
||||
|
||||
/**
|
||||
* @brief Validate that the table contains valid data
|
||||
*
|
||||
* This method performs basic validation checks on the loaded data.
|
||||
*
|
||||
* @return true if the data appears valid, false otherwise
|
||||
*/
|
||||
bool validate() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Parse a single Pokemon JSON file
|
||||
*
|
||||
* @param filePath Path to the JSON file to parse
|
||||
* @return true if parsing was successful, false otherwise
|
||||
*/
|
||||
bool parsePokemonFile(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* @brief Parse a single Pokemon object from JSON
|
||||
*
|
||||
* @param pokemonJson The JSON value representing a Pokemon
|
||||
* @return The parsed PokemonSpecies object
|
||||
*/
|
||||
PokemonSpecies parsePokemonJson(const void* pokemonJson);
|
||||
|
||||
/**
|
||||
* @brief Parse base stats from JSON
|
||||
*
|
||||
* @param statsJson The JSON value containing the stats object
|
||||
* @return The parsed BaseStats object
|
||||
*/
|
||||
BaseStats parseBaseStats(const void* statsJson);
|
||||
|
||||
/**
|
||||
* @brief Parse Pokemon types from JSON
|
||||
*
|
||||
* @param typesJson The JSON array containing the types
|
||||
* @return The parsed PokemonTypes object
|
||||
*/
|
||||
PokemonTypes parseTypes(const void* typesJson);
|
||||
|
||||
private:
|
||||
// Storage for Pokemon species - indexed by ID (1-based)
|
||||
// Index 0 is unused, index 1 = Bulbasaur, etc.
|
||||
std::vector<PokemonSpecies> m_pokemonSpecies;
|
||||
|
||||
// Hash map for name-based lookups
|
||||
std::unordered_map<std::string, uint16_t> m_nameToIdMap;
|
||||
|
||||
// Track the maximum ID for validation
|
||||
uint16_t m_maxId = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Global Pokemon table instance
|
||||
*
|
||||
* This provides a convenient global access point to the Pokemon data.
|
||||
* The table should be initialized once at application startup.
|
||||
*/
|
||||
extern std::unique_ptr<PokemonTable> g_pokemonTable;
|
||||
|
||||
/**
|
||||
* @brief Initialize the global Pokemon table
|
||||
*
|
||||
* This function should be called once at application startup to load
|
||||
* all Pokemon data. It loads from the standard data directory.
|
||||
*
|
||||
* @return true if initialization was successful, false otherwise
|
||||
*/
|
||||
bool initializePokemonTable();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the global Pokemon table
|
||||
*
|
||||
* This function should be called at application shutdown to clean up
|
||||
* the global Pokemon table resources.
|
||||
*/
|
||||
void shutdownPokemonTable();
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif // POKEMON_TABLE_H
|
||||
221
include/core/stats.h
Normal file
221
include/core/stats.h
Normal file
@@ -0,0 +1,221 @@
|
||||
#ifndef STATS_H
|
||||
#define STATS_H
|
||||
|
||||
#include "config.h"
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Forward declaration
|
||||
class PokemonInfo;
|
||||
|
||||
// Base stats structure for a Pokemon species
|
||||
struct BaseStats {
|
||||
uint8_t hp;
|
||||
uint8_t attack;
|
||||
uint8_t defense;
|
||||
uint8_t sp_attack;
|
||||
uint8_t sp_defense;
|
||||
uint8_t speed;
|
||||
|
||||
BaseStats() : hp(0), attack(0), defense(0), sp_attack(0), sp_defense(0), speed(0) {}
|
||||
BaseStats(uint8_t hp_, uint8_t atk, uint8_t def, uint8_t spa, uint8_t spd, uint8_t spe)
|
||||
: hp(hp_), attack(atk), defense(def), sp_attack(spa), sp_defense(spd), speed(spe) {}
|
||||
};
|
||||
|
||||
// Effort Values (EVs) - max 510 total, max 255 per stat
|
||||
struct EffortValues {
|
||||
uint8_t hp;
|
||||
uint8_t attack;
|
||||
uint8_t defense;
|
||||
uint8_t sp_attack;
|
||||
uint8_t sp_defense;
|
||||
uint8_t speed;
|
||||
|
||||
EffortValues() : hp(0), attack(0), defense(0), sp_attack(0), sp_defense(0), speed(0) {}
|
||||
EffortValues(uint8_t hp_, uint8_t atk, uint8_t def, uint8_t spa, uint8_t spd, uint8_t spe)
|
||||
: hp(hp_), attack(atk), defense(def), sp_attack(spa), sp_defense(spd), speed(spe) {}
|
||||
|
||||
// Get total EVs (should not exceed 510)
|
||||
uint16_t getTotal() const {
|
||||
return static_cast<uint16_t>(static_cast<uint16_t>(hp) + attack + defense + sp_attack + sp_defense + speed);
|
||||
}
|
||||
|
||||
// Validate EVs (total <= 510, each <= 255)
|
||||
bool isValid() const {
|
||||
return getTotal() <= 510;
|
||||
}
|
||||
};
|
||||
|
||||
// Individual Values (IVs) - 0-31 per stat
|
||||
// Packed into 32 bits: 5 bits per stat + 2 bits unused
|
||||
struct IndividualValues {
|
||||
private:
|
||||
uint32_t m_packed; // 30 bits used: HP(0-4), ATK(5-9), DEF(10-14), SPA(15-19), SPD(20-24), SPE(25-29)
|
||||
|
||||
public:
|
||||
IndividualValues() : m_packed(0) {}
|
||||
IndividualValues(uint8_t hp_, uint8_t atk, uint8_t def, uint8_t spa, uint8_t spd, uint8_t spe) {
|
||||
setHP(hp_);
|
||||
setAttack(atk);
|
||||
setDefense(def);
|
||||
setSpAttack(spa);
|
||||
setSpDefense(spd);
|
||||
setSpeed(spe);
|
||||
}
|
||||
|
||||
// Getters
|
||||
uint8_t getHP() const { return (m_packed & 0x1F); }
|
||||
uint8_t getAttack() const { return (m_packed >> 5) & 0x1F; }
|
||||
uint8_t getDefense() const { return (m_packed >> 10) & 0x1F; }
|
||||
uint8_t getSpAttack() const { return (m_packed >> 15) & 0x1F; }
|
||||
uint8_t getSpDefense() const { return (m_packed >> 20) & 0x1F; }
|
||||
uint8_t getSpeed() const { return (m_packed >> 25) & 0x1F; }
|
||||
|
||||
// Legacy getters for compatibility
|
||||
uint8_t hp() const { return getHP(); }
|
||||
uint8_t attack() const { return getAttack(); }
|
||||
uint8_t defense() const { return getDefense(); }
|
||||
uint8_t sp_attack() const { return getSpAttack(); }
|
||||
uint8_t sp_defense() const { return getSpDefense(); }
|
||||
uint8_t speed() const { return getSpeed(); }
|
||||
|
||||
// Setters
|
||||
void setHP(uint8_t value) {
|
||||
if (value > 31) value = 31;
|
||||
m_packed = (m_packed & ~0x1FU) | (value & 0x1FU);
|
||||
}
|
||||
void setAttack(uint8_t value) {
|
||||
if (value > 31) value = 31;
|
||||
m_packed = (m_packed & ~(0x1FU << 5)) | ((value & 0x1FU) << 5);
|
||||
}
|
||||
void setDefense(uint8_t value) {
|
||||
if (value > 31) value = 31;
|
||||
m_packed = (m_packed & ~(0x1FU << 10)) | ((value & 0x1FU) << 10);
|
||||
}
|
||||
void setSpAttack(uint8_t value) {
|
||||
if (value > 31) value = 31;
|
||||
m_packed = (m_packed & ~(0x1FU << 15)) | ((value & 0x1FU) << 15);
|
||||
}
|
||||
void setSpDefense(uint8_t value) {
|
||||
if (value > 31) value = 31;
|
||||
m_packed = (m_packed & ~(0x1FU << 20)) | ((value & 0x1FU) << 20);
|
||||
}
|
||||
void setSpeed(uint8_t value) {
|
||||
if (value > 31) value = 31;
|
||||
m_packed = (m_packed & ~(0x1FU << 25)) | ((value & 0x1FU) << 25);
|
||||
}
|
||||
|
||||
// Validate IVs (each <= 31) - always true with our implementation
|
||||
bool isValid() const {
|
||||
return true; // Always valid since we enforce limits in setters
|
||||
}
|
||||
};
|
||||
|
||||
// Computed battle stat
|
||||
struct BattleStats {
|
||||
uint16_t hp;
|
||||
uint16_t attack;
|
||||
uint16_t defense;
|
||||
uint16_t sp_attack;
|
||||
uint16_t sp_defense;
|
||||
uint16_t speed;
|
||||
|
||||
BattleStats() : hp(0), attack(0), defense(0), sp_attack(0), sp_defense(0), speed(0) {}
|
||||
BattleStats(uint16_t hp_, uint16_t atk, uint16_t def, uint16_t spa, uint16_t spd, uint16_t spe)
|
||||
: hp(hp_), attack(atk), defense(def), sp_attack(spa), sp_defense(spd), speed(spe) {}
|
||||
};
|
||||
|
||||
// Pokemon information class - holds data not directly relevant to battle
|
||||
class PokemonInfo {
|
||||
public:
|
||||
PokemonInfo() = default;
|
||||
|
||||
PokemonInfo(const BaseStats& baseStats, uint8_t level = 1, Nature nature = Nature::HARDY(),
|
||||
const IndividualValues& ivs = IndividualValues(),
|
||||
const EffortValues& evs = EffortValues())
|
||||
: m_baseStats(baseStats), m_ivs(ivs), m_evs(evs), m_level(level), m_nature(nature) {}
|
||||
|
||||
// Getters
|
||||
const BaseStats& getBaseStats() const { return m_baseStats; }
|
||||
uint8_t getLevel() const { return m_level; }
|
||||
Nature getNature() const { return m_nature; }
|
||||
const IndividualValues& getIVs() const { return m_ivs; }
|
||||
const EffortValues& getEVs() const { return m_evs; }
|
||||
|
||||
// Setters
|
||||
void setBaseStats(const BaseStats& baseStats) { m_baseStats = baseStats; }
|
||||
void setLevel(uint8_t level) { m_level = (level > 100) ? 100 : level; }
|
||||
void setNature(Nature nature) { m_nature = nature; }
|
||||
void setIVs(const IndividualValues& ivs) { if (ivs.isValid()) m_ivs = ivs; }
|
||||
void setEVs(const EffortValues& evs) { if (evs.isValid()) m_evs = evs; }
|
||||
|
||||
// Calculate battle stats for different generations
|
||||
template<Generation Gen>
|
||||
BattleStats calculateBattleStats() const;
|
||||
|
||||
private:
|
||||
BaseStats m_baseStats; // size 6, align 1
|
||||
IndividualValues m_ivs; // size 6, align 1
|
||||
EffortValues m_evs; // size 6, align 1
|
||||
uint8_t m_level = 1; // size 1, align 1
|
||||
Nature m_nature; // size 1, align 1
|
||||
};
|
||||
|
||||
struct StatCalculatorParams
|
||||
{
|
||||
StatCalculatorParams() = default;
|
||||
StatCalculatorParams(uint8_t base, uint8_t iv, uint8_t ev, uint8_t level, Nature nature, StatIndex statIndex, uint16_t statExp)
|
||||
: m_base(base), m_iv(iv), m_ev(ev), m_level(level), m_nature(nature), m_statIndex(statIndex), m_statExp(statExp) {}
|
||||
|
||||
uint8_t m_base;
|
||||
uint8_t m_iv;
|
||||
uint8_t m_ev;
|
||||
uint8_t m_level;
|
||||
Nature m_nature;
|
||||
StatIndex m_statIndex;
|
||||
uint16_t m_statExp;
|
||||
};
|
||||
|
||||
inline uint16_t CalculateHP_GenI_II(StatCalculatorParams params)
|
||||
{
|
||||
// HP=⌊((Base+DV)×2+⌊⌈sqrt(STATEXP)⌉4⌋)×Level100⌋+Level+10
|
||||
return (((params.m_base + (params.m_iv >> 1u)) << 1u) + (static_cast<uint16_t>(std::ceil(std::sqrt(params.m_statExp))) >> 2u)) * params.m_level / 100u + params.m_level + 10u;
|
||||
}
|
||||
|
||||
inline uint16_t CalculateStat_GenI_II(StatCalculatorParams params)
|
||||
{
|
||||
// OtherStat=⌊((Base+DV)×2+⌊⌈sqrt(STATEXP)⌉4⌋)×Level100⌋+5
|
||||
return (((params.m_base + (params.m_iv >> 1u)) << 1u) + (static_cast<uint16_t>(std::ceil(std::sqrt(params.m_statExp))) >> 2u)) * params.m_level / 100u + 5u;
|
||||
}
|
||||
|
||||
template <Generation Gen>
|
||||
uint16_t CalculateHP(StatCalculatorParams params);
|
||||
template <Generation Gen>
|
||||
uint16_t CalculateStat(StatCalculatorParams params);
|
||||
|
||||
template <> inline uint16_t CalculateHP<Generation::I>(StatCalculatorParams params) { return CalculateHP_GenI_II(params); }
|
||||
template <> inline uint16_t CalculateHP<Generation::II>(StatCalculatorParams params) { return CalculateHP_GenI_II(params); }
|
||||
|
||||
template <> inline uint16_t CalculateStat<Generation::I>(StatCalculatorParams params) { return CalculateStat_GenI_II(params); }
|
||||
template <> inline uint16_t CalculateStat<Generation::II>(StatCalculatorParams params) { return CalculateStat_GenI_II(params); }
|
||||
|
||||
template <Generation Gen>
|
||||
inline uint16_t CalculateHP(StatCalculatorParams params)
|
||||
{
|
||||
// HP=⌊(2×Base+IV+⌊EV4⌋)×Level100⌋+Level+10
|
||||
return ((2 * params.m_base + params.m_iv + (params.m_ev >> 2)) * params.m_level / 100) + params.m_level + 10;
|
||||
}
|
||||
|
||||
template <Generation Gen>
|
||||
inline uint16_t CalculateStat(StatCalculatorParams params)
|
||||
{
|
||||
// OtherStat=⌊(⌊(2×Base+IV+⌊EV4⌋)×Level100⌋+5)×Nature⌋
|
||||
return (((2 * params.m_base + params.m_iv + (params.m_ev >> 2)) * params.m_level / 100) + 5) * params.m_nature.getMultiplier10(params.m_statIndex) / 10;
|
||||
}
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
#endif // STATS_H
|
||||
@@ -3,9 +3,12 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -39,6 +42,9 @@ enum class Type : uint8_t {
|
||||
TYPE_COUNT // Keep this last for array sizing
|
||||
};
|
||||
|
||||
constexpr size_t TYPE_COUNT = static_cast<size_t>(Type::TYPE_COUNT);
|
||||
constexpr size_t TYPE_CHART_SIZE = TYPE_COUNT * TYPE_COUNT;
|
||||
|
||||
// Type multipliers as integers (multiply by 2 for 0.5x, 4 for 0.25x, etc.)
|
||||
enum class TypeMultiplier : uint8_t {
|
||||
ZERO = 0, // 0x damage (immune)
|
||||
@@ -49,16 +55,6 @@ enum class TypeMultiplier : uint8_t {
|
||||
QUADRUPLE = 16 // 4x damage
|
||||
};
|
||||
|
||||
// Compile-time type chart traits
|
||||
template <Generation Gen>
|
||||
struct TypeChartTraits {
|
||||
static constexpr size_t TYPE_COUNT = static_cast<size_t>(Type::TYPE_COUNT);
|
||||
static constexpr size_t CHART_SIZE = TYPE_COUNT * TYPE_COUNT;
|
||||
|
||||
// Each generation has its own type chart
|
||||
static const std::array<TypeMultiplier, CHART_SIZE>& getTypeChart();
|
||||
};
|
||||
|
||||
// Pokemon type representation
|
||||
class PokemonTypes {
|
||||
public:
|
||||
@@ -95,21 +91,13 @@ public:
|
||||
template <Generation Gen>
|
||||
static uint32_t calculateDamageMultiplier(Type attackType, const PokemonTypes& defenderTypes);
|
||||
|
||||
// Load type chart from JSON file
|
||||
// Get type chart for a specific generation
|
||||
template <Generation Gen>
|
||||
static bool loadTypeChartFromFile(const std::string& filename);
|
||||
static const std::span<const TypeMultiplier> getTypeChart();
|
||||
|
||||
public:
|
||||
// Type chart storage for each generation (public for template access)
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::I>::CHART_SIZE> s_gen1Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::II>::CHART_SIZE> s_gen2Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::III>::CHART_SIZE> s_gen3Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::IV>::CHART_SIZE> s_gen4Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::V>::CHART_SIZE> s_gen5Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::VI>::CHART_SIZE> s_gen6Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::VII>::CHART_SIZE> s_gen7Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::VIII>::CHART_SIZE> s_gen8Chart;
|
||||
static std::array<TypeMultiplier, TypeChartTraits<Generation::IX>::CHART_SIZE> s_gen9Chart;
|
||||
static std::array<std::span<const TypeMultiplier>, static_cast<size_t>(Generation::IX) + 1> s_typeChart;
|
||||
};
|
||||
|
||||
// High-performance damage calculation
|
||||
@@ -123,60 +111,12 @@ inline uint32_t calculateDamage(uint32_t baseDamage, Type attackType, const Poke
|
||||
return (baseDamage * rawMultiplier) / static_cast<uint32_t>(TypeMultiplier::NEUTRAL);
|
||||
}
|
||||
|
||||
// Template specializations for type chart access
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::I>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::I>::getTypeChart() {
|
||||
return TypeUtils::s_gen1Chart;
|
||||
template <Generation Gen>
|
||||
inline const std::span<const TypeMultiplier> TypeUtils::getTypeChart() {
|
||||
return s_typeChart[static_cast<size_t>(Gen)];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::II>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::II>::getTypeChart() {
|
||||
return TypeUtils::s_gen2Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::III>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::III>::getTypeChart() {
|
||||
return TypeUtils::s_gen3Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::IV>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::IV>::getTypeChart() {
|
||||
return TypeUtils::s_gen4Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::V>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::V>::getTypeChart() {
|
||||
return TypeUtils::s_gen5Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::VI>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::VI>::getTypeChart() {
|
||||
return TypeUtils::s_gen6Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::VII>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::VII>::getTypeChart() {
|
||||
return TypeUtils::s_gen7Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::VIII>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::VIII>::getTypeChart() {
|
||||
return TypeUtils::s_gen8Chart;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const std::array<TypeMultiplier, TypeChartTraits<Generation::IX>::CHART_SIZE>&
|
||||
TypeChartTraits<Generation::IX>::getTypeChart() {
|
||||
return TypeUtils::s_gen9Chart;
|
||||
}
|
||||
void initializeTypeCharts();
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef POKEMON_BATTLE_SIM_H
|
||||
#define POKEMON_BATTLE_SIM_H
|
||||
|
||||
// Main header file for Pokemon Battle Simulator
|
||||
// Includes all core functionality
|
||||
|
||||
#include "core/types.h"
|
||||
#include "core/pokemon.h"
|
||||
#include "core/battle.h"
|
||||
#include "core/config.h"
|
||||
|
||||
// Forward declarations for functions
|
||||
namespace PokEng {
|
||||
bool simulateBattle(Pokemon& pokemon1, Pokemon& pokemon2);
|
||||
}
|
||||
|
||||
#endif // POKEMON_BATTLE_SIM_H
|
||||
372
src/core/pokemon_table.cpp
Normal file
372
src/core/pokemon_table.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
#include "core/pokemon_table.h"
|
||||
#include "../thirdParty/rapidjson/document.h"
|
||||
#include "../thirdParty/rapidjson/filereadstream.h"
|
||||
#include "../thirdParty/rapidjson/error/en.h"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// Global Pokemon table instance
|
||||
std::unique_ptr<PokemonTable> g_pokemonTable;
|
||||
|
||||
bool PokemonTable::loadFromDataDirectory() {
|
||||
// Clear any existing data
|
||||
clear();
|
||||
|
||||
// Get the path to the data directory relative to the executable
|
||||
fs::path dataDir = fs::current_path() / "data" / "pokemon";
|
||||
|
||||
// If not found, try relative to the build directory (common in CMake builds)
|
||||
if (!fs::exists(dataDir)) {
|
||||
dataDir = fs::current_path() / ".." / "data" / "pokemon";
|
||||
}
|
||||
|
||||
// If still not found, try a few more common locations
|
||||
if (!fs::exists(dataDir)) {
|
||||
dataDir = fs::current_path() / "data" / "pokemon";
|
||||
if (!fs::exists(dataDir)) {
|
||||
std::cerr << "Error: Could not find Pokemon data directory at: " << dataDir << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> jsonFiles;
|
||||
|
||||
// Find all JSON files in the pokemon data directory
|
||||
for (const auto& entry : fs::directory_iterator(dataDir)) {
|
||||
if (entry.is_regular_file() && entry.path().extension() == ".json") {
|
||||
jsonFiles.push_back(entry.path().string());
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonFiles.empty()) {
|
||||
std::cerr << "Error: No Pokemon JSON files found in: " << dataDir << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sort files to ensure consistent loading order
|
||||
std::sort(jsonFiles.begin(), jsonFiles.end());
|
||||
|
||||
std::cout << "Found " << jsonFiles.size() << " Pokemon data files to load" << std::endl;
|
||||
|
||||
return loadFromFiles(jsonFiles);
|
||||
}
|
||||
|
||||
bool PokemonTable::loadFromFiles(const std::vector<std::string>& filePaths) {
|
||||
clear();
|
||||
|
||||
bool success = true;
|
||||
size_t totalPokemonLoaded = 0;
|
||||
|
||||
for (const auto& filePath : filePaths) {
|
||||
if (!parsePokemonFile(filePath)) {
|
||||
std::cerr << "Failed to parse Pokemon file: " << filePath << std::endl;
|
||||
success = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Count Pokemon in this file (rough estimate)
|
||||
std::ifstream file(filePath);
|
||||
if (file.is_open()) {
|
||||
std::string content((std::istreambuf_iterator<char>(file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
size_t pokemonCount = std::count(content.begin(), content.end(), '{');
|
||||
totalPokemonLoaded += pokemonCount / 2; // Rough estimate
|
||||
}
|
||||
}
|
||||
|
||||
if (success && !m_pokemonSpecies.empty()) {
|
||||
std::cout << "Successfully loaded " << size() << " Pokemon species" << std::endl;
|
||||
std::cout << "Max Pokemon ID: " << getMaxId() << std::endl;
|
||||
}
|
||||
|
||||
return success && !m_pokemonSpecies.empty();
|
||||
}
|
||||
|
||||
bool PokemonTable::parsePokemonFile(const std::string& filePath) {
|
||||
using namespace rapidjson;
|
||||
|
||||
// Open the file
|
||||
FILE* fp = fopen(filePath.c_str(), "rb");
|
||||
if (!fp) {
|
||||
std::cerr << "Error: Could not open file: " << filePath << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a file read stream
|
||||
char readBuffer[65536];
|
||||
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
|
||||
|
||||
// Parse the JSON document
|
||||
Document doc;
|
||||
doc.ParseStream(is);
|
||||
|
||||
// Check for parse errors
|
||||
if (doc.HasParseError()) {
|
||||
std::cerr << "JSON parse error in file " << filePath << ": "
|
||||
<< GetParseError_En(doc.GetParseError()) << std::endl;
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close the file
|
||||
fclose(fp);
|
||||
|
||||
// Verify it's an array
|
||||
if (!doc.IsArray()) {
|
||||
std::cerr << "Error: Expected JSON array in file: " << filePath << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse each Pokemon in the array
|
||||
for (const auto& pokemonValue : doc.GetArray()) {
|
||||
if (!pokemonValue.IsObject()) {
|
||||
std::cerr << "Warning: Skipping non-object entry in " << filePath << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
PokemonSpecies species = parsePokemonJson(&pokemonValue);
|
||||
|
||||
// Ensure the vector is large enough
|
||||
if (species.id >= m_pokemonSpecies.size()) {
|
||||
m_pokemonSpecies.resize(species.id + 1);
|
||||
}
|
||||
|
||||
// Store the Pokemon
|
||||
m_pokemonSpecies[species.id] = species;
|
||||
|
||||
// Update the name-to-ID mapping
|
||||
m_nameToIdMap[species.name] = species.id;
|
||||
|
||||
// Update max ID
|
||||
if (species.id > m_maxId) {
|
||||
m_maxId = species.id;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error parsing Pokemon in " << filePath << ": " << e.what() << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PokemonSpecies PokemonTable::parsePokemonJson(const void* pokemonJson) {
|
||||
using namespace rapidjson;
|
||||
|
||||
const Value* pokemonValue = static_cast<const Value*>(pokemonJson);
|
||||
PokemonSpecies species;
|
||||
|
||||
// Parse ID
|
||||
if (pokemonValue->HasMember("id") && (*pokemonValue)["id"].IsUint()) {
|
||||
species.id = static_cast<uint16_t>((*pokemonValue)["id"].GetUint());
|
||||
} else {
|
||||
throw std::runtime_error("Missing or invalid 'id' field");
|
||||
}
|
||||
|
||||
// Parse name
|
||||
if (pokemonValue->HasMember("name") && (*pokemonValue)["name"].IsString()) {
|
||||
species.name = (*pokemonValue)["name"].GetString();
|
||||
} else {
|
||||
throw std::runtime_error("Missing or invalid 'name' field");
|
||||
}
|
||||
|
||||
// Parse base stats
|
||||
if (pokemonValue->HasMember("stats") && (*pokemonValue)["stats"].IsObject()) {
|
||||
species.base_stats = parseBaseStats(&(*pokemonValue)["stats"]);
|
||||
} else {
|
||||
throw std::runtime_error("Missing or invalid 'stats' field");
|
||||
}
|
||||
|
||||
// Parse types
|
||||
if (pokemonValue->HasMember("types") && (*pokemonValue)["types"].IsArray()) {
|
||||
species.types = parseTypes(&(*pokemonValue)["types"]);
|
||||
} else {
|
||||
throw std::runtime_error("Missing or invalid 'types' field");
|
||||
}
|
||||
|
||||
return species;
|
||||
}
|
||||
|
||||
BaseStats PokemonTable::parseBaseStats(const void* statsJson) {
|
||||
using namespace rapidjson;
|
||||
|
||||
const Value* statsValue = static_cast<const Value*>(statsJson);
|
||||
BaseStats baseStats;
|
||||
|
||||
// Helper function to safely get stat value
|
||||
auto getStatValue = [](const Value& obj, const char* key) -> uint8_t {
|
||||
if (obj.HasMember(key) && obj[key].IsUint()) {
|
||||
return static_cast<uint8_t>(std::min(obj[key].GetUint(), 255u));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
baseStats.hp = getStatValue(*statsValue, "hp");
|
||||
baseStats.attack = getStatValue(*statsValue, "attack");
|
||||
baseStats.defense = getStatValue(*statsValue, "defense");
|
||||
baseStats.sp_attack = getStatValue(*statsValue, "special-attack");
|
||||
baseStats.sp_defense = getStatValue(*statsValue, "special-defense");
|
||||
baseStats.speed = getStatValue(*statsValue, "speed");
|
||||
|
||||
return baseStats;
|
||||
}
|
||||
|
||||
PokemonTypes PokemonTable::parseTypes(const void* typesJson) {
|
||||
using namespace rapidjson;
|
||||
|
||||
const Value* typesValue = static_cast<const Value*>(typesJson);
|
||||
PokemonTypes types;
|
||||
|
||||
if (typesValue->Empty()) {
|
||||
return types; // Return empty types
|
||||
}
|
||||
|
||||
// Get the first type (primary)
|
||||
if (typesValue->Size() > 0) {
|
||||
const auto& firstType = (*typesValue)[0];
|
||||
if (firstType.IsString()) {
|
||||
std::string typeStr = firstType.GetString();
|
||||
auto type = TypeUtils::stringToType(typeStr);
|
||||
if (type) {
|
||||
types.setPrimary(*type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the second type (secondary) if it exists
|
||||
if (typesValue->Size() > 1) {
|
||||
const auto& secondType = (*typesValue)[1];
|
||||
if (secondType.IsString()) {
|
||||
std::string typeStr = secondType.GetString();
|
||||
auto type = TypeUtils::stringToType(typeStr);
|
||||
if (type) {
|
||||
types.setSecondary(*type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const PokemonSpecies* PokemonTable::getPokemon(uint16_t id) const {
|
||||
if (id == 0 || id >= m_pokemonSpecies.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &m_pokemonSpecies[id];
|
||||
}
|
||||
|
||||
const PokemonSpecies* PokemonTable::getPokemonByName(std::string_view name) const {
|
||||
auto it = m_nameToIdMap.find(std::string(name));
|
||||
if (it == m_nameToIdMap.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return getPokemon(it->second);
|
||||
}
|
||||
|
||||
bool PokemonTable::hasPokemon(uint16_t id) const {
|
||||
return id > 0 && id < m_pokemonSpecies.size() && m_pokemonSpecies[id].id != 0;
|
||||
}
|
||||
|
||||
size_t PokemonTable::size() const {
|
||||
// Count non-empty entries (ID != 0)
|
||||
return std::count_if(m_pokemonSpecies.begin(), m_pokemonSpecies.end(),
|
||||
[](const PokemonSpecies& species) { return species.id != 0; });
|
||||
}
|
||||
|
||||
bool PokemonTable::empty() const {
|
||||
return m_pokemonSpecies.empty() || size() == 0;
|
||||
}
|
||||
|
||||
uint16_t PokemonTable::getMaxId() const {
|
||||
return m_maxId;
|
||||
}
|
||||
|
||||
void PokemonTable::clear() {
|
||||
m_pokemonSpecies.clear();
|
||||
m_nameToIdMap.clear();
|
||||
m_maxId = 0;
|
||||
}
|
||||
|
||||
const std::vector<PokemonSpecies>& PokemonTable::getAllPokemon() const {
|
||||
return m_pokemonSpecies;
|
||||
}
|
||||
|
||||
bool PokemonTable::validate() const {
|
||||
if (empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that all Pokemon have valid IDs
|
||||
for (uint16_t id = 1; id <= m_maxId; ++id) {
|
||||
const auto* pokemon = getPokemon(id);
|
||||
if (pokemon) {
|
||||
if (pokemon->id != id) {
|
||||
std::cerr << "Validation error: Pokemon at ID " << id
|
||||
<< " has mismatched ID " << pokemon->id << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (pokemon->name.empty()) {
|
||||
std::cerr << "Validation error: Pokemon ID " << id
|
||||
<< " has empty name" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check name-to-ID mapping consistency
|
||||
for (const auto& pair : m_nameToIdMap) {
|
||||
const auto* pokemon = getPokemon(pair.second);
|
||||
if (!pokemon || pokemon->name != pair.first) {
|
||||
std::cerr << "Validation error: Name-to-ID mapping inconsistency for '"
|
||||
<< pair.first << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initializePokemonTable() {
|
||||
if (g_pokemonTable) {
|
||||
std::cout << "Warning: Pokemon table already initialized" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
g_pokemonTable = std::make_unique<PokemonTable>();
|
||||
|
||||
if (!g_pokemonTable->loadFromDataDirectory()) {
|
||||
std::cerr << "Failed to initialize Pokemon table" << std::endl;
|
||||
g_pokemonTable.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!g_pokemonTable->validate()) {
|
||||
std::cerr << "Pokemon table validation failed" << std::endl;
|
||||
g_pokemonTable.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Pokemon table initialized successfully with "
|
||||
<< g_pokemonTable->size() << " Pokemon" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdownPokemonTable() {
|
||||
if (g_pokemonTable) {
|
||||
std::cout << "Shutting down Pokemon table" << std::endl;
|
||||
g_pokemonTable.reset();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace PokEng
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "pokemon_battle_sim.h"
|
||||
#include "core/config.h"
|
||||
#include "core/types.h"
|
||||
#include "../thirdParty/rapidjson/document.h"
|
||||
#include "../thirdParty/rapidjson/filereadstream.h"
|
||||
#include <cstdio>
|
||||
@@ -8,16 +9,6 @@
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Static type chart storage initialization
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::I>::CHART_SIZE> TypeUtils::s_gen1Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::II>::CHART_SIZE> TypeUtils::s_gen2Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::III>::CHART_SIZE> TypeUtils::s_gen3Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::IV>::CHART_SIZE> TypeUtils::s_gen4Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::V>::CHART_SIZE> TypeUtils::s_gen5Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::VI>::CHART_SIZE> TypeUtils::s_gen6Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::VII>::CHART_SIZE> TypeUtils::s_gen7Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::VIII>::CHART_SIZE> TypeUtils::s_gen8Chart;
|
||||
std::array<TypeMultiplier, TypeChartTraits<Generation::IX>::CHART_SIZE> TypeUtils::s_gen9Chart;
|
||||
|
||||
// String to type mapping
|
||||
static const std::unordered_map<std::string_view, Type> s_stringToTypeMap = {
|
||||
@@ -87,103 +78,35 @@ std::string_view TypeUtils::typeToString(Type type) {
|
||||
}
|
||||
|
||||
template <Generation Gen>
|
||||
TypeMultiplier TypeUtils::getTypeEffectiveness(Type attackType, Type defendType) {
|
||||
if (attackType == Type::NONE || defendType == Type::NONE) {
|
||||
return TypeMultiplier::NEUTRAL;
|
||||
}
|
||||
|
||||
const auto& chart = TypeChartTraits<Gen>::getTypeChart();
|
||||
size_t attackIdx = static_cast<size_t>(attackType);
|
||||
size_t defendIdx = static_cast<size_t>(defendType);
|
||||
size_t index = attackIdx * static_cast<size_t>(Type::TYPE_COUNT) + defendIdx;
|
||||
|
||||
if (index < chart.size()) {
|
||||
return chart[index];
|
||||
}
|
||||
|
||||
return TypeMultiplier::NEUTRAL;
|
||||
TypeMultiplier TypeUtils::getTypeEffectiveness(Type attackType, Type defendType)
|
||||
{
|
||||
size_t index = static_cast<uint8_t>(attackType) * static_cast<uint8_t>(Type::TYPE_COUNT) + static_cast<uint8_t>(defendType);
|
||||
return TypeUtils::getTypeChart<Gen>()[index];
|
||||
}
|
||||
|
||||
// Helper function to convert TypeMultiplier enum to actual multiplier value
|
||||
static float typeMultiplierToFloat(TypeMultiplier multiplier) {
|
||||
switch (multiplier) {
|
||||
case TypeMultiplier::ZERO: return 0.0f;
|
||||
case TypeMultiplier::QUARTER: return 0.25f;
|
||||
case TypeMultiplier::HALF: return 0.5f;
|
||||
case TypeMultiplier::NEUTRAL: return 1.0f;
|
||||
case TypeMultiplier::DOUBLE: return 2.0f;
|
||||
case TypeMultiplier::QUADRUPLE: return 4.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
||||
// Example of the JSON file format
|
||||
// "normal": {
|
||||
// "double_damage_from": [
|
||||
// "fighting"
|
||||
// ],
|
||||
// "double_damage_to": [],
|
||||
// "half_damage_from": [],
|
||||
// "half_damage_to": [
|
||||
// "rock",
|
||||
// "steel"
|
||||
// ],
|
||||
// "no_damage_from": [
|
||||
// "ghost"
|
||||
// ],
|
||||
// "no_damage_to": [
|
||||
// "ghost"
|
||||
// ]
|
||||
// }
|
||||
|
||||
// Helper function to convert float multiplier back to integer representation
|
||||
static uint32_t floatToMultiplierInt(float multiplier) {
|
||||
if (multiplier == 0.0f) return static_cast<uint32_t>(TypeMultiplier::ZERO);
|
||||
if (multiplier == 0.25f) return static_cast<uint32_t>(TypeMultiplier::QUARTER);
|
||||
if (multiplier == 0.5f) return static_cast<uint32_t>(TypeMultiplier::HALF);
|
||||
if (multiplier == 1.0f) return static_cast<uint32_t>(TypeMultiplier::NEUTRAL);
|
||||
if (multiplier == 2.0f) return static_cast<uint32_t>(TypeMultiplier::DOUBLE);
|
||||
if (multiplier == 4.0f) return static_cast<uint32_t>(TypeMultiplier::QUADRUPLE);
|
||||
return static_cast<uint32_t>(TypeMultiplier::NEUTRAL);
|
||||
}
|
||||
|
||||
template <Generation Gen>
|
||||
uint32_t TypeUtils::calculateDamageMultiplier(Type attackType, const PokemonTypes& defenderTypes) {
|
||||
if (attackType == Type::NONE) {
|
||||
return static_cast<uint32_t>(TypeMultiplier::NEUTRAL);
|
||||
}
|
||||
|
||||
// Get effectiveness against primary type and convert to float
|
||||
float multiplier = typeMultiplierToFloat(getTypeEffectiveness<Gen>(attackType, defenderTypes.getPrimary()));
|
||||
|
||||
// If there's a secondary type, multiply by its effectiveness
|
||||
if (defenderTypes.hasSecondary()) {
|
||||
float secondaryMultiplier = typeMultiplierToFloat(getTypeEffectiveness<Gen>(attackType, defenderTypes.getSecondary()));
|
||||
multiplier *= secondaryMultiplier;
|
||||
}
|
||||
|
||||
// Convert back to integer representation
|
||||
return floatToMultiplierInt(multiplier);
|
||||
}
|
||||
|
||||
// Explicit template instantiations for all generations
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::I>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::II>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::III>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::IV>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::V>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::VI>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::VII>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::VIII>(Type, Type);
|
||||
template TypeMultiplier TypeUtils::getTypeEffectiveness<Generation::IX>(Type, Type);
|
||||
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::I>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::II>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::III>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::IV>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::V>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::VI>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::VII>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::VIII>(Type, const PokemonTypes&);
|
||||
template uint32_t TypeUtils::calculateDamageMultiplier<Generation::IX>(Type, const PokemonTypes&);
|
||||
|
||||
// Convert float damage factor to TypeMultiplier
|
||||
static TypeMultiplier floatToTypeMultiplier(double factor) {
|
||||
if (factor == 0.0) return TypeMultiplier::ZERO;
|
||||
if (factor == 0.25) return TypeMultiplier::QUARTER;
|
||||
if (factor == 0.5) return TypeMultiplier::HALF;
|
||||
if (factor == 1.0) return TypeMultiplier::NEUTRAL;
|
||||
if (factor == 2.0) return TypeMultiplier::DOUBLE;
|
||||
if (factor == 4.0) return TypeMultiplier::QUADRUPLE;
|
||||
return TypeMultiplier::NEUTRAL; // Default fallback
|
||||
}
|
||||
|
||||
template <Generation Gen>
|
||||
bool TypeUtils::loadTypeChartFromFile(const std::string& filename) {
|
||||
std::array<TypeMultiplier, TYPE_CHART_SIZE> loadTypeChartFromFile(const std::string& filename) {
|
||||
FILE* fp = fopen(filename.c_str(), "r");
|
||||
if (!fp) {
|
||||
return false;
|
||||
return std::array<TypeMultiplier, TYPE_CHART_SIZE>{};
|
||||
}
|
||||
|
||||
char readBuffer[65536];
|
||||
@@ -193,116 +116,168 @@ bool TypeUtils::loadTypeChartFromFile(const std::string& filename) {
|
||||
doc.ParseStream(is);
|
||||
fclose(fp);
|
||||
|
||||
if (doc.HasParseError() || !doc.IsArray()) {
|
||||
return false;
|
||||
if (doc.HasParseError() || !doc.IsObject()) {
|
||||
return std::array<TypeMultiplier, TYPE_CHART_SIZE>{};
|
||||
}
|
||||
|
||||
// Initialize the chart with neutral values
|
||||
// Note: We access the static members directly since getTypeChart() returns const reference
|
||||
if constexpr (Gen == Generation::I) {
|
||||
std::fill(TypeUtils::s_gen1Chart.begin(), TypeUtils::s_gen1Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::II) {
|
||||
std::fill(TypeUtils::s_gen2Chart.begin(), TypeUtils::s_gen2Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::III) {
|
||||
std::fill(TypeUtils::s_gen3Chart.begin(), TypeUtils::s_gen3Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::IV) {
|
||||
std::fill(TypeUtils::s_gen4Chart.begin(), TypeUtils::s_gen4Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::V) {
|
||||
std::fill(TypeUtils::s_gen5Chart.begin(), TypeUtils::s_gen5Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::VI) {
|
||||
std::fill(TypeUtils::s_gen6Chart.begin(), TypeUtils::s_gen6Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::VII) {
|
||||
std::fill(TypeUtils::s_gen7Chart.begin(), TypeUtils::s_gen7Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::VIII) {
|
||||
std::fill(TypeUtils::s_gen8Chart.begin(), TypeUtils::s_gen8Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
} else if constexpr (Gen == Generation::IX) {
|
||||
std::fill(TypeUtils::s_gen9Chart.begin(), TypeUtils::s_gen9Chart.end(), TypeMultiplier::NEUTRAL);
|
||||
}
|
||||
// Create and initialize type chart with neutral effectiveness
|
||||
auto typeChart = std::array<TypeMultiplier, TYPE_CHART_SIZE>();
|
||||
typeChart.fill(TypeMultiplier::NEUTRAL);
|
||||
|
||||
// Parse JSON and populate type chart
|
||||
for (const auto& entry : doc.GetArray()) {
|
||||
if (!entry.IsObject()) continue;
|
||||
for (auto it = doc.MemberBegin(); it != doc.MemberEnd(); ++it) {
|
||||
const std::string defendingTypeStr = it->name.GetString();
|
||||
auto defendingTypeOpt = TypeUtils::stringToType(defendingTypeStr);
|
||||
|
||||
if (!entry.HasMember("attacking_type") || !entry.HasMember("defending_type") ||
|
||||
!entry.HasMember("damage_factor")) {
|
||||
if (!defendingTypeOpt.has_value()) {
|
||||
continue; // Skip unknown types
|
||||
}
|
||||
|
||||
Type defendingType = defendingTypeOpt.value();
|
||||
const auto& typeData = it->value;
|
||||
|
||||
if (!typeData.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& attackTypeStr = entry["attacking_type"].GetString();
|
||||
const auto& defendTypeStr = entry["defending_type"].GetString();
|
||||
double damageFactor = entry["damage_factor"].GetDouble();
|
||||
|
||||
auto attackTypeOpt = stringToType(attackTypeStr);
|
||||
auto defendTypeOpt = stringToType(defendTypeStr);
|
||||
|
||||
if (!attackTypeOpt || !defendTypeOpt) {
|
||||
continue;
|
||||
// Process double_damage_from (types that deal 2x damage to this type)
|
||||
if (typeData.HasMember("double_damage_from") && typeData["double_damage_from"].IsArray()) {
|
||||
for (const auto& attackTypeVal : typeData["double_damage_from"].GetArray()) {
|
||||
if (attackTypeVal.IsString()) {
|
||||
auto attackTypeOpt = TypeUtils::stringToType(attackTypeVal.GetString());
|
||||
if (attackTypeOpt.has_value()) {
|
||||
size_t attackIdx = static_cast<size_t>(attackTypeOpt.value());
|
||||
size_t defendIdx = static_cast<size_t>(defendingType);
|
||||
size_t index = attackIdx * TYPE_COUNT + defendIdx;
|
||||
typeChart[index] = TypeMultiplier::DOUBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type attackType = *attackTypeOpt;
|
||||
Type defendType = *defendTypeOpt;
|
||||
TypeMultiplier multiplier = floatToTypeMultiplier(damageFactor);
|
||||
// Process half_damage_from (types that deal 0.5x damage to this type)
|
||||
if (typeData.HasMember("half_damage_from") && typeData["half_damage_from"].IsArray()) {
|
||||
for (const auto& attackTypeVal : typeData["half_damage_from"].GetArray()) {
|
||||
if (attackTypeVal.IsString()) {
|
||||
auto attackTypeOpt = TypeUtils::stringToType(attackTypeVal.GetString());
|
||||
if (attackTypeOpt.has_value()) {
|
||||
size_t attackIdx = static_cast<size_t>(attackTypeOpt.value());
|
||||
size_t defendIdx = static_cast<size_t>(defendingType);
|
||||
size_t index = attackIdx * TYPE_COUNT + defendIdx;
|
||||
typeChart[index] = TypeMultiplier::HALF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t attackIdx = static_cast<size_t>(attackType);
|
||||
size_t defendIdx = static_cast<size_t>(defendType);
|
||||
size_t index = attackIdx * static_cast<size_t>(Type::TYPE_COUNT) + defendIdx;
|
||||
size_t chartSize = static_cast<size_t>(Type::TYPE_COUNT) * static_cast<size_t>(Type::TYPE_COUNT);
|
||||
// Process no_damage_from (types that deal 0x damage to this type)
|
||||
if (typeData.HasMember("no_damage_from") && typeData["no_damage_from"].IsArray()) {
|
||||
for (const auto& attackTypeVal : typeData["no_damage_from"].GetArray()) {
|
||||
if (attackTypeVal.IsString()) {
|
||||
auto attackTypeOpt = TypeUtils::stringToType(attackTypeVal.GetString());
|
||||
if (attackTypeOpt.has_value()) {
|
||||
size_t attackIdx = static_cast<size_t>(attackTypeOpt.value());
|
||||
size_t defendIdx = static_cast<size_t>(defendingType);
|
||||
size_t index = attackIdx * TYPE_COUNT + defendIdx;
|
||||
typeChart[index] = TypeMultiplier::ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index < chartSize) {
|
||||
// Direct assignment to static members
|
||||
if constexpr (Gen == Generation::I) {
|
||||
TypeUtils::s_gen1Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::II) {
|
||||
TypeUtils::s_gen2Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::III) {
|
||||
TypeUtils::s_gen3Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::IV) {
|
||||
TypeUtils::s_gen4Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::V) {
|
||||
TypeUtils::s_gen5Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::VI) {
|
||||
TypeUtils::s_gen6Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::VII) {
|
||||
TypeUtils::s_gen7Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::VIII) {
|
||||
TypeUtils::s_gen8Chart[index] = multiplier;
|
||||
} else if constexpr (Gen == Generation::IX) {
|
||||
TypeUtils::s_gen9Chart[index] = multiplier;
|
||||
// Process double_damage_to (types this type deals 2x damage to)
|
||||
if (typeData.HasMember("double_damage_to") && typeData["double_damage_to"].IsArray()) {
|
||||
for (const auto& defendTypeVal : typeData["double_damage_to"].GetArray()) {
|
||||
if (defendTypeVal.IsString()) {
|
||||
auto defendTypeOpt = TypeUtils::stringToType(defendTypeVal.GetString());
|
||||
if (defendTypeOpt.has_value()) {
|
||||
size_t attackIdx = static_cast<size_t>(defendingType);
|
||||
size_t defendIdx = static_cast<size_t>(defendTypeOpt.value());
|
||||
size_t index = attackIdx * TYPE_COUNT + defendIdx;
|
||||
typeChart[index] = TypeMultiplier::DOUBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process half_damage_to (types this type deals 0.5x damage to)
|
||||
if (typeData.HasMember("half_damage_to") && typeData["half_damage_to"].IsArray()) {
|
||||
for (const auto& defendTypeVal : typeData["half_damage_to"].GetArray()) {
|
||||
if (defendTypeVal.IsString()) {
|
||||
auto defendTypeOpt = TypeUtils::stringToType(defendTypeVal.GetString());
|
||||
if (defendTypeOpt.has_value()) {
|
||||
size_t attackIdx = static_cast<size_t>(defendingType);
|
||||
size_t defendIdx = static_cast<size_t>(defendTypeOpt.value());
|
||||
size_t index = attackIdx * TYPE_COUNT + defendIdx;
|
||||
typeChart[index] = TypeMultiplier::HALF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process no_damage_to (types this type deals 0x damage to)
|
||||
if (typeData.HasMember("no_damage_to") && typeData["no_damage_to"].IsArray()) {
|
||||
for (const auto& defendTypeVal : typeData["no_damage_to"].GetArray()) {
|
||||
if (defendTypeVal.IsString()) {
|
||||
auto defendTypeOpt = TypeUtils::stringToType(defendTypeVal.GetString());
|
||||
if (defendTypeOpt.has_value()) {
|
||||
size_t attackIdx = static_cast<size_t>(defendingType);
|
||||
size_t defendIdx = static_cast<size_t>(defendTypeOpt.value());
|
||||
size_t index = attackIdx * TYPE_COUNT + defendIdx;
|
||||
typeChart[index] = TypeMultiplier::ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return typeChart;
|
||||
}
|
||||
|
||||
// Explicit template instantiations for loading
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::I>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::II>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::III>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::IV>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::V>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::VI>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::VII>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::VIII>(const std::string&);
|
||||
template bool TypeUtils::loadTypeChartFromFile<Generation::IX>(const std::string&);
|
||||
bool compareTypeChart(const std::array<TypeMultiplier, TYPE_CHART_SIZE>& chart1, const std::array<TypeMultiplier, TYPE_CHART_SIZE>& chart2) {
|
||||
return std::equal(chart1.begin(), chart1.end(), chart2.begin());
|
||||
}
|
||||
|
||||
std::span<const TypeMultiplier> getDuplicateTypeChart(const std::array<TypeMultiplier, TYPE_CHART_SIZE>& chart)
|
||||
{
|
||||
static std::vector<std::array<TypeMultiplier, TYPE_CHART_SIZE>> allCharts;
|
||||
allCharts.reserve(static_cast<size_t>(Generation::IX) + 1);
|
||||
|
||||
// Check if the chart is already in the list
|
||||
for (const auto& otherChart : allCharts) {
|
||||
if (compareTypeChart(chart, otherChart)) {
|
||||
return std::span<const TypeMultiplier>(otherChart);
|
||||
}
|
||||
}
|
||||
allCharts.push_back(chart);
|
||||
return std::span<const TypeMultiplier>(allCharts.back());
|
||||
}
|
||||
|
||||
// Initialize type charts on startup
|
||||
struct TypeChartInitializer {
|
||||
TypeChartInitializer() {
|
||||
// Load type charts for each generation
|
||||
TypeUtils::loadTypeChartFromFile<Generation::I>("../data/type_effectiveness_generation-i.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::II>("../data/type_effectiveness_generation-ii.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::III>("../data/type_effectiveness_generation-iii.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::IV>("../data/type_effectiveness_generation-iv.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::V>("../data/type_effectiveness_generation-v.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::VI>("../data/type_effectiveness_generation-vi.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::VII>("../data/type_effectiveness_generation-vii.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::VIII>("../data/type_effectiveness_generation-viii.json");
|
||||
TypeUtils::loadTypeChartFromFile<Generation::IX>("../data/type_effectiveness_generation-ix.json");
|
||||
}
|
||||
void initializeTypeCharts() {
|
||||
// Load type charts for each generation and store them in static arrays
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::I)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-i.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::II)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-ii.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::III)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-iii.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::IV)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-iv.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::V)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-v.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::VI)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-vi.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::VII)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-vii.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::VIII)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-viii.json"));
|
||||
TypeUtils::s_typeChart[static_cast<size_t>(Generation::IX)] =
|
||||
getDuplicateTypeChart(loadTypeChartFromFile("../data/types/generation-ix.json"));
|
||||
};
|
||||
|
||||
// Static initializer to load type charts at program startup
|
||||
static TypeChartInitializer s_initializer;
|
||||
// Definition of the static type chart array
|
||||
std::array<std::span<const TypeMultiplier>, static_cast<size_t>(Generation::IX) + 1> TypeUtils::s_typeChart;
|
||||
|
||||
|
||||
} // namespace PokEng
|
||||
|
||||
16
src/main.cpp
Normal file
16
src/main.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "core/types.h"
|
||||
#include "core/pokemon_table.h"
|
||||
|
||||
using namespace PokEng;
|
||||
|
||||
int main() {
|
||||
|
||||
initializeTypeCharts();
|
||||
initializePokemonTable();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
# Configure the project
|
||||
cmake -B build -S .
|
||||
|
||||
# Build the project (includes tests)
|
||||
cmake --build build
|
||||
|
||||
# Run all tests
|
||||
cmake --build build --target test
|
||||
107
tests/unit/core/test_pokemon_table.cpp
Normal file
107
tests/unit/core/test_pokemon_table.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "core/pokemon_table.h"
|
||||
|
||||
using namespace PokEng;
|
||||
|
||||
class PokemonTableTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Initialize the global Pokemon table for each test
|
||||
ASSERT_TRUE(initializePokemonTable());
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Clean up the global Pokemon table after each test
|
||||
shutdownPokemonTable();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PokemonTableTest, Initialization) {
|
||||
ASSERT_TRUE(g_pokemonTable != nullptr);
|
||||
EXPECT_GT(g_pokemonTable->size(), 0);
|
||||
EXPECT_GT(g_pokemonTable->getMaxId(), 0);
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, BulbasaurLookup) {
|
||||
const auto* bulbasaur = g_pokemonTable->getPokemon(1);
|
||||
ASSERT_TRUE(bulbasaur != nullptr);
|
||||
EXPECT_EQ(bulbasaur->id, 1);
|
||||
EXPECT_EQ(bulbasaur->name, "bulbasaur");
|
||||
EXPECT_EQ(bulbasaur->base_stats.hp, 45);
|
||||
EXPECT_EQ(bulbasaur->base_stats.attack, 49);
|
||||
EXPECT_EQ(bulbasaur->base_stats.defense, 49);
|
||||
EXPECT_EQ(bulbasaur->base_stats.sp_attack, 65);
|
||||
EXPECT_EQ(bulbasaur->base_stats.sp_defense, 65);
|
||||
EXPECT_EQ(bulbasaur->base_stats.speed, 45);
|
||||
|
||||
// Check types
|
||||
EXPECT_EQ(bulbasaur->types.getPrimary(), Type::GRASS);
|
||||
EXPECT_EQ(bulbasaur->types.getSecondary(), Type::POISON);
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, NameBasedLookup) {
|
||||
const auto* charizard = g_pokemonTable->getPokemonByName("charizard");
|
||||
ASSERT_TRUE(charizard != nullptr);
|
||||
EXPECT_EQ(charizard->id, 6); // Charizard's ID
|
||||
EXPECT_EQ(charizard->name, "charizard");
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, InvalidIdLookup) {
|
||||
const auto* invalid = g_pokemonTable->getPokemon(99999);
|
||||
EXPECT_TRUE(invalid == nullptr);
|
||||
|
||||
// Test ID 0 (should be invalid)
|
||||
const auto* zero = g_pokemonTable->getPokemon(0);
|
||||
EXPECT_TRUE(zero == nullptr);
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, InvalidNameLookup) {
|
||||
const auto* invalid = g_pokemonTable->getPokemonByName("nonexistentpokemon");
|
||||
EXPECT_TRUE(invalid == nullptr);
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, HasPokemonFunction) {
|
||||
EXPECT_TRUE(g_pokemonTable->hasPokemon(1)); // Bulbasaur
|
||||
EXPECT_TRUE(g_pokemonTable->hasPokemon(150)); // Mewtwo
|
||||
EXPECT_FALSE(g_pokemonTable->hasPokemon(0));
|
||||
EXPECT_FALSE(g_pokemonTable->hasPokemon(99999));
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, PerformanceTest) {
|
||||
// Test that lookups are fast enough (less than 1ms for 1000 lookups)
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
uint16_t id = (i % g_pokemonTable->getMaxId()) + 1;
|
||||
const auto* pokemon = g_pokemonTable->getPokemon(id);
|
||||
ASSERT_TRUE(pokemon != nullptr);
|
||||
// Just access some data to ensure the pointer is valid
|
||||
volatile uint16_t hp = pokemon->base_stats.hp;
|
||||
(void)hp; // Prevent optimization
|
||||
}
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
||||
|
||||
// Should be much faster than 1ms for 1000 lookups
|
||||
EXPECT_LT(duration.count(), 1);
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, Validation) {
|
||||
EXPECT_TRUE(g_pokemonTable->validate());
|
||||
}
|
||||
|
||||
TEST_F(PokemonTableTest, MewtwoStats) {
|
||||
const auto* mewtwo = g_pokemonTable->getPokemon(150);
|
||||
ASSERT_TRUE(mewtwo != nullptr);
|
||||
EXPECT_EQ(mewtwo->id, 150);
|
||||
EXPECT_EQ(mewtwo->name, "mewtwo");
|
||||
EXPECT_EQ(mewtwo->base_stats.hp, 106);
|
||||
EXPECT_EQ(mewtwo->base_stats.attack, 110);
|
||||
EXPECT_EQ(mewtwo->base_stats.defense, 90);
|
||||
EXPECT_EQ(mewtwo->base_stats.sp_attack, 154);
|
||||
EXPECT_EQ(mewtwo->base_stats.sp_defense, 90);
|
||||
EXPECT_EQ(mewtwo->base_stats.speed, 130);
|
||||
EXPECT_EQ(mewtwo->types.getPrimary(), Type::PSYCHIC);
|
||||
EXPECT_EQ(mewtwo->types.getSecondary(), Type::NONE);
|
||||
}
|
||||
171
tests/unit/core/test_stats.cpp
Normal file
171
tests/unit/core/test_stats.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "core/stats.h"
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Test fixture for stats tests
|
||||
class StatsTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Set up test fixtures
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Clean up test fixtures
|
||||
}
|
||||
};
|
||||
|
||||
// Generation I && II example
|
||||
// HP Attack Defense Sp.Atk Sp.Def Speed
|
||||
// Base stat 35 55 30 50 50 90
|
||||
// IV 14 16 26 18 10 0
|
||||
// StatXP 22850 23140 17280 19625 24795 0
|
||||
// Total 189 137 101 128 112 190
|
||||
|
||||
/**
|
||||
// Test type string conversion
|
||||
TEST_F(StatsTest, CalculateHP_GenI_II) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 35;
|
||||
pikachuParams.m_iv = 14;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::HP;
|
||||
pikachuParams.m_statExp = 22850;
|
||||
|
||||
EXPECT_EQ(CalculateHP<Generation::I>(pikachuParams), 189);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenI_II_Attack) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 55;
|
||||
pikachuParams.m_iv = 16;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::ATTACK;
|
||||
pikachuParams.m_statExp = 23140;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::I>(pikachuParams), 137);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenI_II_Defense) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 30;
|
||||
pikachuParams.m_iv = 26;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::DEFENSE;
|
||||
pikachuParams.m_statExp = 17280;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::I>(pikachuParams), 101);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenI_II_SpAttack) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 50;
|
||||
pikachuParams.m_iv = 18;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::SP_ATTACK;
|
||||
pikachuParams.m_statExp = 19625;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::I>(pikachuParams), 128);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenI_II_SpDefense) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 50;
|
||||
pikachuParams.m_iv = 10;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::SP_DEFENSE;
|
||||
pikachuParams.m_statExp = 24795;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::I>(pikachuParams), 112);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenI_II_Speed) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 90;
|
||||
pikachuParams.m_iv = 0;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::SPEED;
|
||||
pikachuParams.m_statExp = 0;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::I>(pikachuParams), 190);
|
||||
}
|
||||
|
||||
// Generation 3+ example
|
||||
// HP Attack Defense Sp.Atk Sp.Def Speed
|
||||
// Base stat 108 130 95 80 85 102
|
||||
// IV 24 12 30 16 23 5
|
||||
// EV 74 190 91 48 84 23
|
||||
// Total 289 278 193 135 171 171
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenIII) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 108;
|
||||
pikachuParams.m_iv = 24;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::ATTACK;
|
||||
pikachuParams.m_statExp = 74;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::III>(pikachuParams), 278);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenIII_Defense) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 130;
|
||||
pikachuParams.m_iv = 12;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::DEFENSE;
|
||||
pikachuParams.m_statExp = 190;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::III>(pikachuParams), 193);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenIII_SpAttack) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 80;
|
||||
pikachuParams.m_iv = 16;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::SP_ATTACK;
|
||||
pikachuParams.m_statExp = 48;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::III>(pikachuParams), 135);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenIII_SpDefense) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 85;
|
||||
pikachuParams.m_iv = 23;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::SP_DEFENSE;
|
||||
pikachuParams.m_statExp = 84;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::III>(pikachuParams), 171);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateStat_GenIII_Speed) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 102;
|
||||
pikachuParams.m_iv = 5;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::SPEED;
|
||||
pikachuParams.m_statExp = 23;
|
||||
|
||||
EXPECT_EQ(CalculateStat<Generation::III>(pikachuParams), 171);
|
||||
}
|
||||
|
||||
TEST_F(StatsTest, CalculateHP_GenIII) {
|
||||
StatCalculatorParams pikachuParams;
|
||||
pikachuParams.m_base = 108;
|
||||
pikachuParams.m_iv = 24;
|
||||
pikachuParams.m_level = 81;
|
||||
pikachuParams.m_statIndex = StatIndex::HP;
|
||||
pikachuParams.m_statExp = 74;
|
||||
|
||||
EXPECT_EQ(CalculateHP<Generation::III>(pikachuParams), 289);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
} // namespace PokEng
|
||||
@@ -1,272 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "pokemon_battle_sim.h"
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
namespace PokEng {
|
||||
|
||||
// Test fixture for type system tests
|
||||
class TypeSystemTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
// Set up test fixtures
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Clean up test fixtures
|
||||
}
|
||||
};
|
||||
|
||||
// Test type string conversion
|
||||
TEST_F(TypeSystemTest, StringToTypeConversion) {
|
||||
// Test valid conversions
|
||||
EXPECT_EQ(TypeUtils::stringToType("fire"), Type::FIRE);
|
||||
EXPECT_EQ(TypeUtils::stringToType("WATER"), Type::WATER); // Case insensitive
|
||||
EXPECT_EQ(TypeUtils::stringToType("Normal"), Type::NORMAL);
|
||||
EXPECT_EQ(TypeUtils::stringToType("none"), Type::NONE);
|
||||
|
||||
// Test invalid conversions
|
||||
EXPECT_FALSE(TypeUtils::stringToType("invalid_type").has_value());
|
||||
EXPECT_FALSE(TypeUtils::stringToType("").has_value());
|
||||
}
|
||||
|
||||
TEST_F(TypeSystemTest, TypeToStringConversion) {
|
||||
// Test valid conversions
|
||||
EXPECT_EQ(TypeUtils::typeToString(Type::FIRE), "fire");
|
||||
EXPECT_EQ(TypeUtils::typeToString(Type::WATER), "water");
|
||||
EXPECT_EQ(TypeUtils::typeToString(Type::NONE), "none");
|
||||
EXPECT_EQ(TypeUtils::typeToString(Type::DARK), "dark");
|
||||
EXPECT_EQ(TypeUtils::typeToString(Type::FAIRY), "fairy");
|
||||
|
||||
// Test out of range (shouldn't happen in practice but good to test)
|
||||
EXPECT_EQ(TypeUtils::typeToString(static_cast<Type>(static_cast<uint8_t>(Type::TYPE_COUNT) + 10)), "unknown");
|
||||
}
|
||||
|
||||
// Test PokemonTypes class
|
||||
TEST_F(TypeSystemTest, PokemonTypesBasic) {
|
||||
// Single type Pokemon
|
||||
PokemonTypes charizard(Type::FIRE);
|
||||
EXPECT_EQ(charizard.getPrimary(), Type::FIRE);
|
||||
EXPECT_EQ(charizard.getSecondary(), Type::NONE);
|
||||
EXPECT_FALSE(charizard.hasSecondary());
|
||||
|
||||
// Dual type Pokemon
|
||||
PokemonTypes arcanine(Type::FIRE, Type::NORMAL);
|
||||
EXPECT_EQ(arcanine.getPrimary(), Type::FIRE);
|
||||
EXPECT_EQ(arcanine.getSecondary(), Type::NORMAL);
|
||||
EXPECT_TRUE(arcanine.hasSecondary());
|
||||
}
|
||||
|
||||
TEST_F(TypeSystemTest, PokemonTypesModification) {
|
||||
PokemonTypes pokemon;
|
||||
|
||||
// Test default state
|
||||
EXPECT_EQ(pokemon.getPrimary(), Type::NONE);
|
||||
EXPECT_EQ(pokemon.getSecondary(), Type::NONE);
|
||||
|
||||
// Test setting types
|
||||
pokemon.setPrimary(Type::WATER);
|
||||
pokemon.setSecondary(Type::FLYING);
|
||||
|
||||
EXPECT_EQ(pokemon.getPrimary(), Type::WATER);
|
||||
EXPECT_EQ(pokemon.getSecondary(), Type::FLYING);
|
||||
EXPECT_TRUE(pokemon.hasSecondary());
|
||||
}
|
||||
|
||||
// Test type effectiveness for Generation 1
|
||||
TEST_F(TypeSystemTest, TypeEffectivenessGen1) {
|
||||
// Test some well-known type matchups from Generation 1
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::WATER, Type::FIRE), TypeMultiplier::DOUBLE);
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::FIRE, Type::WATER), TypeMultiplier::HALF);
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::NORMAL, Type::ROCK), TypeMultiplier::HALF);
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::ELECTRIC, Type::GROUND), TypeMultiplier::ZERO);
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::FIGHTING, Type::GHOST), TypeMultiplier::ZERO);
|
||||
}
|
||||
|
||||
TEST_F(TypeSystemTest, TypeEffectivenessNeutral) {
|
||||
// Test neutral effectiveness (1x damage)
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::NORMAL, Type::NORMAL), TypeMultiplier::NEUTRAL);
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::FIRE, Type::FIRE), TypeMultiplier::NEUTRAL);
|
||||
|
||||
// Test NONE types
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::NONE, Type::FIRE), TypeMultiplier::NEUTRAL);
|
||||
EXPECT_EQ(TypeUtils::getTypeEffectiveness<Generation::I>(Type::FIRE, Type::NONE), TypeMultiplier::NEUTRAL);
|
||||
}
|
||||
|
||||
// Test damage multiplier calculations
|
||||
TEST_F(TypeSystemTest, DamageMultiplierSingleType) {
|
||||
// Single type Pokemon
|
||||
PokemonTypes charizard(Type::FIRE);
|
||||
|
||||
// Fire attack on Fire type (1.0x - same type is neutral)
|
||||
uint32_t multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(Type::FIRE, charizard);
|
||||
EXPECT_EQ(multiplier, static_cast<uint32_t>(TypeMultiplier::NEUTRAL));
|
||||
|
||||
// Water attack on Fire type (2x)
|
||||
multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(Type::WATER, charizard);
|
||||
EXPECT_EQ(multiplier, static_cast<uint32_t>(TypeMultiplier::DOUBLE));
|
||||
}
|
||||
|
||||
TEST_F(TypeSystemTest, DamageMultiplierDualType) {
|
||||
// Dual type Pokemon (Water/Flying)
|
||||
PokemonTypes gyarados(Type::WATER, Type::FLYING);
|
||||
|
||||
// Electric attack on Water/Flying (2x * 2x = 4x)
|
||||
uint32_t multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(Type::ELECTRIC, gyarados);
|
||||
EXPECT_EQ(multiplier, static_cast<uint32_t>(TypeMultiplier::QUADRUPLE));
|
||||
|
||||
// Grass attack on Water/Flying (0.5x * 0.5x = 0.25x)
|
||||
multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(Type::GRASS, gyarados);
|
||||
EXPECT_EQ(multiplier, static_cast<uint32_t>(TypeMultiplier::QUARTER));
|
||||
}
|
||||
|
||||
TEST_F(TypeSystemTest, DamageMultiplierNoneAttack) {
|
||||
PokemonTypes charizard(Type::FIRE);
|
||||
|
||||
// NONE attack type should always return neutral multiplier
|
||||
uint32_t multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(Type::NONE, charizard);
|
||||
EXPECT_EQ(multiplier, static_cast<uint32_t>(TypeMultiplier::NEUTRAL));
|
||||
}
|
||||
|
||||
// Test the high-level damage calculation function
|
||||
TEST_F(TypeSystemTest, CalculateDamage) {
|
||||
PokemonTypes charizard(Type::FIRE);
|
||||
const uint32_t baseDamage = 100;
|
||||
|
||||
// Fire attack on Fire type: 100 * 1.0 = 100 (same type is neutral)
|
||||
uint32_t damage = calculateDamage<Generation::I>(baseDamage, Type::FIRE, charizard);
|
||||
EXPECT_EQ(damage, 100);
|
||||
|
||||
// Water attack on Fire type: 100 * 2 = 200
|
||||
damage = calculateDamage<Generation::I>(baseDamage, Type::WATER, charizard);
|
||||
EXPECT_EQ(damage, 200);
|
||||
|
||||
// Normal attack on Fire type: 100 * 1 = 100
|
||||
damage = calculateDamage<Generation::I>(baseDamage, Type::NORMAL, charizard);
|
||||
EXPECT_EQ(damage, 100);
|
||||
}
|
||||
|
||||
TEST_F(TypeSystemTest, CalculateDamageDualType) {
|
||||
PokemonTypes gyarados(Type::WATER, Type::FLYING);
|
||||
const uint32_t baseDamage = 100;
|
||||
|
||||
// Electric attack on Water/Flying: 100 * 4 = 400
|
||||
uint32_t damage = calculateDamage<Generation::I>(baseDamage, Type::ELECTRIC, gyarados);
|
||||
EXPECT_EQ(damage, 400);
|
||||
|
||||
// Grass attack on Water/Flying: 100 * 0.25 = 25
|
||||
damage = calculateDamage<Generation::I>(baseDamage, Type::GRASS, gyarados);
|
||||
EXPECT_EQ(damage, 25);
|
||||
}
|
||||
|
||||
// Test edge cases
|
||||
TEST_F(TypeSystemTest, EdgeCases) {
|
||||
// Test with zero base damage
|
||||
PokemonTypes pokemon(Type::FIRE);
|
||||
uint32_t damage = calculateDamage<Generation::I>(0, Type::WATER, pokemon);
|
||||
EXPECT_EQ(damage, 0);
|
||||
|
||||
// Test immunity (0x multiplier)
|
||||
damage = calculateDamage<Generation::I>(100, Type::GROUND, PokemonTypes(Type::ELECTRIC));
|
||||
EXPECT_EQ(damage, 0);
|
||||
}
|
||||
|
||||
// Test different generations have different type charts
|
||||
TEST_F(TypeSystemTest, GenerationDifferences) {
|
||||
// Ghost/Fighting immunity in Gen 1
|
||||
uint32_t gen1Multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(
|
||||
Type::FIGHTING, PokemonTypes(Type::GHOST));
|
||||
EXPECT_EQ(gen1Multiplier, static_cast<uint32_t>(TypeMultiplier::ZERO));
|
||||
|
||||
// In later generations, this might be different (Normal/Fighting would be neutral)
|
||||
// Note: This is just a demonstration - we'd need actual Gen 2+ data to test properly
|
||||
}
|
||||
|
||||
// Parameterized test for various type combinations
|
||||
class TypeCombinationTest : public ::testing::TestWithParam<std::tuple<Type, Type, uint32_t>> {
|
||||
};
|
||||
|
||||
TEST_P(TypeCombinationTest, VariousTypeCombinations) {
|
||||
auto [attackType, defendType, expectedMultiplier] = GetParam();
|
||||
|
||||
PokemonTypes defender(defendType);
|
||||
uint32_t actualMultiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(attackType, defender);
|
||||
|
||||
EXPECT_EQ(actualMultiplier, expectedMultiplier)
|
||||
<< "Attack: " << TypeUtils::typeToString(attackType)
|
||||
<< ", Defense: " << TypeUtils::typeToString(defendType);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
TypeCombinations,
|
||||
TypeCombinationTest,
|
||||
::testing::Values(
|
||||
std::make_tuple(Type::WATER, Type::FIRE, static_cast<uint32_t>(TypeMultiplier::DOUBLE)),
|
||||
std::make_tuple(Type::FIRE, Type::WATER, static_cast<uint32_t>(TypeMultiplier::HALF)),
|
||||
std::make_tuple(Type::NORMAL, Type::ROCK, static_cast<uint32_t>(TypeMultiplier::HALF)),
|
||||
std::make_tuple(Type::ELECTRIC, Type::GROUND, static_cast<uint32_t>(TypeMultiplier::ZERO)),
|
||||
std::make_tuple(Type::NORMAL, Type::NORMAL, static_cast<uint32_t>(TypeMultiplier::NEUTRAL))
|
||||
)
|
||||
);
|
||||
|
||||
// Performance test to ensure type lookups are fast
|
||||
TEST_F(TypeSystemTest, PerformanceTest) {
|
||||
PokemonTypes pokemon(Type::FIRE, Type::FLYING);
|
||||
|
||||
// Test that multiple lookups are fast (this would be caught by benchmark tests too)
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
uint32_t multiplier = TypeUtils::calculateDamageMultiplier<Generation::I>(Type::WATER, pokemon);
|
||||
(void)multiplier; // Prevent optimization
|
||||
}
|
||||
}
|
||||
|
||||
// Test the high-level damage calculation functions
|
||||
TEST_F(TypeSystemTest, CalculateDamageFunctions) {
|
||||
// Test calculateTypeDamage with single type
|
||||
uint32_t damage1 = calculateTypeDamage<Generation::I>(100, Type::WATER, Type::FIRE);
|
||||
EXPECT_EQ(damage1, 200);
|
||||
|
||||
uint32_t damage2 = calculateTypeDamage<Generation::I>(100, Type::FIRE, Type::WATER);
|
||||
EXPECT_EQ(damage2, 50);
|
||||
|
||||
// Test calculateTypeDamage with dual type
|
||||
uint32_t damage3 = calculateTypeDamage<Generation::I>(100, Type::ELECTRIC, Type::WATER, Type::FLYING);
|
||||
EXPECT_EQ(damage3, 400);
|
||||
|
||||
// Test immunity
|
||||
uint32_t damage4 = calculateTypeDamage<Generation::I>(100, Type::GROUND, Type::ELECTRIC);
|
||||
EXPECT_EQ(damage4, 0);
|
||||
}
|
||||
|
||||
// Test Pokemon damage calculation methods
|
||||
TEST_F(TypeSystemTest, PokemonDamageCalculation) {
|
||||
Pokemon charizard(6, 100, Type::FIRE, Type::FLYING);
|
||||
|
||||
// Test various attack types
|
||||
uint32_t fireDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::FIRE);
|
||||
EXPECT_EQ(fireDamage, 100); // Fire vs Fire/Flying: 1.0x (neutral for Fire) * 1.0x (neutral for Flying)
|
||||
|
||||
uint32_t waterDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::WATER);
|
||||
EXPECT_EQ(waterDamage, 200);
|
||||
|
||||
uint32_t electricDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::ELECTRIC);
|
||||
EXPECT_EQ(electricDamage, 200); // 2x vs Flying, neutral vs Fire
|
||||
|
||||
uint32_t groundDamage = charizard.calculateDamageTaken<Generation::I>(100, Type::GROUND);
|
||||
EXPECT_EQ(groundDamage, 0); // Ground is immune to Flying
|
||||
}
|
||||
|
||||
// Test generation differences
|
||||
TEST_F(TypeSystemTest, GenerationDifferencesTest) {
|
||||
// Steel type was introduced in Gen 2
|
||||
uint32_t gen1Damage = calculateTypeDamage<Generation::I>(100, Type::NORMAL, Type::STEEL);
|
||||
uint32_t gen8Damage = calculateTypeDamage<Generation::VIII>(100, Type::NORMAL, Type::STEEL);
|
||||
|
||||
// Results may differ based on loaded type charts
|
||||
EXPECT_GE(gen1Damage, 0);
|
||||
EXPECT_GE(gen8Damage, 0);
|
||||
EXPECT_LE(gen1Damage, 400);
|
||||
EXPECT_LE(gen8Damage, 400);
|
||||
}
|
||||
|
||||
} // namespace PokEng
|
||||
2
thirdParty/rapidjson/allocators.h
vendored
2
thirdParty/rapidjson/allocators.h
vendored
@@ -634,7 +634,7 @@ private:
|
||||
BaseAllocator baseAllocator_;
|
||||
};
|
||||
|
||||
#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
|
||||
#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++20
|
||||
template <typename BaseAllocator>
|
||||
class StdAllocator<void, BaseAllocator> :
|
||||
public std::allocator<void>
|
||||
|
||||
2
thirdParty/rapidjson/rapidjson.h
vendored
2
thirdParty/rapidjson/rapidjson.h
vendored
@@ -643,7 +643,7 @@ RAPIDJSON_NAMESPACE_END
|
||||
#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// C++17 features
|
||||
// C++20 features
|
||||
|
||||
#ifndef RAPIDJSON_HAS_CXX17
|
||||
#define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L)
|
||||
|
||||
@@ -1,305 +1,208 @@
|
||||
# Pokemon Data Downloader
|
||||
# Pokemon Data Tools
|
||||
|
||||
A comprehensive tool for downloading Pokemon battle data from the PokeAPI using the `pokebase` library. This tool supports segmented downloading, data validation, and exports data in JSON format optimized for the C++ Pokemon battle simulator.
|
||||
This directory contains tools for downloading and processing Pokemon data from the PokeAPI.
|
||||
|
||||
## Features
|
||||
## Pokemon Downloader (`pokemon_downloader.py`)
|
||||
|
||||
- **Segmented Downloads**: Download specific ranges of Pokemon or moves for testing and incremental data collection
|
||||
- **Concurrent Processing**: Multi-threaded downloads with configurable worker counts
|
||||
- **Data Validation**: Built-in JSON schema validation for data integrity
|
||||
- **Rate Limiting**: Respectful API usage with automatic rate limiting
|
||||
- **Progress Tracking**: Beautiful progress bars and detailed logging
|
||||
- **Battle-Ready Data**: Exports complete Pokemon stats, moves, types, and effectiveness data
|
||||
- **CLI Interface**: Easy-to-use command-line interface with multiple commands
|
||||
A comprehensive tool for downloading generation-specific Pokemon data from the PokeAPI.
|
||||
|
||||
## Installation
|
||||
### Features
|
||||
|
||||
1. Install dependencies:
|
||||
```bash
|
||||
cd /testbed
|
||||
pip install -r tools/requirements.txt
|
||||
```
|
||||
- **Type Effectiveness**: Downloads type matchup charts for each generation
|
||||
- **Pokemon Data**: Downloads Pokemon species data including stats, types, and abilities
|
||||
- **Moves Data**: Downloads move information filtered by generation availability
|
||||
- **Progress Tracking**: Uses progress bars and detailed logging
|
||||
- **Error Handling**: Robust error handling with retry logic
|
||||
- **Flexible Output**: Configurable output directory structure
|
||||
|
||||
2. The tool is ready to use! No additional setup required.
|
||||
### Usage
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Download a Small Set of Pokemon (Testing)
|
||||
#### Basic Usage
|
||||
|
||||
```bash
|
||||
# Download first 5 Pokemon with their moves
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 1 --end 5 --include-moves
|
||||
# Download all data for all generations
|
||||
python pokemon_downloader.py --all-generations --all-data-types
|
||||
|
||||
# Download specific Pokemon (Pikachu)
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 25 --end 25 --include-moves
|
||||
# Download specific generations and data types
|
||||
python pokemon_downloader.py --generations generation-i,generation-ii --data-types types,pokemon
|
||||
|
||||
# Download only type effectiveness for Generation I
|
||||
python pokemon_downloader.py --generations generation-i --data-types types
|
||||
```
|
||||
|
||||
### Download Specific Moves
|
||||
#### Command Line Options
|
||||
|
||||
- `--generations`: Comma-separated list of generations (generation-i, generation-ii, etc.)
|
||||
- `--all-generations`: Download data for all available generations
|
||||
- `--data-types`: Comma-separated list of data types (types, pokemon, moves)
|
||||
- `--all-data-types`: Download all data types
|
||||
- `--output-dir`: Output directory (default: data)
|
||||
|
||||
#### Examples
|
||||
|
||||
```bash
|
||||
# Download first 10 moves
|
||||
python -m tools.data.pokemon_downloader download-moves --move-ids "1,2,3,4,5,6,7,8,9,10"
|
||||
# Download Pokemon and moves for Generation I and II
|
||||
python tools/data/pokemon_downloader.py \
|
||||
--generations generation-i,generation-ii \
|
||||
--data-types pokemon,moves \
|
||||
--output-dir data
|
||||
|
||||
# Download all type effectiveness data
|
||||
python tools/data/pokemon_downloader.py \
|
||||
--all-generations \
|
||||
--data-types types
|
||||
```
|
||||
|
||||
### Download Type Effectiveness Data
|
||||
### Output Structure
|
||||
|
||||
```bash
|
||||
# Download complete type effectiveness chart
|
||||
python -m tools.data.pokemon_downloader download-types
|
||||
The tool creates the following directory structure:
|
||||
|
||||
```
|
||||
data/
|
||||
├── types/
|
||||
│ ├── generation-i.json
|
||||
│ ├── generation-ii.json
|
||||
│ └── ...
|
||||
├── pokemon/
|
||||
│ ├── generation-i.json
|
||||
│ ├── generation-ii.json
|
||||
│ └── ...
|
||||
└── moves/
|
||||
├── generation-i.json
|
||||
├── generation-ii.json
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Download Complete Gen 1 Dataset
|
||||
### Data Formats
|
||||
|
||||
```bash
|
||||
# Download all Gen 1 Pokemon (1-151) with moves and type data
|
||||
python -m tools.data.pokemon_downloader download-complete --start 1 --end 151
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
### Global Options
|
||||
|
||||
- `--output-dir`: Directory to save downloaded data (default: `data`)
|
||||
- `--cache-dir`: Directory for API response caching (default: `.cache`)
|
||||
- `--no-validation`: Disable data validation before saving
|
||||
|
||||
### Commands
|
||||
|
||||
#### `download-pokemon`
|
||||
Download Pokemon data for a specific ID range.
|
||||
|
||||
```bash
|
||||
python -m tools.data.pokemon_downloader download-pokemon [OPTIONS]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--start`: Starting Pokemon ID (default: 1)
|
||||
- `--end`: Ending Pokemon ID (default: 10)
|
||||
- `--workers`: Number of concurrent workers (default: 5)
|
||||
- `--include-moves`: Also download moves for these Pokemon
|
||||
|
||||
#### `download-moves`
|
||||
Download specific moves by ID.
|
||||
|
||||
```bash
|
||||
python -m tools.data.pokemon_downloader download-moves --move-ids "1,2,3,4,5"
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--move-ids`: Comma-separated list of move IDs
|
||||
- `--workers`: Number of concurrent workers (default: 5)
|
||||
|
||||
#### `download-types`
|
||||
Download type effectiveness data.
|
||||
|
||||
```bash
|
||||
python -m tools.data.pokemon_downloader download-types
|
||||
```
|
||||
|
||||
#### `download-complete`
|
||||
Download complete dataset (Pokemon, moves, and type effectiveness).
|
||||
|
||||
```bash
|
||||
python -m tools.data.pokemon_downloader download-complete [OPTIONS]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--start`: Starting Pokemon ID (default: 1)
|
||||
- `--end`: Ending Pokemon ID (default: 151 for Gen 1)
|
||||
- `--workers`: Number of concurrent workers (default: 5)
|
||||
|
||||
## Data Structure
|
||||
|
||||
### Pokemon Data Format
|
||||
#### Type Effectiveness (`types/generation-X.json`)
|
||||
|
||||
```json
|
||||
{
|
||||
"1": {
|
||||
"id": 1,
|
||||
"name": "bulbasaur",
|
||||
"types": ["grass", "poison"],
|
||||
"base_stats": {
|
||||
"hp": 45,
|
||||
"attack": 49,
|
||||
"defense": 49,
|
||||
"special_attack": 65,
|
||||
"special_defense": 65,
|
||||
"speed": 45
|
||||
},
|
||||
"abilities": ["overgrow", "chlorophyll"],
|
||||
"moves": [1, 2, 3, 4, ...],
|
||||
"weight": 69,
|
||||
"height": 7,
|
||||
"base_experience": 64
|
||||
"fire": {
|
||||
"double_damage_from": ["water", "ground", "rock"],
|
||||
"double_damage_to": ["grass", "ice", "bug", "steel"],
|
||||
"half_damage_from": ["fire", "water", "rock", "dragon"],
|
||||
"half_damage_to": ["fire", "water", "rock", "dragon"],
|
||||
"no_damage_from": ["fire"],
|
||||
"no_damage_to": ["fire"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Move Data Format
|
||||
|
||||
```json
|
||||
{
|
||||
"1": {
|
||||
"id": 1,
|
||||
"name": "pound",
|
||||
"type": "normal",
|
||||
"power": 40,
|
||||
"accuracy": 100,
|
||||
"pp": 35,
|
||||
"priority": 0,
|
||||
"damage_class": "physical",
|
||||
"effect_id": null,
|
||||
"effect_chance": null,
|
||||
"target": "selected-pokemon",
|
||||
"description": "Inflicts regular damage."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Type Effectiveness Format
|
||||
#### Pokemon Data (`pokemon/generation-X.json`)
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"attacking_type": "fire",
|
||||
"defending_type": "grass",
|
||||
"damage_factor": 2.0
|
||||
},
|
||||
{
|
||||
"attacking_type": "water",
|
||||
"defending_type": "fire",
|
||||
"damage_factor": 2.0
|
||||
"id": 1,
|
||||
"name": "bulbasaur",
|
||||
"types": ["grass", "poison"],
|
||||
"stats": {
|
||||
"hp": 45,
|
||||
"attack": 49,
|
||||
"defense": 49,
|
||||
"special-attack": 65,
|
||||
"special-defense": 65,
|
||||
"speed": 45
|
||||
},
|
||||
"abilities": [...],
|
||||
"species": {
|
||||
"generation": "generation-i",
|
||||
"is_legendary": false,
|
||||
"is_mythical": false
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Examples
|
||||
#### Moves Data (`moves/generation-X.json`)
|
||||
|
||||
### Basic Usage (Python API)
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from tools.data.pokemon_downloader import PokemonDownloader
|
||||
|
||||
# Initialize downloader
|
||||
downloader = PokemonDownloader(
|
||||
output_dir=Path("my_pokemon_data"),
|
||||
validate_data=True
|
||||
)
|
||||
|
||||
# Download first 10 Pokemon
|
||||
pokemon_data = downloader.download_pokemon_batch(1, 10)
|
||||
downloader.save_pokemon_data(pokemon_data, "starter_pokemon.json")
|
||||
|
||||
# Download some moves
|
||||
move_ids = [1, 2, 3, 4, 5] # Pound, Karate Chop, etc.
|
||||
moves_data = downloader.download_moves_batch(move_ids)
|
||||
downloader.save_moves_data(moves_data, "basic_moves.json")
|
||||
|
||||
# Download type effectiveness
|
||||
effectiveness = downloader.download_type_effectiveness()
|
||||
downloader.save_type_effectiveness(effectiveness, "types.json")
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "pound",
|
||||
"power": 40,
|
||||
"pp": 35,
|
||||
"accuracy": 100,
|
||||
"type": "normal",
|
||||
"damage_class": "physical",
|
||||
"generation": "generation-i"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Testing Small Segments
|
||||
### Dependencies
|
||||
|
||||
```python
|
||||
# Test with just 3 Pokemon
|
||||
python tools/data/test_downloader.py
|
||||
The tool requires the following Python packages (available in `tools/requirements.txt`):
|
||||
|
||||
- `requests` - HTTP requests to PokeAPI
|
||||
- `tqdm` - Progress bars
|
||||
- `argparse` - Command line argument parsing (built-in)
|
||||
|
||||
### API Rate Limiting
|
||||
|
||||
The tool includes:
|
||||
- Retry logic with exponential backoff
|
||||
- Respectful request timing
|
||||
- User-agent identification
|
||||
- Error handling for rate limits
|
||||
|
||||
### New Features (Latest Update)
|
||||
|
||||
**Efficient Moves Download:**
|
||||
- Downloads all moves once and saves to `data/all_moves.json`
|
||||
- Subsequent generations filter from this master file instead of re-downloading
|
||||
- Dramatically reduces API calls and download time
|
||||
|
||||
**Smart Caching:**
|
||||
- Checks if data files already exist and contain expected amount of data
|
||||
- Skips re-downloading if files are present and valid
|
||||
- Supports partial downloads (e.g., if some Pokemon are missing, only downloads missing ones)
|
||||
|
||||
**File Structure:**
|
||||
```
|
||||
data/
|
||||
├── all_moves.json # Complete moves database (all generations)
|
||||
├── types/
|
||||
│ ├── generation-i.json # Type effectiveness for each generation
|
||||
│ ├── generation-ii.json
|
||||
│ └── ...
|
||||
├── pokemon/
|
||||
│ ├── generation-i.json # Pokemon data for each generation
|
||||
│ ├── generation-ii.json
|
||||
│ └── ...
|
||||
└── moves/
|
||||
├── generation-i.json # Moves available in each generation
|
||||
├── generation-ii.json # (filtered from all_moves.json)
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Custom Data Validation
|
||||
### Performance Improvements
|
||||
|
||||
```python
|
||||
from tools.data.schemas import DataValidator
|
||||
- **Moves**: Downloads all 900+ moves once, then filters per generation
|
||||
- **Caching**: Checks file existence and validity before downloading
|
||||
- **Batch Processing**: Downloads complete datasets efficiently
|
||||
- **Resume Support**: Can continue interrupted downloads
|
||||
|
||||
validator = DataValidator()
|
||||
### Usage Examples with Caching
|
||||
|
||||
# Validate Pokemon data
|
||||
errors = validator.validate_pokemon_collection(pokemon_data)
|
||||
if errors:
|
||||
print("Validation errors:", errors)
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Rate Limiting**: The tool implements 100ms delays between API calls to be respectful
|
||||
- **Concurrent Workers**: Default of 5 workers balances speed with API courtesy
|
||||
- **Caching**: API responses are cached to avoid redundant requests
|
||||
- **Memory Usage**: Large datasets are processed in batches to manage memory
|
||||
|
||||
## Recommended Usage Patterns
|
||||
|
||||
### For Development/Testing
|
||||
```bash
|
||||
# Start small - download just a few Pokemon
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 1 --end 3 --include-moves
|
||||
# First run - downloads all data
|
||||
python tools/data/pokemon_downloader.py --all-generations --all-data-types
|
||||
|
||||
# Test specific Pokemon you're interested in
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 25 --end 25 --include-moves # Pikachu
|
||||
# Subsequent runs - uses cached data (much faster!)
|
||||
python tools/data/pokemon_downloader.py --all-generations --all-data-types
|
||||
|
||||
# Only downloads missing data
|
||||
python tools/data/pokemon_downloader.py --generations generation-v --data-types pokemon
|
||||
```
|
||||
|
||||
### For Production Data
|
||||
```bash
|
||||
# Download by generations or batches
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 1 --end 50 --include-moves
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 51 --end 100 --include-moves
|
||||
python -m tools.data.pokemon_downloader download-pokemon --start 101 --end 151 --include-moves
|
||||
### Notes
|
||||
|
||||
# Always download type effectiveness data
|
||||
python -m tools.data.pokemon_downloader download-types
|
||||
```
|
||||
|
||||
### For Complete Gen 1 Dataset
|
||||
```bash
|
||||
# One command for everything (will take several minutes)
|
||||
python -m tools.data.pokemon_downloader download-complete --start 1 --end 151
|
||||
```
|
||||
|
||||
## Data Validation
|
||||
|
||||
The tool includes comprehensive JSON schema validation:
|
||||
|
||||
- **Pokemon Data**: Validates stats, types, abilities, and structure
|
||||
- **Move Data**: Validates power, accuracy, PP, and damage classes
|
||||
- **Type Effectiveness**: Validates damage multipliers and type names
|
||||
- **Generation 1 Focus**: Ensures only valid Gen 1 types and data
|
||||
|
||||
Validation errors are displayed during save operations but don't prevent saving (warnings only).
|
||||
|
||||
## Integration with C++ Battle Simulator
|
||||
|
||||
The exported JSON files are designed to be easily consumed by the C++ battle simulator:
|
||||
|
||||
1. **Pokemon Data**: Direct mapping to Pokemon class properties
|
||||
2. **Move Data**: Complete move information for battle calculations
|
||||
3. **Type Effectiveness**: Lookup table for damage calculations
|
||||
4. **Consistent IDs**: All data uses consistent Pokemon and move IDs
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Network Errors**: The tool retries failed requests automatically
|
||||
2. **Rate Limiting**: Built-in delays prevent API rate limiting
|
||||
3. **Memory Usage**: Large downloads are processed in batches
|
||||
4. **Validation Warnings**: Usually safe to ignore, indicate minor data inconsistencies
|
||||
|
||||
### Getting Help
|
||||
|
||||
- Run tests: `python tools/data/test_downloader.py`
|
||||
- Check logs: The tool provides detailed logging for debugging
|
||||
- Validate data: Use `--no-validation` flag if validation is too strict
|
||||
|
||||
## Contributing
|
||||
|
||||
To extend the downloader:
|
||||
|
||||
1. Add new data structures to `pokemon_downloader.py`
|
||||
2. Update validation schemas in `schemas.py`
|
||||
3. Add tests to `test_downloader.py`
|
||||
4. Update this documentation
|
||||
|
||||
## License
|
||||
|
||||
This tool is part of the Pokemon Battle Simulator project and follows the same license terms.
|
||||
- Some Pokemon and moves appear in multiple generations
|
||||
- Type effectiveness is consistent across generations in the base game
|
||||
- The tool respects the PokeAPI fair use policy
|
||||
- Data is cached locally to avoid repeated API calls
|
||||
- `all_moves.json` contains the complete moves database for efficient filtering
|
||||
|
||||
@@ -1,228 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example usage of the Pokemon Data Downloader.
|
||||
Example usage of the Pokemon Data Downloader
|
||||
|
||||
This script demonstrates various ways to use the Pokemon downloader
|
||||
for different scenarios and use cases.
|
||||
This script demonstrates how to use the pokemon_downloader.py tool
|
||||
to download different types of Pokemon data from the PokeAPI.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add the tools directory to Python path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
def run_command(cmd, description):
|
||||
"""Run a command and print the description."""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Running: {description}")
|
||||
print(f"Command: {' '.join(cmd)}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
from data.pokemon_downloader import PokemonDownloader
|
||||
from data.schemas import DataValidator
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.table import Table
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
def example_basic_download():
|
||||
"""Example 1: Basic Pokemon download."""
|
||||
console.print(Panel.fit("Example 1: Basic Pokemon Download", style="bold blue"))
|
||||
|
||||
# Create downloader with custom output directory
|
||||
downloader = PokemonDownloader(output_dir=Path("example_data"))
|
||||
|
||||
# Download first 3 Pokemon (Bulbasaur, Ivysaur, Venusaur)
|
||||
console.print("Downloading first 3 Pokemon...")
|
||||
pokemon_data = downloader.download_pokemon_batch(1, 3, max_workers=2)
|
||||
|
||||
if pokemon_data:
|
||||
# Save to file
|
||||
downloader.save_pokemon_data(pokemon_data, "starter_pokemon.json")
|
||||
|
||||
# Display summary
|
||||
table = downloader.get_stats_summary(pokemon_data)
|
||||
console.print(table)
|
||||
|
||||
console.print("✅ Basic download complete!\n")
|
||||
|
||||
|
||||
def example_moves_download():
|
||||
"""Example 2: Download specific moves."""
|
||||
console.print(Panel.fit("Example 2: Download Specific Moves", style="bold blue"))
|
||||
|
||||
downloader = PokemonDownloader(output_dir=Path("example_data"))
|
||||
|
||||
# Download some classic moves
|
||||
classic_moves = [1, 2, 33, 34, 36] # Pound, Karate Chop, Tackle, Body Slam, Take Down
|
||||
console.print(f"Downloading {len(classic_moves)} classic moves...")
|
||||
|
||||
moves_data = downloader.download_moves_batch(classic_moves, max_workers=3)
|
||||
|
||||
if moves_data:
|
||||
downloader.save_moves_data(moves_data, "classic_moves.json")
|
||||
|
||||
# Show move details
|
||||
table = Table(title="Downloaded Moves")
|
||||
table.add_column("Name", style="cyan")
|
||||
table.add_column("Type", style="green")
|
||||
table.add_column("Power", style="magenta")
|
||||
table.add_column("Accuracy", style="yellow")
|
||||
|
||||
for move in moves_data.values():
|
||||
power_str = str(move.power) if move.power else "—"
|
||||
accuracy_str = str(move.accuracy) if move.accuracy else "—"
|
||||
table.add_row(
|
||||
move.name.title(),
|
||||
move.type.title(),
|
||||
power_str,
|
||||
accuracy_str
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
|
||||
console.print("✅ Moves download complete!\n")
|
||||
|
||||
|
||||
def example_validation():
|
||||
"""Example 3: Data validation."""
|
||||
console.print(Panel.fit("Example 3: Data Validation", style="bold blue"))
|
||||
|
||||
validator = DataValidator()
|
||||
|
||||
# Create sample Pokemon data for validation
|
||||
sample_pokemon = {
|
||||
"25": { # Pikachu
|
||||
"id": 25,
|
||||
"name": "pikachu",
|
||||
"types": ["electric"],
|
||||
"base_stats": {
|
||||
"hp": 35,
|
||||
"attack": 55,
|
||||
"defense": 40,
|
||||
"special_attack": 50,
|
||||
"special_defense": 50,
|
||||
"speed": 90
|
||||
},
|
||||
"abilities": ["static", "lightning-rod"],
|
||||
"moves": [1, 2, 3, 4, 5],
|
||||
"weight": 60,
|
||||
"height": 4,
|
||||
"base_experience": 112
|
||||
}
|
||||
}
|
||||
|
||||
# Validate the data
|
||||
errors = validator.validate_pokemon_collection(sample_pokemon)
|
||||
|
||||
if errors:
|
||||
console.print(f"❌ Validation found {len(errors)} errors:")
|
||||
for error in errors:
|
||||
console.print(f" - {error}")
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
print("✓ Success!")
|
||||
if result.stdout:
|
||||
print("Output:", result.stdout)
|
||||
else:
|
||||
console.print("✅ Sample Pokemon data is valid!")
|
||||
|
||||
console.print("✅ Validation example complete!\n")
|
||||
|
||||
|
||||
def example_type_effectiveness():
|
||||
"""Example 4: Download type effectiveness data."""
|
||||
console.print(Panel.fit("Example 4: Type Effectiveness", style="bold blue"))
|
||||
|
||||
downloader = PokemonDownloader(output_dir=Path("example_data"))
|
||||
|
||||
console.print("Downloading type effectiveness data...")
|
||||
effectiveness_data = downloader.download_type_effectiveness()
|
||||
|
||||
if effectiveness_data:
|
||||
downloader.save_type_effectiveness(effectiveness_data, "type_chart.json")
|
||||
|
||||
# Show some interesting type matchups
|
||||
table = Table(title="Sample Type Effectiveness")
|
||||
table.add_column("Attacking Type", style="cyan")
|
||||
table.add_column("Defending Type", style="green")
|
||||
table.add_column("Effectiveness", style="magenta")
|
||||
|
||||
# Show super effective matchups
|
||||
super_effective = [e for e in effectiveness_data if e.damage_factor == 2.0][:5]
|
||||
for entry in super_effective:
|
||||
table.add_row(
|
||||
entry.attacking_type.title(),
|
||||
entry.defending_type.title(),
|
||||
"Super Effective (2x)"
|
||||
)
|
||||
|
||||
console.print(table)
|
||||
console.print(f"Total effectiveness entries: {len(effectiveness_data)}")
|
||||
|
||||
console.print("✅ Type effectiveness download complete!\n")
|
||||
|
||||
|
||||
def example_integrated_workflow():
|
||||
"""Example 5: Integrated workflow - Pokemon with their moves."""
|
||||
console.print(Panel.fit("Example 5: Integrated Workflow", style="bold blue"))
|
||||
|
||||
downloader = PokemonDownloader(output_dir=Path("example_data"))
|
||||
|
||||
# Download a specific Pokemon (Charizard)
|
||||
console.print("Downloading Charizard (ID: 6)...")
|
||||
pokemon_data = downloader.download_pokemon_batch(6, 6, max_workers=1)
|
||||
|
||||
if pokemon_data:
|
||||
charizard = pokemon_data[6]
|
||||
console.print(f"✅ Downloaded {charizard.name.title()}")
|
||||
console.print(f" - Types: {', '.join(charizard.types)}")
|
||||
console.print(f" - Base stats total: {sum(charizard.base_stats.__dict__.values())}")
|
||||
console.print(f" - Can learn {len(charizard.moves)} moves")
|
||||
|
||||
# Download first 15 moves that Charizard can learn
|
||||
charizard_moves = charizard.moves[:15]
|
||||
console.print(f"\nDownloading {len(charizard_moves)} of Charizard's moves...")
|
||||
|
||||
moves_data = downloader.download_moves_batch(charizard_moves, max_workers=3)
|
||||
|
||||
if moves_data:
|
||||
# Save both datasets
|
||||
downloader.save_pokemon_data(pokemon_data, "charizard.json")
|
||||
downloader.save_moves_data(moves_data, "charizard_moves.json")
|
||||
|
||||
# Show some moves
|
||||
console.print("\nSample moves Charizard can learn:")
|
||||
for move_id, move in list(moves_data.items())[:5]:
|
||||
power_str = f"{move.power} power" if move.power else "status move"
|
||||
console.print(f" - {move.name.title()} ({move.type} type, {power_str})")
|
||||
|
||||
console.print("✅ Integrated workflow complete!\n")
|
||||
|
||||
print("✗ Failed!")
|
||||
if result.stderr:
|
||||
print("Error:", result.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
"""Run all examples."""
|
||||
console.print(Panel.fit(
|
||||
"🔥 Pokemon Data Downloader Examples",
|
||||
style="bold red"
|
||||
))
|
||||
|
||||
console.print("This script demonstrates various usage patterns for the Pokemon downloader.\n")
|
||||
|
||||
# Run examples
|
||||
try:
|
||||
example_basic_download()
|
||||
example_moves_download()
|
||||
example_validation()
|
||||
example_type_effectiveness()
|
||||
example_integrated_workflow()
|
||||
|
||||
console.print(Panel.fit(
|
||||
"🎉 All examples completed successfully!\n\n"
|
||||
"Check the 'example_data' directory for downloaded files.\n"
|
||||
"You can now use these patterns in your own projects.",
|
||||
style="bold green"
|
||||
))
|
||||
|
||||
except KeyboardInterrupt:
|
||||
console.print("\n⚠️ Examples interrupted by user")
|
||||
except Exception as e:
|
||||
console.print(f"\n❌ Error running examples: {e}")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
"""Demonstrate various usage examples of the Pokemon downloader."""
|
||||
|
||||
print("Pokemon Data Downloader - Usage Examples")
|
||||
print("=========================================")
|
||||
|
||||
# Ensure we're in the right directory
|
||||
if not Path("tools/data/pokemon_downloader.py").exists():
|
||||
print("Error: Please run this script from the project root directory")
|
||||
sys.exit(1)
|
||||
|
||||
# Example 1: Download type effectiveness for Generation I
|
||||
run_command([
|
||||
"python", "tools/data/pokemon_downloader.py",
|
||||
"--generations", "generation-i",
|
||||
"--data-types", "types"
|
||||
], "Download type effectiveness for Generation I")
|
||||
|
||||
# Example 2: Download Pokemon data for multiple generations
|
||||
run_command([
|
||||
"python", "tools/data/pokemon_downloader.py",
|
||||
"--generations", "generation-i,generation-ii",
|
||||
"--data-types", "pokemon"
|
||||
], "Download Pokemon data for Generations I and II")
|
||||
|
||||
# Example 3: Download moves data for Generation I
|
||||
run_command([
|
||||
"python", "tools/data/pokemon_downloader.py",
|
||||
"--generations", "generation-i",
|
||||
"--data-types", "moves"
|
||||
], "Download moves data for Generation I")
|
||||
|
||||
# Example 4: Download all data types for one generation
|
||||
run_command([
|
||||
"python", "tools/data/pokemon_downloader.py",
|
||||
"--generations", "generation-i",
|
||||
"--all-data-types"
|
||||
], "Download all data types for Generation I")
|
||||
|
||||
# Example 5: Download specific data to custom directory
|
||||
custom_dir = "my_pokemon_data"
|
||||
run_command([
|
||||
"python", "tools/data/pokemon_downloader.py",
|
||||
"--generations", "generation-i",
|
||||
"--data-types", "types",
|
||||
"--output-dir", custom_dir
|
||||
], f"Download type data to custom directory: {custom_dir}")
|
||||
|
||||
# Show help
|
||||
print(f"\n{'='*60}")
|
||||
print("Available command line options:")
|
||||
print(f"{'='*60}")
|
||||
subprocess.run([
|
||||
"python", "tools/data/pokemon_downloader.py", "--help"
|
||||
])
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print("Examples completed successfully!")
|
||||
print("Check the 'data' directory for downloaded files.")
|
||||
print(f"{'='*60}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
main()
|
||||
|
||||
|
||||
1128
tools/data/pokemon_downloader.py
Normal file → Executable file
1128
tools/data/pokemon_downloader.py
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user