Rework level calculation (#2196)
* rework level calculation * rework level calculations * generated --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: ggurdin <46800240+ggurdin@users.noreply.github.com>
This commit is contained in:
parent
642dfaf4de
commit
be5ea2b927
2 changed files with 39 additions and 19 deletions
|
|
@ -177,25 +177,50 @@ class ConstructListModel {
|
|||
if (totalXP < 0) {
|
||||
totalXP = 0;
|
||||
}
|
||||
level = calculateLevelWithXp(totalXP);
|
||||
}
|
||||
|
||||
// Don't call .floor() if NaN or Infinity
|
||||
// https://pangea-chat.sentry.io/issues/6052871310
|
||||
final double levelCalculation = 1 + sqrt((1 + 8 * totalXP / 100) / 2);
|
||||
if (!levelCalculation.isNaN && levelCalculation.isFinite) {
|
||||
level = levelCalculation.floor();
|
||||
int calculateLevelWithXp(int totalXP) {
|
||||
// [D] is the "compression factor". It determines how quickly
|
||||
/// or slowly the level grows relative to XP
|
||||
const double D = 2500;
|
||||
final doubleScore = (1 + sqrt((1 + (8.0 * totalXP / D)) / 2.0));
|
||||
if (!doubleScore.isNaN && doubleScore.isFinite) {
|
||||
return doubleScore.floor();
|
||||
} else {
|
||||
level = 1;
|
||||
ErrorHandler.logError(
|
||||
e: "Calculated level in Nan or Infinity",
|
||||
data: {
|
||||
"totalXP": totalXP,
|
||||
"prevXP": prevXP,
|
||||
"level": levelCalculation,
|
||||
"level": doubleScore,
|
||||
},
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int calculateXpWithLevel(int level) {
|
||||
// [D] is the same "compression factor" as in calculateLevelWithXp.
|
||||
const double D = 2500.0;
|
||||
|
||||
// If level <= 1, XP should be 0 or negative by this math.
|
||||
// In practice, you might clamp it to 0:
|
||||
if (level <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert level to double for the math
|
||||
final double lc = level.toDouble();
|
||||
|
||||
// XP from the inverse formula:
|
||||
final double xpDouble = (D / 8.0) * (2.0 * pow(lc - 1.0, 2.0) - 1.0);
|
||||
|
||||
// Floor or clamp to ensure non-negative.
|
||||
final int xp = xpDouble.floor();
|
||||
return (xp < 0) ? 0 : xp;
|
||||
}
|
||||
|
||||
// TODO; make this non-nullable, returning empty if not found
|
||||
ConstructUses? getConstructUses(ConstructIdentifier identifier) {
|
||||
final partialKey = "${identifier.lemma}-${identifier.type.string}";
|
||||
|
|
|
|||
|
|
@ -49,22 +49,17 @@ class GetAnalyticsController extends BaseController {
|
|||
|
||||
// the minimum XP required for a given level
|
||||
int get _minXPForLevel {
|
||||
return _calculateMinXpForLevel(constructListModel.level);
|
||||
return constructListModel.calculateXpWithLevel(constructListModel.level);
|
||||
}
|
||||
|
||||
// the minimum XP required for the next level
|
||||
int get _minXPForNextLevel {
|
||||
return _calculateMinXpForLevel(constructListModel.level + 1);
|
||||
return constructListModel
|
||||
.calculateXpWithLevel(constructListModel.level + 1);
|
||||
}
|
||||
|
||||
int get minXPForNextLevel => _minXPForNextLevel;
|
||||
|
||||
/// Calculates the minimum XP required for a specific level.
|
||||
int _calculateMinXpForLevel(int level) {
|
||||
if (level == 1) return 0; // Ensure level 1 starts at 0 XP
|
||||
return ((100 / 8) * (2 * pow(level - 1, 2))).floor();
|
||||
}
|
||||
|
||||
// the progress within the current level as a percentage (0.0 to 1.0)
|
||||
double get levelProgress {
|
||||
final progress = (constructListModel.totalXP - _minXPForLevel) /
|
||||
|
|
@ -197,8 +192,8 @@ class GetAnalyticsController extends BaseController {
|
|||
}
|
||||
|
||||
Future<void> _onLevelDown(final int lowerLevel, final int upperLevel) async {
|
||||
final offset =
|
||||
_calculateMinXpForLevel(lowerLevel) - constructListModel.totalXP;
|
||||
final offset = constructListModel.calculateXpWithLevel(lowerLevel) -
|
||||
constructListModel.totalXP;
|
||||
await _pangeaController.userController.addXPOffset(offset);
|
||||
constructListModel.updateConstructs(
|
||||
[],
|
||||
|
|
@ -391,8 +386,8 @@ class GetAnalyticsController extends BaseController {
|
|||
// generate level up analytics as a construct summary
|
||||
ConstructSummary summary;
|
||||
try {
|
||||
final int maxXP = _calculateMinXpForLevel(upperLevel);
|
||||
final int minXP = _calculateMinXpForLevel(lowerLevel);
|
||||
final int maxXP = constructListModel.calculateXpWithLevel(upperLevel);
|
||||
final int minXP = constructListModel.calculateXpWithLevel(lowerLevel);
|
||||
int diffXP = maxXP - minXP;
|
||||
if (diffXP < 0) diffXP = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue