v1.3.0: fixed a few score errors and added a score breakdown window

This commit is contained in:
Evan Debenham
2022-05-12 22:47:39 -04:00
parent b3decdd4cc
commit b6471276e2
6 changed files with 168 additions and 17 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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();

View File

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

View File

@@ -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 ) {

View File

@@ -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 <http://www.gnu.org/licenses/>
*/
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();
}
}