mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Make great strides towards an actual game-aware API
Huzzah! Also, I decided to namespace identifiers. For now. We'll see how it goes.
This commit is contained in:
parent
aa32cf0b53
commit
969d671c48
2 changed files with 470 additions and 380 deletions
|
@ -17,6 +17,7 @@ from pathlib import Path
|
|||
import re
|
||||
import sys
|
||||
|
||||
from camel import Camel
|
||||
from classtools import reify
|
||||
from construct import *
|
||||
|
||||
|
@ -92,364 +93,364 @@ GAME_RELEASE_MD5SUM_INDEX = {
|
|||
|
||||
|
||||
GROWTH_RATES = {
|
||||
0: 'medium',
|
||||
3: 'medium-slow',
|
||||
4: 'fast',
|
||||
5: 'slow',
|
||||
0: 'growth-rate.medium',
|
||||
3: 'growth-rate.medium-slow',
|
||||
4: 'growth-rate.fast',
|
||||
5: 'growth-rate.slow',
|
||||
}
|
||||
|
||||
EVOLUTION_TRIGGERS = {
|
||||
1: 'level-up',
|
||||
2: 'use-item',
|
||||
3: 'trade',
|
||||
1: 'evolution-trigger.level-up',
|
||||
2: 'evolution-trigger.use-item',
|
||||
3: 'evolution-trigger.trade',
|
||||
}
|
||||
|
||||
# TODO these are loci, not enums, so hardcoding all their identifiers here
|
||||
# makes me nonspecifically uncomfortable
|
||||
POKEMON_IDENTIFIERS = {
|
||||
1: 'bulbasaur',
|
||||
2: 'ivysaur',
|
||||
3: 'venusaur',
|
||||
4: 'charmander',
|
||||
5: 'charmeleon',
|
||||
6: 'charizard',
|
||||
7: 'squirtle',
|
||||
8: 'wartortle',
|
||||
9: 'blastoise',
|
||||
10: 'caterpie',
|
||||
11: 'metapod',
|
||||
12: 'butterfree',
|
||||
13: 'weedle',
|
||||
14: 'kakuna',
|
||||
15: 'beedrill',
|
||||
16: 'pidgey',
|
||||
17: 'pidgeotto',
|
||||
18: 'pidgeot',
|
||||
19: 'rattata',
|
||||
20: 'raticate',
|
||||
21: 'spearow',
|
||||
22: 'fearow',
|
||||
23: 'ekans',
|
||||
24: 'arbok',
|
||||
25: 'pikachu',
|
||||
26: 'raichu',
|
||||
27: 'sandshrew',
|
||||
28: 'sandslash',
|
||||
29: 'nidoran-f',
|
||||
30: 'nidorina',
|
||||
31: 'nidoqueen',
|
||||
32: 'nidoran-m',
|
||||
33: 'nidorino',
|
||||
34: 'nidoking',
|
||||
35: 'clefairy',
|
||||
36: 'clefable',
|
||||
37: 'vulpix',
|
||||
38: 'ninetales',
|
||||
39: 'jigglypuff',
|
||||
40: 'wigglytuff',
|
||||
41: 'zubat',
|
||||
42: 'golbat',
|
||||
43: 'oddish',
|
||||
44: 'gloom',
|
||||
45: 'vileplume',
|
||||
46: 'paras',
|
||||
47: 'parasect',
|
||||
48: 'venonat',
|
||||
49: 'venomoth',
|
||||
50: 'diglett',
|
||||
51: 'dugtrio',
|
||||
52: 'meowth',
|
||||
53: 'persian',
|
||||
54: 'psyduck',
|
||||
55: 'golduck',
|
||||
56: 'mankey',
|
||||
57: 'primeape',
|
||||
58: 'growlithe',
|
||||
59: 'arcanine',
|
||||
60: 'poliwag',
|
||||
61: 'poliwhirl',
|
||||
62: 'poliwrath',
|
||||
63: 'abra',
|
||||
64: 'kadabra',
|
||||
65: 'alakazam',
|
||||
66: 'machop',
|
||||
67: 'machoke',
|
||||
68: 'machamp',
|
||||
69: 'bellsprout',
|
||||
70: 'weepinbell',
|
||||
71: 'victreebel',
|
||||
72: 'tentacool',
|
||||
73: 'tentacruel',
|
||||
74: 'geodude',
|
||||
75: 'graveler',
|
||||
76: 'golem',
|
||||
77: 'ponyta',
|
||||
78: 'rapidash',
|
||||
79: 'slowpoke',
|
||||
80: 'slowbro',
|
||||
81: 'magnemite',
|
||||
82: 'magneton',
|
||||
83: 'farfetchd',
|
||||
84: 'doduo',
|
||||
85: 'dodrio',
|
||||
86: 'seel',
|
||||
87: 'dewgong',
|
||||
88: 'grimer',
|
||||
89: 'muk',
|
||||
90: 'shellder',
|
||||
91: 'cloyster',
|
||||
92: 'gastly',
|
||||
93: 'haunter',
|
||||
94: 'gengar',
|
||||
95: 'onix',
|
||||
96: 'drowzee',
|
||||
97: 'hypno',
|
||||
98: 'krabby',
|
||||
99: 'kingler',
|
||||
100: 'voltorb',
|
||||
101: 'electrode',
|
||||
102: 'exeggcute',
|
||||
103: 'exeggutor',
|
||||
104: 'cubone',
|
||||
105: 'marowak',
|
||||
106: 'hitmonlee',
|
||||
107: 'hitmonchan',
|
||||
108: 'lickitung',
|
||||
109: 'koffing',
|
||||
110: 'weezing',
|
||||
111: 'rhyhorn',
|
||||
112: 'rhydon',
|
||||
113: 'chansey',
|
||||
114: 'tangela',
|
||||
115: 'kangaskhan',
|
||||
116: 'horsea',
|
||||
117: 'seadra',
|
||||
118: 'goldeen',
|
||||
119: 'seaking',
|
||||
120: 'staryu',
|
||||
121: 'starmie',
|
||||
122: 'mr-mime',
|
||||
123: 'scyther',
|
||||
124: 'jynx',
|
||||
125: 'electabuzz',
|
||||
126: 'magmar',
|
||||
127: 'pinsir',
|
||||
128: 'tauros',
|
||||
129: 'magikarp',
|
||||
130: 'gyarados',
|
||||
131: 'lapras',
|
||||
132: 'ditto',
|
||||
133: 'eevee',
|
||||
134: 'vaporeon',
|
||||
135: 'jolteon',
|
||||
136: 'flareon',
|
||||
137: 'porygon',
|
||||
138: 'omanyte',
|
||||
139: 'omastar',
|
||||
140: 'kabuto',
|
||||
141: 'kabutops',
|
||||
142: 'aerodactyl',
|
||||
143: 'snorlax',
|
||||
144: 'articuno',
|
||||
145: 'zapdos',
|
||||
146: 'moltres',
|
||||
147: 'dratini',
|
||||
148: 'dragonair',
|
||||
149: 'dragonite',
|
||||
150: 'mewtwo',
|
||||
151: 'mew',
|
||||
1: 'pokemon.bulbasaur',
|
||||
2: 'pokemon.ivysaur',
|
||||
3: 'pokemon.venusaur',
|
||||
4: 'pokemon.charmander',
|
||||
5: 'pokemon.charmeleon',
|
||||
6: 'pokemon.charizard',
|
||||
7: 'pokemon.squirtle',
|
||||
8: 'pokemon.wartortle',
|
||||
9: 'pokemon.blastoise',
|
||||
10: 'pokemon.caterpie',
|
||||
11: 'pokemon.metapod',
|
||||
12: 'pokemon.butterfree',
|
||||
13: 'pokemon.weedle',
|
||||
14: 'pokemon.kakuna',
|
||||
15: 'pokemon.beedrill',
|
||||
16: 'pokemon.pidgey',
|
||||
17: 'pokemon.pidgeotto',
|
||||
18: 'pokemon.pidgeot',
|
||||
19: 'pokemon.rattata',
|
||||
20: 'pokemon.raticate',
|
||||
21: 'pokemon.spearow',
|
||||
22: 'pokemon.fearow',
|
||||
23: 'pokemon.ekans',
|
||||
24: 'pokemon.arbok',
|
||||
25: 'pokemon.pikachu',
|
||||
26: 'pokemon.raichu',
|
||||
27: 'pokemon.sandshrew',
|
||||
28: 'pokemon.sandslash',
|
||||
29: 'pokemon.nidoran-f',
|
||||
30: 'pokemon.nidorina',
|
||||
31: 'pokemon.nidoqueen',
|
||||
32: 'pokemon.nidoran-m',
|
||||
33: 'pokemon.nidorino',
|
||||
34: 'pokemon.nidoking',
|
||||
35: 'pokemon.clefairy',
|
||||
36: 'pokemon.clefable',
|
||||
37: 'pokemon.vulpix',
|
||||
38: 'pokemon.ninetales',
|
||||
39: 'pokemon.jigglypuff',
|
||||
40: 'pokemon.wigglytuff',
|
||||
41: 'pokemon.zubat',
|
||||
42: 'pokemon.golbat',
|
||||
43: 'pokemon.oddish',
|
||||
44: 'pokemon.gloom',
|
||||
45: 'pokemon.vileplume',
|
||||
46: 'pokemon.paras',
|
||||
47: 'pokemon.parasect',
|
||||
48: 'pokemon.venonat',
|
||||
49: 'pokemon.venomoth',
|
||||
50: 'pokemon.diglett',
|
||||
51: 'pokemon.dugtrio',
|
||||
52: 'pokemon.meowth',
|
||||
53: 'pokemon.persian',
|
||||
54: 'pokemon.psyduck',
|
||||
55: 'pokemon.golduck',
|
||||
56: 'pokemon.mankey',
|
||||
57: 'pokemon.primeape',
|
||||
58: 'pokemon.growlithe',
|
||||
59: 'pokemon.arcanine',
|
||||
60: 'pokemon.poliwag',
|
||||
61: 'pokemon.poliwhirl',
|
||||
62: 'pokemon.poliwrath',
|
||||
63: 'pokemon.abra',
|
||||
64: 'pokemon.kadabra',
|
||||
65: 'pokemon.alakazam',
|
||||
66: 'pokemon.machop',
|
||||
67: 'pokemon.machoke',
|
||||
68: 'pokemon.machamp',
|
||||
69: 'pokemon.bellsprout',
|
||||
70: 'pokemon.weepinbell',
|
||||
71: 'pokemon.victreebel',
|
||||
72: 'pokemon.tentacool',
|
||||
73: 'pokemon.tentacruel',
|
||||
74: 'pokemon.geodude',
|
||||
75: 'pokemon.graveler',
|
||||
76: 'pokemon.golem',
|
||||
77: 'pokemon.ponyta',
|
||||
78: 'pokemon.rapidash',
|
||||
79: 'pokemon.slowpoke',
|
||||
80: 'pokemon.slowbro',
|
||||
81: 'pokemon.magnemite',
|
||||
82: 'pokemon.magneton',
|
||||
83: 'pokemon.farfetchd',
|
||||
84: 'pokemon.doduo',
|
||||
85: 'pokemon.dodrio',
|
||||
86: 'pokemon.seel',
|
||||
87: 'pokemon.dewgong',
|
||||
88: 'pokemon.grimer',
|
||||
89: 'pokemon.muk',
|
||||
90: 'pokemon.shellder',
|
||||
91: 'pokemon.cloyster',
|
||||
92: 'pokemon.gastly',
|
||||
93: 'pokemon.haunter',
|
||||
94: 'pokemon.gengar',
|
||||
95: 'pokemon.onix',
|
||||
96: 'pokemon.drowzee',
|
||||
97: 'pokemon.hypno',
|
||||
98: 'pokemon.krabby',
|
||||
99: 'pokemon.kingler',
|
||||
100: 'pokemon.voltorb',
|
||||
101: 'pokemon.electrode',
|
||||
102: 'pokemon.exeggcute',
|
||||
103: 'pokemon.exeggutor',
|
||||
104: 'pokemon.cubone',
|
||||
105: 'pokemon.marowak',
|
||||
106: 'pokemon.hitmonlee',
|
||||
107: 'pokemon.hitmonchan',
|
||||
108: 'pokemon.lickitung',
|
||||
109: 'pokemon.koffing',
|
||||
110: 'pokemon.weezing',
|
||||
111: 'pokemon.rhyhorn',
|
||||
112: 'pokemon.rhydon',
|
||||
113: 'pokemon.chansey',
|
||||
114: 'pokemon.tangela',
|
||||
115: 'pokemon.kangaskhan',
|
||||
116: 'pokemon.horsea',
|
||||
117: 'pokemon.seadra',
|
||||
118: 'pokemon.goldeen',
|
||||
119: 'pokemon.seaking',
|
||||
120: 'pokemon.staryu',
|
||||
121: 'pokemon.starmie',
|
||||
122: 'pokemon.mr-mime',
|
||||
123: 'pokemon.scyther',
|
||||
124: 'pokemon.jynx',
|
||||
125: 'pokemon.electabuzz',
|
||||
126: 'pokemon.magmar',
|
||||
127: 'pokemon.pinsir',
|
||||
128: 'pokemon.tauros',
|
||||
129: 'pokemon.magikarp',
|
||||
130: 'pokemon.gyarados',
|
||||
131: 'pokemon.lapras',
|
||||
132: 'pokemon.ditto',
|
||||
133: 'pokemon.eevee',
|
||||
134: 'pokemon.vaporeon',
|
||||
135: 'pokemon.jolteon',
|
||||
136: 'pokemon.flareon',
|
||||
137: 'pokemon.porygon',
|
||||
138: 'pokemon.omanyte',
|
||||
139: 'pokemon.omastar',
|
||||
140: 'pokemon.kabuto',
|
||||
141: 'pokemon.kabutops',
|
||||
142: 'pokemon.aerodactyl',
|
||||
143: 'pokemon.snorlax',
|
||||
144: 'pokemon.articuno',
|
||||
145: 'pokemon.zapdos',
|
||||
146: 'pokemon.moltres',
|
||||
147: 'pokemon.dratini',
|
||||
148: 'pokemon.dragonair',
|
||||
149: 'pokemon.dragonite',
|
||||
150: 'pokemon.mewtwo',
|
||||
151: 'pokemon.mew',
|
||||
}
|
||||
|
||||
TYPE_IDENTIFIERS = {
|
||||
0: 'normal',
|
||||
1: 'fighting',
|
||||
2: 'flying',
|
||||
3: 'poison',
|
||||
4: 'ground',
|
||||
5: 'rock',
|
||||
#6: 'bird',
|
||||
7: 'bug',
|
||||
8: 'ghost',
|
||||
9: 'steel',
|
||||
20: 'fire',
|
||||
21: 'water',
|
||||
22: 'grass',
|
||||
23: 'electric',
|
||||
24: 'psychic',
|
||||
25: 'ice',
|
||||
26: 'dragon',
|
||||
27: 'dark',
|
||||
0: 'type.normal',
|
||||
1: 'type.fighting',
|
||||
2: 'type.flying',
|
||||
3: 'type.poison',
|
||||
4: 'type.ground',
|
||||
5: 'type.rock',
|
||||
#6: 'type.bird',
|
||||
7: 'type.bug',
|
||||
8: 'type.ghost',
|
||||
9: 'type.steel',
|
||||
20: 'type.fire',
|
||||
21: 'type.water',
|
||||
22: 'type.grass',
|
||||
23: 'type.electric',
|
||||
24: 'type.psychic',
|
||||
25: 'type.ice',
|
||||
26: 'type.dragon',
|
||||
27: 'type.dark',
|
||||
}
|
||||
|
||||
MOVE_IDENTIFIERS = {
|
||||
# TODO stupid hack for initial moveset
|
||||
0: '--',
|
||||
|
||||
1: 'pound',
|
||||
2: 'karate-chop',
|
||||
3: 'double-slap',
|
||||
4: 'comet-punch',
|
||||
5: 'mega-punch',
|
||||
6: 'pay-day',
|
||||
7: 'fire-punch',
|
||||
8: 'ice-punch',
|
||||
9: 'thunder-punch',
|
||||
10: 'scratch',
|
||||
11: 'vice-grip',
|
||||
12: 'guillotine',
|
||||
13: 'razor-wind',
|
||||
14: 'swords-dance',
|
||||
15: 'cut',
|
||||
16: 'gust',
|
||||
17: 'wing-attack',
|
||||
18: 'whirlwind',
|
||||
19: 'fly',
|
||||
20: 'bind',
|
||||
21: 'slam',
|
||||
22: 'vine-whip',
|
||||
23: 'stomp',
|
||||
24: 'double-kick',
|
||||
25: 'mega-kick',
|
||||
26: 'jump-kick',
|
||||
27: 'rolling-kick',
|
||||
28: 'sand-attack',
|
||||
29: 'headbutt',
|
||||
30: 'horn-attack',
|
||||
31: 'fury-attack',
|
||||
32: 'horn-drill',
|
||||
33: 'tackle',
|
||||
34: 'body-slam',
|
||||
35: 'wrap',
|
||||
36: 'take-down',
|
||||
37: 'thrash',
|
||||
38: 'double-edge',
|
||||
39: 'tail-whip',
|
||||
40: 'poison-sting',
|
||||
41: 'twineedle',
|
||||
42: 'pin-missile',
|
||||
43: 'leer',
|
||||
44: 'bite',
|
||||
45: 'growl',
|
||||
46: 'roar',
|
||||
47: 'sing',
|
||||
48: 'supersonic',
|
||||
49: 'sonic-boom',
|
||||
50: 'disable',
|
||||
51: 'acid',
|
||||
52: 'ember',
|
||||
53: 'flamethrower',
|
||||
54: 'mist',
|
||||
55: 'water-gun',
|
||||
56: 'hydro-pump',
|
||||
57: 'surf',
|
||||
58: 'ice-beam',
|
||||
59: 'blizzard',
|
||||
60: 'psybeam',
|
||||
61: 'bubble-beam',
|
||||
62: 'aurora-beam',
|
||||
63: 'hyper-beam',
|
||||
64: 'peck',
|
||||
65: 'drill-peck',
|
||||
66: 'submission',
|
||||
67: 'low-kick',
|
||||
68: 'counter',
|
||||
69: 'seismic-toss',
|
||||
70: 'strength',
|
||||
71: 'absorb',
|
||||
72: 'mega-drain',
|
||||
73: 'leech-seed',
|
||||
74: 'growth',
|
||||
75: 'razor-leaf',
|
||||
76: 'solar-beam',
|
||||
77: 'poison-powder',
|
||||
78: 'stun-spore',
|
||||
79: 'sleep-powder',
|
||||
80: 'petal-dance',
|
||||
81: 'string-shot',
|
||||
82: 'dragon-rage',
|
||||
83: 'fire-spin',
|
||||
84: 'thunder-shock',
|
||||
85: 'thunderbolt',
|
||||
86: 'thunder-wave',
|
||||
87: 'thunder',
|
||||
88: 'rock-throw',
|
||||
89: 'earthquake',
|
||||
90: 'fissure',
|
||||
91: 'dig',
|
||||
92: 'toxic',
|
||||
93: 'confusion',
|
||||
94: 'psychic',
|
||||
95: 'hypnosis',
|
||||
96: 'meditate',
|
||||
97: 'agility',
|
||||
98: 'quick-attack',
|
||||
99: 'rage',
|
||||
100: 'teleport',
|
||||
101: 'night-shade',
|
||||
102: 'mimic',
|
||||
103: 'screech',
|
||||
104: 'double-team',
|
||||
105: 'recover',
|
||||
106: 'harden',
|
||||
107: 'minimize',
|
||||
108: 'smokescreen',
|
||||
109: 'confuse-ray',
|
||||
110: 'withdraw',
|
||||
111: 'defense-curl',
|
||||
112: 'barrier',
|
||||
113: 'light-screen',
|
||||
114: 'haze',
|
||||
115: 'reflect',
|
||||
116: 'focus-energy',
|
||||
117: 'bide',
|
||||
118: 'metronome',
|
||||
119: 'mirror-move',
|
||||
120: 'self-destruct',
|
||||
121: 'egg-bomb',
|
||||
122: 'lick',
|
||||
123: 'smog',
|
||||
124: 'sludge',
|
||||
125: 'bone-club',
|
||||
126: 'fire-blast',
|
||||
127: 'waterfall',
|
||||
128: 'clamp',
|
||||
129: 'swift',
|
||||
130: 'skull-bash',
|
||||
131: 'spike-cannon',
|
||||
132: 'constrict',
|
||||
133: 'amnesia',
|
||||
134: 'kinesis',
|
||||
135: 'soft-boiled',
|
||||
136: 'high-jump-kick',
|
||||
137: 'glare',
|
||||
138: 'dream-eater',
|
||||
139: 'poison-gas',
|
||||
140: 'barrage',
|
||||
141: 'leech-life',
|
||||
142: 'lovely-kiss',
|
||||
143: 'sky-attack',
|
||||
144: 'transform',
|
||||
145: 'bubble',
|
||||
146: 'dizzy-punch',
|
||||
147: 'spore',
|
||||
148: 'flash',
|
||||
149: 'psywave',
|
||||
150: 'splash',
|
||||
151: 'acid-armor',
|
||||
152: 'crabhammer',
|
||||
153: 'explosion',
|
||||
154: 'fury-swipes',
|
||||
155: 'bonemerang',
|
||||
156: 'rest',
|
||||
157: 'rock-slide',
|
||||
158: 'hyper-fang',
|
||||
159: 'sharpen',
|
||||
160: 'conversion',
|
||||
161: 'tri-attack',
|
||||
162: 'super-fang',
|
||||
163: 'slash',
|
||||
164: 'substitute',
|
||||
165: 'struggle',
|
||||
1: 'move.pound',
|
||||
2: 'move.karate-chop',
|
||||
3: 'move.double-slap',
|
||||
4: 'move.comet-punch',
|
||||
5: 'move.mega-punch',
|
||||
6: 'move.pay-day',
|
||||
7: 'move.fire-punch',
|
||||
8: 'move.ice-punch',
|
||||
9: 'move.thunder-punch',
|
||||
10: 'move.scratch',
|
||||
11: 'move.vice-grip',
|
||||
12: 'move.guillotine',
|
||||
13: 'move.razor-wind',
|
||||
14: 'move.swords-dance',
|
||||
15: 'move.cut',
|
||||
16: 'move.gust',
|
||||
17: 'move.wing-attack',
|
||||
18: 'move.whirlwind',
|
||||
19: 'move.fly',
|
||||
20: 'move.bind',
|
||||
21: 'move.slam',
|
||||
22: 'move.vine-whip',
|
||||
23: 'move.stomp',
|
||||
24: 'move.double-kick',
|
||||
25: 'move.mega-kick',
|
||||
26: 'move.jump-kick',
|
||||
27: 'move.rolling-kick',
|
||||
28: 'move.sand-attack',
|
||||
29: 'move.headbutt',
|
||||
30: 'move.horn-attack',
|
||||
31: 'move.fury-attack',
|
||||
32: 'move.horn-drill',
|
||||
33: 'move.tackle',
|
||||
34: 'move.body-slam',
|
||||
35: 'move.wrap',
|
||||
36: 'move.take-down',
|
||||
37: 'move.thrash',
|
||||
38: 'move.double-edge',
|
||||
39: 'move.tail-whip',
|
||||
40: 'move.poison-sting',
|
||||
41: 'move.twineedle',
|
||||
42: 'move.pin-missile',
|
||||
43: 'move.leer',
|
||||
44: 'move.bite',
|
||||
45: 'move.growl',
|
||||
46: 'move.roar',
|
||||
47: 'move.sing',
|
||||
48: 'move.supersonic',
|
||||
49: 'move.sonic-boom',
|
||||
50: 'move.disable',
|
||||
51: 'move.acid',
|
||||
52: 'move.ember',
|
||||
53: 'move.flamethrower',
|
||||
54: 'move.mist',
|
||||
55: 'move.water-gun',
|
||||
56: 'move.hydro-pump',
|
||||
57: 'move.surf',
|
||||
58: 'move.ice-beam',
|
||||
59: 'move.blizzard',
|
||||
60: 'move.psybeam',
|
||||
61: 'move.bubble-beam',
|
||||
62: 'move.aurora-beam',
|
||||
63: 'move.hyper-beam',
|
||||
64: 'move.peck',
|
||||
65: 'move.drill-peck',
|
||||
66: 'move.submission',
|
||||
67: 'move.low-kick',
|
||||
68: 'move.counter',
|
||||
69: 'move.seismic-toss',
|
||||
70: 'move.strength',
|
||||
71: 'move.absorb',
|
||||
72: 'move.mega-drain',
|
||||
73: 'move.leech-seed',
|
||||
74: 'move.growth',
|
||||
75: 'move.razor-leaf',
|
||||
76: 'move.solar-beam',
|
||||
77: 'move.poison-powder',
|
||||
78: 'move.stun-spore',
|
||||
79: 'move.sleep-powder',
|
||||
80: 'move.petal-dance',
|
||||
81: 'move.string-shot',
|
||||
82: 'move.dragon-rage',
|
||||
83: 'move.fire-spin',
|
||||
84: 'move.thunder-shock',
|
||||
85: 'move.thunderbolt',
|
||||
86: 'move.thunder-wave',
|
||||
87: 'move.thunder',
|
||||
88: 'move.rock-throw',
|
||||
89: 'move.earthquake',
|
||||
90: 'move.fissure',
|
||||
91: 'move.dig',
|
||||
92: 'move.toxic',
|
||||
93: 'move.confusion',
|
||||
94: 'move.psychic',
|
||||
95: 'move.hypnosis',
|
||||
96: 'move.meditate',
|
||||
97: 'move.agility',
|
||||
98: 'move.quick-attack',
|
||||
99: 'move.rage',
|
||||
100: 'move.teleport',
|
||||
101: 'move.night-shade',
|
||||
102: 'move.mimic',
|
||||
103: 'move.screech',
|
||||
104: 'move.double-team',
|
||||
105: 'move.recover',
|
||||
106: 'move.harden',
|
||||
107: 'move.minimize',
|
||||
108: 'move.smokescreen',
|
||||
109: 'move.confuse-ray',
|
||||
110: 'move.withdraw',
|
||||
111: 'move.defense-curl',
|
||||
112: 'move.barrier',
|
||||
113: 'move.light-screen',
|
||||
114: 'move.haze',
|
||||
115: 'move.reflect',
|
||||
116: 'move.focus-energy',
|
||||
117: 'move.bide',
|
||||
118: 'move.metronome',
|
||||
119: 'move.mirror-move',
|
||||
120: 'move.self-destruct',
|
||||
121: 'move.egg-bomb',
|
||||
122: 'move.lick',
|
||||
123: 'move.smog',
|
||||
124: 'move.sludge',
|
||||
125: 'move.bone-club',
|
||||
126: 'move.fire-blast',
|
||||
127: 'move.waterfall',
|
||||
128: 'move.clamp',
|
||||
129: 'move.swift',
|
||||
130: 'move.skull-bash',
|
||||
131: 'move.spike-cannon',
|
||||
132: 'move.constrict',
|
||||
133: 'move.amnesia',
|
||||
134: 'move.kinesis',
|
||||
135: 'move.soft-boiled',
|
||||
136: 'move.high-jump-kick',
|
||||
137: 'move.glare',
|
||||
138: 'move.dream-eater',
|
||||
139: 'move.poison-gas',
|
||||
140: 'move.barrage',
|
||||
141: 'move.leech-life',
|
||||
142: 'move.lovely-kiss',
|
||||
143: 'move.sky-attack',
|
||||
144: 'move.transform',
|
||||
145: 'move.bubble',
|
||||
146: 'move.dizzy-punch',
|
||||
147: 'move.spore',
|
||||
148: 'move.flash',
|
||||
149: 'move.psywave',
|
||||
150: 'move.splash',
|
||||
151: 'move.acid-armor',
|
||||
152: 'move.crabhammer',
|
||||
153: 'move.explosion',
|
||||
154: 'move.fury-swipes',
|
||||
155: 'move.bonemerang',
|
||||
156: 'move.rest',
|
||||
157: 'move.rock-slide',
|
||||
158: 'move.hyper-fang',
|
||||
159: 'move.sharpen',
|
||||
160: 'move.conversion',
|
||||
161: 'move.tri-attack',
|
||||
162: 'move.super-fang',
|
||||
163: 'move.slash',
|
||||
164: 'move.substitute',
|
||||
165: 'move.struggle',
|
||||
}
|
||||
|
||||
|
||||
|
@ -1178,11 +1179,11 @@ evos_moves_struct = Struct(
|
|||
Embedded(Switch(
|
||||
'evo_arguments',
|
||||
lambda ctx: ctx.evo_trigger, {
|
||||
'level-up': Struct(
|
||||
'evolution-trigger.level-up': Struct(
|
||||
'---',
|
||||
ULInt8('evo_level'),
|
||||
),
|
||||
'use-item': Struct(
|
||||
'evolution-trigger.use-item': Struct(
|
||||
'---',
|
||||
# TODO item enum too wow!
|
||||
ULInt8('evo_item'),
|
||||
|
@ -1190,7 +1191,7 @@ evos_moves_struct = Struct(
|
|||
ULInt8('evo_level'),
|
||||
),
|
||||
# TODO ??? always seems to be 1 here too
|
||||
'trade': Struct(
|
||||
'evolution-trigger.trade': Struct(
|
||||
'---',
|
||||
ULInt8('evo_level'),
|
||||
),
|
||||
|
@ -1280,8 +1281,14 @@ class RBYCart:
|
|||
Return a dict of raw file offsets. The keys are the names used in the
|
||||
pokered project.
|
||||
"""
|
||||
# The base stats are always in the same place in RBY, and only slightly
|
||||
# off in RG. Not sure why! But it hopefully means recompilation
|
||||
# doesn't affect them.
|
||||
addresses = {
|
||||
# These seem to always be the same. Not sure why!
|
||||
# These ones have, thusfar, defied automatic detection, as they're
|
||||
# just part of a big old block of data — so I can't just look for
|
||||
# code nearby.
|
||||
# TODO these are for rby; fix for rg, and maybe y?
|
||||
'BaseStats': unbank('0E:43DE'),
|
||||
'MewBaseStats': unbank('01:425B'),
|
||||
}
|
||||
|
@ -1624,6 +1631,7 @@ class RBYCart:
|
|||
def pokemon_records(self):
|
||||
"""List of pokemon_structs."""
|
||||
self.stream.seek(self.addrs['BaseStats'])
|
||||
print(self.stream.read(100).hex())
|
||||
records = Array(self.NUM_POKEMON - 1, pokemon_struct).parse_stream(self.stream)
|
||||
# Mew's data is, awkwardly, stored separately
|
||||
self.stream.seek(self.addrs['MewBaseStats'])
|
||||
|
@ -1713,13 +1721,16 @@ class WriterWrapper:
|
|||
return getattr(self.locus, key)
|
||||
|
||||
|
||||
def main():
|
||||
def main(root):
|
||||
# TODO does this need to take arguments? or like, sprite mode i guess
|
||||
carts = []
|
||||
for filename in sys.argv[1:]:
|
||||
cart = RBYCart(Path(filename))
|
||||
carts.append(cart)
|
||||
|
||||
root /= carts[0].game
|
||||
root.mkdir(exist_ok=True)
|
||||
|
||||
#loader = RBYLoader(*carts)
|
||||
pokemons = OrderedDict([
|
||||
(POKEMON_IDENTIFIERS[id + 1], schema.Pokemon())
|
||||
|
@ -1788,11 +1799,10 @@ def main():
|
|||
evolutions.append(evo)
|
||||
writer.evolutions = evolutions
|
||||
|
||||
|
||||
from camel import Camel
|
||||
print(Camel([schema.POKEDEX_TYPES]).dump(pokemons))
|
||||
|
||||
with (root / 'pokemon.yaml').open('w') as f:
|
||||
f.write(Camel([schema.POKEDEX_TYPES]).dump(pokemons))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
# TODO yeah fix this up
|
||||
main(Path('pokedex/data'))
|
||||
|
|
|
@ -3,21 +3,40 @@
|
|||
from collections import defaultdict
|
||||
from collections import OrderedDict
|
||||
from pprint import pprint
|
||||
import types
|
||||
|
||||
import camel
|
||||
|
||||
|
||||
|
||||
class _Attribute:
|
||||
name = None
|
||||
_creation_order = 0
|
||||
|
||||
def __init__(self):
|
||||
self._creation_order = _Attribute._creation_order
|
||||
_Attribute._creation_order += 1
|
||||
|
||||
def __get__(self, inst, owner):
|
||||
# TODO this is intended for the glom object, not a slice
|
||||
return self.Glommed(self, inst)
|
||||
|
||||
def __set_name__(self, cls, name):
|
||||
self.name = name
|
||||
|
||||
class Glommed:
|
||||
def __init__(self, prop, obj):
|
||||
self.prop = prop
|
||||
self.obj = obj
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} of {!r}.{}: {!r}>".format(
|
||||
type(self).__qualname__,
|
||||
self.obj,
|
||||
self.prop.name,
|
||||
{game: getattr(slice, self.prop.name) for game, slice in self.obj._slices.items()},
|
||||
)
|
||||
|
||||
|
||||
# TODO classtools, key sort by _creation_order
|
||||
|
||||
|
||||
|
@ -55,20 +74,48 @@ class _ForwardDeclaration:
|
|||
pass
|
||||
|
||||
|
||||
class Slice:
|
||||
is_slice = True
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
class LocusMeta(type):
|
||||
def __init__(cls, name, bases, attrs):
|
||||
for key, attr in attrs.items():
|
||||
if hasattr(attr, '__set_name__'):
|
||||
attr.__set_name__(cls, key)
|
||||
|
||||
super().__init__(name, bases, attrs)
|
||||
# TODO uhh yeah figure this out. possibly related to attrs
|
||||
cls.index = {}
|
||||
|
||||
# TODO need default values
|
||||
# This is purely a backport of Python 3.6 functionality, and is taken from
|
||||
# PEP 487. Once the minimum version supported is 3.6, this metaclass can
|
||||
# go away entirely.
|
||||
if not hasattr(object, '__init_subclass__'):
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if len(args) != 3:
|
||||
return super().__new__(cls, *args)
|
||||
name, bases, ns = args
|
||||
init = ns.get('__init_subclass__')
|
||||
if isinstance(init, types.FunctionType):
|
||||
ns['__init_subclass__'] = classmethod(init)
|
||||
else:
|
||||
init = None
|
||||
self = super().__new__(cls, name, bases, ns)
|
||||
for k, v in self.__dict__.items():
|
||||
func = getattr(v, '__set_name__', None)
|
||||
if func is not None:
|
||||
func(self, k)
|
||||
sup = super(self, self)
|
||||
if hasattr(sup, '__init_subclass__'):
|
||||
sup.__init_subclass__(**kwargs)
|
||||
return self
|
||||
|
||||
|
||||
class Locus(metaclass=LocusMeta):
|
||||
_attributes = {}
|
||||
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
# super().__init_subclass__(**kwargs)
|
||||
cls._attributes = cls._attributes.copy()
|
||||
for key, value in cls.__dict__.items():
|
||||
if isinstance(value, _Attribute):
|
||||
cls._attributes[key] = value
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
cls = type(self)
|
||||
|
||||
|
@ -78,6 +125,25 @@ class Locus(metaclass=LocusMeta):
|
|||
|
||||
setattr(self, key, value)
|
||||
|
||||
def __repr__(self):
|
||||
return "<{}: {}>".format(
|
||||
type(self).__qualname__,
|
||||
self.identifier,
|
||||
)
|
||||
|
||||
|
||||
class VersionedLocus(Locus):
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super(VersionedLocus, cls).__init_subclass__(**kwargs)
|
||||
|
||||
if not issubclass(cls, Slice):
|
||||
class Sliced(cls, Slice):
|
||||
base_class = cls
|
||||
|
||||
# TODO this is a circular reference; do i care?
|
||||
cls.Sliced = Sliced
|
||||
|
||||
cls._slices = {}
|
||||
|
||||
# TODO seems to me that each of these, regardless of whether they have any
|
||||
# additional data attached or not, are restricted to a fixed extra-game-ular
|
||||
|
@ -91,10 +157,9 @@ MoveSet = _ForwardDeclaration()
|
|||
Pokedex = _ForwardDeclaration()
|
||||
|
||||
|
||||
|
||||
|
||||
class Pokemon(Locus):
|
||||
# TODO version, language. but those are kind of meta-fields; do they need treating specially?
|
||||
class Pokémon(VersionedLocus):
|
||||
# TODO version, language. but those are kind of meta-fields; do they need
|
||||
# treating specially?
|
||||
# TODO in old games, names are unique per game; in later games, they differ
|
||||
# per language. what do i do about that?
|
||||
name = _Value(str)
|
||||
|
@ -125,19 +190,34 @@ class Pokemon(Locus):
|
|||
# TODO should this be written in hex, maybe?
|
||||
game_index = _Value(int)
|
||||
|
||||
Pokemon = Pokémon
|
||||
|
||||
|
||||
class Repository:
|
||||
def __init__(self):
|
||||
# type -> identifier -> list of objects
|
||||
self.objects = defaultdict(lambda: defaultdict(set))
|
||||
# type -> identifier -> object
|
||||
self.objects = defaultdict(lambda: {})
|
||||
# type -> property -> value -> list of objects
|
||||
self.index = defaultdict(lambda: defaultdict(lambda: defaultdict(set)))
|
||||
|
||||
def add(self, obj):
|
||||
# TODO this should be declared by the type itself, obviously
|
||||
cls = type(obj)
|
||||
self.objects[cls][obj.identifier].add(obj)
|
||||
self.index[cls][cls.name][obj.name].add(obj)
|
||||
# TODO both branches here should check for duplicates
|
||||
if isinstance(obj, Slice):
|
||||
cls = cls.base_class
|
||||
if obj.identifier not in self.objects[cls]:
|
||||
glom = cls()
|
||||
glom.identifier = obj.identifier
|
||||
self.objects[cls][obj.identifier] = glom
|
||||
else:
|
||||
glom = self.objects[cls][obj.identifier]
|
||||
# TODO this... feels special-cased, but i guess, it is?
|
||||
glom._slices[obj.game] = obj
|
||||
else:
|
||||
self.objects[cls][obj.identifier] = obj
|
||||
# TODO this is more complex now that names are multi-language
|
||||
#self.index[cls][cls.name][obj.name].add(obj)
|
||||
|
||||
def fetch(self, cls, identifier):
|
||||
# TODO wrap in a... multi-thing
|
||||
|
@ -161,7 +241,8 @@ def _dump_locus(locus):
|
|||
|
||||
@POKEDEX_TYPES.loader('pokemon', version=None)
|
||||
def _load_locus(data, version):
|
||||
cls = Pokemon
|
||||
cls = Pokemon.Sliced
|
||||
# TODO wrap with a writer thing?
|
||||
obj = cls()
|
||||
for key, value in data.items():
|
||||
key = key.replace('-', '_')
|
||||
|
@ -176,26 +257,24 @@ def _temp_main():
|
|||
|
||||
# just testing for now
|
||||
cam = camel.Camel([POKEDEX_TYPES])
|
||||
PATH = 'pokedex/data/gen1/red/en/pokemon.yaml'
|
||||
PATH = 'pokedex/data/ww-red/pokemon.yaml'
|
||||
with open(PATH) as f:
|
||||
all_pokemon = cam.load(f.read())
|
||||
for identifier, pokemon in all_pokemon.items():
|
||||
# TODO i don't reeeally like this, but configuring a camel to do it
|
||||
# is a little unwieldy
|
||||
pokemon.version = 'red'
|
||||
pokemon.language = 'en'
|
||||
pokemon.game = 'ww-red'
|
||||
# TODO this in particular seems extremely clumsy, but identifiers ARE fundamentally keys...
|
||||
pokemon.identifier = identifier
|
||||
|
||||
repository.add(pokemon)
|
||||
PATH = 'pokedex/data/gen1/red/fr/pokemon.yaml'
|
||||
PATH = 'pokedex/data/ww-blue/pokemon.yaml'
|
||||
with open(PATH) as f:
|
||||
all_pokemon = cam.load(f.read())
|
||||
for identifier, pokemon in all_pokemon.items():
|
||||
# TODO i don't reeeally like this, but configuring a camel to do it
|
||||
# is a little unwieldy
|
||||
pokemon.version = 'red'
|
||||
pokemon.language = 'fr'
|
||||
pokemon.game = 'ww-blue'
|
||||
# TODO this in particular seems extremely clumsy, but identifiers ARE fundamentally keys...
|
||||
pokemon.identifier = identifier
|
||||
|
||||
|
@ -206,11 +285,12 @@ def _temp_main():
|
|||
# - but what about the vast majority of properties that are the same in every language and only vary by version?
|
||||
# - what about later games, where only some properties vary by language? in the extreme case, xy/oras are single games!
|
||||
|
||||
eevee = repository.fetch(Pokemon, 'eevee')
|
||||
# TODO should this prepend the prefix automatically... eh
|
||||
eevee = repository.fetch(Pokemon, 'pokemon.eevee')
|
||||
pprint(eevee)
|
||||
return
|
||||
eevee = Pokemon['eevee']
|
||||
# TODO i feel like this should work: eevee = repository.Pokemon['eevee']
|
||||
print(eevee.name)
|
||||
print(eevee.types)
|
||||
|
||||
|
||||
# TODO alright so we need to figure out the "index" part, and how you
|
||||
|
|
Loading…
Reference in a new issue