mirror of
https://github.com/chenasraf/pokedex_flutter.git
synced 2026-05-17 17:48:04 +00:00
feat: type matchups
This commit is contained in:
@@ -63,5 +63,69 @@ class PokemonHelper {
|
||||
return move.flavorTextEntries.firstWhereOrNull((n) => n.language.name == 'en')?.flavorText ??
|
||||
(move.flavorTextEntries.isNotEmpty ? move.flavorTextEntries.first.flavorText : '');
|
||||
}
|
||||
|
||||
static List<TypeMultiplier> getTypeDefenseMultipliers(List<Type> types) {
|
||||
final typeMap = <String, double>{};
|
||||
final typeNameMap = <String, NamedAPIResource>{};
|
||||
for (final type in types) {
|
||||
for (final damage in type.damageRelations.doubleDamageFrom) {
|
||||
typeNameMap[damage.name] ??= damage;
|
||||
typeMap[damage.name] = (typeMap[damage.name] ?? 1) * 2;
|
||||
}
|
||||
for (final damage in type.damageRelations.halfDamageFrom) {
|
||||
typeNameMap[damage.name] ??= damage;
|
||||
typeMap[damage.name] = (typeMap[damage.name] ?? 1) * 0.5;
|
||||
}
|
||||
for (final damage in type.damageRelations.noDamageFrom) {
|
||||
typeNameMap[damage.name] ??= damage;
|
||||
typeMap[damage.name] = (typeMap[damage.name] ?? 1) * 0;
|
||||
}
|
||||
}
|
||||
return typeMap.entries.map((e) {
|
||||
return TypeMultiplier(typeNameMap[e.key]!, e.value);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
static List<TypeMultiplier> getTypeAttackMultipliers(List<Type> types) {
|
||||
final typeMap = <String, double>{};
|
||||
final typeNameMap = <String, NamedAPIResource>{};
|
||||
for (final type in types) {
|
||||
for (final damage in type.damageRelations.doubleDamageTo) {
|
||||
typeNameMap[damage.name] ??= damage;
|
||||
typeMap[damage.name] = (typeMap[damage.name] ?? 1) * 2;
|
||||
}
|
||||
for (final damage in type.damageRelations.halfDamageTo) {
|
||||
typeNameMap[damage.name] ??= damage;
|
||||
typeMap[damage.name] = (typeMap[damage.name] ?? 1) * 0.5;
|
||||
}
|
||||
for (final damage in type.damageRelations.noDamageTo) {
|
||||
typeNameMap[damage.name] ??= damage;
|
||||
typeMap[damage.name] = (typeMap[damage.name] ?? 1) * 0;
|
||||
}
|
||||
}
|
||||
return typeMap.entries.map((e) {
|
||||
return TypeMultiplier(typeNameMap[e.key]!, e.value);
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
class TypeMultiplier {
|
||||
TypeMultiplier(this.type, this.multiplier);
|
||||
|
||||
final NamedAPIResource type;
|
||||
final double multiplier;
|
||||
|
||||
String get name => type.name;
|
||||
String get multiplierString =>
|
||||
{
|
||||
0.5: '½',
|
||||
0.25: '¼',
|
||||
}[multiplier] ??
|
||||
multiplier.toStringAsFixed(2).replaceAll(RegExp(r'0+$'), '').replaceAll(RegExp(r'\.$'), '');
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '$name x $multiplierString';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,22 +48,60 @@ class PokemonDetailsPage extends StatelessWidget {
|
||||
PokemonImage(poke: poke, size: imgSize, shiny: true),
|
||||
],
|
||||
),
|
||||
() => const Text('Weaknesses', textScaleFactor: 1.2),
|
||||
() => const Text('Weak against', textScaleFactor: 1.2),
|
||||
() => FutureBuilder(
|
||||
future: Future.wait(poke.types.map((t) => t.type.get())),
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.hasData
|
||||
? snapshot.data!
|
||||
.toList()
|
||||
.fold(<NamedAPIResource>[], (prev, type) => prev..addAll(type.damageRelations.doubleDamageFrom))
|
||||
: <NamedAPIResource>[];
|
||||
? PokemonHelper.getTypeDefenseMultipliers(snapshot.data!.toList()).where((e) => e.multiplier >= 2)
|
||||
: <TypeMultiplier>[];
|
||||
return Wrap(
|
||||
children: [
|
||||
for (final weakness in data)
|
||||
for (final type in data)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Chip(
|
||||
label: Text('${weakness.name.capitalize()} x2'),
|
||||
label: Text('${type.type.name.capitalize()} x ${type.multiplierString}'),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
() => const Text('Resistant to', textScaleFactor: 1.2),
|
||||
() => FutureBuilder(
|
||||
future: Future.wait(poke.types.map((t) => t.type.get())),
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.hasData
|
||||
? PokemonHelper.getTypeDefenseMultipliers(snapshot.data!.toList()).where((e) => e.multiplier < 1 && e.multiplier > 0)
|
||||
: <TypeMultiplier>[];
|
||||
return Wrap(
|
||||
children: [
|
||||
for (final type in data)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Chip(
|
||||
label: Text('${type.type.name.capitalize()} x ${type.multiplierString}'),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
() => const Text('No damage from', textScaleFactor: 1.2),
|
||||
() => FutureBuilder(
|
||||
future: Future.wait(poke.types.map((t) => t.type.get())),
|
||||
builder: (context, snapshot) {
|
||||
final data = snapshot.hasData
|
||||
? PokemonHelper.getTypeDefenseMultipliers(snapshot.data!.toList()).where((e) => e.multiplier == 0)
|
||||
: <TypeMultiplier>[];
|
||||
return Wrap(
|
||||
children: [
|
||||
for (final type in data)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Chip(
|
||||
label: Text('${type.type.name.capitalize()} x ${type.multiplierString}'),
|
||||
),
|
||||
)
|
||||
],
|
||||
@@ -150,7 +188,7 @@ class PokemonDetailsPage extends StatelessWidget {
|
||||
children: [
|
||||
if (icon != null)
|
||||
Container(
|
||||
color: Colors.purple,
|
||||
// color: Colors.purple,
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: icon,
|
||||
width: 40,
|
||||
@@ -163,9 +201,12 @@ class PokemonDetailsPage extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemBuilder: (context, index) => children[index].call(),
|
||||
itemCount: children.length,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ListView.builder(
|
||||
itemBuilder: (context, index) => children[index].call(),
|
||||
itemCount: children.length,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user