v0.6.2: redesigned secret door and searching mechanics

This commit is contained in:
Evan Debenham 2017-09-03 18:05:02 -04:00
parent 8122e961ee
commit a5df5e9b5b
9 changed files with 105 additions and 90 deletions

View File

@ -74,7 +74,7 @@ public class Hunger extends Buff implements Hero.Doom {
if (isStarving()) {
partialDamage += target.HT/100f;
partialDamage += STEP * target.HT/1000f;
if (partialDamage > 1){
target.damage( (int)partialDamage, this);
@ -139,7 +139,9 @@ public class Hunger extends Buff implements Hero.Doom {
if (level < 0) {
level = 0;
} else if (level > STARVING) {
float excess = level - STARVING;
level = STARVING;
partialDamage += excess * (target.HT/1000f);
}
BuffIndicator.refreshHero();

View File

@ -136,8 +136,9 @@ public class Hero extends Char {
public static final int STARTING_STR = 10;
private static final float TIME_TO_REST = 1f;
private static final float TIME_TO_SEARCH = 2f;
private static final float TIME_TO_REST = 1f;
private static final float TIME_TO_SEARCH = 2f;
private static final float HUNGER_FOR_SEARCH = 6f;
public HeroClass heroClass = HeroClass.ROGUE;
public HeroSubClass subClass = HeroSubClass.NONE;
@ -152,8 +153,6 @@ public class Hero extends Char {
private Char enemy;
private Item theKey;
public boolean resting = false;
public MissileWeapon rangedWeapon = null;
@ -180,7 +179,6 @@ public class Hero extends Char {
HP = HT = 20;
STR = STARTING_STR;
awareness = 0.1f;
belongings = new Belongings( this );
@ -249,7 +247,6 @@ public class Hero extends Char {
defenseSkill = bundle.getInt( DEFENSE );
STR = bundle.getInt( STRENGTH );
updateAwareness();
lvl = bundle.getInt( LEVEL );
exp = bundle.getInt( EXPERIENCE );
@ -1215,9 +1212,6 @@ public class Hero extends Char {
Sample.INSTANCE.play( Assets.SND_LEVELUP );
}
if (lvl < 10) {
updateAwareness();
}
}
if (levelUp) {
@ -1234,13 +1228,6 @@ public class Hero extends Char {
return 5 + lvl * 5;
}
void updateAwareness() {
awareness = (float)(1 - Math.pow(
(heroClass == HeroClass.ROGUE ? 0.85 : 0.90),
(1 + Math.min( lvl, 9 )) * 0.5
));
}
public boolean isStarving() {
return buff(Hunger.class) != null && ((Hunger)buff( Hunger.class )).isStarving();
}
@ -1487,16 +1474,7 @@ public class Hero extends Char {
boolean smthFound = false;
int positive = 0;
int negative = 0;
int distance = 1 + positive + negative;
float level = intentional ? (2 * awareness - awareness * awareness) : awareness;
if (distance <= 0) {
level /= 2 - distance;
distance = 1;
}
int distance = 1;
int cx = pos % Dungeon.level.width();
int cy = pos / Dungeon.level.width();
@ -1518,11 +1496,7 @@ public class Hero extends Char {
}
TalismanOfForesight.Foresight foresight = buff( TalismanOfForesight.Foresight.class );
//cursed talisman of foresight makes unintentionally finding things impossible.
if (foresight != null && foresight.isCursed()){
level = -1;
}
boolean cursed = foresight != null && foresight.isCursed();
for (int y = ay; y <= by; y++) {
for (int x = ax, p = ax + y * Dungeon.level.width(); x <= bx; x++, p++) {
@ -1533,20 +1507,41 @@ public class Hero extends Char {
sprite.parent.addToBack( new CheckedCell( p ) );
}
if (Level.secret[p] && (intentional || Random.Float() < level)) {
if (Level.secret[p]){
int oldValue = Dungeon.level.map[p];
float chance;
//intentional searches always succeed
if (intentional){
chance = 1f;
GameScene.discoverTile( p, oldValue );
//unintentional searches always fail with a cursed talisman
} else if (cursed) {
chance = 0f;
Dungeon.level.discover( p );
//unintentional trap detection scales from 40% at floor 0 to 30% at floor 25
} else if (Dungeon.level.map[p] == Terrain.SECRET_TRAP) {
chance = 0.4f - (Dungeon.depth / 250f);
ScrollOfMagicMapping.discover( p );
//unintentional door detection scales from 20% at floor 0 to 0% at floor 20
} else {
chance = 0.2f - (Dungeon.depth / 100f);
}
smthFound = true;
if (Random.Float() < chance) {
if (foresight != null && !foresight.isCursed())
foresight.charge();
int oldValue = Dungeon.level.map[p];
GameScene.discoverTile( p, oldValue );
Dungeon.level.discover( p );
ScrollOfMagicMapping.discover( p );
smthFound = true;
if (foresight != null && !foresight.isCursed())
foresight.charge();
}
}
}
}
@ -1556,12 +1551,13 @@ public class Hero extends Char {
if (intentional) {
sprite.showStatus( CharSprite.DEFAULT, Messages.get(this, "search") );
sprite.operate( pos );
if (foresight != null && foresight.isCursed()){
if (cursed){
GLog.n(Messages.get(this, "search_distracted"));
spendAndNext(TIME_TO_SEARCH * 3);
buff(Hunger.class).reduceHunger(TIME_TO_SEARCH - (2*HUNGER_FOR_SEARCH));
} else {
spendAndNext(TIME_TO_SEARCH);
buff(Hunger.class).reduceHunger(TIME_TO_SEARCH - HUNGER_FOR_SEARCH);
}
spendAndNext(TIME_TO_SEARCH);
}

View File

@ -80,7 +80,6 @@ public enum HeroClass {
break;
}
hero.updateAwareness();
}
private static void initCommon( Hero hero ) {

View File

@ -28,6 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EmptyRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap;
import com.watabou.utils.Graph;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
@ -104,14 +105,14 @@ public abstract class RegularPainter extends Painter {
rooms = new ArrayList<>();
}
Random.shuffle(rooms);
for (Room r : rooms) {
placeDoors( r );
r.paint( level );
}
for (Room r : rooms) {
paintDoors( level, r );
}
paintDoors( level, rooms );
if (waterFill > 0f) {
paintWater( level, rooms );
@ -151,44 +152,52 @@ public abstract class RegularPainter extends Painter {
}
}
protected void paintDoors( Level l, Room r ) {
for (Room n : r.connected.keySet()) {
protected void paintDoors( Level l, ArrayList<Room> rooms ) {
for (Room r : rooms) {
for (Room n : r.connected.keySet()) {
if (joinRooms( l, r, n )) {
if (joinRooms(l, r, n)) {
continue;
}
continue;
}
Room.Door d = r.connected.get(n);
int door = d.x + d.y * l.width();
Room.Door d = r.connected.get( n );
int door = d.x + d.y * l.width();
switch (d.type) {
case EMPTY:
l.map[door] = Terrain.EMPTY;
break;
case TUNNEL:
l.map[door] = l.tunnelTile();
break;
case REGULAR:
if (Dungeon.depth <= 1) {
l.map[door] = Terrain.DOOR;
if (d.type == Room.Door.Type.REGULAR){
//chance for a hidden door scales from 3/21 on floor 2 to 3/3 on floor 20
if (Dungeon.depth > 1 &&
(Dungeon.depth >= 20 || Random.Int(23 - Dungeon.depth) < Dungeon.depth)) {
d.type = Room.Door.Type.HIDDEN;
Graph.buildDistanceMap(rooms, r);
//don't hide if it would make this room only accessible by hidden doors
if (n.distance == Integer.MAX_VALUE){
d.type = Room.Door.Type.UNLOCKED;
}
} else {
boolean secret = (Dungeon.depth < 6 ? Random.Int( 12 - Dungeon.depth ) : Random.Int( 6 )) == 0;
l.map[door] = secret ? Terrain.SECRET_DOOR : Terrain.DOOR;
d.type = Room.Door.Type.UNLOCKED;
}
break;
case UNLOCKED:
l.map[door] = Terrain.DOOR;
break;
case HIDDEN:
l.map[door] = Terrain.SECRET_DOOR;
break;
case BARRICADE:
l.map[door] = Terrain.BARRICADE;
break;
case LOCKED:
l.map[door] = Terrain.LOCKED_DOOR;
break;
}
switch (d.type) {
case EMPTY:
l.map[door] = Terrain.EMPTY;
break;
case TUNNEL:
l.map[door] = l.tunnelTile();
break;
case UNLOCKED:
l.map[door] = Terrain.DOOR;
break;
case HIDDEN:
l.map[door] = Terrain.SECRET_DOOR;
break;
case BARRICADE:
l.map[door] = Terrain.BARRICADE;
break;
case LOCKED:
l.map[door] = Terrain.LOCKED_DOOR;
break;
}
}
}
}

View File

@ -336,7 +336,16 @@ public class Room extends Rect implements Graph.Node, Bundlable {
@Override
public Collection<Room> edges() {
return neigbours;
ArrayList<Room> edges = new ArrayList<>();
for( Room r : connected.keySet()){
Door d = connected.get(r);
//for the purposes of path building, ignore all doors that are locked, blocked, or hidden
if (d.type == Door.Type.EMPTY || d.type == Door.Type.TUNNEL
|| d.type == Door.Type.UNLOCKED || d.type == Door.Type.REGULAR){
edges.add(r);
}
}
return edges;
}
public String legacyType = "NULL";

View File

@ -61,7 +61,7 @@ public class BlacksmithRoom extends StandardRoom {
}
for (Door door : connected.values()) {
door.set( Door.Type.UNLOCKED );
door.set( Door.Type.REGULAR );
Painter.drawInside( level, this, door, 1, Terrain.EMPTY );
}

View File

@ -87,7 +87,7 @@ public class HallwayRoom extends EmptyRoom {
}
for (Door door : connected.values()) {
door.set( Door.Type.UNLOCKED );
door.set( Door.Type.REGULAR );
}
}

View File

@ -154,7 +154,7 @@ public class SewerPipeRoom extends StandardRoom {
}
for (Door door : connected.values()) {
door.set( Door.Type.UNLOCKED );
door.set( Door.Type.REGULAR );
}
}

View File

@ -218,7 +218,7 @@ actors.hero.hero.locked_door=You don't have a matching key.
actors.hero.hero.noticed_smth=You noticed something.
actors.hero.hero.wait=...
actors.hero.hero.search=search
actors.hero.hero.search_distracted=You can't concentrate, searching takes a while.
actors.hero.hero.search_distracted=It's hard to concentrate, searching is exhausting.
actors.hero.hero.pain_resist=The pain helps you resist the urge to sleep.
actors.hero.hero.revive=The ankh explodes with life-giving energy!