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