import 'package:flutter/material.dart'; import 'package:pokedex/Consts.dart'; enum Generation { One, Two, Three, Four, Five, Six, Seven, Eight, Nine; 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), Colors.black), 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), Colors.black), Dark(Color.fromARGB(255, 51, 51, 51), Colors.black), 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 { HighFriendship, ThunderStone, WaterStone, Trading, MoonStone, FireStone, LeafStone, Alola, OutsideAlola, Night, Day, AttackGreaterThanDefense, AttackLessThanDefense, AttackEqualDefense, Galar, OutsideGalar, } 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() { Pokemon pkmn = Pokemon.values.where((x) => x.id == to).first; var arrow = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( Constants.isMobile ? Icons.arrow_downward : Icons.arrow_forward, size: 48, ), Text(printEvolution(), style: TextStyle(fontSize: 24)), ], ); Column col = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( pkmn.toDexPath(), width: Constants.isMobile ? 64 : 128, height: Constants.isMobile ? 64 : 128, ), pkmn.getTypeWidgets(), ], ); Column rw = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [arrow, col], ); 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. Row arrowRow; List arrows = []; List pkmnRow = []; Row rowPkmn; for (var pkmn in alternates) { int index = alternates.indexOf(pkmn); Pokemon _pkmn = Pokemon.values.where((x) => x.id == pkmn).first; arrows.add( Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( Constants.isMobile ? Icons.arrow_downward : Icons.arrow_forward, size: 48, ), Text( _prntEV(conditions[index], levels[index]), style: TextStyle(fontSize: 24), ), //Text(printEvolution(), style: TextStyle(fontSize: 24)), ], ), ); pkmnRow.add( Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( _pkmn.toDexPath(), width: Constants.isMobile ? 64 : 128, height: Constants.isMobile ? 64 : 128, ), _pkmn.getTypeWidgets(), ], ), ); } arrowRow = Row( crossAxisAlignment: CrossAxisAlignment.start, children: arrows, ); rowPkmn = Row( crossAxisAlignment: CrossAxisAlignment.start, children: pkmnRow, ); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [arrowRow, rowPkmn], ); } } enum LearnType { TM, HM } enum Move { Growl(LearnType.TM, Type.Normal, "Growl", 0, 100, 40), Tackle(LearnType.TM, Type.Normal, "Tackle", 40, 100, 35), VineWhip(LearnType.TM, Type.Grass, "Vine Whip", 45, 100, 25), RazorLeaf(LearnType.TM, Type.Grass, "Razor Leaf", 55, 95, 25), SolarBeam(LearnType.TM, Type.Grass, "Solar Beam", 120, 100, 10), PoisonPowder(LearnType.TM, Type.Poison, "Poison Powder", 0, 75, 35), SleepPowder(LearnType.TM, Type.Grass, "Sleep Powder", 0, 75, 15), TakeDown(LearnType.TM, Type.Normal, "Take Down", 90, 85, 20), DoubleEdge(LearnType.TM, Type.Normal, "Double-Edge", 120, 100, 15), LeechSeed(LearnType.TM, Type.Grass, "Leech Seed", 0, 90, 10), Growth(LearnType.TM, Type.Normal, "Growth", 0, 0, 20), PoisonSting(LearnType.TM, Type.Poison, "Poison Sting", 15, 100, 35), StringShot(LearnType.TM, Type.Bug, "String Shot", 0, 95, 40), BugBite(LearnType.TM, Type.Bug, "Bug Bite", 60, 100, 20), Confusion(LearnType.TM, Type.Psychic, "Confusion", 50, 100, 25); final LearnType type; final Type moveType; final String moveName; final int power; final int accuracy; final int pp; const Move( this.type, this.moveType, this.moveName, this.power, this.accuracy, this.pp, ); } enum Pokemon { Bulbasaur(1, "Bulbasaur", Generation.One, [ Type.Grass, Type.Poison, ], SingleEvolution(2, 16)), Ivysaur(2, "Ivysaur", Generation.One, [ Type.Grass, Type.Poison, ], SingleEvolution(3, 32)), Venusaur(3, "Venusaur", Generation.One, [Type.Grass, Type.Poison], null), Charmander(4, "Charmander", Generation.One, [ Type.Fire, ], SingleEvolution(5, 16)), Charmeleon(5, "Charmeleon", Generation.One, [ Type.Fire, ], SingleEvolution(6, 36)), Charizard(6, "Charizard", Generation.One, [Type.Fire, Type.Flying], null), Squirtle(7, "Squirtle", Generation.One, [Type.Water], SingleEvolution(8, 16)), Wartortle(8, "Wartortle", Generation.One, [ Type.Water, ], SingleEvolution(9, 36)), Blastoise(9, "Blastoise", Generation.One, [Type.Water], null), Caterpie(10, "Caterpie", Generation.One, [Type.Bug], SingleEvolution(11, 7)), Metapod(11, "Metapod", Generation.One, [Type.Bug], SingleEvolution(12, 10)), Butterfree(12, "Butterfree", Generation.One, [Type.Bug, Type.Flying], null), Weedle(13, "Weedle", Generation.One, [ Type.Bug, Type.Poison, ], SingleEvolution(14, 7)), Kakuna(14, "Kakuna", Generation.One, [ Type.Bug, Type.Poison, ], SingleEvolution(15, 10)), Beedrill(15, "Beedrill", Generation.One, [Type.Bug, Type.Poison], null), Pidgey(16, "Pidgey", Generation.One, [ Type.Normal, Type.Flying, ], SingleEvolution(17, 18)), Pidgeotto(17, "Pidgeotto", Generation.One, [ Type.Normal, Type.Flying, ], SingleEvolution(18, 36)), Pidgeot(18, "Pidgeot", Generation.One, [Type.Normal, Type.Flying], null), Rattata(19, "Rattata", Generation.One, [ Type.Normal, ], SingleEvolution(20, 20)), Raticate(20, "Raticate", Generation.One, [Type.Normal], null), Spearow(21, "Spearow", Generation.One, [ Type.Normal, Type.Flying, ], SingleEvolution(22, 20)), Fearow(22, "Fearow", Generation.One, [Type.Normal, Type.Flying], null), Pikachu( 25, "Pikachu", Generation.One, [Type.Electric], SingleEvolution(26, -1, condition: [EvolutionCondition.ThunderStone]), ), Raichu(26, "Raichu", Generation.One, [Type.Electric], null), Sandshrew(27, "Sandshrew", Generation.One, [ Type.Ground, ], SingleEvolution(28, 22)), Sandslash(28, "Sandslash", Generation.One, [Type.Ground], null), NidoranF(29, "NidoranF", Generation.One, [ Type.Poison, ], SingleEvolution(30, 16)), Nidorina(30, "Nidorina", Generation.One, [ Type.Poison, ], SingleEvolution(31, 36)), NidoQueen(31, "NidoQueen", Generation.One, [Type.Poison, Type.Ground], null), NidoranM(32, "NidoranM", Generation.One, [ Type.Poison, ], SingleEvolution(33, 16)), Nidorino(33, "Nidorino", Generation.One, [ Type.Poison, ], SingleEvolution(34, 36)), NidoKing(34, "NidoKing", Generation.One, [Type.Poison, Type.Ground], null), Clefairy( 35, "Clefairy", Generation.One, [Type.Fairy], SingleEvolution(36, -1, condition: [EvolutionCondition.MoonStone]), ), Clefable(36, "Clefable", Generation.One, [Type.Fairy], null), Vulpix( 37, "Vulpix", Generation.One, [Type.Fire], SingleEvolution(38, -1, condition: [EvolutionCondition.FireStone]), ), NineTales(38, "NineTales", Generation.One, [Type.Fire], null), Jigglypuff( 39, "Jigglypuff", Generation.One, [Type.Fairy], SingleEvolution(40, -1, condition: [EvolutionCondition.MoonStone]), ), WigglyTuff(40, "Wigglytuff", Generation.One, [Type.Fairy], null), Zubat(41, "Zubat", Generation.One, [ Type.Poison, Type.Flying, ], SingleEvolution(42, 22)), Golbat(42, "Golbat", Generation.One, [Type.Poison, Type.Flying], null), Oddish(43, "Oddish", Generation.One, [ Type.Poison, Type.Grass, ], SingleEvolution(44, 21)), Gloom( 44, "Gloom", Generation.One, [Type.Poison, Type.Grass], SingleEvolution(45, -1, condition: [EvolutionCondition.LeafStone]), ), Vileplume(45, "Vileplume", Generation.One, [Type.Poison, Type.Grass], null), Paras(46, "Paras", Generation.One, [ Type.Bug, Type.Grass, ], SingleEvolution(47, 24)), Parasect(47, "Parasect", Generation.One, [Type.Bug, Type.Grass], null), Venonat(48, "Venonat", Generation.One, [ Type.Bug, Type.Poison, ], SingleEvolution(49, 31)), Venomoth(49, "Venomoth", Generation.One, [Type.Bug, Type.Poison], null), Diglett(50, "Diglett", Generation.One, [ Type.Ground, ], SingleEvolution(51, 26)), Dugtrio(51, "Dugtrio", Generation.One, [Type.Ground], null), Meowth(52, "Meowth", Generation.One, [Type.Normal], SingleEvolution(53, 28)), Persian(53, "Persian", Generation.One, [Type.Normal], null), Psyduck(54, "Psyduck", Generation.One, [Type.Water], SingleEvolution(55, 33)), Golduck(55, "Golduck", Generation.One, [Type.Water], null), Mankey(56, "Mankey", Generation.One, [ Type.Fighting, ], SingleEvolution(57, 28)), Primeape(57, "Primeape", Generation.One, [Type.Fighting], null), Growlithe( 58, "Growlithe", Generation.One, [Type.Fire], SingleEvolution(59, -1, condition: [EvolutionCondition.FireStone]), ), Arcanine(59, "Aranine", Generation.One, [Type.Fire], null), Poliwag(60, "Poliwag", Generation.One, [Type.Water], SingleEvolution(61, 25)), Poliwhirl( 61, "Poliwhirl", Generation.One, [Type.Water], SingleEvolution(62, -1, condition: [EvolutionCondition.WaterStone]), ), Poliwrath(62, "Poliwrath", Generation.One, [Type.Water], null), Abra(63, "Abra", Generation.One, [Type.Psychic], SingleEvolution(64, 16)), Kadabra( 64, "Kadabra", Generation.One, [Type.Psychic], SingleEvolution(65, -1, condition: [EvolutionCondition.Trading]), ), Alakazam(65, "Alakazam", Generation.One, [Type.Psychic], null), Machop(66, "Machop", Generation.One, [ Type.Fighting, ], SingleEvolution(67, 28)), Machoke( 67, "Machoke", Generation.One, [Type.Fighting], SingleEvolution(68, -1, condition: [EvolutionCondition.Trading]), ), Machamp(68, "Machamp", Generation.One, [Type.Fighting], null), Bellsprout(69, "Bellsprout", Generation.One, [ Type.Grass, Type.Poison, ], SingleEvolution(70, 21)), Weepinbell( 70, "Weepinbell", Generation.One, [Type.Grass, Type.Poison], SingleEvolution(71, -1, condition: [EvolutionCondition.LeafStone]), ), Victreebel(71, "Victreebel", Generation.One, [Type.Grass, Type.Poison], null), Tentacool(72, "Tentacool", Generation.One, [ Type.Water, Type.Poison, ], SingleEvolution(73, 30)), Tentacruel(73, "Tentacruel", Generation.One, [Type.Water, Type.Poison], null), Geodude(74, "Geodude", Generation.One, [ Type.Rock, Type.Ground, ], SingleEvolution(75, 25)), Graveler( 75, "Graveler", Generation.One, [Type.Rock, Type.Ground], SingleEvolution(76, -1, condition: [EvolutionCondition.Trading]), ), Golem(76, "Golem", Generation.One, [Type.Rock, Type.Ground], null), Ponyta(77, "Ponyta", Generation.One, [Type.Fire], SingleEvolution(78, 40)), Rapidash(78, "Rapidash", Generation.One, [Type.Fire], null), Slowpoke(79, "Slowpoke", Generation.One, [ Type.Water, Type.Psychic, ], SingleEvolution(80, 37)), Slowbro(80, "Slowbro", Generation.One, [Type.Water, Type.Psychic], null), Magnemite(81, "Magnemite", Generation.One, [ Type.Electric, Type.Steel, ], SingleEvolution(82, 30)), Magneton(82, "Magneton", Generation.One, [Type.Electric, Type.Steel], null), Farfetchd(83, "Farfetch'd", Generation.One, [Type.Fighting], null), Doduo(84, "Doduo", Generation.One, [ Type.Normal, Type.Flying, ], SingleEvolution(85, 31)), Dodrio(85, "Dodrio", Generation.One, [Type.Normal, Type.Flying], null), Seel(86, "Seel", Generation.One, [Type.Water], SingleEvolution(87, 34)), Dewgong(87, "Dewgong", Generation.One, [Type.Water, Type.Ice], null), Grimer(88, "Grimer", Generation.One, [Type.Poison], SingleEvolution(89, 38)), Muk(89, "Muk", Generation.One, [Type.Poison], null), Shellder( 90, "Shellder", Generation.One, [Type.Water], SingleEvolution(91, -1, condition: [EvolutionCondition.WaterStone]), ), Cloyster(91, "Cloyster", Generation.One, [Type.Water, Type.Ice], null), Gastly(92, "Gastly", Generation.One, [ Type.Ghost, Type.Poison, ], SingleEvolution(93, 25)), Haunter( 93, "Haunter", Generation.One, [Type.Ghost, Type.Poison], SingleEvolution(94, -1, condition: [EvolutionCondition.Trading]), ), Gengar(94, "Gengar", Generation.One, [Type.Ghost, Type.Poison], null), Onix(95, "Onix", Generation.One, [Type.Rock, Type.Ground], null), Drowzee(96, "Drowzee", Generation.One, [ Type.Psychic, ], SingleEvolution(97, 26)), Hypno(97, "Hypno", Generation.One, [Type.Psychic], null), Krabby(98, "Krabby", Generation.One, [Type.Water], SingleEvolution(99, 28)), Kingler(99, "Kingler", Generation.One, [Type.Water], null), Voltorb(100, "Voltorb", Generation.One, [ Type.Electric, ], SingleEvolution(101, 30)), Electrode(101, "Electrode", Generation.One, [Type.Electric], null), Exeggcute( 102, "Exeggcute", Generation.One, [Type.Grass, Type.Psychic], SingleEvolution(103, -1, condition: [EvolutionCondition.LeafStone]), ), Exeggutor(103, "Exeggutor", Generation.One, [Type.Grass, Type.Psychic], null), Cubone( 104, "Cubone", Generation.One, [Type.Ground], SingleEvolution(105, 28, condition: [EvolutionCondition.OutsideAlola]), ), Marowak(105, "Marowak", Generation.One, [Type.Ground], null), Hitmonlee(106, "Hitmonlee", Generation.One, [Type.Fighting], null), Hitmonchan(107, "Hitmonchan", Generation.One, [Type.Fighting], null), Lickitung(108, "Lickitung", Generation.One, [Type.Normal], null), Koffing( 109, "Koffing", Generation.One, [Type.Poison], SingleEvolution(110, 35, condition: [EvolutionCondition.OutsideGalar]), ), Weezing(110, "Weezing", Generation.One, [Type.Poison], null), Rhyhorn(111, "Rhyhorn", Generation.One, [ Type.Ground, Type.Rock, ], SingleEvolution(112, 42)), Rhydon(112, "Rhydon", Generation.One, [Type.Ground, Type.Rock], null), Chansey(113, "Chansey", Generation.One, [Type.Normal], null), Tangela(114, "Tangela", Generation.One, [Type.Grass], null), Kangaskhan(115, "Kangaskhan", Generation.One, [Type.Normal], null), Horsea(116, "Horsea", Generation.One, [Type.Water], SingleEvolution(117, 32)), Seadra(117, "Seadra", Generation.One, [Type.Water], null), Goldeen(118, "Goldeen", Generation.One, [ Type.Water, ], SingleEvolution(119, 33)), Seaking(119, "Seaking", Generation.One, [Type.Water], null), Staryu( 120, "Staryu", Generation.One, [Type.Water], SingleEvolution(121, -1, condition: [EvolutionCondition.WaterStone]), ), Starmie(121, "Starmie", Generation.One, [Type.Water, Type.Psychic], null), MrMime(122, "Mr. Mime", Generation.One, [Type.Psychic, Type.Fairy], null), Scyther(123, "Scyther", Generation.One, [Type.Bug, Type.Flying], null), Jynx(124, "Jynx", Generation.One, [Type.Ice, Type.Psychic], null), Electabuzz(125, "Electabuzz", Generation.One, [Type.Electric], null), Magmar(126, "Magmar", Generation.One, [Type.Fire], null), Pinsir(127, "Pinsir", Generation.One, [Type.Bug], null), Tauros(128, "Tauros", Generation.One, [Type.Normal], null), Magikarp(129, "Magikarp", Generation.One, [ Type.Water, ], SingleEvolution(130, 20)), Gyarados(130, "Gyarados", Generation.One, [Type.Water, Type.Flying], null), Lapras(131, "Lapras", Generation.One, [Type.Water, Type.Ice], null), Ditto(132, "Ditto", Generation.One, [Type.Normal], null), Eevee( 133, "Eevee", Generation.One, [Type.Normal], BranchedEvolution([134, 135, 136], [-1, -1, -1], [ [EvolutionCondition.WaterStone], [EvolutionCondition.ThunderStone], [EvolutionCondition.FireStone], ]), ), Vaporeon(134, "Vaporeon", Generation.One, [Type.Water], null), Jolteon(135, "Jolteon", Generation.One, [Type.Electric], null), Flareon(136, "Flareon", Generation.One, [Type.Fire], null); final int id; final String properName; final Generation generation; final List types; final Evolution? evolution; final int dexID; bool get hasEvolutions => evolution != null; const Pokemon( this.id, this.properName, this.generation, this.types, this.evolution, { this.dexID = -1, }); int get pokeDexID => dexID == -1 ? id : dexID; String toDexPath() { 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: Constants.isMobile ? 16 : 32), ), ), ); } return Row(children: widgets); } String printName({var proper = false}) { String sRet; if (!proper) { sRet = name.replaceAll("_", " "); } else { sRet = properName; } if (sRet.endsWith("F")) sRet = "${sRet.substring(0, sRet.length - 1)}♀"; if (sRet.endsWith("M")) sRet = "${sRet.substring(0, sRet.length - 1)}♂"; return sRet; } List getEvolutions(int subID) { print("SUBID ${subID}"); if (!hasEvolutions) return []; List Evs = []; print("Processing evolutions for ${properName}"); if (evolution is SingleEvolution) { print("Single Evolution identified"); Evs.add( Pokemon.values .where((x) => x.id == (evolution! as SingleEvolution).to) .first, ); } else { print("Branching Evolution identified"); // Handle branched evolutions. Refactor below to accomodate a list of pokemon. for (var ev in (evolution! as BranchedEvolution).alternates) { Evs.add(Pokemon.values.where((x) => x.id == ev).first); } } List sprites = []; if (subID == 0) { sprites.add(Text("Evolutions: ", style: TextStyle(fontSize: 24))); sprites.add( Image.asset( toDexPath(), width: Constants.isMobile ? 64 : 128, height: Constants.isMobile ? 64 : 128, ), ); sprites.add(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; } }