From b6471276e23c33bc7dc64418d47a6512342e5fe0 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 12 May 2022 22:47:39 -0400 Subject: [PATCH] v1.3.0: fixed a few score errors and added a score breakdown window --- .../messages/windows/windows.properties | 17 +++ .../shatteredpixeldungeon/Badges.java | 1 - .../shatteredpixeldungeon/Rankings.java | 12 +- .../ShatteredPixelDungeon.java | 4 +- .../windows/WndRanking.java | 29 +++-- .../windows/WndScoreBreakdown.java | 122 ++++++++++++++++++ 6 files changed, 168 insertions(+), 17 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndScoreBreakdown.java diff --git a/core/src/main/assets/messages/windows/windows.properties b/core/src/main/assets/messages/windows/windows.properties index fa85c14c1..20cae1e16 100644 --- a/core/src/main/assets/messages/windows/windows.properties +++ b/core/src/main/assets/messages/windows/windows.properties @@ -181,6 +181,23 @@ windows.wndsadghost.confirm=Confirm windows.wndsadghost.cancel=Cancel windows.wndsadghost.farewell=Farewell, adventurer! +windows.wndscorebreakdown.title=Score Breakdown +windows.wndscorebreakdown.progress_title=Progression +windows.wndscorebreakdown.progress_desc=Based on maximum depth and hero level. +windows.wndscorebreakdown.treasure_title=Treasure +windows.wndscorebreakdown.treasure_desc=Based on gold collected and held item value. +windows.wndscorebreakdown.treasure_desc_old=Based on gold collected. +windows.wndscorebreakdown.explore_title=Exploration +windows.wndscorebreakdown.explore_desc=Based on floors with all items found, all secrets found, and all puzzles solved. +windows.wndscorebreakdown.bosses_title=Bosses +windows.wndscorebreakdown.bosses_desc=Based on bosses defeated, reduced by taking avoidable damage during boss fights. +windows.wndscorebreakdown.quests_title=Quests +windows.wndscorebreakdown.quests_desc=Based on quests completed. +windows.wndscorebreakdown.win_multiplier=Win Multiplier +windows.wndscorebreakdown.challenge_multiplier=Challenge Multiplier +windows.wndscorebreakdown.total=Total Score +windows.wndscorebreakdown.old_score_desc=Games started prior to v1.3 have fewer scoring categories, but progression is ~50% larger and treasure has a higher cap + windows.wndsettings$displaytab.title=Display Settings windows.wndsettings$displaytab.fullscreen=Fullscreen windows.wndsettings$displaytab.saver=Power Saver diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java index 90f2eb918..f42693a37 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Badges.java @@ -901,7 +901,6 @@ public class Badges { displayBadge( badge ); } - //TODO this is calibrated for scoring changes I plan to make public static void validateHighScore( int score ){ Badge badge = null; if (score >= 5000) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Rankings.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Rankings.java index ac48a45d2..b6a4ea87c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Rankings.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Rankings.java @@ -118,7 +118,7 @@ public enum Rankings { //assumes a ranking is loaded, or game is ending public int calculateScore(){ - if (Dungeon.initialVersion > ShatteredPixelDungeon.v1_2_3+1){ + if (Dungeon.initialVersion > ShatteredPixelDungeon.v1_2_3){ Statistics.progressScore = Dungeon.hero.lvl * Statistics.deepestFloor * 65; Statistics.progressScore = Math.min(Statistics.progressScore, 50_000); @@ -134,23 +134,25 @@ public enum Rankings { Statistics.treasureScore = Statistics.goldCollected + Statistics.heldItemValue; Statistics.treasureScore = Math.min(Statistics.treasureScore, 20_000); + Statistics.exploreScore = 0; int scorePerFloor = Statistics.floorsExplored.size * 50; for (Boolean b : Statistics.floorsExplored.valueList()){ if (b) Statistics.exploreScore += scorePerFloor; } + Statistics.totalBossScore = 0; for (int i : Statistics.bossScores){ if (i > 0) Statistics.totalBossScore += i; } + Statistics.totalQuestScore = 0; for (int i : Statistics.questScores){ if (i > 0) Statistics.totalQuestScore += i; } Statistics.winMultiplier = 1f; - if (Statistics.amuletObtained) Statistics.winMultiplier += 0.75f; - if (Statistics.gameWon) Statistics.winMultiplier += 0.25f; - if (Statistics.ascended) Statistics.winMultiplier += 0.25f; + if (Statistics.gameWon) Statistics.winMultiplier += 1f; + if (Statistics.ascended) Statistics.winMultiplier += 0.5f; //pre v1.3.0 runs have different score calculations //only progress and treasure score, and they are each up to 50% bigger @@ -264,7 +266,7 @@ public enum Rankings { Dungeon.initialVersion = data.getInt(GAME_VERSION); - if (Dungeon.initialVersion < ShatteredPixelDungeon.v1_2_3+1){ + if (Dungeon.initialVersion <= ShatteredPixelDungeon.v1_2_3){ Statistics.gameWon = rec.win; } rec.score = calculateScore(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java index a7709e36f..d95e55211 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java @@ -40,8 +40,8 @@ public class ShatteredPixelDungeon extends Game { public static final int v0_9_3c = 557; //557 on iOS, 554 on other platforms public static final int v1_0_3 = 574; - public static final int v1_1_2 = 587; - public static final int v1_2_3 = 627; + public static final int v1_1_2 = 588; + public static final int v1_2_3 = 628; public ShatteredPixelDungeon( PlatformSupport platform ) { super( sceneClass == null ? WelcomeScene.class : sceneClass, platform ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java index 4a3e2972b..149b34f56 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndRanking.java @@ -35,6 +35,7 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite; import com.shatteredpixel.shatteredpixeldungeon.ui.BadgesGrid; import com.shatteredpixel.shatteredpixeldungeon.ui.BadgesList; +import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton; import com.shatteredpixel.shatteredpixeldungeon.ui.Icons; import com.shatteredpixel.shatteredpixeldungeon.ui.ItemSlot; import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton; @@ -50,6 +51,7 @@ import com.watabou.noosa.audio.Sample; import com.shatteredpixel.shatteredpixeldungeon.ui.Button; import com.watabou.noosa.ui.Component; +import java.text.NumberFormat; import java.util.Locale; public class WndRanking extends WndTabbed { @@ -225,24 +227,33 @@ public class WndRanking extends WndTabbed { pos += GAP; - //TODO score breakdown page! - pos = statSlot( this, "Score", Integer.toString( Statistics.totalScore ), pos ); + NumberFormat num = NumberFormat.getInstance(Locale.US); + pos = statSlot( this, Messages.get(this, "score"), num.format( Statistics.totalScore ), pos ); + IconButton scoreInfo = new IconButton(Icons.get(Icons.INFO)){ + @Override + protected void onClick() { + super.onClick(); + ShatteredPixelDungeon.scene().addToFront(new WndScoreBreakdown()); + } + }; + scoreInfo.setSize(16, 16); + scoreInfo.setPos(WIDTH-scoreInfo.width(), pos-14); + add(scoreInfo); pos += GAP; int strBonus = Dungeon.hero.STR() - Dungeon.hero.STR; if (strBonus > 0) pos = statSlot(this, Messages.get(this, "str"), Dungeon.hero.STR + " + " + strBonus, pos); else if (strBonus < 0) pos = statSlot(this, Messages.get(this, "str"), Dungeon.hero.STR + " - " + -strBonus, pos ); else pos = statSlot(this, Messages.get(this, "str"), Integer.toString(Dungeon.hero.STR), pos); - pos = statSlot( this, Messages.get(this, "duration"), Integer.toString( (int)Statistics.duration ), pos ); - pos = statSlot( this, Messages.get(this, "depth"), Integer.toString( Statistics.deepestFloor ), pos ); - + pos = statSlot( this, Messages.get(this, "duration"), num.format( (int)Statistics.duration ), pos ); + pos = statSlot( this, Messages.get(this, "depth"), num.format( Statistics.deepestFloor ), pos ); pos += GAP; - pos = statSlot( this, Messages.get(this, "enemies"), Integer.toString( Statistics.enemiesSlain ), pos ); - pos = statSlot( this, Messages.get(this, "gold"), Integer.toString( Statistics.goldCollected ), pos ); - pos = statSlot( this, Messages.get(this, "food"), Integer.toString( Statistics.foodEaten ), pos ); - pos = statSlot( this, Messages.get(this, "alchemy"), Integer.toString( Statistics.itemsCrafted ), pos ); + pos = statSlot( this, Messages.get(this, "enemies"), num.format( Statistics.enemiesSlain ), pos ); + pos = statSlot( this, Messages.get(this, "gold"), num.format( Statistics.goldCollected ), pos ); + pos = statSlot( this, Messages.get(this, "food"), num.format( Statistics.foodEaten ), pos ); + pos = statSlot( this, Messages.get(this, "alchemy"), num.format( Statistics.itemsCrafted ), pos ); } private float statSlot( Group parent, String label, String value, float pos ) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndScoreBreakdown.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndScoreBreakdown.java new file mode 100644 index 000000000..134a9c5b4 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndScoreBreakdown.java @@ -0,0 +1,122 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2022 Evan Debenham + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +package com.shatteredpixel.shatteredpixeldungeon.windows; + +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.Statistics; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; +import com.shatteredpixel.shatteredpixeldungeon.ui.Icons; +import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock; +import com.shatteredpixel.shatteredpixeldungeon.ui.Window; +import com.watabou.noosa.Group; + +import java.text.NumberFormat; +import java.util.Locale; + +public class WndScoreBreakdown extends Window { + + private static final int WIDTH = 115; + + private int GAP = 4; + + public WndScoreBreakdown(){ + + IconTitle title = new IconTitle( Icons.get(Icons.INFO), Messages.get(this, "title")); + title.setRect(0, 0, WIDTH, 16); + add(title); + + float pos = title.bottom()+2; + + NumberFormat num = NumberFormat.getInstance(Locale.US); + if (Dungeon.initialVersion > ShatteredPixelDungeon.v1_2_3) { + pos = statSlot(this, Messages.get(this, "progress_title"), + num.format(Statistics.progressScore), pos, Statistics.progressScore >= 50_000); + pos = addInfo(this, Messages.get(this, "progress_desc"), pos); + pos = statSlot(this, Messages.get(this, "treasure_title"), + num.format(Statistics.treasureScore), pos, Statistics.treasureScore >= 20_000); + pos = addInfo(this, Messages.get(this, "treasure_desc"), pos); + pos = statSlot(this, Messages.get(this, "explore_title"), + num.format(Statistics.exploreScore), pos, Statistics.exploreScore >= 20_000); + pos = addInfo(this, Messages.get(this, "explore_desc"), pos); + pos = statSlot(this, Messages.get(this, "bosses_title"), + num.format(Statistics.totalBossScore), pos, Statistics.totalBossScore >= 15_000); + pos = addInfo(this, Messages.get(this, "bosses_desc"), pos); + pos = statSlot(this, Messages.get(this, "quests_title"), + num.format(Statistics.totalQuestScore), pos, Statistics.totalQuestScore >= 10_000); + pos = addInfo(this, Messages.get(this, "quests_desc"), pos); + } else { + pos = statSlot(this, Messages.get(this, "progress_title"), + num.format(Statistics.progressScore), pos, Statistics.progressScore >= 78_000); + pos = addInfo(this, Messages.get(this, "progress_desc"), pos); + pos = statSlot(this, Messages.get(this, "treasure_title"), + num.format(Statistics.treasureScore), pos, Statistics.treasureScore >= 30_000); + pos = addInfo(this, Messages.get(this, "treasure_desc_old"), pos); + } + + if (Statistics.winMultiplier > 1) { + pos = statSlot(this, Messages.get(this, "win_multiplier"), Statistics.winMultiplier + "x", pos, false); + } + if (Statistics.chalMultiplier > 1) { + pos = statSlot(this, Messages.get(this, "challenge_multiplier"), Statistics.chalMultiplier + "x", pos, false); + } + pos = statSlot(this, Messages.get(this, "total"), num.format(Statistics.totalScore), pos, false); + + if (Dungeon.initialVersion <= ShatteredPixelDungeon.v1_2_3){ + pos = addInfo(this, Messages.get(this, "old_score_desc"), pos); + } + + resize(WIDTH, (int)pos); + + } + + private float statSlot(Group parent, String label, String value, float pos, boolean highlight ) { + + RenderedTextBlock txt = PixelScene.renderTextBlock( label, 7 ); + if (highlight) txt.hardlight(Window.TITLE_COLOR); + txt.setPos(0, pos); + parent.add( txt ); + + txt = PixelScene.renderTextBlock( value, 7 ); + if (highlight) txt.hardlight(Window.TITLE_COLOR); + txt.setPos(WIDTH * 0.7f, pos); + PixelScene.align(txt); + parent.add( txt ); + + return pos + GAP + txt.height(); + } + + private float addInfo(Group parent, String info, float pos){ + + RenderedTextBlock txt = PixelScene.renderTextBlock( info, 5 ); + txt.maxWidth(WIDTH); + txt.hardlight(0x999999); + txt.setPos(0, pos-2); + parent.add( txt ); + + return pos - 2 + GAP + txt.height(); + + } + + +}