diff --git a/pokedex/data/csv/conquest_episode_names.csv b/pokedex/data/csv/conquest_episode_names.csv new file mode 100644 index 0000000..c15bbeb --- /dev/null +++ b/pokedex/data/csv/conquest_episode_names.csv @@ -0,0 +1,39 @@ +episode_id,local_language_id,name +1,9,The Legend of Ransei +2,9,The Road to Conquest +3,9,Happily Ever After +4,9,The Burden of Peace +5,9,The Way of the Warrior +6,9,The Joy of Battle +7,9,Pride and Precociousness +8,9,Tragic Determination +9,9,A Shroud of Darkness +10,9,Not Worth Fighting Over... 1 +11,9,Teaching Them a Lesson +12,9,The Reluctant Genius +13,9,The Unparalleled Warrior +14,9,A Ninja amongst Ninjas +15,9,Archenemies +16,9,Time for Battle! +17,9,Land of Love and Righteousness +18,9,Love is a Battlefield +19,9,The Final Gamble +20,9,Blowing in the Wind +21,9,Ransei's Legendary Beauty +22,9,All Grown Up +23,9,The Rebel +24,9,That Which He Holds Dear +25,9,Not Worth Fighting Over... 2 +26,9,The Rose of Ransei +27,9,The Visionary's Quest +28,9,Grace and Beauty +29,9,Pokémari and Me +30,9,The Dragon's Dream +31,9,Putting the Books Down +32,9,A Date with Destiny +33,9,This One Goes Out to My Fans +34,9,Simply the Best +35,9,Not Worth Fighting Over... 3 +36,9,A Fate Born of Beauty +37,9,The Free Spirit's Path +38,9,Two Heroes of Ransei diff --git a/pokedex/data/csv/conquest_episode_warriors.csv b/pokedex/data/csv/conquest_episode_warriors.csv new file mode 100644 index 0000000..d26abf6 --- /dev/null +++ b/pokedex/data/csv/conquest_episode_warriors.csv @@ -0,0 +1,41 @@ +episode_id,warrior_id +1,1 +1,2 +2,3 +3,5 +4,19 +5,26 +6,14 +7,7 +8,9 +9,18 +10,36 +11,11 +12,20 +13,33 +14,24 +15,12 +16,25 +17,28 +18,29 +19,10 +20,22 +21,17 +22,23 +23,6 +24,16 +25,37 +26,4 +27,21 +28,34 +29,15 +30,13 +31,8 +32,31 +33,27 +34,30 +35,38 +36,32 +37,35 +38,1 +38,2 diff --git a/pokedex/data/csv/conquest_episodes.csv b/pokedex/data/csv/conquest_episodes.csv new file mode 100644 index 0000000..2323883 --- /dev/null +++ b/pokedex/data/csv/conquest_episodes.csv @@ -0,0 +1,39 @@ +id,identifier +1,the-legend-of-ransei +2,the-road-to-conquest +3,happily-ever-after +4,the-burden-of-peace +5,the-way-of-the-warrior +6,the-joy-of-battle +7,pride-and-precociousness +8,tragic-determination +9,a-shroud-of-darkness +10,not-worth-fighting-over-1 +11,teaching-them-a-lesson +12,the-reluctant-genius +13,the-unparalleled-warrior +14,a-ninja-amongst-ninjas +15,archenemies +16,time-for-battle +17,land-of-love-and-righteousness +18,love-is-a-battlefield +19,the-final-gamble +20,blowing-in-the-wind +21,ranseis-legendary-beauty +22,all-grown-up +23,the-rebel +24,that-which-he-holds-dear +25,not-worth-fighting-over-2 +26,the-rose-of-ransei +27,the-visionarys-quest +28,grace-and-beauty +29,pokemari-and-me +30,the-dragons-dream +31,putting-the-books-down +32,a-date-with-destiny +33,this-one-goes-out-to-my-fans +34,simply-the-best +35,not-worth-fighting-over-3 +36,a-fate-born-of-beauty +37,the-free-spirits-path +38,two-heroes-of-ransei diff --git a/pokedex/data/csv/conquest_transformation_pokemon.csv b/pokedex/data/csv/conquest_transformation_pokemon.csv new file mode 100644 index 0000000..4a6cf1f --- /dev/null +++ b/pokedex/data/csv/conquest_transformation_pokemon.csv @@ -0,0 +1,90 @@ +transformation_id,pokemon_species_id +3,133 +3,134 +3,135 +3,136 +3,196 +3,197 +3,470 +3,471 +6,133 +6,134 +6,135 +6,136 +6,196 +6,197 +6,470 +6,471 +8,635 +8,644 +10,39 +10,40 +12,391 +12,392 +13,643 +15,502 +15,503 +17,404 +17,405 +19,496 +19,497 +21,131 +21,144 +23,533 +23,534 +25,42 +25,169 +27,383 +27,464 +29,627 +29,628 +31,150 +31,475 +33,204 +33,205 +35,525 +35,526 +37,200 +37,429 +39,570 +39,571 +41,306 +41,379 +43,25 +43,26 +45,608 +45,609 +47,397 +47,398 +49,575 +49,576 +51,93 +51,94 +53,215 +53,461 +55,5 +55,6 +57,253 +57,254 +59,64 +59,65 +61,361 +61,478 +63,554 +63,555 +65,636 +65,637 +67,447 +67,448 +69,376 +69,483 +71,394 +71,395 +73,411 +73,639 +75,624 +75,625 +77,611 +77,612 +79,552 +79,553 diff --git a/pokedex/data/csv/conquest_transformation_warriors.csv b/pokedex/data/csv/conquest_transformation_warriors.csv new file mode 100644 index 0000000..cf6ceb2 --- /dev/null +++ b/pokedex/data/csv/conquest_transformation_warriors.csv @@ -0,0 +1,8 @@ +transformation_id,present_warrior_id +43,21 +45,20 +55,12 +59,14 +67,3 +69,19 +69,34 diff --git a/pokedex/data/csv/conquest_warrior_transformation.csv b/pokedex/data/csv/conquest_warrior_transformation.csv new file mode 100644 index 0000000..728b7ab --- /dev/null +++ b/pokedex/data/csv/conquest_warrior_transformation.csv @@ -0,0 +1,42 @@ +transformed_warrior_rank_id,is_automatic,required_link,completed_episode_id,current_episode_id,distant_warrior_id,female_warlord_count,pokemon_count,collection_type_id,warrior_count +2,1,,,,,,,, +3,0,80,,38,,,,, +5,1,,,,,,,, +6,0,80,,38,,,,, +8,0,80,,2,,,,, +10,0,55,,,,,,, +12,0,60,,,,,,, +13,0,70,,,,,,, +15,0,65,,,,,,, +17,0,60,,,22,,,, +19,0,60,,,,,100,, +21,0,70,8,,,,,, +23,0,60,,,,,,, +25,0,60,,,,,,4, +27,0,75,6,,,,,, +29,0,60,,30,,,,, +31,0,75,15,,,,,, +33,0,55,,,,,,, +35,0,60,,,,,,, +37,0,60,,,,,,8, +39,0,60,,,,,,, +41,0,70,,,,,,,50 +43,0,60,,,,,,, +45,0,60,,,,,,, +47,0,60,,,7,,,, +49,0,60,,,,,,, +51,0,60,,,,,,, +53,0,60,,,,,,, +55,0,65,,,,,,, +57,0,60,,,,3,,, +59,0,60,,,,,,, +61,0,55,,,,,,, +63,0,55,,,,,,, +65,0,65,,,,,,, +67,0,60,,,,,,, +69,0,80,,,,,,, +71,0,65,,,,,,, +73,0,70,,,,,,, +75,0,60,,,,,,, +77,0,60,,,,,,, +79,0,60,,,,,,, diff --git a/pokedex/db/tables.py b/pokedex/db/tables.py index 04c3a02..b307171 100644 --- a/pokedex/db/tables.py +++ b/pokedex/db/tables.py @@ -217,6 +217,38 @@ class BerryFlavor(TableBase): flavor = Column(Integer, nullable=False, info=dict(description="The level of the flavor in the berry")) +class ConquestEpisode(TableBase): + u"""An episode from Pokémon Conquest: one of a bunch of mini-stories + featuring a particular warrior. + + The main story, "The Legend of Ransei", also counts, even though it's not + in the episode select menu and there's no way to replay it. + """ + __tablename__ = 'conquest_episodes' + __singlename__ = 'episode' + id = Column(Integer, primary_key=True, autoincrement=True, + info=dict(description=u'An ID for this episode.')) + identifier = Column(Unicode(30), nullable=False, + info=dict(description=u'A readable identifier for this episode.', format='identifier')) + +create_translation_table('conquest_episode_names', ConquestEpisode, 'names', + relation_lazy='joined', + name=Column(Unicode(30), nullable=False, index=True, + info=dict(description='The name.', format='plaintext', official=True)) +) + +class ConquestEpisodeWarrior(TableBase): + u"""A warrior featured in an episode in Pokémon Conquest. + + This needs its own table because of the player having two episodes and + there being two players. + """ + __tablename__ = 'conquest_episode_warriors' + episode_id = Column(Integer, ForeignKey('conquest_episodes.id'), primary_key=True, + info=dict(description=u'The ID of the episode.')) + warrior_id = Column(Integer, ForeignKey('conquest_warriors.id'), primary_key=True, + info=dict(description=u'The ID of the warrior.')) + class ConquestKingdom(TableBase): u"""A kingdom in Pokémon Conquest. """ @@ -415,6 +447,31 @@ create_translation_table('conquest_stat_names', ConquestStat, 'names', info=dict(description='The name.', format='plaintext', official=True)) ) +class ConquestTransformationPokemon(TableBase): + u"""A Pokémon that satisfies a warrior transformation's link condition. + + If a warrior has one or more Pokémon listed here, they only need to raise + one of them to the required link. + """ + __tablename__ = 'conquest_transformation_pokemon' + transformation_id = Column(Integer, ForeignKey('conquest_warrior_transformation.transformed_warrior_rank_id'), primary_key=True, + info=dict(description=u'The ID of the corresponding transformation, in turn a warrior rank ID.')) + pokemon_species_id = Column(Integer, ForeignKey('pokemon_species.id'), primary_key=True, + info=dict(description=u'The ID of the Pokémon species.')) + +class ConquestTransformationWarrior(TableBase): + u"""A warrior who must be present in the same nation as another warrior for + the latter to transform into their next rank. + + If a warrior has one or more other warriors listed here, they *all* need to + gather in the same nation for the transformation to take place. + """ + __tablename__ = 'conquest_transformation_warriors' + transformation_id = Column(Integer, ForeignKey('conquest_warrior_transformation.transformed_warrior_rank_id'), primary_key=True, + info=dict(description=u'The ID of the corresponding transformation, in turn a warrior rank ID.')) + present_warrior_id = Column(Integer, ForeignKey('conquest_warriors.id'), primary_key=True, + info=dict(description=u'The ID of the other warrior who must be present.')) + class ConquestWarrior(TableBase): u"""A warrior in Pokémon Conquest. """ @@ -532,6 +589,35 @@ create_translation_table('conquest_warrior_stat_names', ConquestWarriorStat, 'na info=dict(description='The name.', format='plaintext', official=True)) ) +class ConquestWarriorTransformation(TableBase): + u"""The conditions under which a warrior must perform an action in order + to transform to the next rank. + + Or most of them, anyway. See also ConquestTransformationPokemon and + ConquestTransformationWarrior. + """ + __tablename__ = 'conquest_warrior_transformation' + transformed_warrior_rank_id = Column(Integer, ForeignKey('conquest_warrior_ranks.id'), primary_key=True, + info=dict(description=u'The ID of the post-transformation warrior rank.')) + is_automatic = Column(Boolean, nullable=False, + info=dict(description=u'True iff the transformation happens automatically in the story with no further requirements.')) + required_link = Column(Integer, nullable=True, + info=dict(description=u'The link percentage the warrior must reach with one of several specific Pokémon, if any.')) + completed_episode_id = Column(Integer, ForeignKey('conquest_episodes.id'), nullable=True, + info=dict(description=u'The ID of the episode the player must have completed, if any.')) + current_episode_id = Column(Integer, ForeignKey('conquest_episodes.id'), nullable=True, + info=dict(description=u'The ID of the episode the player must currently be playing, if any.')) + distant_warrior_id = Column(Integer, ForeignKey('conquest_warriors.id'), nullable=True, + info=dict(description=u'The ID of another warrior who must be in the army, but not in the same kingdom or in any adjacent kingdom.')) + female_warlord_count = Column(Integer, nullable=True, + info=dict(description=u'The number of female warlords who must be in the same nation.')) + pokemon_count = Column(Integer, nullable=True, + info=dict(description=u'The number of Pokémon that must be registered in the gallery.')) + collection_type_id = Column(Integer, ForeignKey('types.id'), nullable=True, + info=dict(description=u'The ID of a type all Pokémon of which must be registered in the gallery.')) + warrior_count = Column(Integer, nullable=True, + info=dict(description=u'The number of warriors that must be registered in the gallery.')) + class ContestCombo(TableBase): u"""Combo of two moves in a Contest. """ @@ -2031,6 +2117,11 @@ Berry.natural_gift_type = relationship(Type, innerjoin=True) BerryFlavor.contest_type = relationship(ContestType, innerjoin=True) +ConquestEpisode.warriors = relationship(ConquestWarrior, + secondary=ConquestEpisodeWarrior.__table__, + innerjoin=True, + backref='episodes') + ConquestKingdom.type = relationship(Type, uselist=False, innerjoin=True, lazy='joined', @@ -2112,6 +2203,27 @@ ConquestWarriorRankStatMap.stat = relationship(ConquestWarriorStat, uselist=False, backref='stat_map') +ConquestWarriorTransformation.completed_episode = relationship(ConquestEpisode, + primaryjoin=ConquestWarriorTransformation.completed_episode_id==ConquestEpisode.id, + uselist=False) +ConquestWarriorTransformation.current_episode = relationship(ConquestEpisode, + primaryjoin=ConquestWarriorTransformation.current_episode_id==ConquestEpisode.id, + uselist=False) +ConquestWarriorTransformation.distant_warrior = relationship(ConquestWarrior, + uselist=False) +ConquestWarriorTransformation.pokemon = relationship(PokemonSpecies, + secondary=ConquestTransformationPokemon.__table__, + order_by=PokemonSpecies.conquest_order) +ConquestWarriorTransformation.present_warriors = relationship(ConquestWarrior, + secondary=ConquestTransformationWarrior.__table__, + order_by=ConquestWarrior.id) +ConquestWarriorTransformation.type = relationship(Type, + uselist=False) +ConquestWarriorTransformation.warrior_rank = relationship(ConquestWarriorRank, + uselist=False, + innerjoin=True, lazy='joined', + backref=backref('transformation', uselist=False, innerjoin=True)) + ContestCombo.first = relationship(Move, primaryjoin=ContestCombo.first_move_id==Move.id,