v1.3.0: added support for custom seeded runs

This commit is contained in:
Evan Debenham
2022-04-16 13:35:21 -04:00
parent e2bbe2c4e9
commit 9eaaceb7a2
17 changed files with 220 additions and 85 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -47,6 +47,10 @@ scenes.gamescene.trample=Trample
scenes.gamescene.examine=Examine
scenes.heroselectscene.title=Choose Your Hero
scenes.heroselectscene.custom_seed_title=Enter a Custom Seed
scenes.heroselectscene.custom_seed_desc=The same seed and game version always generate the same dungeon! Seeds are nine uppercase letters (e.g. ABC-DEF-GHI), but you can enter anything you want and the game will convert it. _Games with a custom seed cannot earn badges or appear in rankings._
scenes.heroselectscene.custom_seed_set=Set
scenes.heroselectscene.custom_seed_clear=Clear
scenes.interlevelscene$mode.descend=Descending...
scenes.interlevelscene$mode.ascend=Ascending...

View File

@@ -46,6 +46,8 @@ windows.wndgameinprogress.str=Strength
windows.wndgameinprogress.health=Health
windows.wndgameinprogress.gold=Gold Collected
windows.wndgameinprogress.depth=Maximum Depth
windows.wndgameinprogress.dungeon_seed=Dungeon Seed
windows.wndgameinprogress.custom_seed=_Custom Seed_
windows.wndgameinprogress.continue=Continue
windows.wndgameinprogress.erase=Erase
windows.wndgameinprogress.erase_warn_title=Are you sure you want to delete this save?
@@ -62,6 +64,8 @@ windows.wndhero$statstab.str=Strength
windows.wndhero$statstab.health=Health
windows.wndhero$statstab.gold=Gold Collected
windows.wndhero$statstab.depth=Maximum Depth
windows.wndhero$statstab.dungeon_seed=Dungeon Seed
windows.wndhero$statstab.custom_seed=_Custom Seed_
windows.wndheroinfo.talents=talents
windows.wndheroinfo.talents_msg=The hero gains one talent point each time they level up. Higher tier talents appear after defeating the second boss.

View File

