Skip to content

Commit

Permalink
This now allows us to show the required exp. materials in the calculator
Browse files Browse the repository at this point in the history
  • Loading branch information
Wolfteam committed Mar 7, 2021
1 parent 4160c8d commit 28a0654
Show file tree
Hide file tree
Showing 18 changed files with 345 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
image: Assets.getCharacterPath(char.image),
name: translation.name,
rarity: char.rarity,
materials: _getCharacterMaterialsToUse(char, e.currentAscensionLevel, e.desiredAscensionLevel, e.skills),
materials: _getCharacterMaterialsToUse(char, e.currentLevel, e.desiredLevel, e.currentAscensionLevel, e.desiredAscensionLevel, e.skills),
currentLevel: e.currentLevel,
desiredLevel: e.desiredLevel,
skills: e.skills,
desiredAscensionLevel: e.desiredAscensionLevel,
currentAscensionLevel: e.currentAscensionLevel,
)
];

return currentState.copyWith.call(items: items, summary: _generateSummary(items.expand((i) => i.materials).toList()));
final materialsForSummary = _buildMaterialsForSummary(items);
return currentState.copyWith.call(items: items, summary: _generateSummary(materialsForSummary));
},
addWeapon: (e) async {
await _telemetryService.trackCalculatorItemAscMaterialLoaded(e.key);
Expand All @@ -64,30 +64,33 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
image: weapon.fullImagePath,
name: translation.name,
rarity: weapon.rarity,
materials: _getWeaponMaterialsToUse(weapon, e.currentAscensionLevel, e.desiredAscensionLevel),
materials: _getWeaponMaterialsToUse(weapon, e.currentLevel, e.desiredLevel, e.currentAscensionLevel, e.desiredAscensionLevel),
currentLevel: e.currentLevel,
desiredLevel: e.desiredLevel,
desiredAscensionLevel: e.desiredAscensionLevel,
currentAscensionLevel: e.currentAscensionLevel,
)
];
return currentState.copyWith.call(items: items, summary: _generateSummary(items.expand((i) => i.materials).toList()));
final materialsForSummary = _buildMaterialsForSummary(items);
return currentState.copyWith.call(items: items, summary: _generateSummary(materialsForSummary));
},
removeItem: (e) async {
final items = [...currentState.items];
items.removeAt(e.index);
return currentState.copyWith.call(items: items, summary: _generateSummary(items.expand((i) => i.materials).toList()));
final materialsForSummary = _buildMaterialsForSummary(items);
return currentState.copyWith.call(items: items, summary: _generateSummary(materialsForSummary));
},
updateCharacter: (e) async {
final currentChar = currentState.items.elementAt(e.index);
final char = _genshinService.getCharacter(currentChar.key);
final updatedChar = currentChar.copyWith.call(
materials: _getCharacterMaterialsToUse(char, e.currentAscensionLevel, e.desiredAscensionLevel, e.skills),
materials: _getCharacterMaterialsToUse(char, e.currentLevel, e.desiredLevel, e.currentAscensionLevel, e.desiredAscensionLevel, e.skills),
currentLevel: e.currentLevel,
desiredLevel: e.desiredLevel,
skills: e.skills,
desiredAscensionLevel: e.desiredAscensionLevel,
currentAscensionLevel: e.currentAscensionLevel,
isActive: e.isActive,
);

return _updateItem(e.index, updatedChar);
Expand All @@ -96,11 +99,12 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
final currentWeapon = currentState.items.elementAt(e.index);
final weapon = _genshinService.getWeapon(currentWeapon.key);
final updatedWeapon = currentWeapon.copyWith.call(
materials: _getWeaponMaterialsToUse(weapon, e.currentAscensionLevel, e.desiredAscensionLevel),
materials: _getWeaponMaterialsToUse(weapon, e.currentLevel, e.desiredLevel, e.currentAscensionLevel, e.desiredAscensionLevel),
currentLevel: e.currentLevel,
desiredLevel: e.desiredLevel,
desiredAscensionLevel: e.desiredAscensionLevel,
currentAscensionLevel: e.currentAscensionLevel,
isActive: e.isActive,
);

return _updateItem(e.index, updatedWeapon);
Expand Down Expand Up @@ -164,6 +168,10 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
case MaterialType.ingredient:
key = AscensionMaterialSummaryType.others;
break;
case MaterialType.expWeapon:
case MaterialType.expCharacter:
key = AscensionMaterialSummaryType.exp;
break;
}
newValue = MaterialSummary.others(
key: material.key,
Expand All @@ -187,10 +195,14 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu

List<ItemAscensionMaterialModel> _getCharacterMaterialsToUse(
CharacterFileModel char,
int currentLevel,
int desiredLevel,
int currentAscensionLevel,
int desiredAscensionLevel,
List<CharacterSkill> skills,
) {
final expMaterials = _getItemExperienceMaterials(currentLevel, desiredLevel, true);

final ascensionMaterials =
char.ascensionMaterials.where((m) => m.rank > currentAscensionLevel && m.rank <= desiredAscensionLevel).expand((e) => e.materials).toList();

Expand Down Expand Up @@ -223,20 +235,23 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
}
}

