Added ability effects. Rewrote short effects. #39
[zzz-pokedex.git] / pokedex / db / tables.py
1 # encoding: utf8
2
3 from sqlalchemy import Column, ForeignKey, MetaData, Table
4 from sqlalchemy.ext.declarative import declarative_base
5 from sqlalchemy.ext.associationproxy import association_proxy
6 from sqlalchemy.orm import backref, relation
7 from sqlalchemy.sql import and_
8 from sqlalchemy.types import *
9
10 from pokedex.db import rst
11
12 metadata = MetaData()
13 TableBase = declarative_base(metadata=metadata)
14
15 class Ability(TableBase):
16 __tablename__ = 'abilities'
17 __singlename__ = 'ability'
18 id = Column(Integer, primary_key=True, nullable=False)
19 name = Column(Unicode(24), nullable=False)
20 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
21 effect = Column(rst.RstTextColumn(5120), nullable=False)
22 short_effect = Column(rst.RstTextColumn(255), nullable=False)
23 flavor_text = Column(Unicode(64), nullable=False)
24
25 class Berry(TableBase):
26 __tablename__ = 'berries'
27 id = Column(Integer, primary_key=True, nullable=False)
28 item_id = Column(Integer, ForeignKey('items.id'), nullable=False)
29 firmness_id = Column(Integer, ForeignKey('berry_firmness.id'), nullable=False)
30 natural_gift_power = Column(Integer, nullable=True)
31 natural_gift_type_id = Column(Integer, ForeignKey('types.id'), nullable=True)
32 size = Column(Integer, nullable=False)
33 max_harvest = Column(Integer, nullable=False)
34 growth_time = Column(Integer, nullable=False)
35 soil_dryness = Column(Integer, nullable=False)
36 smoothness = Column(Integer, nullable=False)
37
38 class BerryFirmness(TableBase):
39 __tablename__ = 'berry_firmness'
40 id = Column(Integer, primary_key=True, nullable=False)
41 name = Column(Unicode(10), nullable=False)
42
43 class BerryFlavor(TableBase):
44 __tablename__ = 'berry_flavors'
45 berry_id = Column(Integer, ForeignKey('berries.id'), primary_key=True, nullable=False, autoincrement=False)
46 contest_type_id = Column(Integer, ForeignKey('contest_types.id'), primary_key=True, nullable=False, autoincrement=False)
47 flavor = Column(Integer, nullable=False)
48
49 class ContestCombo(TableBase):
50 __tablename__ = 'contest_combos'
51 first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
52 second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
53
54 class ContestEffect(TableBase):
55 __tablename__ = 'contest_effects'
56 id = Column(Integer, primary_key=True, nullable=False)
57 appeal = Column(SmallInteger, nullable=False)
58 jam = Column(SmallInteger, nullable=False)
59 flavor_text = Column(Unicode(64), nullable=False)
60 effect = Column(Unicode(255), nullable=False)
61
62 class ContestType(TableBase):
63 __tablename__ = 'contest_types'
64 id = Column(Integer, primary_key=True, nullable=False)
65 name = Column(Unicode(6), nullable=False)
66 flavor = Column(Unicode(6), nullable=False)
67 color = Column(Unicode(6), nullable=False)
68
69 class EggGroup(TableBase):
70 __tablename__ = 'egg_groups'
71 id = Column(Integer, primary_key=True, nullable=False)
72 name = Column(Unicode(16), nullable=False)
73
74 class Encounter(TableBase):
75 """Rows in this table represent encounters with wild Pokémon. Bear with
76 me, here.
77
78 Within a given area in a given game, encounters are differentiated by the
79 "slot" they are in and the state of the game world.
80
81 What the player is doing to get an encounter, such as surfing or walking
82 through tall grass, is called terrain. Each terrain has its own set of
83 encounter slots.
84
85 Within a terrain, slots are defined primarily by rarity. Each slot can
86 also be affected by world conditions; for example, the 20% slot for walking
87 in tall grass is affected by whether a swarm is in effect in that area.
88 "Is there a swarm?" is a condition; "there is a swarm" and "there is not a
89 swarm" are the possible values of this condition.
90
91 A slot (20% walking in grass) and any appropriate world conditions (no
92 swarm) are thus enough to define a specific encounter.
93
94 Well, okay, almost: each slot actually appears twice.
95 """
96
97 __tablename__ = 'encounters'
98 id = Column(Integer, primary_key=True, nullable=False)
99 version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False)
100 location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False)
101 encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), nullable=False, autoincrement=False)
102 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False)
103 min_level = Column(Integer, nullable=False, autoincrement=False)
104 max_level = Column(Integer, nullable=False, autoincrement=False)
105
106 class EncounterCondition(TableBase):
107 """Rows in this table represent varying conditions in the game world, such
108 as time of day.
109 """
110
111 __tablename__ = 'encounter_conditions'
112 id = Column(Integer, primary_key=True, nullable=False)
113 name = Column(Unicode(64), nullable=False)
114
115 class EncounterConditionValue(TableBase):
116 """Rows in this table represent possible states for a condition; for
117 example, the state of 'swarm' could be 'swarm' or 'no swarm'.
118 """
119
120 __tablename__ = 'encounter_condition_values'
121 id = Column(Integer, primary_key=True, nullable=False)
122 encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=False, nullable=False, autoincrement=False)
123 name = Column(Unicode(64), nullable=False)
124 is_default = Column(Boolean, nullable=False)
125
126 class EncounterConditionValueMap(TableBase):
127 """Maps encounters to the specific conditions under which they occur."""
128
129 __tablename__ = 'encounter_condition_value_map'
130 encounter_id = Column(Integer, ForeignKey('encounters.id'), primary_key=True, nullable=False, autoincrement=False)
131 encounter_condition_value_id = Column(Integer, ForeignKey('encounter_condition_values.id'), primary_key=True, nullable=False, autoincrement=False)
132
133 class EncounterTerrain(TableBase):
134 """Rows in this table represent ways the player can enter a wild encounter,
135 e.g., surfing, fishing, or walking through tall grass.
136 """
137
138 __tablename__ = 'encounter_terrain'
139 id = Column(Integer, primary_key=True, nullable=False)
140 name = Column(Unicode(64), nullable=False)
141
142 class EncounterSlot(TableBase):
143 """Rows in this table represent an abstract "slot" within a terrain,
144 associated with both some set of conditions and a rarity.
145
146 Note that there are two encounters per slot, so the rarities will only add
147 up to 50.
148 """
149
150 __tablename__ = 'encounter_slots'
151 id = Column(Integer, primary_key=True, nullable=False)
152 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, autoincrement=False)
153 encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=False, nullable=False, autoincrement=False)
154 slot = Column(Integer, nullable=True)
155 rarity = Column(Integer, nullable=False)
156
157 class EncounterSlotCondition(TableBase):
158 """Lists all conditions that affect each slot."""
159
160 __tablename__ = 'encounter_slot_conditions'
161 encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), primary_key=True, nullable=False, autoincrement=False)
162 encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=True, nullable=False, autoincrement=False)
163
164 class EvolutionChain(TableBase):
165 __tablename__ = 'evolution_chains'
166 id = Column(Integer, primary_key=True, nullable=False)
167 growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), nullable=False)
168 steps_to_hatch = Column(Integer, nullable=False)
169 baby_trigger_item = Column(Unicode(12))
170
171 class EvolutionMethod(TableBase):
172 __tablename__ = 'evolution_methods'
173 id = Column(Integer, primary_key=True, nullable=False)
174 name = Column(Unicode(64), nullable=False)
175 description = Column(Unicode(255), nullable=False)
176
177 class Experience(TableBase):
178 __tablename__ = 'experience'
179 growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), primary_key=True, nullable=False)
180 level = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
181 experience = Column(Integer, nullable=False)
182
183 class Generation(TableBase):
184 __tablename__ = 'generations'
185 id = Column(Integer, primary_key=True, nullable=False)
186 main_region_id = Column(Integer, ForeignKey('regions.id'))
187 canonical_pokedex_id = Column(Integer, ForeignKey('pokedexes.id'))
188 name = Column(Unicode(16), nullable=False)
189
190 class GrowthRate(TableBase):
191 """`formula` is written in LaTeX math notation."""
192 __tablename__ = 'growth_rates'
193 id = Column(Integer, primary_key=True, nullable=False)
194 name = Column(Unicode(20), nullable=False)
195 formula = Column(Unicode(500), nullable=False)
196
197 class Item(TableBase):
198 __tablename__ = 'items'
199 __singlename__ = 'item'
200 id = Column(Integer, primary_key=True, nullable=False)
201 name = Column(Unicode(16), nullable=False)
202 category_id = Column(Integer, ForeignKey('item_categories.id'), nullable=False)
203 cost = Column(Integer, nullable=False)
204 fling_power = Column(Integer, nullable=True)
205 fling_effect_id = Column(Integer, ForeignKey('item_fling_effects.id'), nullable=True)
206 effect = Column(rst.RstTextColumn(5120), nullable=False)
207
208 @property
209 def appears_underground(self):
210 return any(flag.identifier == u'underground' for flag in self.flags)
211
212 class ItemCategory(TableBase):
213 __tablename__ = 'item_categories'
214 id = Column(Integer, primary_key=True, nullable=False)
215 pocket_id = Column(Integer, ForeignKey('item_pockets.id'), nullable=False)
216 name = Column(Unicode(16), nullable=False)
217
218 class ItemFlag(TableBase):
219 __tablename__ = 'item_flags'
220 id = Column(Integer, primary_key=True, nullable=False)
221 identifier = Column(Unicode(24), nullable=False)
222 name = Column(Unicode(64), nullable=False)
223
224 class ItemFlagMap(TableBase):
225 __tablename__ = 'item_flag_map'
226 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False)
227 item_flag_id = Column(Integer, ForeignKey('item_flags.id'), primary_key=True, autoincrement=False, nullable=False)
228
229 class ItemFlavorText(TableBase):
230 __tablename__ = 'item_flavor_text'
231 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False)
232 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, autoincrement=False, nullable=False)
233 flavor_text = Column(Unicode(255), nullable=False)
234
235 class ItemFlingEffect(TableBase):
236 __tablename__ = 'item_fling_effects'
237 id = Column(Integer, primary_key=True, nullable=False)
238 effect = Column(Unicode(255), nullable=False)
239
240 class ItemInternalID(TableBase):
241 __tablename__ = 'item_internal_ids'
242 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False)
243 generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, autoincrement=False, nullable=False)
244 internal_id = Column(Integer, nullable=False)
245
246 class ItemPocket(TableBase):
247 __tablename__ = 'item_pockets'
248 id = Column(Integer, primary_key=True, nullable=False)
249 identifier = Column(Unicode(16), nullable=False)
250 name = Column(Unicode(16), nullable=False)
251
252 class Language(TableBase):
253 __tablename__ = 'languages'
254 id = Column(Integer, primary_key=True, nullable=False)
255 iso639 = Column(Unicode(2), nullable=False)
256 iso3166 = Column(Unicode(2), nullable=False)
257 name = Column(Unicode(16), nullable=False)
258
259 class Location(TableBase):
260 __tablename__ = 'locations'
261 __singlename__ = 'location'
262 id = Column(Integer, primary_key=True, nullable=False)
263 region_id = Column(Integer, ForeignKey('regions.id'))
264 name = Column(Unicode(64), nullable=False)
265
266 class LocationArea(TableBase):
267 __tablename__ = 'location_areas'
268 id = Column(Integer, primary_key=True, nullable=False)
269 location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
270 internal_id = Column(Integer, nullable=False)
271 name = Column(Unicode(64), nullable=True)
272
273 class LocationAreaEncounterRate(TableBase):
274 __tablename__ = 'location_area_encounter_rates'
275 location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
276 encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
277 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, autoincrement=False)
278 rate = Column(Integer, nullable=True)
279
280 class Machine(TableBase):
281 __tablename__ = 'machines'
282 machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
283 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
284 move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
285
286 class MoveBattleStyle(TableBase):
287 __tablename__ = 'move_battle_styles'
288 id = Column(Integer, primary_key=True, nullable=False)
289 name = Column(Unicode(8), nullable=False)
290
291 class MoveEffectCategory(TableBase):
292 __tablename__ = 'move_effect_categories'
293 id = Column(Integer, primary_key=True, nullable=False)
294 name = Column(Unicode(64), nullable=False)
295 can_affect_user = Column(Boolean, nullable=False)
296
297 class MoveEffectCategoryMap(TableBase):
298 __tablename__ = 'move_effect_category_map'
299 move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False)
300 move_effect_category_id = Column(Integer, ForeignKey('move_effect_categories.id'), primary_key=True, nullable=False)
301 affects_user = Column(Boolean, primary_key=True, nullable=False)
302
303 class MoveDamageClass(TableBase):
304 __tablename__ = 'move_damage_classes'
305 id = Column(Integer, primary_key=True, nullable=False)
306 name = Column(Unicode(8), nullable=False)
307 description = Column(Unicode(64), nullable=False)
308
309 class MoveEffect(TableBase):
310 __tablename__ = 'move_effects'
311 id = Column(Integer, primary_key=True, nullable=False)
312 priority = Column(SmallInteger, nullable=False)
313 short_effect = Column(Unicode(256), nullable=False)
314 effect = Column(Unicode(5120), nullable=False)
315
316 class MoveFlag(TableBase):
317 __tablename__ = 'move_flags'
318 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
319 move_flag_type_id = Column(Integer, ForeignKey('move_flag_types.id'), primary_key=True, nullable=False, autoincrement=False)
320
321 class MoveFlagType(TableBase):
322 __tablename__ = 'move_flag_types'
323 id = Column(Integer, primary_key=True, nullable=False)
324 name = Column(Unicode(32), nullable=False)
325 description = Column(rst.RstTextColumn(128), nullable=False)
326
327 class MoveFlavorText(TableBase):
328 __tablename__ = 'move_flavor_text'
329 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
330 generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, nullable=False, autoincrement=False)
331 flavor_text = Column(Unicode(255), nullable=False)
332
333 class MoveName(TableBase):
334 __tablename__ = 'move_names'
335 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
336 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
337 name = Column(Unicode(16), nullable=False)
338
339 class MoveTarget(TableBase):
340 __tablename__ = 'move_targets'
341 id = Column(Integer, primary_key=True, nullable=False)
342 name = Column(Unicode(32), nullable=False)
343 description = Column(Unicode(128), nullable=False)
344
345 class Move(TableBase):
346 __tablename__ = 'moves'
347 __singlename__ = 'move'
348 id = Column(Integer, primary_key=True, nullable=False)
349 name = Column(Unicode(12), nullable=False)
350 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
351 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
352 power = Column(SmallInteger)
353 pp = Column(SmallInteger, nullable=False)
354 accuracy = Column(SmallInteger)
355 target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False)
356 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False)
357 effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False)
358 effect_chance = Column(Integer)
359 contest_type_id = Column(Integer, ForeignKey('contest_types.id'), nullable=True)
360 contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True)
361 super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=False)
362
363 class Nature(TableBase):
364 __tablename__ = 'natures'
365 __singlename__ = 'nature'
366 id = Column(Integer, primary_key=True, nullable=False)
367 name = Column(Unicode(8), nullable=False)
368 decreased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False)
369 increased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False)
370 hates_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False)
371 likes_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False)
372
373 class NatureBattleStylePreference(TableBase):
374 __tablename__ = 'nature_battle_style_preferences'
375 nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False)
376 move_battle_style_id = Column(Integer, ForeignKey('move_battle_styles.id'), primary_key=True, nullable=False)
377 low_hp_preference = Column(Integer, nullable=False)
378 high_hp_preference = Column(Integer, nullable=False)
379
380 class NaturePokeathlonStat(TableBase):
381 __tablename__ = 'nature_pokeathlon_stats'
382 nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False)
383 pokeathlon_stat_id = Column(Integer, ForeignKey('pokeathlon_stats.id'), primary_key=True, nullable=False)
384 max_change = Column(Integer, nullable=False)
385
386 class PokeathlonStat(TableBase):
387 __tablename__ = 'pokeathlon_stats'
388 id = Column(Integer, primary_key=True, nullable=False)
389 name = Column(Unicode(8), nullable=False)
390
391 class Pokedex(TableBase):
392 __tablename__ = 'pokedexes'
393 id = Column(Integer, primary_key=True, nullable=False)
394 region_id = Column(Integer, ForeignKey('regions.id'), nullable=True)
395 name = Column(Unicode(16), nullable=False)
396 description = Column(Unicode(512))
397
398 class PokedexVersionGroup(TableBase):
399 __tablename__ = 'pokedex_version_groups'
400 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
401 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
402
403 class Pokemon(TableBase):
404 """The core to this whole mess.
405
406 Note that I use both 'forme' and 'form' in both code and the database. I
407 only use 'forme' when specifically referring to Pokémon that have multiple
408 distinct species as forms—i.e., different stats or movesets. 'Form' is a
409 more general term referring to any variation within a species, including
410 purely cosmetic forms like Unown.
411 """
412 __tablename__ = 'pokemon'
413 __singlename__ = 'pokemon'
414 id = Column(Integer, primary_key=True, nullable=False)
415 name = Column(Unicode(20), nullable=False)
416 forme_name = Column(Unicode(16))
417 forme_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
418 generation_id = Column(Integer, ForeignKey('generations.id'))
419 evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'))
420 evolution_parent_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
421 evolution_method_id = Column(Integer, ForeignKey('evolution_methods.id'))
422 evolution_parameter = Column(Unicode(32))
423 height = Column(Integer, nullable=False)
424 weight = Column(Integer, nullable=False)
425 species = Column(Unicode(16), nullable=False)
426 color_id = Column(Integer, ForeignKey('pokemon_colors.id'), nullable=False)
427 pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=False)
428 habitat_id = Column(Integer, ForeignKey('pokemon_habitats.id'), nullable=True)
429 gender_rate = Column(Integer, nullable=False)
430 capture_rate = Column(Integer, nullable=False)
431 base_experience = Column(Integer, nullable=False)
432 base_happiness = Column(Integer, nullable=False)
433 is_baby = Column(Boolean, nullable=False)
434 has_gen4_fem_sprite = Column(Boolean, nullable=False)
435 has_gen4_fem_back_sprite = Column(Boolean, nullable=False)
436
437 ### Stuff to handle alternate Pokémon forms
438
439 @property
440 def national_id(self):
441 """Returns the National Pokédex number for this Pokémon. Use this
442 instead of the id directly; alternate formes may make the id incorrect.
443 """
444
445 if self.forme_base_pokemon_id:
446 return self.forme_base_pokemon_id
447 return self.id
448
449 @property
450 def full_name(self):
451 """Returns the name of this Pokémon, including its Forme, if any."""
452
453 if self.forme_name:
454 return "%s %s" % (self.forme_name.title(), self.name)
455 return self.name
456
457 @property
458 def normal_form(self):
459 """Returns the normal form for this Pokémon; i.e., this will return
460 regular Deoxys when called on any Deoxys form.
461 """
462
463 if self.forme_base_pokemon:
464 return self.forme_base_pokemon
465
466 return self
467
468 ### Not forms!
469
470 def stat(self, stat_name):
471 """Returns a PokemonStat record for the given stat name (or Stat row
472 object). Uses the normal has-many machinery, so all the stats are
473 effectively cached.
474 """
475 if isinstance(stat_name, Stat):
476 stat_name = stat_name.name
477
478 for pokemon_stat in self.stats:
479 if pokemon_stat.stat.name == stat_name:
480 return pokemon_stat
481
482 return None
483
484 class PokemonAbility(TableBase):
485 __tablename__ = 'pokemon_abilities'
486 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
487 ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False)
488 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
489
490 class PokemonColor(TableBase):
491 __tablename__ = 'pokemon_colors'
492 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
493 name = Column(Unicode(6), nullable=False)
494
495 class PokemonDexNumber(TableBase):
496 __tablename__ = 'pokemon_dex_numbers'
497 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
498 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
499 pokedex_number = Column(Integer, nullable=False)
500
501 class PokemonEggGroup(TableBase):
502 __tablename__ = 'pokemon_egg_groups'
503 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
504 egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False)
505
506 class PokemonFlavorText(TableBase):
507 __tablename__ = 'pokemon_flavor_text'
508 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
509 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
510 flavor_text = Column(Unicode(255), nullable=False)
511
512 class PokemonFormGroup(TableBase):
513 __tablename__ = 'pokemon_form_groups'
514 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
515 is_battle_only = Column(Boolean, nullable=False)
516 description = Column(Unicode(512), nullable=False)
517
518 class PokemonFormSprite(TableBase):
519 __tablename__ = 'pokemon_form_sprites'
520 id = Column(Integer, primary_key=True, nullable=False)
521 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
522 introduced_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
523 name = Column(Unicode(16), nullable=True)
524 is_default = Column(Boolean, nullable=True)
525
526 class PokemonHabitat(TableBase):
527 __tablename__ = 'pokemon_habitats'
528 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
529 name = Column(Unicode(16), nullable=False)
530
531 class PokemonItem(TableBase):
532 __tablename__ = 'pokemon_items'
533 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
534 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
535 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False)
536 rarity = Column(Integer, nullable=False)
537
538 class PokemonMove(TableBase):
539 __tablename__ = 'pokemon_moves'
540 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
541 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
542 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False, index=True)
543 pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), primary_key=True, nullable=False, autoincrement=False)
544 level = Column(Integer, primary_key=True, nullable=True, autoincrement=False)
545 order = Column(Integer, nullable=True)
546
547 class PokemonMoveMethod(TableBase):
548 __tablename__ = 'pokemon_move_methods'
549 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
550 name = Column(Unicode(64), nullable=False)
551 description = Column(Unicode(255), nullable=False)
552
553 class PokemonName(TableBase):
554 __tablename__ = 'pokemon_names'
555 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
556 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
557 name = Column(Unicode(16), nullable=False)
558
559 class PokemonShape(TableBase):
560 __tablename__ = 'pokemon_shapes'
561 id = Column(Integer, primary_key=True, nullable=False)
562 name = Column(Unicode(24), nullable=False)
563 awesome_name = Column(Unicode(16), nullable=False)
564
565 class PokemonStat(TableBase):
566 __tablename__ = 'pokemon_stats'
567 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
568 stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False)
569 base_stat = Column(Integer, nullable=False)
570 effort = Column(Integer, nullable=False)
571
572 class PokemonType(TableBase):
573 __tablename__ = 'pokemon_types'
574 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
575 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
576 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
577
578 class Region(TableBase):
579 """Major areas of the world: Kanto, Johto, etc."""
580 __tablename__ = 'regions'
581 id = Column(Integer, primary_key=True, nullable=False)
582 name = Column(Unicode(16), nullable=False)
583
584 class Stat(TableBase):
585 __tablename__ = 'stats'
586 id = Column(Integer, primary_key=True, nullable=False)
587 name = Column(Unicode(16), nullable=False)
588
589 class SuperContestCombo(TableBase):
590 __tablename__ = 'super_contest_combos'
591 first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
592 second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
593
594 class SuperContestEffect(TableBase):
595 __tablename__ = 'super_contest_effects'
596 id = Column(Integer, primary_key=True, nullable=False)
597 appeal = Column(SmallInteger, nullable=False)
598 flavor_text = Column(Unicode(64), nullable=False)
599
600 class TypeEfficacy(TableBase):
601 __tablename__ = 'type_efficacy'
602 damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
603 target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
604 damage_factor = Column(Integer, nullable=False)
605
606 class Type(TableBase):
607 __tablename__ = 'types'
608 __singlename__ = 'type'
609 id = Column(Integer, primary_key=True, nullable=False)
610 name = Column(Unicode(8), nullable=False)
611 abbreviation = Column(Unicode(3), nullable=False)
612 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
613 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False) ## ??? is none; everything else is physical or special
614
615 class VersionGroup(TableBase):
616 __tablename__ = 'version_groups'
617 id = Column(Integer, primary_key=True, nullable=False)
618 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
619
620 class VersionGroupRegion(TableBase):
621 __tablename__ = 'version_group_regions'
622 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False)
623 region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False)
624
625 class Version(TableBase):
626 __tablename__ = 'versions'
627 id = Column(Integer, primary_key=True, nullable=False)
628 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False)
629 name = Column(Unicode(32), nullable=False)
630
631
632 ### Relations down here, to avoid ordering problems
633 Ability.generation = relation(Generation, backref='abilities')
634
635 Berry.berry_firmness = relation(BerryFirmness, backref='berries')
636 Berry.firmness = association_proxy('berry_firmness', 'name')
637 Berry.flavors = relation(BerryFlavor, order_by=BerryFlavor.contest_type_id, backref='berry')
638 Berry.natural_gift_type = relation(Type)
639
640 BerryFlavor.contest_type = relation(ContestType)
641
642 ContestCombo.first = relation(Move, primaryjoin=ContestCombo.first_move_id==Move.id,
643 backref='contest_combo_first')
644 ContestCombo.second = relation(Move, primaryjoin=ContestCombo.second_move_id==Move.id,
645 backref='contest_combo_second')
646
647 Encounter.location_area = relation(LocationArea, backref='encounters')
648 Encounter.pokemon = relation(Pokemon, backref='encounters')
649 Encounter.version = relation(Version, backref='encounters')
650 Encounter.slot = relation(EncounterSlot, backref='encounters')
651
652 EncounterConditionValue.condition = relation(EncounterCondition, backref='values')
653
654 Encounter.condition_value_map = relation(EncounterConditionValueMap, backref='encounter')
655 Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
656 EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
657 backref='encounter_map')
658
659 EncounterSlot.terrain = relation(EncounterTerrain, backref='slots')
660
661 EncounterSlot.condition_map = relation(EncounterSlotCondition, backref='slot')
662 EncounterSlot.conditions = association_proxy('condition_map', 'condition')
663 EncounterSlotCondition.condition = relation(EncounterCondition,
664 backref='slot_map')
665
666 EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')
667
668 Experience.growth_rate = relation(GrowthRate, backref='experience_table')
669
670 Generation.canonical_pokedex = relation(Pokedex, backref='canonical_for_generation')
671 Generation.versions = relation(Version, secondary=VersionGroup.__table__)
672 Generation.main_region = relation(Region)
673
674 GrowthRate.max_experience_obj = relation(Experience, primaryjoin=and_(Experience.growth_rate_id == GrowthRate.id, Experience.level == 100), uselist=False)
675 GrowthRate.max_experience = association_proxy('max_experience_obj', 'experience')
676
677 Item.berry = relation(Berry, uselist=False, backref='item')
678 Item.flags = relation(ItemFlag, secondary=ItemFlagMap.__table__)
679 Item.flavor_text = relation(ItemFlavorText, order_by=ItemFlavorText.version_group_id.asc(), backref='item')
680 Item.fling_effect = relation(ItemFlingEffect, backref='items')
681 Item.category = relation(ItemCategory)
682 Item.pocket = association_proxy('category', 'pocket')
683
684 ItemCategory.items = relation(Item, order_by=Item.name)
685 ItemCategory.pocket = relation(ItemPocket)
686
687 ItemFlavorText.version_group = relation(VersionGroup)
688
689 ItemPocket.categories = relation(ItemCategory, order_by=ItemCategory.name)
690
691 Location.region = relation(Region, backref='locations')
692
693 LocationArea.location = relation(Location, backref='areas')
694
695 Machine.version_group = relation(VersionGroup)
696
697 Move.contest_effect = relation(ContestEffect, backref='moves')
698 Move.contest_combo_next = association_proxy('contest_combo_first', 'second')
699 Move.contest_combo_prev = association_proxy('contest_combo_second', 'first')
700 Move.contest_type = relation(ContestType, backref='moves')
701 Move.damage_class = relation(MoveDamageClass, backref='moves')
702 Move.flags = association_proxy('move_flags', 'flag')
703 Move.flavor_text = relation(MoveFlavorText, order_by=MoveFlavorText.generation_id, backref='move')
704 Move.foreign_names = relation(MoveName, backref='pokemon')
705 Move.generation = relation(Generation, backref='moves')
706 Move.machines = relation(Machine, backref='move')
707 Move.move_effect = relation(MoveEffect, backref='moves')
708 Move.move_flags = relation(MoveFlag, backref='move')
709 Move.super_contest_effect = relation(SuperContestEffect, backref='moves')
710 Move.super_contest_combo_next = association_proxy('super_contest_combo_first', 'second')
711 Move.super_contest_combo_prev = association_proxy('super_contest_combo_second', 'first')
712 Move.target = relation(MoveTarget, backref='moves')
713 Move.type = relation(Type, backref='moves')
714
715 Move.effect = rst.MoveEffectProperty('effect')
716 Move.priority = association_proxy('move_effect', 'priority')
717 Move.short_effect = rst.MoveEffectProperty('short_effect')
718
719 MoveEffect.category_map = relation(MoveEffectCategoryMap)
720 MoveEffect.categories = association_proxy('category_map', 'category')
721 MoveEffectCategoryMap.category = relation(MoveEffectCategory)
722
723 MoveFlag.flag = relation(MoveFlagType)
724
725 MoveFlavorText.generation = relation(Generation)
726
727 MoveName.language = relation(Language)
728
729 Nature.decreased_stat = relation(Stat, primaryjoin=Nature.decreased_stat_id==Stat.id,
730 backref='decreasing_natures')
731 Nature.increased_stat = relation(Stat, primaryjoin=Nature.increased_stat_id==Stat.id,
732 backref='increasing_natures')
733 Nature.hates_flavor = relation(ContestType, primaryjoin=Nature.hates_flavor_id==ContestType.id,
734 backref='hating_natures')
735 Nature.likes_flavor = relation(ContestType, primaryjoin=Nature.likes_flavor_id==ContestType.id,
736 backref='liking_natures')
737 Nature.battle_style_preferences = relation(NatureBattleStylePreference,
738 order_by=NatureBattleStylePreference.move_battle_style_id,
739 backref='nature')
740 Nature.pokeathlon_effects = relation(NaturePokeathlonStat, order_by=NaturePokeathlonStat.pokeathlon_stat_id)
741
742 NatureBattleStylePreference.battle_style = relation(MoveBattleStyle, backref='nature_preferences')
743
744 NaturePokeathlonStat.pokeathlon_stat = relation(PokeathlonStat, backref='nature_effects')
745
746 Pokedex.region = relation(Region, backref='pokedexes')
747 Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__, backref='pokedexes')
748
749 Pokemon.abilities = relation(Ability, secondary=PokemonAbility.__table__,
750 order_by=PokemonAbility.slot,
751 backref='pokemon')
752 Pokemon.formes = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.forme_base_pokemon_id,
753 backref=backref('forme_base_pokemon',
754 remote_side=[Pokemon.id]))
755 Pokemon.pokemon_color = relation(PokemonColor, backref='pokemon')
756 Pokemon.color = association_proxy('pokemon_color', 'name')
757 Pokemon.dex_numbers = relation(PokemonDexNumber, backref='pokemon')
758 Pokemon.default_form_sprite = relation(PokemonFormSprite,
759 primaryjoin=and_(
760 Pokemon.id==PokemonFormSprite.pokemon_id,
761 PokemonFormSprite.is_default==True,
762 ),
763 uselist=False)
764 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
765 order_by=PokemonEggGroup.egg_group_id,
766 backref='pokemon')
767 Pokemon.evolution_chain = relation(EvolutionChain, backref='pokemon')
768 Pokemon.evolution_method = relation(EvolutionMethod)
769 Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
770 backref=backref('evolution_parent',
771 remote_side=[Pokemon.id]))
772 Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.version_id.asc(), backref='pokemon')
773 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
774 Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
775 Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
776 Pokemon.items = relation(PokemonItem, backref='pokemon')
777 Pokemon.generation = relation(Generation, backref='pokemon')
778 Pokemon.shape = relation(PokemonShape, backref='pokemon')
779 Pokemon.stats = relation(PokemonStat, backref='pokemon')
780 Pokemon.types = relation(Type, secondary=PokemonType.__table__)
781
782 PokemonDexNumber.pokedex = relation(Pokedex)
783
784 PokemonFlavorText.version = relation(Version)
785
786 PokemonItem.item = relation(Item, backref='pokemon')
787 PokemonItem.version = relation(Version)
788
789 PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
790 uselist=False))
791 PokemonFormSprite.pokemon = relation(Pokemon, backref='form_sprites')
792 PokemonFormSprite.introduced_in = relation(VersionGroup)
793
794 PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
795 PokemonMove.version_group = relation(VersionGroup)
796 PokemonMove.machine = relation(Machine, backref='pokemon_moves',
797 primaryjoin=and_(Machine.version_group_id==PokemonMove.version_group_id,
798 Machine.move_id==PokemonMove.move_id),
799 foreign_keys=[Machine.version_group_id, Machine.move_id],
800 uselist=False)
801 PokemonMove.move = relation(Move, backref='pokemon_moves')
802 PokemonMove.method = relation(PokemonMoveMethod)
803
804 PokemonName.language = relation(Language)
805
806 PokemonStat.stat = relation(Stat)
807
808 # This is technically a has-many; Generation.main_region_id -> Region.id
809 Region.generation = relation(Generation, uselist=False)
810 Region.version_group_regions = relation(VersionGroupRegion, backref='region',
811 order_by='VersionGroupRegion.version_group_id')
812 Region.version_groups = association_proxy('version_group_regions', 'version_group')
813
814 SuperContestCombo.first = relation(Move, primaryjoin=SuperContestCombo.first_move_id==Move.id,
815 backref='super_contest_combo_first')
816 SuperContestCombo.second = relation(Move, primaryjoin=SuperContestCombo.second_move_id==Move.id,
817 backref='super_contest_combo_second')
818
819 Type.damage_efficacies = relation(TypeEfficacy,
820 primaryjoin=Type.id
821 ==TypeEfficacy.damage_type_id,
822 backref='damage_type')
823 Type.target_efficacies = relation(TypeEfficacy,
824 primaryjoin=Type.id
825 ==TypeEfficacy.target_type_id,
826 backref='target_type')
827
828 Type.generation = relation(Generation, backref='types')
829 Type.damage_class = relation(MoveDamageClass, backref='types')
830
831 Version.version_group = relation(VersionGroup, backref='versions')
832 Version.generation = association_proxy('version_group', 'generation')
833
834 VersionGroup.generation = relation(Generation, backref='version_groups')
835 VersionGroup.version_group_regions = relation(VersionGroupRegion, backref='version_group')
836 VersionGroup.regions = association_proxy('version_group_regions', 'region')