@@ -283,7 +283,7 @@ public class Badges {
}
}
public static int unlocked(boolean global){
public static int totalUnlocked(boolean global){
if (global) return Badges.global.size();
else return Badges.local.size();
}
@@ -533,7 +533,7 @@ public class Badges {
for (Catalog cat : Catalog.values()){
if (cat.allSeen()){
Badge b = Catalog.catalogBadges.get(cat);
if (!global.contains(b)){
if (!isUnlocked(b)){
displayBadge(b);
}
}
@@ -654,7 +654,7 @@ public class Badges {
break;
}
local.add( badge );
addGlobal(badge);
unlock(badge);
if (isUnlocked( Badge.BOSS_SLAIN_1_WARRIOR ) &&
isUnlocked( Badge.BOSS_SLAIN_1_MAGE ) &&
@@ -697,7 +697,7 @@ public class Badges {
return;
}
local.add( badge );
addGlobal(badge);
unlock(badge);
if (isUnlocked( Badge.BOSS_SLAIN_3_GLADIATOR ) &&
isUnlocked( Badge.BOSS_SLAIN_3_BERSERKER ) &&
@@ -735,11 +735,11 @@ public class Badges {
break;
}
addGlobal(badge);
unlock(badge);
}
public static void validateRatmogrify(){
addGlobal(Badge.FOUND_RATMOGRIFY);
unlock(Badge.FOUND_RATMOGRIFY);
}
public static void validateMageUnlock(){
@@ -788,7 +788,7 @@ public class Badges {
break;
}
local.add( badge );
addGlobal(badge);
unlock(badge);
if (isUnlocked( Badge.VICTORY_WARRIOR ) &&
isUnlocked( Badge.VICTORY_MAGE ) &&
@@ -855,11 +855,11 @@ public class Badges {
badge = Badge.CHAMPION_1;
}
if (challenges >= 3){
addGlobal(badge);
unlock(badge);
badge = Badge.CHAMPION_2;
}
if (challenges >= 6){
addGlobal(badge);
unlock(badge);
badge = Badge.CHAMPION_3;
}
local.add(badge);
@@ -868,11 +868,11 @@ public class Badges {
private static void displayBadge( Badge badge ) {
if (badge == null) {
if (badge == null || Dungeon.usingCustomSeed) {
return;
}
if (global.contains( badge )) {
if (isUnlocked( badge )) {
if (!badge.meta) {
GLog.h( Messages.get(Badges.class, "endorsed", badge.title()) );
@@ -881,8 +881,7 @@ public class Badges {
} else {
global.add( badge );
saveNeeded = true;
unlock(badge);
GLog.h( Messages.get(Badges.class, "new", badge.title() + " (" + badge.desc() + ")") );
GLog.newLine();
@@ -905,8 +904,8 @@ public class Badges {
saveNeeded = true;
}
public static void addGlobal( Badge badge ){
if (!global.contains(badge)){
public static void unlock( Badge badge ){
if (!isUnlocked(badge) && !Dungeon.usingCustomSeed){
global.add( badge );
saveNeeded = true;
}

View File

@@ -50,8 +50,8 @@ public class Bones {
depth = Dungeon.depth;
//heroes which have won the game, who die far above their farthest depth, or who are challenged drop no bones.
if (Statistics.amuletObtained || (Statistics.deepestFloor - 5) >= depth || Dungeon.challenges > 0) {
//heroes drop no bones if they have the amulet, die far above their farthest depth, are challenged, or are playing with a custom seed.
if (Statistics.amuletObtained || (Statistics.deepestFloor - 5) >= depth || Dungeon.challenges > 0 || Dungeon.usingCustomSeed) {
depth = -1;
return;
}
@@ -141,8 +141,8 @@ public class Bones {
}
} else {
//heroes who are challenged cannot find bones
if (depth == Dungeon.depth && Dungeon.challenges == 0) {
//heroes who are challenged or on a seeded run cannot find bones
if (depth == Dungeon.depth && Dungeon.challenges == 0 && !Dungeon.usingCustomSeed) {
Bundle emptyBones = new Bundle();
emptyBones.put(LEVEL, 0);
try {

View File

@@ -172,6 +172,7 @@ public class Dungeon {
public static int version;
public static long seed;
public static boolean usingCustomSeed;
public static void init() {
@@ -179,7 +180,13 @@ public class Dungeon {
challenges = SPDSettings.challenges();
mobsToChampion = -1;
seed = DungeonSeed.randomSeed();
if (SPDSettings.customSeed() != -1){
seed = SPDSettings.customSeed();
usingCustomSeed = true;
} else {
seed = DungeonSeed.randomSeed();
usingCustomSeed = false;
}
Actor.clear();
Actor.resetNextID();
@@ -441,6 +448,7 @@ public class Dungeon {
private static final String VERSION = "version";
private static final String SEED = "seed";
private static final String CUSTOM_SEED = "custom_seed";
private static final String CHALLENGES = "challenges";
private static final String MOBS_TO_CHAMPION = "mobs_to_champion";
private static final String HERO = "hero";
@@ -462,6 +470,7 @@ public class Dungeon {
version = Game.versionCode;
bundle.put( VERSION, version );
bundle.put( SEED, seed );
bundle.put( CUSTOM_SEED, usingCustomSeed );
bundle.put( CHALLENGES, challenges );
bundle.put( MOBS_TO_CHAMPION, mobsToChampion );
bundle.put( HERO, hero );
@@ -537,7 +546,7 @@ public class Dungeon {
saveGame( GamesInProgress.curSlot );
saveLevel( GamesInProgress.curSlot );
GamesInProgress.set( GamesInProgress.curSlot, depth, challenges, hero );
GamesInProgress.set( GamesInProgress.curSlot, depth, challenges, seed, usingCustomSeed, hero );
}
}
@@ -553,6 +562,7 @@ public class Dungeon {
version = bundle.getInt( VERSION );
seed = bundle.contains( SEED ) ? bundle.getLong( SEED ) : DungeonSeed.randomSeed();
usingCustomSeed = bundle.getBoolean( CUSTOM_SEED );
Actor.clear();
Actor.restoreNextID( bundle );
@@ -683,6 +693,9 @@ public class Dungeon {
info.depth = bundle.getInt( DEPTH );
info.version = bundle.getInt( VERSION );
info.challenges = bundle.getInt( CHALLENGES );
info.seed = bundle.getLong( SEED );
info.customSeed = bundle.getBoolean( CUSTOM_SEED );
Hero.preview( info, bundle.getBundle( HERO ) );
Statistics.preview( info, bundle );
}

View File

@@ -121,13 +121,16 @@ public class GamesInProgress {
}
}
public static void set(int slot, int depth, int challenges,
public static void set(int slot, int depth, int challenges, long seed, boolean customSeed,
Hero hero) {
Info info = new Info();
info.slot = slot;
info.depth = depth;
info.challenges = challenges;
info.seed = seed;
info.customSeed = customSeed;
info.level = hero.lvl;
info.str = hero.STR;
@@ -160,6 +163,9 @@ public class GamesInProgress {
public int depth;
public int version;
public int challenges;
public long seed;
public boolean customSeed;
public int level;
public int str;

View File

@@ -61,6 +61,9 @@ public enum Rankings {
public void submit( boolean win, Class cause ) {
//games with custom seeds do not appear in rankings
if (Dungeon.usingCustomSeed) return;
load();
Record rec = new Record();

View File

@@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Languages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.shatteredpixel.shatteredpixeldungeon.utils.DungeonSeed;
import com.watabou.noosa.Game;
import com.watabou.noosa.audio.Music;
import com.watabou.noosa.audio.Sample;
@@ -179,6 +180,7 @@ public class SPDSettings extends GameSettings {
public static final String KEY_LAST_CLASS = "last_class";
public static final String KEY_CHALLENGES = "challenges";
public static final String KEY_CUSTOM_SEED = "custom_seed";
public static final String KEY_INTRO = "intro";
public static final String KEY_SUPPORT_NAGGED= "support_nagged";
@@ -207,6 +209,14 @@ public class SPDSettings extends GameSettings {
return getInt( KEY_CHALLENGES, 0, 0, Challenges.MAX_VALUE );
}
public static void customSeed( long value ){
put( KEY_CUSTOM_SEED, value );
}
public static long customSeed() {
return getLong( KEY_CUSTOM_SEED, -1, -1, DungeonSeed.TOTAL_SEEDS-1);
}
public static void supportNagged( boolean value ) {
put( KEY_SUPPORT_NAGGED, value );
}

View File

@@ -21,8 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.scenes;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
@@ -40,6 +38,8 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
import com.shatteredpixel.shatteredpixeldungeon.ui.StyledButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.shatteredpixel.shatteredpixeldungeon.ui.WndTextInput;
import com.shatteredpixel.shatteredpixeldungeon.utils.DungeonSeed;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndChallenges;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndHeroInfo;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndKeyBindings;
@@ -64,6 +64,7 @@ public class HeroSelectScene extends PixelScene {
private ArrayList<StyledButton> heroBtns = new ArrayList<>();
private StyledButton startBtn;
private IconButton infoButton;
private IconButton seedButton;
private IconButton challengeButton;
private IconButton btnExit;
@@ -146,7 +147,7 @@ public class HeroSelectScene extends PixelScene {
}
};
infoButton.visible = false;
infoButton.setSize(21, 21);
infoButton.setSize(20, 21);
add(infoButton);
HeroClass[] classes = HeroClass.values();
@@ -192,14 +193,67 @@ public class HeroSelectScene extends PixelScene {
return Messages.titleCase(Messages.get(WndChallenges.class, "title"));
}
};
challengeButton.setRect(heroBtnleft + 16, Camera.main.height-HeroBtn.HEIGHT-16, 21, 21);
challengeButton.setRect(heroBtnleft + 16, Camera.main.height-HeroBtn.HEIGHT-16, 20, 21);
challengeButton.visible = false;
seedButton = new IconButton( Icons.get(Icons.SEED)){
@Override
protected void onClick() {
String existingSeedtext = SPDSettings.customSeed() == -1 ? "" : DungeonSeed.convertToCode(SPDSettings.customSeed());
ShatteredPixelDungeon.scene().addToFront( new WndTextInput(Messages.get(HeroSelectScene.class, "custom_seed_title"),
Messages.get(HeroSelectScene.class, "custom_seed_desc"),
existingSeedtext,
30,
false,
Messages.get(HeroSelectScene.class, "custom_seed_set"),
Messages.get(HeroSelectScene.class, "custom_seed_clear")){
@Override
public void onSelect(boolean positive, String text) {
long seed = DungeonSeed.convertFromText(text);
if (positive && seed != -1){
SPDSettings.customSeed(seed);
icon.hardlight(1f, 1.5f, 0.67f);
} else {
SPDSettings.customSeed(-1);
icon.resetColor();
}
}
});
}
@Override
protected void onPointerUp() {
if (SPDSettings.customSeed() != -1){
icon.hardlight(1f, 1.5f, 0.67f);
} else {
icon.resetColor();
}
}
@Override
public void update() {
if( !visible && GamesInProgress.selectedClass != null){
visible = true;
}
super.update();
}
@Override
protected String hoverText() {
return Messages.get(HeroSelectScene.class, "custom_seed_title");
}
};
if (SPDSettings.customSeed() != -1) seedButton.icon().hardlight(1f, 1.5f, 0.67f);
seedButton.setRect(challengeButton.left()-16, challengeButton.top(), 16, 21);
seedButton.visible = false;
if (DeviceCompat.isDebug() || Badges.isUnlocked(Badges.Badge.VICTORY)){
add(seedButton);
add(challengeButton);
} else {
Dungeon.challenges = 0;
SPDSettings.challenges(0);
SPDSettings.customSeed(-1);
}
btnExit = new ExitButton();
@@ -251,6 +305,9 @@ public class HeroSelectScene extends PixelScene {
challengeButton.visible = true;
challengeButton.setPos(startBtn.left()-challengeButton.width(), startBtn.top());
seedButton.visible = true;
seedButton.setPos(challengeButton.left()-seedButton.width(), challengeButton.top());
}
private float uiAlpha;
@@ -274,6 +331,7 @@ public class HeroSelectScene extends PixelScene {
startBtn.alpha(alpha);
btnExit.icon().alpha(alpha);
challengeButton.icon().alpha(alpha);
seedButton.icon().alpha(alpha);
infoButton.icon().alpha(alpha);
}
}

View File

@@ -202,6 +202,10 @@ public class StartScene extends PixelScene {
depth.resetColor();
level.resetColor();
}
if (info.customSeed){
steps.hardlight(1f, 1.5f, 0.67f);
}
}

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
@@ -60,6 +61,7 @@ public enum Icons {
CHALLENGE_ON,
RENAME_OFF,
RENAME_ON,
SEED,
LEFTARROW,
RIGHTARROW,
@@ -92,7 +94,7 @@ public enum Icons {
SLEEP,
ALERT,
LOST,
DEPTH,
DEPTH, //depth icons have two variants, for regular and seeded runs
DEPTH_CHASM,
DEPTH_WATER,
DEPTH_GRASS,
@@ -203,11 +205,14 @@ public enum Icons {
case RENAME_ON:
icon.frame( icon.texture.uvRectBySize( 176, 32, 15, 14 ) );
break;
case SEED:
icon.frame( icon.texture.uvRectBySize( 192, 32, 10, 10 ) );
break;
case LEFTARROW:
icon.frame( icon.texture.uvRectBySize( 192, 32, 14, 8 ) );
icon.frame( icon.texture.uvRectBySize( 208, 32, 14, 8 ) );
break;
case RIGHTARROW:
icon.frame( icon.texture.uvRectBySize( 208, 32, 14, 8 ) );
icon.frame( icon.texture.uvRectBySize( 224, 32, 14, 8 ) );
break;
case UNCHECKED:
@@ -290,31 +295,31 @@ public enum Icons {
icon.frame( icon.texture.uvRectBySize( 40, 72, 8, 8 ) );
break;
case DEPTH:
icon.frame( icon.texture.uvRectBySize( 48, 64, 6, 7 ) );
icon.frame( icon.texture.uvRectBySize( 48, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 6, 7 ) );
break;
case DEPTH_CHASM:
icon.frame( icon.texture.uvRectBySize( 56, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 56, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case DEPTH_WATER:
icon.frame( icon.texture.uvRectBySize( 64, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 64, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case DEPTH_GRASS:
icon.frame( icon.texture.uvRectBySize( 72, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 72, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case DEPTH_DARK:
icon.frame( icon.texture.uvRectBySize( 80, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 80, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case DEPTH_LARGE:
icon.frame( icon.texture.uvRectBySize( 88, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 88, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case DEPTH_TRAPS:
icon.frame( icon.texture.uvRectBySize( 96, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 96, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case DEPTH_SECRETS:
icon.frame( icon.texture.uvRectBySize( 104, 64, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 104, 64 + (Dungeon.usingCustomSeed ? 8 : 0), 7, 7 ) );
break;
case CHAL_COUNT:
icon.frame( icon.texture.uvRectBySize( 48, 72, 7, 7 ) );
icon.frame( icon.texture.uvRectBySize( 112, 64, 7, 7 ) );
break;
case LIBGDX:

View File

@@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.ui;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.shatteredpixel.shatteredpixeldungeon.Chrome;
import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene;
import com.watabou.noosa.TextInput;
@@ -29,14 +28,14 @@ import com.watabou.utils.DeviceCompat;
public class WndTextInput extends Window {
private static final int WIDTH = 120;
private static final int W_LAND_MULTI = 200; //in the specific case of multiline in landscape
private static final int WIDTH = 130;
private static final int W_LAND_EXTRA = 200; //extra width is sometimes used in landscape
private static final int MARGIN = 2;
private static final int BUTTON_HEIGHT = 16;
private TextInput textBox;
public WndTextInput(final String title, final String initialValue, final int maxLength,
public WndTextInput(final String title, final String body, final String initialValue, final int maxLength,
final boolean multiLine, final String posTxt, final String negTxt) {
super();
@@ -50,17 +49,32 @@ public class WndTextInput extends Window {
}
final int width;
if (PixelScene.landscape() && multiLine) {
width = W_LAND_MULTI; //more editing space for landscape users
if (PixelScene.landscape() && (multiLine || body != null)) {
width = W_LAND_EXTRA; //more space for landscape users
} else {
width = WIDTH;
}
final RenderedTextBlock txtTitle = PixelScene.renderTextBlock(title, 9);
txtTitle.maxWidth(width);
txtTitle.hardlight(Window.TITLE_COLOR);
txtTitle.setPos((width - txtTitle.width()) / 2, 2);
add(txtTitle);
float pos = 2;
if (title != null) {
final RenderedTextBlock txtTitle = PixelScene.renderTextBlock(title, 9);
txtTitle.maxWidth(width);
txtTitle.hardlight(Window.TITLE_COLOR);
txtTitle.setPos((width - txtTitle.width()) / 2, 2);
add(txtTitle);
pos = txtTitle.bottom() + 2 * MARGIN;
}
if (body != null) {
final RenderedTextBlock txtBody = PixelScene.renderTextBlock(body, 6);
txtBody.maxWidth(width);
txtBody.setPos(0, pos);
add(txtBody);
pos = txtBody.bottom() + 2 * MARGIN;
}
int textSize = (int)PixelScene.uiCamera.zoom * (multiLine ? 6 : 9);
textBox = new TextInput(Chrome.get(Chrome.Type.TOAST_WHITE), multiLine, textSize){
@@ -74,8 +88,6 @@ public class WndTextInput extends Window {
if (initialValue != null) textBox.setText(initialValue);
textBox.setMaxLength(maxLength);
float pos = txtTitle.bottom() + 2 * MARGIN;
//sets different height depending on whether this is a single or multi line input.
final float inputHeight;
if (multiLine) {

View File

@@ -26,7 +26,7 @@ import com.watabou.utils.Random;
//This class defines the parameters for seeds in ShatteredPD and contains a few convenience methods
public class DungeonSeed {
private static long TOTAL_SEEDS = 5429503678976L; //26^9 possible seeds
public static long TOTAL_SEEDS = 5429503678976L; //26^9 possible seeds
public static long randomSeed(){
return Random.Long( TOTAL_SEEDS );
@@ -41,8 +41,12 @@ public class DungeonSeed {
//Takes a seed code (@@@@@@@@@) and converts it to the equivalent long value
public static long convertFromCode( String code ){
if (code.length() != 9)
//ignore whitespace characters and dashes
code = code.replaceAll("[-\\s]", "");
if (code.length() != 9) {
throw new IllegalArgumentException("codes must be 9 A-Z characters.");
}
long result = 0;
for (int i = 8; i >= 0; i--) {
@@ -57,12 +61,13 @@ public class DungeonSeed {
//Takes a long value and converts it to the equivalent seed code
public static String convertToCode( long seed ){
if (seed < 0 || seed >= TOTAL_SEEDS)
if (seed < 0 || seed >= TOTAL_SEEDS) {
throw new IllegalArgumentException("seeds must be within the range [0, TOTAL_SEEDS)");
}
//this almost gives us the right answer, but its 0-p instead of A-Z
String interrim = Long.toString(seed, 26);
String result = "";
StringBuilder result = new StringBuilder();
//so we convert
for (int i = 0; i < 9; i++) {
@@ -72,21 +77,42 @@ public class DungeonSeed {
if (c <= '9') c += 17; //convert 0-9 to A-J
else c -= 22; //convert a-p to K-Z
result += c;
result.append(c);
} else {
result = 'A' + result; //pad with A (zeroes) until we reach length of 9
result.insert(0, 'A'); //pad with A (zeroes) until we reach length of 9
}
}
return result;
//insert dashes for readability
result.insert(3, '-');
result.insert(7, '-');
return result.toString();
}
//Using this we can let users input 'fun' plaintext seeds and convert them to a long equivalent.
// This is basically the same as string.hashcode except with long, and accounting for overflow
// to ensure the produced seed is always in the range [0, TOTAL_SEEDS)
//Creates a seed from arbitrary user text input
public static long convertFromText( String inputText ){
if (inputText.isEmpty()) return -1;
//First see if input is a seed code, use that format if it is
try {
return convertFromCode(inputText);
} catch (IllegalArgumentException e){
}
//Then see if input is a number (ignoring spaces), if so parse as a long seed (with overflow)
try {
return Long.parseLong(inputText.replaceAll("\\s", "")) % TOTAL_SEEDS;
} catch (NumberFormatException e){
}
//Finally, if the user has entered unformatted text, convert it to a long seed equivalent
// This is basically the same as string.hashcode except with long, and overflow
// this lets the user input 'fun' seeds, like names or places
long total = 0;
for (char c : inputText.toCharArray()){
total = 31 * total + c;

View File

@@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
import com.shatteredpixel.shatteredpixeldungeon.ui.RedButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.shatteredpixel.shatteredpixeldungeon.utils.DungeonSeed;
import com.watabou.noosa.Game;
import com.shatteredpixel.shatteredpixeldungeon.ui.Button;
import com.watabou.utils.Bundle;
@@ -70,23 +71,6 @@ public class WndGameInProgress extends Window {
title.setRect( 0, 0, WIDTH, 0 );
add(title);
//manually produces debug information about a run, mainly useful for levelgen errors
Button debug = new Button(){
@Override
protected boolean onLongClick() {
try {
Bundle bundle = FileUtils.bundleFromFile(GamesInProgress.gameFile(slot));
ShatteredPixelDungeon.scene().addToFront(new WndMessage("_Debug Info:_\n\n" +
"Version: " + Game.version + " (" + Game.versionCode + ")\n" +
"Seed: " + bundle.getLong("seed") + "\n" +
"Challenge Mask: " + info.challenges));
} catch (IOException ignored) { }
return true;
}
};
debug.setRect(0, 0, title.imIcon.width(), title.imIcon.height);
add(debug);
if (info.challenges > 0) GAP -= 2;
pos = title.bottom() + GAP;
@@ -119,6 +103,11 @@ public class WndGameInProgress extends Window {
pos += GAP;
statSlot( Messages.get(this, "gold"), info.goldCollected );
statSlot( Messages.get(this, "depth"), info.maxDepth );
if (info.customSeed){
statSlot( Messages.get(this, "custom_seed"), "_" + DungeonSeed.convertToCode(info.seed) + "_" );
} else {
statSlot( Messages.get(this, "dungeon_seed"), DungeonSeed.convertToCode(info.seed) );
}
pos += GAP;
@@ -175,7 +164,7 @@ public class WndGameInProgress extends Window {
add( txt );
txt = PixelScene.renderTextBlock( value, 8 );
txt.setPos(WIDTH * 0.6f, pos);
txt.setPos(WIDTH * 0.55f, pos);
PixelScene.align(txt);
add( txt );

View File

@@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.windows;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
@@ -41,12 +40,10 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.TalentButton;
import com.shatteredpixel.shatteredpixeldungeon.ui.TalentsPane;
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
import com.watabou.gltextures.SmartTexture;
import com.watabou.gltextures.TextureCache;
import com.shatteredpixel.shatteredpixeldungeon.utils.DungeonSeed;
import com.watabou.noosa.Gizmo;
import com.watabou.noosa.Group;
import com.watabou.noosa.Image;
import com.watabou.noosa.TextureFilm;
import com.watabou.noosa.ui.Component;
import java.util.ArrayList;
@@ -188,6 +185,11 @@ public class WndHero extends WndTabbed {
statSlot( Messages.get(this, "gold"), Statistics.goldCollected );
statSlot( Messages.get(this, "depth"), Statistics.deepestFloor );
if (Dungeon.usingCustomSeed){
statSlot( Messages.get(this, "custom_seed"), "_" + DungeonSeed.convertToCode(Dungeon.seed) + "_" );
} else {
statSlot( Messages.get(this, "dungeon_seed"), DungeonSeed.convertToCode(Dungeon.seed) );
}
pos += GAP;
}
@@ -199,7 +201,7 @@ public class WndHero extends WndTabbed {
add( txt );
txt = PixelScene.renderTextBlock( value, 8 );
txt.setPos(WIDTH * 0.6f, pos);
txt.setPos(WIDTH * 0.55f, pos);
PixelScene.align(txt);
add( txt );

View File

@@ -330,7 +330,7 @@ public class WndRanking extends WndTabbed {
camera = WndRanking.this.camera;
Component badges;
if (Badges.unlocked(false) <= 7){
if (Badges.totalUnlocked(false) <= 7){
badges = new BadgesList(false);
} else {
badges = new BadgesGrid(false);