diff --git a/COMPLETED.md b/COMPLETED.md new file mode 100644 index 0000000..c725225 --- /dev/null +++ b/COMPLETED.md @@ -0,0 +1,395 @@ + +# Generation One + +- [x] Bulbasaur +- [x] Ivysaur +- [x] Venusaur +- [ ] Charmander +- [ ] Charmeleon +- [ ] Charizard +- [ ] Squirtle +- [ ] Wartortle +- [ ] Blastoise +- [x] Caterpie +- [ ] Metapod +- [ ] Butterfree +- [ ] Weedle +- [ ] Kakuna +- [ ] Beedrill +- [ ] Pidgey +- [ ] Pidgeotto +- [ ] Pidgeot +- [ ] Rattata +- [ ] Raticate +- [ ] Spearow +- [ ] Fearow +- [ ] Ekans +- [ ] Arbok +- [ ] Pikachu +- [ ] Raichu +- [ ] Sandshrew +- [ ] Sandslash +- [ ] NidoranF +- [ ] Nidorina +- [ ] NidoQueen +- [ ] NidoranM +- [ ] Nidorino +- [ ] NidoKing +- [ ] Clefairy +- [ ] Clefable +- [ ] Vulpix +- [ ] NineTales +- [ ] Jigglypuff +- [ ] WigglyTuff +- [ ] Zubat +- [ ] Golbat +- [ ] Oddish +- [ ] Gloom +- [ ] Vileplume +- [ ] Paras +- [ ] Parasect +- [ ] Venonat +- [ ] Venomoth +- [ ] Diglett +- [ ] Dugtrio +- [ ] Meowth +- [ ] Persian +- [ ] Psyduck +- [ ] Golduck +- [ ] Mankey +- [ ] Primeape +- [ ] Growlithe +- [ ] Arcanine +- [ ] Poliwag +- [ ] Poliwhirl +- [ ] Poliwrath +- [ ] Abra +- [ ] Kadabra +- [ ] Alakazam +- [ ] Machop +- [ ] Machoke +- [ ] Machamp +- [ ] Bellsprout +- [ ] Weepinbell +- [ ] Victreebel +- [ ] Tentacool +- [ ] Tentacruel +- [ ] Geodude +- [ ] Graveler +- [ ] Golem +- [ ] Ponyta +- [ ] Rapidash +- [ ] Slowpoke +- [ ] Slowbro +- [ ] Magnemite +- [ ] Magneton +- [ ] Farfetch'd +- [ ] Doduo +- [ ] Dodrio +- [ ] Seel +- [ ] Dewgong +- [ ] Grimer +- [ ] Muk +- [ ] Shellder +- [ ] Cloyster +- [ ] Gastly +- [ ] Haunter +- [ ] Gengar +- [ ] Onix +- [ ] Drowzee +- [ ] Hypno +- [ ] Krabby +- [ ] Kingler +- [ ] Voltorb +- [ ] Electrode +- [ ] Exeggcute +- [ ] Exeggutor +- [ ] Cubone +- [ ] Marowak +- [ ] Hitmonlee +- [ ] Hitmonchan +- [ ] Lickitung +- [ ] Koffing +- [ ] Weezing +- [ ] Rhyhorn +- [ ] Rhydon +- [ ] Chansey +- [ ] Tangela +- [ ] Kangaskhan +- [ ] Horsea +- [ ] Seadra +- [ ] Goldeen +- [ ] Seaking +- [ ] Staryu +- [ ] Starmie +- [ ] Mr. Mime +- [ ] Scyther +- [ ] Jynx +- [ ] Electabuzz +- [ ] Magmar +- [ ] Pinsir +- [ ] Tauros +- [ ] Magikarp +- [ ] Gyarados +- [ ] Lapras +- [ ] Ditto +- [ ] Eevee +- [ ] Vaporeon +- [ ] Jolteon +- [ ] Flareon +- [ ] Porygon +- [ ] Omanyte +- [ ] Omastar +- [ ] Kabuto +- [ ] Kabutops +- [ ] Aerodactyl +- [ ] Snorlax +- [ ] Articuno +- [ ] Zapdos +- [ ] Moltres +- [ ] Dratini +- [ ] Dragonair +- [ ] Dragonite +- [ ] Mewtwo +- [ ] Mew + +# Generation Two + +- [ ] Chikorita +- [ ] Bayleef +- [ ] Meganium +- [ ] Cyndaquil +- [ ] Quilava +- [ ] Typhlosion +- [ ] Totodile +- [ ] Croconaw +- [ ] Feraligatr +- [ ] Sentret +- [ ] Furret +- [ ] Hoothoot +- [ ] Noctowl +- [ ] Ledyba +- [ ] Ledian +- [ ] Spinarak +- [ ] Ariados +- [ ] Crobat +- [ ] Chinchou +- [ ] Lanturn +- [ ] Pichu +- [ ] Cleffa +- [ ] Igglybuff +- [ ] Togepi +- [ ] Togetic +- [ ] Natu +- [ ] Xatu +- [ ] Mareep +- [ ] Flaaffy +- [ ] Ampharos +- [ ] Bellossom +- [ ] Marill +- [ ] Azumarill +- [ ] Sudowoodo +- [ ] Politoed +- [ ] Hoppip +- [ ] Skiploom +- [ ] Jumpluff +- [ ] Aipom +- [ ] Sunkern +- [ ] Sunflora +- [ ] Yanma +- [ ] Wooper +- [ ] Quagsire +- [ ] Espeon +- [ ] Umbreon +- [ ] Murkrow +- [ ] Slowking +- [ ] Misdreavus +- [ ] Unown +- [ ] Wobbuffet +- [ ] Girafarig +- [ ] Pineco +- [ ] Forretress +- [ ] Dunsparce +- [ ] Gligar +- [ ] Steelix +- [ ] Snubbull +- [ ] Granbull +- [ ] Qwilfish +- [ ] Scizor +- [ ] Shuckle +- [ ] Heracross +- [ ] Sneasel +- [ ] Teddiursa +- [ ] Ursaring +- [ ] Slugma +- [ ] Magcargo +- [ ] Swinub +- [ ] Piloswine +- [ ] Corsola +- [ ] Remoraid +- [ ] Octillery +- [ ] Delibird +- [ ] Mantine +- [ ] Skarmory +- [ ] Houndour +- [ ] Houndoom +- [ ] Kingdra +- [ ] Phanpy +- [ ] Donphan +- [ ] Porygon2 +- [ ] Stantler +- [ ] Smeargle +- [ ] Tyrogue +- [ ] Hitmontop +- [ ] Smoochum +- [ ] Elekid +- [ ] Magby +- [ ] Miltank +- [ ] Blissey +- [ ] Raikou +- [ ] Entei +- [ ] Suicune +- [ ] Larvitar +- [ ] Pupitar +- [ ] Tyranitar +- [ ] Lugia +- [ ] Ho-Oh +- [ ] Celebi + +# Generation Three + +- [ ] Treecko +- [ ] Grovyle +- [ ] Sceptile +- [ ] Torchic +- [ ] Combusken +- [ ] Blaziken +- [ ] Mudkip +- [ ] Marshtomp +- [ ] Swampert +- [ ] Poochyena +- [ ] Mightyena +- [ ] Zigzagoon +- [ ] Linoone +- [ ] Wurmple +- [ ] Silcoon +- [ ] Beautifly +- [ ] Cascoon +- [ ] Dustox +- [ ] Lotad +- [ ] Lombre +- [ ] Ludicolo +- [ ] Seedot +- [ ] Nuzleaf +- [ ] Shiftry +- [ ] Taillow +- [ ] Swellow +- [ ] Wingull +- [ ] Pelipper +- [ ] Ralts +- [ ] Kirlia +- [ ] Gardevoir +- [ ] Surskit +- [ ] Masquerain +- [ ] Shroomish +- [ ] Breloom +- [ ] Slakoth +- [ ] Vigoroth +- [ ] Slaking +- [ ] Nincada +- [ ] Ninjask +- [ ] Shedinja +- [ ] Whismur +- [ ] Loudred +- [ ] Exploud +- [ ] Makuhita +- [ ] Hariyama +- [ ] Azurill +- [ ] Nosepass +- [ ] Skitty +- [ ] Delcatty +- [ ] Sableye +- [ ] Mawile +- [ ] Aron +- [ ] Lairon +- [ ] Aggron +- [ ] Meditite +- [ ] Medicham +- [ ] Electrike +- [ ] Manectric +- [ ] Plusle +- [ ] Minun +- [ ] Volbeat +- [ ] Illumise +- [ ] Roselia +- [ ] Gulpin +- [ ] Swalot +- [ ] Carvanha +- [ ] Sharpedo +- [ ] Wailmer +- [ ] Wailord +- [ ] Numel +- [ ] Camerupt +- [ ] Torkoal +- [ ] Spoink +- [ ] Grumpig +- [ ] Spinda +- [ ] Trapinch +- [ ] Vibrava +- [ ] Flygon +- [ ] Cacnea +- [ ] Cacturne +- [ ] Swablu +- [ ] Altaria +- [ ] Zangoose +- [ ] Seviper +- [ ] Lunatone +- [ ] Solrock +- [ ] Barboach +- [ ] Whiscash +- [ ] Corphish +- [ ] Crawdaunt +- [ ] Baltoy +- [ ] Claydol +- [ ] Lileep +- [ ] Cradily +- [ ] Anorith +- [ ] Armaldo +- [ ] Feebas +- [ ] Milotic +- [ ] Castform +- [ ] Kecleon +- [ ] Shuppet +- [ ] Banette +- [ ] Duskull +- [ ] Dusclops +- [ ] Tropius +- [ ] Chimecho +- [ ] Absol +- [ ] Wynaut +- [ ] Snorunt +- [ ] Glalie +- [ ] Spheal +- [ ] Sealeo +- [ ] Walrein +- [ ] Clamperl +- [ ] Huntail +- [ ] Gorebyss +- [ ] Relicanth +- [ ] Luvdisc +- [ ] Bagon +- [ ] Shelgon +- [ ] Salamence +- [ ] Beldum +- [ ] Metang +- [ ] Metagross +- [ ] Regirock +- [ ] Regice +- [ ] Registeel +- [ ] Latias +- [ ] Latios +- [ ] Kyogre +- [ ] Groudon +- [ ] Rayquaza +- [ ] Jirachi +- [ ] Deoxys diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ab97f25 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# Ways to Contribute + +So you want to contribute to my neat little PokeDex? Awesome. + +Here is what we need. + +1. More pokemon sprites and dex entries. +2. Location information +3. Description data. + +## More Sprites and Entries + +If you look in `lib/pokemon.dart` you'll see where all the Pokemon are registered at. Simply download the sprites from a site like https://pokemondb.net/sprites + +I have been using the HQ-3D sprite from Gen 8. + +Currently these are the completed Generations. + +- [x] Generation 1 +- [x] Generation 2 +- [x] Generation 3 +- [ ] Generation 4 +- [ ] Generation 5 +- [ ] Generation 6 +- [ ] Generation 7 +- [ ] Generation 8 +- [ ] Generation 9 + +## Location Information + +Among other things, acquiring and merging in location information is extremely helpful. + +This is added to the pokemon entry in the PokeDex as a optional parameter list. + +## Descriptions + +Descriptions are another piece of information that is lacking. See the COMPLETED.md file for info on which Pokemon have completed information (UP TO THE CURRENT GENERATION) + +## State + +At this stage, while i won't stop you from contributing it, I am only adding, myself, the location and description information for the generation we have completed. So, as of writing this, we've completed Generation 3. So location and descriptions from 1-3 is what is being added by myself. Upon completion of Gen 4, i plan to go back and add in all of those entries. diff --git a/lib/Consts.dart b/lib/Consts.dart index a299b76..1e51ada 100644 --- a/lib/Consts.dart +++ b/lib/Consts.dart @@ -1,7 +1,7 @@ import 'dart:io'; class Constants { - static const VERSION = "1.0.032525+2222"; + static const VERSION = "1.0.032625+0019"; //static bool get isMobile => Platform.isAndroid || Platform.isIOS; } diff --git a/lib/MainApp.dart b/lib/MainApp.dart index 1697e7a..119bf93 100644 --- a/lib/MainApp.dart +++ b/lib/MainApp.dart @@ -4,6 +4,7 @@ import 'package:pokedex/Consts.dart'; import 'package:pokedex/Session.dart'; import 'package:pokedex/filters.dart'; import 'package:pokedex/pokemon.dart'; +import 'package:pokedex/pokemonHelpers.dart'; class MainApp extends StatefulWidget { const MainApp({super.key}); @@ -182,7 +183,7 @@ class _DexEntryState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Type: ", style: TextStyle(fontSize: 24)), - _pkmn.getTypeWidgets(), + PokemonHelpers.getTypeWidgets(_pkmn), ], ), Row( @@ -196,26 +197,28 @@ class _DexEntryState extends State { ), if (_pkmn.extraVariants.isNotEmpty) Text("Extra Variations: ", style: TextStyle(fontSize: 24)), - if (_pkmn.extraVariants.isNotEmpty) _pkmn.getVariations(), + if (_pkmn.extraVariants.isNotEmpty) + PokemonHelpers.getVariations(_pkmn), SizedBox(height: 32), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: _pkmn.getEvolutions(0), + children: PokemonHelpers.getEvolutions(0, _pkmn), ), ), if (SessionData.enableDescription && _pkmn.dexEntries.isNotEmpty) Text("Description: ", style: TextStyle(fontSize: 24)), if (SessionData.enableDescription && _pkmn.dexEntries.isNotEmpty) - _pkmn.printDescription(), + PokemonHelpers.printDescription(_pkmn), SizedBox(height: 50), if (_pkmn.locations.isNotEmpty) Text("Where to find:", style: TextStyle(fontSize: 24)), - if (_pkmn.locations.isNotEmpty) _pkmn.printLocations(), + if (_pkmn.locations.isNotEmpty) + PokemonHelpers.printLocations(_pkmn), ], ), ), diff --git a/lib/Session.dart b/lib/Session.dart index c7b42f1..31cb5f2 100644 --- a/lib/Session.dart +++ b/lib/Session.dart @@ -1,8 +1,5 @@ import 'dart:math'; -import 'package:flutter/widgets.dart'; -import 'package:pokedex/Consts.dart'; -import 'package:pokedex/filters.dart'; import 'package:pokedex/pokemon.dart'; class SessionData { @@ -54,43 +51,6 @@ class SessionData { return "assets/sprites/unown-${digit.toLowerCase()}.png"; } - static Widget PrintUnown() { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: getUnownList(), - ); - } - - static List getUnownList() { - List widgets = []; - List tmpWidgets = []; - - int i = 0; - int end = 3; - for (var digit in ALPHABET) { - tmpWidgets.add( - Image.asset("assets/sprites/unown-${digit.toLowerCase()}.png"), - ); - - i++; - if (i >= end) { - widgets.add( - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: tmpWidgets, - ), - ); - i = 0; - tmpWidgets = []; - } - } - widgets.add( - Row(crossAxisAlignment: CrossAxisAlignment.start, children: tmpWidgets), - ); - - return widgets; - } - static int highestGenID() { if (_lastMaxID != Pokemon.values.length) resetHighestGenCache(); if (_cachedHighest != -1) return _cachedHighest; diff --git a/lib/dexMisc.dart b/lib/dexMisc.dart index 53a1136..f53883c 100644 --- a/lib/dexMisc.dart +++ b/lib/dexMisc.dart @@ -42,7 +42,8 @@ enum GameRoute { // The following mark the pokemon as not usually obtainable TradeOrMigrate(commonName: "Trade or Migrate from another game"), BreedOnly(commonName: "Only obtainable via breeding"), - Evolve(commonName: "Evolve another pokemon"); + Evolve(commonName: "Evolve another pokemon"), + Unavailable; final String commonName; const GameRoute({this.commonName = ""}); diff --git a/lib/pokemon.dart b/lib/pokemon.dart index bcd787b..05ad4fc 100644 --- a/lib/pokemon.dart +++ b/lib/pokemon.dart @@ -1,9 +1,9 @@ // ignore_for_file: constant_identifier_names -import 'package:flutter/material.dart'; import 'package:pokedex/Consts.dart'; import 'package:pokedex/Session.dart'; import 'package:pokedex/dexMisc.dart'; +import 'package:pokedex/pokemonHelpers.dart'; enum Generation { One(1, 151), @@ -20,54 +20,6 @@ enum Generation { final int idEnd; const Generation(this.idStart, this.idEnd); - - toSpritePath() { - switch (this) { - case Generation.One: - return 'assets/sprites/gen1'; - case Generation.Two: - return 'assets/sprites/gen2'; - case Generation.Three: - return 'assets/sprites/gen3'; - case Generation.Four: - return 'assets/sprites/gen4'; - case Generation.Five: - return 'assets/sprites/gen5'; - case Generation.Six: - return 'assets/sprites/gen6'; - case Generation.Seven: - return 'assets/sprites/gen7'; - case Generation.Eight: - return 'assets/sprites/gen8'; - case Generation.Nine: - return 'assets/sprites/gen9'; - } - } -} - -enum Type { - Normal(Color.fromARGB(255, 192, 192, 192), Colors.black), - Fire(Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 255, 255)), - Water(Color.fromARGB(255, 0, 174, 255), Colors.black), - Electric(Color(0xffFFD700), Colors.black), - Grass(Color.fromARGB(255, 0, 255, 0), Colors.black), - Ice(Color.fromARGB(255, 0, 255, 255), Colors.black), - Fighting(Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 255, 255)), - Poison(Color.fromARGB(255, 128, 0, 128), Color.fromARGB(255, 255, 255, 255)), - Ground(Color.fromARGB(255, 128, 126, 0), Colors.black), - Flying(Color.fromARGB(255, 128, 128, 255), Colors.black), - Psychic(Color.fromARGB(255, 255, 0, 255), Color.fromARGB(255, 255, 255, 255)), - Bug(Color.fromARGB(255, 128, 128, 0), Colors.black), - Rock(Color.fromARGB(255, 128, 128, 128), Colors.black), - Ghost(Color.fromARGB(255, 128, 0, 128), Colors.black), - Dragon(Color.fromARGB(255, 85, 0, 102), Color.fromARGB(255, 255, 255, 255)), - Dark(Color.fromARGB(255, 51, 51, 51), Color.fromARGB(255, 255, 255, 255)), - Steel(Color.fromARGB(255, 192, 192, 192), Colors.black), - Fairy(Color.fromARGB(255, 255, 102, 255), Colors.black); - - final Color backgroundColor; - final Color textColor; - const Type(this.backgroundColor, this.textColor); } enum EvolutionCondition { @@ -106,160 +58,6 @@ enum EvolutionCondition { DeepSeaScale, } -abstract class Evolution { - const Evolution(); - String printEvolution(); - - Widget getEvolution(); -} - -class SingleEvolution extends Evolution { - final int to; - final int level; - final List? condition; - - const SingleEvolution(this.to, this.level, {this.condition}); - - @override - String printEvolution() { - String sRet = ""; - if (level != -1) { - sRet += "Level $level"; - } - if (condition != null) { - if (sRet.isNotEmpty) { - sRet += "\n"; - } - - for (var cond in condition!) { - sRet += cond.name; - } - } - return sRet; - } - - @override - Widget getEvolution() { - if (to >= SessionData.highestGenID() + 1) { - return Column(); - } - Pokemon pkmn = Pokemon.values.where((x) => x.id == to).first; - - List cardRow = []; - - cardRow.add( - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.arrow_downward, size: 48), - Card( - elevation: 50, - child: SizedBox( - width: 256, - height: 256, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - - children: [ - Text(printEvolution(), style: TextStyle(fontSize: 16)), - - Image.asset(pkmn.toDexPath(), width: 64, height: 64), - Text(pkmn.pokemonName, style: TextStyle(fontSize: 24)), - pkmn.getTypeWidgets(), - ], - ), - ), - ), - ], - ), - ); - - Column rw = Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [Row(children: cardRow)], - ); - - return rw; - } -} - -class BranchedEvolution extends Evolution { - final List alternates; - final List levels; - final List> conditions; - - const BranchedEvolution(this.alternates, this.levels, this.conditions); - - @override - String printEvolution() { - return ""; - } - - String _prntEV(List conds, int level) { - String sRet = ""; - if (level != -1) { - sRet += "Level ${level}"; - } - for (var condition in conds) { - sRet += condition.name + " "; - } - return sRet; - } - - @override - Widget getEvolution() { - // This is a branched evolution. So first, we print the arrows, and conditions. - - List cardRow = []; - - for (var pkmn in alternates) { - int index = alternates.indexOf(pkmn); - - if (pkmn >= SessionData.highestGenID() + 1) { - print("Index too high"); - continue; - } - - Pokemon _pkmn = Pokemon.values.where((x) => x.id == pkmn).first; - - cardRow.add( - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.arrow_downward, size: 48), - Card( - elevation: 50, - child: SizedBox( - width: 256, - height: 256, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - - children: [ - Text( - _prntEV(conditions[index], levels[index]), - style: TextStyle(fontSize: 16), - ), - - Image.asset(_pkmn.toDexPath(), width: 64, height: 64), - Text(_pkmn.pokemonName, style: TextStyle(fontSize: 24)), - _pkmn.getTypeWidgets(), - ], - ), - ), - ), - ], - ), - ); - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [Row(children: cardRow)], - ); - } -} - enum LearnType { TM, HM } enum Move { @@ -2122,24 +1920,6 @@ enum Pokemon { return 'assets/sprites/${printName().replaceAll("♀", "-f").replaceAll("♂", "-m").toLowerCase()}.png'; } - Widget getTypeWidgets() { - List widgets = []; - for (Type type in types) { - widgets.add( - ElevatedButton( - onPressed: () {}, - style: ButtonStyle( - backgroundColor: WidgetStatePropertyAll(type.backgroundColor), - foregroundColor: WidgetStatePropertyAll(type.textColor), - ), - - child: Text(type.name, style: TextStyle(fontSize: 16)), - ), - ); - } - return Row(children: widgets); - } - String printName({var proper = false}) { String sRet; @@ -2154,181 +1934,4 @@ enum Pokemon { return sRet; } - - Widget getVariations() { - List variants = []; - if (id == Pokemon.Unown.id) - variants = SessionData.getUnownList(); - else { - List tmpRow = []; - int i = 0; - int row = 3; - for (var variant in extraVariants) { - tmpRow.add(Image.asset("assets/sprites/${variant}.png")); - - i++; - if (i >= row) { - variants.add(Row(children: tmpRow)); - tmpRow = []; - i = 0; - } - } - - if (tmpRow.isNotEmpty) variants.add(Row(children: tmpRow)); - } - - return Column(children: variants); - } - - List getEvolutions(int subID) { - //print("SUBID ${subID}"); - - List Evs = []; - - // ID must be in inclusive range of 1...MAXGeneration - if (previousPokemon != -1 && - previousPokemon <= SessionData.highestGenID()) { - if (previousPokemon != -1 && subID == 0) { - Pokemon pkmn = - Pokemon.values.where((x) => x.id == previousPokemon).first; - return pkmn.getEvolutions(0); - } - } - - if (!hasEvolutions) return []; - - //print("Processing evolutions for ${pokemonName}"); - - if (evolution is SingleEvolution) { - //print("Single Evolution identified"); - var pokemon = - Pokemon.values - .where((x) => x.id == (evolution! as SingleEvolution).to) - .first; - - if (pokemon.id <= SessionData.highestGenID()) Evs.add(pokemon); - } else { - //print("Branching Evolution identified"); - // Handle branched evolutions. Refactor below to accomodate a list of pokemon. - for (var ev in (evolution! as BranchedEvolution).alternates) { - if (!(ev >= SessionData.highestGenID())) { - var pokemon = Pokemon.values.where((x) => x.id == ev).first; - if (pokemon.id <= SessionData.highestGenID()) Evs.add(pokemon); - } - } - } - - List sprites = []; - - if (subID == 0) { - sprites.add(Text("Evolutions: ", style: TextStyle(fontSize: 24))); - sprites.add( - Card( - elevation: 50, - child: SizedBox( - width: 256, - height: 256, - child: Column( - children: [ - Image.asset(toDexPath(), width: 64, height: 64), - Text(pokemonName, style: TextStyle(fontSize: 24)), - getTypeWidgets(), - ], - ), - ), - ), - ); - sprites.add(evolution!.getEvolution()); - //print("Main page EV."); - } else { - sprites.add(evolution!.getEvolution()); - } - - List afterEvs = []; - for (var ev in Evs) { - afterEvs.addAll(ev.getEvolutions(subID + 1)); - //print("Processing evolution: ${ev.properName}"); - } - - sprites.add( - Row(crossAxisAlignment: CrossAxisAlignment.start, children: afterEvs), - ); - - return sprites; - } - - Widget printDescription() { - List widgets = []; - - for (var descs in dexEntries) { - if (descs.gameGen.idStart > SessionData.highestGenID()) continue; - - List gameNames = [descs.game.toString()]; - - for (var extra in descs.additionalGames) { - gameNames.add(extra.toString()); - } - - widgets.add( - Card.filled( - elevation: 50, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Text( - "Game: ${gameNames.join(", ")}\nDescription: ${descs.desc}", - ), - ], - ), - ), - ), - ); - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: widgets, - ); - } - - Widget printLocations() { - List widgets = []; - - for (var locs in locations) { - if (locs.gameGen.idStart > SessionData.highestGenID()) continue; - - List routes = []; - for (var rt in locs.routes) { - routes.add(rt.toString()); - } - - List gameNames = [locs.game.toString()]; - - for (var extra in locs.additionalGames) { - gameNames.add(extra.toString()); - } - - widgets.add( - Card.outlined( - elevation: 50, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Text( - "Game: ${gameNames.join(", ")}\n\nRoutes/Method: ${routes.join(", ")}", - ), - ], - ), - ), - ), - ); - } - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: widgets, - ); - } } diff --git a/lib/pokemonHelpers.dart b/lib/pokemonHelpers.dart new file mode 100644 index 0000000..8b3b8c0 --- /dev/null +++ b/lib/pokemonHelpers.dart @@ -0,0 +1,410 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:pokedex/Session.dart'; +import 'package:pokedex/pokemon.dart'; + +enum Type { + Normal(Color.fromARGB(255, 192, 192, 192), Colors.black), + Fire(Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 255, 255)), + Water(Color.fromARGB(255, 0, 174, 255), Colors.black), + Electric(Color(0xffFFD700), Colors.black), + Grass(Color.fromARGB(255, 0, 255, 0), Colors.black), + Ice(Color.fromARGB(255, 0, 255, 255), Colors.black), + Fighting(Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 255, 255)), + Poison(Color.fromARGB(255, 128, 0, 128), Color.fromARGB(255, 255, 255, 255)), + Ground(Color.fromARGB(255, 128, 126, 0), Colors.black), + Flying(Color.fromARGB(255, 128, 128, 255), Colors.black), + Psychic(Color.fromARGB(255, 255, 0, 255), Color.fromARGB(255, 255, 255, 255)), + Bug(Color.fromARGB(255, 128, 128, 0), Colors.black), + Rock(Color.fromARGB(255, 128, 128, 128), Colors.black), + Ghost(Color.fromARGB(255, 128, 0, 128), Colors.black), + Dragon(Color.fromARGB(255, 85, 0, 102), Color.fromARGB(255, 255, 255, 255)), + Dark(Color.fromARGB(255, 51, 51, 51), Color.fromARGB(255, 255, 255, 255)), + Steel(Color.fromARGB(255, 192, 192, 192), Colors.black), + Fairy(Color.fromARGB(255, 255, 102, 255), Colors.black); + + final Color backgroundColor; + final Color textColor; + const Type(this.backgroundColor, this.textColor); +} + +class PokemonHelpers { + static List getUnownList() { + List widgets = []; + List tmpWidgets = []; + + int i = 0; + int end = 3; + for (var digit in SessionData.ALPHABET) { + tmpWidgets.add( + Image.asset("assets/sprites/unown-${digit.toLowerCase()}.png"), + ); + + i++; + if (i >= end) { + widgets.add( + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: tmpWidgets, + ), + ); + i = 0; + tmpWidgets = []; + } + } + widgets.add( + Row(crossAxisAlignment: CrossAxisAlignment.start, children: tmpWidgets), + ); + + return widgets; + } + + static Widget getTypeWidgets(Pokemon pokemon) { + List widgets = []; + for (Type type in pokemon.types) { + widgets.add( + ElevatedButton( + onPressed: () {}, + style: ButtonStyle( + backgroundColor: WidgetStatePropertyAll(type.backgroundColor), + foregroundColor: WidgetStatePropertyAll(type.textColor), + ), + + child: Text(type.name, style: TextStyle(fontSize: 16)), + ), + ); + } + return Row(children: widgets); + } + + static Widget getVariations(Pokemon pokemon) { + List variants = []; + if (pokemon.id == Pokemon.Unown.id) { + variants = getUnownList(); + } else { + List tmpRow = []; + int i = 0; + int row = 3; + for (var variant in pokemon.extraVariants) { + tmpRow.add(Image.asset("assets/sprites/${variant}.png")); + + i++; + if (i >= row) { + variants.add(Row(children: tmpRow)); + tmpRow = []; + i = 0; + } + } + + if (tmpRow.isNotEmpty) variants.add(Row(children: tmpRow)); + } + + return Column(children: variants); + } + + static List getEvolutions(int subID, Pokemon pokemon) { + //print("SUBID ${subID}"); + + List Evs = []; + + // ID must be in inclusive range of 1...MAXGeneration + if (pokemon.previousPokemon != -1 && + pokemon.previousPokemon <= SessionData.highestGenID()) { + if (pokemon.previousPokemon != -1 && subID == 0) { + Pokemon pkmn = + Pokemon.values.where((x) => x.id == pokemon.previousPokemon).first; + return getEvolutions(0, pkmn); + } + } + + if (!pokemon.hasEvolutions) return []; + + //print("Processing evolutions for ${pokemonName}"); + + if (pokemon.evolution is SingleEvolution) { + //print("Single Evolution identified"); + var pkmnx = + Pokemon.values + .where((x) => x.id == (pokemon.evolution! as SingleEvolution).to) + .first; + + if (pkmnx.id <= SessionData.highestGenID()) Evs.add(pkmnx); + } else { + //print("Branching Evolution identified"); + // Handle branched evolutions. Refactor below to accomodate a list of pokemon. + for (var ev in (pokemon.evolution! as BranchedEvolution).alternates) { + if (!(ev >= SessionData.highestGenID())) { + var pkmnx = Pokemon.values.where((x) => x.id == ev).first; + if (pkmnx.id <= SessionData.highestGenID()) Evs.add(pkmnx); + } + } + } + + List sprites = []; + + if (subID == 0) { + sprites.add(Text("Evolutions: ", style: TextStyle(fontSize: 24))); + sprites.add( + Card( + elevation: 50, + child: SizedBox( + width: 256, + height: 256, + child: Column( + children: [ + Image.asset(pokemon.toDexPath(), width: 64, height: 64), + Text(pokemon.pokemonName, style: TextStyle(fontSize: 24)), + getTypeWidgets(pokemon), + ], + ), + ), + ), + ); + sprites.add(pokemon.evolution!.getEvolution()); + //print("Main page EV."); + } else { + sprites.add(pokemon.evolution!.getEvolution()); + } + + List afterEvs = []; + for (var ev in Evs) { + afterEvs.addAll(getEvolutions(subID + 1, ev)); + //print("Processing evolution: ${ev.properName}"); + } + + sprites.add( + Row(crossAxisAlignment: CrossAxisAlignment.start, children: afterEvs), + ); + + return sprites; + } + + static Widget printDescription(Pokemon pokemon) { + List widgets = []; + + for (var descs in pokemon.dexEntries) { + if (descs.gameGen.idStart > SessionData.highestGenID()) continue; + + List gameNames = [descs.game.toString()]; + + for (var extra in descs.additionalGames) { + gameNames.add(extra.toString()); + } + + widgets.add( + Card.filled( + elevation: 50, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text( + "Game: ${gameNames.join(", ")}\nDescription: ${descs.desc}", + ), + ], + ), + ), + ), + ); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: widgets, + ); + } + + static Widget printLocations(Pokemon pokemon) { + List widgets = []; + + for (var locs in pokemon.locations) { + if (locs.gameGen.idStart > SessionData.highestGenID()) continue; + + List routes = []; + for (var rt in locs.routes) { + routes.add(rt.toString()); + } + + List gameNames = [locs.game.toString()]; + + for (var extra in locs.additionalGames) { + gameNames.add(extra.toString()); + } + + widgets.add( + Card.outlined( + elevation: 50, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text( + "Game: ${gameNames.join(", ")}\n\nRoutes/Method: ${routes.join(", ")}", + ), + ], + ), + ), + ), + ); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: widgets, + ); + } +} + +abstract class Evolution { + const Evolution(); + String printEvolution(); + + Widget getEvolution(); +} + +class SingleEvolution extends Evolution { + final int to; + final int level; + final List? condition; + + const SingleEvolution(this.to, this.level, {this.condition}); + + @override + String printEvolution() { + String sRet = ""; + if (level != -1) { + sRet += "Level $level"; + } + if (condition != null) { + if (sRet.isNotEmpty) { + sRet += "\n"; + } + + for (var cond in condition!) { + sRet += cond.name; + } + } + return sRet; + } + + @override + Widget getEvolution() { + if (to >= SessionData.highestGenID() + 1) { + return Column(); + } + Pokemon pkmn = Pokemon.values.where((x) => x.id == to).first; + + List cardRow = []; + + cardRow.add( + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.arrow_downward, size: 48), + Card( + elevation: 50, + child: SizedBox( + width: 256, + height: 256, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + + children: [ + Text(printEvolution(), style: TextStyle(fontSize: 16)), + + Image.asset(pkmn.toDexPath(), width: 64, height: 64), + Text(pkmn.pokemonName, style: TextStyle(fontSize: 24)), + PokemonHelpers.getTypeWidgets(pkmn), + ], + ), + ), + ), + ], + ), + ); + + Column rw = Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [Row(children: cardRow)], + ); + + return rw; + } +} + +class BranchedEvolution extends Evolution { + final List alternates; + final List levels; + final List> conditions; + + const BranchedEvolution(this.alternates, this.levels, this.conditions); + + @override + String printEvolution() { + return ""; + } + + String _prntEV(List conds, int level) { + String sRet = ""; + if (level != -1) { + sRet += "Level ${level}"; + } + for (var condition in conds) { + sRet += condition.name + " "; + } + return sRet; + } + + @override + Widget getEvolution() { + // This is a branched evolution. So first, we print the arrows, and conditions. + + List cardRow = []; + + for (var pkmn in alternates) { + int index = alternates.indexOf(pkmn); + + if (pkmn >= SessionData.highestGenID() + 1) { + print("Index too high"); + continue; + } + + Pokemon _pkmn = Pokemon.values.where((x) => x.id == pkmn).first; + + cardRow.add( + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.arrow_downward, size: 48), + Card( + elevation: 50, + child: SizedBox( + width: 256, + height: 256, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + + children: [ + Text( + _prntEV(conditions[index], levels[index]), + style: TextStyle(fontSize: 16), + ), + + Image.asset(_pkmn.toDexPath(), width: 64, height: 64), + Text(_pkmn.pokemonName, style: TextStyle(fontSize: 24)), + PokemonHelpers.getTypeWidgets(_pkmn), + ], + ), + ), + ), + ], + ), + ); + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [Row(children: cardRow)], + ); + } +} diff --git a/lib/updateTool.dart b/lib/updateTool.dart new file mode 100644 index 0000000..f348827 --- /dev/null +++ b/lib/updateTool.dart @@ -0,0 +1,184 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:libac_dart/nbt/Stream.dart'; +import 'package:libacflutter/Constants.dart'; +import 'package:pokedex/Session.dart'; +import 'package:pokedex/pokemon.dart'; + +Future main(List args) async { + runApp(CompletedGenerator()); + + return 0; +} + +class CompletedGenerator extends StatefulWidget { + @override + State createState() { + return _completedGen(); + } +} + +class _completedGen extends State { + @override + Widget build(BuildContext context) { + return MaterialApp(theme: ThemeData.dark(), home: MainGen()); + } +} + +class MainGen extends StatefulWidget { + @override + State createState() { + return _main(); + } +} + +class _main extends State { + bool firstLaunch = true; + double progress = 0; + String statusMessage = ""; + Generation gen = Generation.One; + StringBuilder sb = StringBuilder(); + int index = 0; + Generation? currentGen = null; + int maxTasks = 5; + + int state = 0; + + @override + void didChangeDependencies() { + if (firstLaunch) { + firstLaunch = false; + setState(() { + statusMessage = "Warming up..."; + progress = 0.0; + }); + + Timer.periodic(Duration(milliseconds: 100), (x) async { + if (state == 0) { + sleep(Duration(seconds: 5)); + statusMessage = "Acquiring game generation"; + progress = 0.25; + setState(() {}); + + state++; + } else if (state == 1) { + SessionData.resetHighestGenCache(); + int highest = SessionData.highestGenID(); + // Get actual generation + gen = Generation.One; + for (var _gen in Generation.values) { + if (_gen.idStart < highest) { + gen = _gen; + } + } + + statusMessage = "Generation acquired"; + progress = 1.0; + state++; + + setState(() {}); + } else if (state == 2) { + statusMessage = "Generation ${gen.name}"; + + progress = 0.0; + state++; + + setState(() {}); + } else if (state == 3) { + statusMessage = "Analyzing Pokemon..."; + index = 0; + currentGen = null; + state++; + + setState(() {}); + } else if (state == 4) { + maxTasks += Pokemon.values.length; + state++; + setState(() {}); + } else if ((state - index) == 5) { + // Pokemon iteration task + int iterNumber = state - 5; + + if (iterNumber >= Pokemon.values.length) { + state++; + setState(() {}); + return; + } + + var pokemon = Pokemon.values[iterNumber]; + + if (currentGen != pokemon.generation) { + sb.append("\n# Generation ${pokemon.generation.name}\n\n"); + currentGen = pokemon.generation; + } + + progress = index * 100 / Pokemon.values.length; + statusMessage = + ("- Analysis of pokemon ${pokemon.pokemonName} has begun"); + + // TODO : This needs to check locations and dex entries to see if they are up to date with the latest generation. + // The future task should take into account the generation the pokemon was introduced in. (EX. If introduced in gen 2, it won't have data entries for gen 1). + + if (pokemon.locations.isEmpty && pokemon.dexEntries.isEmpty) { + sb.append("- [ ] ${pokemon.pokemonName}\n"); + } else { + if (pokemon.locations.isNotEmpty && pokemon.dexEntries.isNotEmpty) { + sb.append("- [x] ${pokemon.pokemonName}\n"); + } else if (pokemon.locations.isNotEmpty) { + sb.append("- [ ] ${pokemon.pokemonName} (MISSING DEX ENTRIES)\n"); + } else if (pokemon.dexEntries.isNotEmpty) { + sb.append( + "- [ ] ${pokemon.pokemonName} (MISSING LOCATION ENTRIES)\n", + ); + } + } + index++; + progress = progress / 100; // push it into a 0-1 range. + state++; + + setState(() {}); + } else if (state - index == 6) { + // Task - write file + maxTasks += 3; + statusMessage = "Saving to COMPLETED.md"; + File complete = File("COMPLETED.md"); + progress = 99.75; + state++; + setState(() {}); + await complete.writeAsString(sb.toString()); + } else if (state - index == 7) { + statusMessage = "Data generation completed"; + progress = 1.0; + state++; + setState(() {}); + } else if (state - index == 8) { + x.cancel(); + sleep(Duration(seconds: 10)); + exit(0); + } + }); + } + super.didChangeDependencies(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Data Generator"), + backgroundColor: LibACFlutterConstants.TITLEBAR_COLOR, + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Status: ${statusMessage}", style: TextStyle(fontSize: 24)), + Text("Progress: ${progress * 100}%", style: TextStyle(fontSize: 24)), + Text("Task ${state}/${maxTasks}", style: TextStyle(fontSize: 24)), + LinearProgressIndicator(value: progress, minHeight: 30), + ], + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 40e2a37..bd92678 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.032525+2222 +version: 1.0.032625+0019 environment: sdk: ^3.7.0 diff --git a/update_completed.sh b/update_completed.sh new file mode 100755 index 0000000..4dfbc13 --- /dev/null +++ b/update_completed.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +flutter build linux -t lib/updateTool.dart +build/linux/x64/release/bundle/pokedex \ No newline at end of file