v0.4.3: implement seeds into levelgen (not currently user enterable)

This commit is contained in:
Evan Debenham
2016-09-23 21:00:17 -04:00
parent 84f61ff37e
commit 1565030825
7 changed files with 201 additions and 30 deletions
@@ -58,6 +58,7 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.scenes.StartScene;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.utils.DungeonSeed;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect;
import com.watabou.noosa.Game;
import com.watabou.utils.Bundlable;
@@ -70,7 +71,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
public class Dungeon {
@@ -136,18 +136,30 @@ public class Dungeon {
public static SparseArray<ArrayList<Item>> droppedItems;
public static int version;
public static long seed;
public static void init() {
version = Game.versionCode;
challenges = ShatteredPixelDungeon.challenges();
seed = DungeonSeed.randomSeed();
Actor.clear();
Actor.resetNextID();
Scroll.initLabels();
Potion.initColors();
Ring.initGems();
Random.seed( seed );
Scroll.initLabels();
Potion.initColors();
Ring.initGems();
transmutation = Random.IntRange( 6, 14 );
Room.shuffleTypes();
Random.seed();
Statistics.reset();
Journal.reset();
@@ -162,8 +174,6 @@ public class Dungeon {
for (limitedDrops a : limitedDrops.values())
a.count = 0;
transmutation = Random.IntRange( 6, 14 );
chapters = new HashSet<Integer>();
@@ -171,8 +181,6 @@ public class Dungeon {
Wandmaker.Quest.reset();
Blacksmith.Quest.reset();
Imp.Quest.reset();
Room.shuffleTypes();
Generator.initArtifacts();
hero = new Hero();
@@ -275,6 +283,19 @@ public class Dungeon {
level.reset();
switchLevel( level, level.entrance );
}
public static long seedCurDepth(){
return seedForDepth(depth);
}
public static long seedForDepth(int depth){
Random.seed( seed );
for (int i = 0; i < depth; i ++)
Random.Long(); //we don't care about these values, just need to go through them
long result = Random.Long();
Random.seed();
return result;
}
public static boolean shopOnLevel() {
return depth == 6 || depth == 11 || depth == 16;
@@ -375,6 +396,7 @@ public class Dungeon {
private static final String RN_DEPTH_FILE = "ranger%d.dat";
private static final String VERSION = "version";
private static final String SEED = "seed";
private static final String CHALLENGES = "challenges";
private static final String HERO = "hero";
private static final String GOLD = "gold";
@@ -420,6 +442,7 @@ public class Dungeon {
version = Game.versionCode;
bundle.put( VERSION, version );
bundle.put( SEED, seed );
bundle.put( CHALLENGES, challenges );
bundle.put( HERO, hero );
bundle.put( GOLD, gold );
@@ -519,6 +542,8 @@ public class Dungeon {
version = bundle.getInt( VERSION );
seed = bundle.contains( SEED ) ? bundle.getLong( SEED ) : DungeonSeed.randomSeed();
Generator.reset();
Actor.restoreNextID( bundle );
@@ -173,6 +173,8 @@ public abstract class Level implements Bundlable {
public void create() {
Random.seed( Dungeon.seedCurDepth() );
setupSize();
PathFinder.setMapSize(width(), height());
passable = new boolean[length()];
@@ -275,6 +277,8 @@ public abstract class Level implements Bundlable {
createMobs();
createItems();
Random.seed();
}
protected void setupSize(){
@@ -407,7 +407,7 @@ public abstract class RegularLevel extends Level {
split( new Rect( rect.left, vh, rect.right, rect.bottom ) );
} else
if ((Math.random() <= (minRoomSize * minRoomSize / rect.square()) && w <= maxRoomSize && h <= maxRoomSize) || w < minRoomSize || h < minRoomSize) {
if ((Random.Float() <= (minRoomSize * minRoomSize / rect.square()) && w <= maxRoomSize && h <= maxRoomSize) || w < minRoomSize || h < minRoomSize) {
rooms.add( (Room)new Room().set( rect ) );
@@ -0,0 +1,98 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 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.utils;
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 randomSeed(){
return Random.Long( TOTAL_SEEDS );
}
//Seed codes take the form @@@-@@@-@@@ where @ is any letter from A to Z (only uppercase)
//This is effectively a base-26 number system, therefore 26^9 unique seeds are possible.
//Seed codes exist to make sharing and inputting seeds easier
//ZZZ-ZZZ-ZZZ is much easier to enter and share than 5,429,503,678,975
//Takes a seed code (@@@@@@@@@) and converts it to the equivalent long value
public static long convertFromCode( String code ){
if (code.length() != 9)
throw new IllegalArgumentException("codes must be 9 A-Z characters.");
long result = 0;
for (int i = 8; i >= 0; i--) {
char c = code.charAt(i);
if (c > 'Z' || c < 'A')
throw new IllegalArgumentException("codes must be 9 A-Z characters.");
result += (c - 65) * Math.pow(26, (8 - i));
}
return result;
}
//Takes a long value and converts it to the equivalent seed code
public static String convertToCode( long seed ){
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 = "";
//so we convert
for (int i = 0; i < 9; i++) {
if (i < interrim.length()){
char c = interrim.charAt(i);
if (c <= '9') c += 17; //convert 0-9 to A-J
else c -= 22; //convert a-p to K-Z
result += c;
} else {
result = 'A' + result; //pad with A (zeroes) until we reach length of 9
}
}
return result;
}
//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)
public static long convertFromText( String inputText ){
long total = 0;
for (char c : inputText.toCharArray()){
total = 31 * total + c;
}
if (total < 0) total += Long.MAX_VALUE;
total %= TOTAL_SEEDS;
return total;
}
}