v1.1.0: added teleport functionality for non-regular (i.e. boss) levels

This commit is contained in:
Evan Debenham 2021-09-24 20:14:22 -04:00
parent 42bc39bf72
commit be40007183
5 changed files with 74 additions and 14 deletions

View File

@ -36,7 +36,7 @@ public class Displacement extends Armor.Glyph {
public int proc(Armor armor, Char attacker, Char defender, int damage ) { public int proc(Armor armor, Char attacker, Char defender, int damage ) {
if (defender == Dungeon.hero && Random.Int(20) == 0){ if (defender == Dungeon.hero && Random.Int(20) == 0){
ScrollOfTeleportation.teleportHero(Dungeon.hero); ScrollOfTeleportation.teleportChar(Dungeon.hero);
return 0; return 0;
} }

View File

@ -204,14 +204,14 @@ public class LloydsBeacon extends Artifact {
updateQuickslot(); updateQuickslot();
if (Actor.findChar(target) == curUser){ if (Actor.findChar(target) == curUser){
ScrollOfTeleportation.teleportHero(curUser); ScrollOfTeleportation.teleportChar(curUser);
curUser.spendAndNext(1f); curUser.spendAndNext(1f);
} else { } else {
final Ballistica bolt = new Ballistica( curUser.pos, target, Ballistica.MAGIC_BOLT ); final Ballistica bolt = new Ballistica( curUser.pos, target, Ballistica.MAGIC_BOLT );
final Char ch = Actor.findChar(bolt.collisionPos); final Char ch = Actor.findChar(bolt.collisionPos);
if (ch == curUser){ if (ch == curUser){
ScrollOfTeleportation.teleportHero(curUser); ScrollOfTeleportation.teleportChar(curUser);
curUser.spendAndNext( 1f ); curUser.spendAndNext( 1f );
} else { } else {
Sample.INSTANCE.play( Assets.Sounds.ZAP ); Sample.INSTANCE.play( Assets.Sounds.ZAP );

View File

@ -56,7 +56,9 @@ public class ScrollOfTeleportation extends Scroll {
Sample.INSTANCE.play( Assets.Sounds.READ ); Sample.INSTANCE.play( Assets.Sounds.READ );
teleportPreferringUnseen( curUser ); if (teleportPreferringUnseen( curUser )){
readAnimation();
}
identify(); identify();
if (!Dungeon.bossLevel()) { if (!Dungeon.bossLevel()) {
@ -91,9 +93,8 @@ public class ScrollOfTeleportation extends Scroll {
public static boolean teleportChar( Char ch ) { public static boolean teleportChar( Char ch ) {
if (Dungeon.bossLevel()){ if (!(Dungeon.level instanceof RegularLevel)){
GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") ); return teleportInNonRegularLevel( ch, false );
return false;
} }
int count = 20; int count = 20;
@ -127,11 +128,10 @@ public class ScrollOfTeleportation extends Scroll {
} }
} }
public static void teleportPreferringUnseen( Hero hero ){ public static boolean teleportPreferringUnseen( Hero hero ){
if (Dungeon.bossLevel() || !(Dungeon.level instanceof RegularLevel)){ if (!(Dungeon.level instanceof RegularLevel)){
teleportHero( hero ); return teleportInNonRegularLevel( hero, true );
return;
} }
RegularLevel level = (RegularLevel) Dungeon.level; RegularLevel level = (RegularLevel) Dungeon.level;
@ -163,7 +163,7 @@ public class ScrollOfTeleportation extends Scroll {
} }
if (candidates.isEmpty()){ if (candidates.isEmpty()){
teleportHero( hero ); return teleportChar( hero );
} else { } else {
int pos = Random.element(candidates); int pos = Random.element(candidates);
boolean secretDoor = false; boolean secretDoor = false;
@ -195,10 +195,69 @@ public class ScrollOfTeleportation extends Scroll {
} }
Dungeon.observe(); Dungeon.observe();
GameScene.updateFog(); GameScene.updateFog();
return true;
} }
} }
//teleports to a random pathable location on the floor
//prefers not seen(optional) > not visible > visible
public static boolean teleportInNonRegularLevel(Char ch, boolean preferNotSeen ){
ArrayList<Integer> visibleValid = new ArrayList<>();
ArrayList<Integer> notVisibleValid = new ArrayList<>();
ArrayList<Integer> notSeenValid = new ArrayList<>();
boolean[] passable = Dungeon.level.passable;
if (Char.hasProp(ch, Char.Property.LARGE)){
passable = BArray.or(passable, Dungeon.level.openSpace, null);
}
PathFinder.buildDistanceMap(ch.pos, passable);
for (int i = 0; i < Dungeon.level.length(); i++){
if (PathFinder.distance[i] < Integer.MAX_VALUE
&& !Dungeon.level.secret[i]
&& Actor.findChar(i) == null){
if (preferNotSeen && !Dungeon.level.visited[i]){
notSeenValid.add(i);
} else if (Dungeon.level.heroFOV[i]){
visibleValid.add(i);
} else {
notVisibleValid.add(i);
}
}
}
int pos;
if (!notSeenValid.isEmpty()){
pos = Random.element(notSeenValid);
} else if (!notVisibleValid.isEmpty()){
pos = Random.element(notVisibleValid);
} else if (!visibleValid.isEmpty()){
pos = Random.element(visibleValid);
} else {
GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") );
return false;
}
appear( ch, pos );
Dungeon.level.occupyCell( ch );
if (ch == Dungeon.hero) {
GLog.i( Messages.get(ScrollOfTeleportation.class, "tele") );
Dungeon.observe();
GameScene.updateFog();
Dungeon.hero.interrupt();
}
return true;
}
public static void appear( Char ch, int pos ) { public static void appear( Char ch, int pos ) {
ch.sprite.interruptMotion(); ch.sprite.interruptMotion();

View File

@ -43,7 +43,8 @@ public class PhaseShift extends TargetedSpell {
final Char ch = Actor.findChar(bolt.collisionPos); final Char ch = Actor.findChar(bolt.collisionPos);
if (ch == hero){ if (ch == hero){
ScrollOfTeleportation.teleportHero(curUser); //TODO probably want this to not work on the hero for balance reasons?
ScrollOfTeleportation.teleportChar(curUser);
} else if (ch != null) { } else if (ch != null) {
int count = 20; int count = 20;
int pos; int pos;

View File

@ -70,7 +70,7 @@ public class Fadeleaf extends Plant {
Game.switchScene( InterlevelScene.class ); Game.switchScene( InterlevelScene.class );
} else { } else {
ScrollOfTeleportation.teleportHero((Hero) ch); ScrollOfTeleportation.teleportChar((Hero) ch);
} }
} else if (ch instanceof Mob && !ch.properties().contains(Char.Property.IMMOVABLE)) { } else if (ch instanceof Mob && !ch.properties().contains(Char.Property.IMMOVABLE)) {