return _flatMaterialsList(ascensionMaterials + skillMaterials);
return _flatMaterialsList(expMaterials + ascensionMaterials + skillMaterials);
}

List<ItemAscensionMaterialModel> _getWeaponMaterialsToUse(
WeaponFileModel weapon,
int currentLevel,
int desiredLevel,
int currentAscensionLevel,
int desiredAscensionLevel,
) {
final expMaterials = _getItemExperienceMaterials(currentLevel, desiredLevel, false);
final materials = weapon.ascensionMaterials
.where((m) => m.level > _mapToWeaponLevel(currentAscensionLevel) && m.level <= _mapToWeaponLevel(desiredAscensionLevel))
.expand((m) => m.materials)
.toList();

return _flatMaterialsList(materials);
return _flatMaterialsList(expMaterials + materials);
}

List<ItemAscensionMaterialModel> _flatMaterialsList(List<ItemAscensionMaterialModel> current) {
Expand All @@ -255,7 +270,12 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
final items = [...currentState.items];
items.removeAt(index);
items.insert(index, updatedItem);
return currentState.copyWith.call(items: items, summary: _generateSummary(items.expand((i) => i.materials).toList()));
final materialsForSummary = _buildMaterialsForSummary(items);
return currentState.copyWith.call(items: items, summary: _generateSummary(materialsForSummary));
}

List<ItemAscensionMaterialModel> _buildMaterialsForSummary(List<ItemAscensionMaterials> items) {
return items.where((i) => i.isActive).expand((i) => i.materials).toList();
}

int _mapToWeaponLevel(int val) {
Expand All @@ -269,4 +289,32 @@ class CalculatorAscMaterialsBloc extends Bloc<CalculatorAscMaterialsEvent, Calcu
return entry.value;
}
}

List<ItemAscensionMaterialModel> _getItemExperienceMaterials(int currentLevel, int desiredLevel, bool forCharacters) {
final materials = <ItemAscensionMaterialModel>[];
//Here we order the exp materials in a way that the one that gives more exp is first and so on
final expMaterials = _genshinService.getMaterials(forCharacters ? MaterialType.expCharacter : MaterialType.expWeapon)
..sort((x, y) => (y.experienceAttributes.experience - x.experienceAttributes.experience).round());
var requiredExp = getItemTotalExp(currentLevel, desiredLevel, forCharacters);
final moraMaterial = _genshinService.getMaterials(MaterialType.currency).first;

for (final material in expMaterials) {
if (requiredExp <= 0) {
break;
}

final matExp = material.experienceAttributes.experience;
final quantity = (requiredExp / matExp).floor();
if (quantity == 0) {
continue;
}
materials.add(ItemAscensionMaterialModel(quantity: quantity, image: material.image, materialType: material.type));
requiredExp -= quantity * matExp;

final requiredMora = quantity * material.experienceAttributes.pricePerUsage;
materials.add(ItemAscensionMaterialModel(quantity: requiredMora.round(), image: moraMaterial.image, materialType: moraMaterial.type));
}

return materials.reversed.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ abstract class CalculatorAscMaterialsEvent with _$CalculatorAscMaterialsEvent {
@required int currentAscensionLevel,
@required int desiredAscensionLevel,
@required List<CharacterSkill> skills,
@required bool isActive,
}) = _UpdateCharacter;

