feat: type matchups

This commit is contained in:
Chen Asraf
2023-07-12 01:22:45 +03:00
parent ab4aa19351
commit fd6ec6dacf
2 changed files with 116 additions and 11 deletions

View File

@@ -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';
}
}

View File

@@ -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,
),
),
);
}