diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Displacement.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Displacement.java index 7d9097c71..cbe63e222 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Displacement.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Displacement.java @@ -36,7 +36,7 @@ public class Displacement extends Armor.Glyph { public int proc(Armor armor, Char attacker, Char defender, int damage ) { if (defender == Dungeon.hero && Random.Int(20) == 0){ - ScrollOfTeleportation.teleportHero(Dungeon.hero); + ScrollOfTeleportation.teleportChar(Dungeon.hero); return 0; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java index 55d1e8ffc..c93469ed5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/LloydsBeacon.java @@ -204,14 +204,14 @@ public class LloydsBeacon extends Artifact { updateQuickslot(); if (Actor.findChar(target) == curUser){ - ScrollOfTeleportation.teleportHero(curUser); + ScrollOfTeleportation.teleportChar(curUser); curUser.spendAndNext(1f); } else { final Ballistica bolt = new Ballistica( curUser.pos, target, Ballistica.MAGIC_BOLT ); final Char ch = Actor.findChar(bolt.collisionPos); if (ch == curUser){ - ScrollOfTeleportation.teleportHero(curUser); + ScrollOfTeleportation.teleportChar(curUser); curUser.spendAndNext( 1f ); } else { Sample.INSTANCE.play( Assets.Sounds.ZAP ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java index c3d3317b1..6619c5343 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTeleportation.java @@ -56,7 +56,9 @@ public class ScrollOfTeleportation extends Scroll { Sample.INSTANCE.play( Assets.Sounds.READ ); - teleportPreferringUnseen( curUser ); + if (teleportPreferringUnseen( curUser )){ + readAnimation(); + } identify(); if (!Dungeon.bossLevel()) { @@ -91,9 +93,8 @@ public class ScrollOfTeleportation extends Scroll { public static boolean teleportChar( Char ch ) { - if (Dungeon.bossLevel()){ - GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") ); - return false; + if (!(Dungeon.level instanceof RegularLevel)){ + return teleportInNonRegularLevel( ch, false ); } 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)){ - teleportHero( hero ); - return; + if (!(Dungeon.level instanceof RegularLevel)){ + return teleportInNonRegularLevel( hero, true ); } RegularLevel level = (RegularLevel) Dungeon.level; @@ -163,7 +163,7 @@ public class ScrollOfTeleportation extends Scroll { } if (candidates.isEmpty()){ - teleportHero( hero ); + return teleportChar( hero ); } else { int pos = Random.element(candidates); boolean secretDoor = false; @@ -195,10 +195,69 @@ public class ScrollOfTeleportation extends Scroll { } Dungeon.observe(); 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 visibleValid = new ArrayList<>(); + ArrayList notVisibleValid = new ArrayList<>(); + ArrayList 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 ) { ch.sprite.interruptMotion(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java index 35c30eda2..d2a9a7a88 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/PhaseShift.java @@ -43,7 +43,8 @@ public class PhaseShift extends TargetedSpell { final Char ch = Actor.findChar(bolt.collisionPos); 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) { int count = 20; int pos; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Fadeleaf.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Fadeleaf.java index f0bb2b4d1..2a8b4ef57 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Fadeleaf.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/plants/Fadeleaf.java @@ -70,7 +70,7 @@ public class Fadeleaf extends Plant { Game.switchScene( InterlevelScene.class ); } else { - ScrollOfTeleportation.teleportHero((Hero) ch); + ScrollOfTeleportation.teleportChar((Hero) ch); } } else if (ch instanceof Mob && !ch.properties().contains(Char.Property.IMMOVABLE)) {