v1.3.0: added support for custom seeded runs
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -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...
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +202,10 @@ public class StartScene extends PixelScene {
|
||||
depth.resetColor();
|
||||
level.resetColor();
|
||||
}
|
||||
|
||||
if (info.customSeed){
|
||||
steps.hardlight(1f, 1.5f, 0.67f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user