const factory CalculatorAscMaterialsEvent.addWeapon({
Expand All @@ -36,6 +37,7 @@ abstract class CalculatorAscMaterialsEvent with _$CalculatorAscMaterialsEvent {
@required int desiredLevel,
@required int currentAscensionLevel,
@required int desiredAscensionLevel,
@required bool isActive,
}) = _UpdateWeapon;

const factory CalculatorAscMaterialsEvent.removeItem({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ abstract class ItemAscensionMaterials with _$ItemAscensionMaterials {
@required int desiredAscensionLevel,
@required List<CharacterSkill> skills,
@Default(true) bool isCharacter,
@Default(true) bool isActive,
}) = _ForCharacter;

const factory ItemAscensionMaterials.forWeapons({
Expand All @@ -34,5 +35,6 @@ abstract class ItemAscensionMaterials with _$ItemAscensionMaterials {
//This are here just for convenience
@Default([]) List<CharacterSkill> skills,
@Default(false) bool isCharacter,
@Default(true) bool isActive,
}) = _ForWeapon;
}
23 changes: 22 additions & 1 deletion lib/domain/models/db/materials/material_file_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,38 @@ abstract class MaterialFileModel implements _$MaterialFileModel {
@late
String get fullImagePath => Assets.getMaterialPath(image, type);

@late
bool get isAnExperienceMaterial => type == MaterialType.expWeapon || type == MaterialType.expCharacter;

@late
ExperienceMaterialAttributesModel get experienceAttributes =>
isAnExperienceMaterial ? ExperienceMaterialAttributesModel.fromJson(attributes) : null;

factory MaterialFileModel({
@required String key,
@required String image,
@required bool isFromBoss,
@required bool isForCharacters,
@required bool isForWeapons,
@required MaterialType type,
@required List<int> days,
@required int level,
@required double level,
Map<String, dynamic> attributes,
}) = _MaterialFileModel;

MaterialFileModel._();

factory MaterialFileModel.fromJson(Map<String, dynamic> json) => _$MaterialFileModelFromJson(json);
}

@freezed
abstract class ExperienceMaterialAttributesModel implements _$ExperienceMaterialAttributesModel {
factory ExperienceMaterialAttributesModel({
@required double experience,
@required double pricePerUsage,
}) = _ExperienceMaterialAttributesModel;

ExperienceMaterialAttributesModel._();

factory ExperienceMaterialAttributesModel.fromJson(Map<String, dynamic> json) => _$ExperienceMaterialAttributesModelFromJson(json);
}
4 changes: 2 additions & 2 deletions lib/domain/models/db/materials/materials_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import 'package:freezed_annotation/freezed_annotation.dart';
import 'material_file_model.dart';

part 'materials_file.freezed.dart';

part 'materials_file.g.dart';

@freezed
abstract class MaterialsFile implements _$MaterialsFile {
@late
List<MaterialFileModel> get materials => talents + weapon + weaponPrimary + common + currency + elemental + jewels + locals;
List<MaterialFileModel> get materials => talents + weapon + weaponPrimary + common + currency + elemental + jewels + locals + experience;

factory MaterialsFile({
@required List<MaterialFileModel> talents,
Expand All @@ -20,6 +19,7 @@ abstract class MaterialsFile implements _$MaterialsFile {
@required List<MaterialFileModel> elemental,
@required List<MaterialFileModel> jewels,
@required List<MaterialFileModel> locals,
@required List<MaterialFileModel> experience,
}) = _MaterialsFile;

MaterialsFile._();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
class ItemExperience {
class ItemExperienceModel {
final int level;
final int nextLevelExp;
final int totalExp;
final double nextLevelExp;
final double totalExp;
final bool isForCharacter;

bool get maxReached => level == -1;

const ItemExperience.forCharacters(
const ItemExperienceModel.forCharacters(
this.level,
this.nextLevelExp,
this.totalExp,
) : isForCharacter = true;

const ItemExperience.forWeapons(
const ItemExperienceModel.forWeapons(
this.level,
this.nextLevelExp,
this.totalExp,
Expand Down
2 changes: 1 addition & 1 deletion lib/domain/models/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export 'elements/element_reaction_card_model.dart';
export 'home/today_char_ascension_materials_model.dart';
export 'home/today_weapon_ascension_material_model.dart';
export 'items/item_ascension_material_model.dart';
export 'items/item_experience.dart';
export 'items/item_experience_model.dart';
export 'language_model.dart';
export 'settings/app_settings.dart';
export 'tierlist/tierlist_row_model.dart';
Expand Down
1 change: 1 addition & 0 deletions lib/domain/services/genshin_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ abstract class GenshinService {
List<ElementReactionCardModel> getElementResonances();

MaterialFileModel getMaterialByImage(String image);
List<MaterialFileModel> getMaterials(MaterialType type);

int getServerDay(AppServerResetTimeType type);
}
40 changes: 40 additions & 0 deletions lib/domain/utils/currency_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'package:intl/intl.dart';

class CurrencyUtils {
static String formatNumber(
int amount, {
int decimalDigits = 0,
bool symbolToTheRight = true,
String thousandSeparator = '.',
String decimalSeparator = ',',
}) {
return _refineSeparator(
amount,
decimalDigits,
thousandSeparator,
decimalSeparator,
);
}

static String _baseFormat(
int amount,
int decimalDigits,
) =>
NumberFormat.currency(
symbol: '',
decimalDigits: decimalDigits,
locale: 'en_US',
).format(amount);

static String _refineSeparator(
int amount,
int decimalDigits,
String thousandSeparator,
String decimalSeparator,
) =>
_baseFormat(amount, decimalDigits)
.replaceAll(',', '(,)')
.replaceAll('.', '(.)')
.replaceAll('(,)', thousandSeparator)
.replaceAll('(.)', decimalSeparator);
}
5 changes: 5 additions & 0 deletions lib/infrastructure/genshin_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,11 @@ class GenshinServiceImpl implements GenshinService {
return _materialsFile.materials.firstWhere((m) => m.fullImagePath == image);
}

@override
List<MaterialFileModel> getMaterials(MaterialType type) {
return _materialsFile.materials.where((m) => m.type == type).toList();
}

@override
int getServerDay(AppServerResetTimeType type) {
final now = DateTime.now();
Expand Down

0 comments on commit 28a0654

Please sign in to comment.