From 911f71e59eb75ec99268c0c68676b7c8255f2451 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 11 Jun 2019 01:05:35 -0400 Subject: [PATCH] v0.7.4: intelligent allies now follow the hero between depths --- .../shatteredpixeldungeon/Dungeon.java | 2 +- .../actors/mobs/Mob.java | 54 +++++++++++++++++++ .../items/artifacts/DriedRose.java | 33 +----------- .../scenes/InterlevelScene.java | 22 ++++---- 4 files changed, 67 insertions(+), 44 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index 4e602485e..91fe9adeb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -345,7 +345,7 @@ public class Dungeon { PathFinder.setMapSize(level.width(), level.height()); Dungeon.level = level; - DriedRose.restoreGhostHero( level, pos ); + Mob.restoreAllies( level, pos ); Actor.init(); Actor respawner = level.respawner(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java index abbae4254..a1399d062 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java @@ -46,12 +46,14 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Surprise; import com.shatteredpixel.shatteredpixeldungeon.effects.Wound; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass; import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth; import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Lucky; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.plants.Swiftthistle; @@ -59,9 +61,11 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.utils.Bundle; import com.watabou.utils.GameMath; +import com.watabou.utils.PathFinder; import com.watabou.utils.Random; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; public abstract class Mob extends Char { @@ -886,5 +890,55 @@ public abstract class Mob extends Char { return true; } } + + + private static ArrayList heldAllies = new ArrayList<>(); + + public static void holdAllies( Level level ){ + heldAllies.clear(); + for (Mob mob : level.mobs.toArray( new Mob[0] )) { + //preserve the ghost no matter where they are + if (mob instanceof DriedRose.GhostHero) { + level.mobs.remove( mob ); + heldAllies.add(mob); + + //preserve intelligent allies if they are near the hero + } else if (mob.alignment == Alignment.ALLY + && mob.intelligentAlly + && Dungeon.level.distance(Dungeon.hero.pos, mob.pos) <= 3){ + level.mobs.remove( mob ); + heldAllies.add(mob); + } + } + } + + public static void restoreAllies( Level level, int pos ){ + if (!heldAllies.isEmpty()){ + + ArrayList candidatePositions = new ArrayList<>(); + for (int i : PathFinder.NEIGHBOURS8) { + if (!Dungeon.level.solid[i+pos] && level.findMob(i+pos) == null){ + candidatePositions.add(i+pos); + } + } + Collections.shuffle(candidatePositions); + + for (Mob ally : heldAllies) { + level.mobs.add(ally); + + if (!candidatePositions.isEmpty()){ + ally.pos = candidatePositions.remove(0); + } else { + ally.pos = pos; + } + + } + } + heldAllies.clear(); + } + + public static void clearHeldAllies(){ + heldAllies.clear(); + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java index dad8f6b39..5dc5bb820 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java @@ -92,6 +92,7 @@ public class DriedRose extends Artifact { public int droppedPetals = 0; public static final String AC_SUMMON = "SUMMON"; + public static final String AC_DIRECT = "DIRECT"; public static final String AC_OUTFIT = "OUTFIT"; @Override @@ -260,38 +261,6 @@ public class DriedRose extends Artifact { if (bundle.contains(WEAPON)) weapon = (MeleeWeapon)bundle.get( WEAPON ); if (bundle.contains(ARMOR)) armor = (Armor)bundle.get( ARMOR ); } - - // *** static methods for transferring a ghost hero between floors *** - - private static GhostHero heldGhost; - - public static void holdGhostHero( Level level ){ - for (Mob mob : level.mobs.toArray( new Mob[0] )) { - if (mob instanceof DriedRose.GhostHero) { - level.mobs.remove( mob ); - heldGhost = (GhostHero) mob; - break; - } - } - } - - public static void restoreGhostHero( Level level, int pos ){ - if (heldGhost != null){ - level.mobs.add( heldGhost ); - - int ghostPos; - do { - ghostPos = pos + PathFinder.NEIGHBOURS8[Random.Int(8)]; - } while (Dungeon.level.solid[ghostPos] || level.findMob(ghostPos) != null); - - heldGhost.pos = ghostPos; - heldGhost = null; - } - } - - public static void clearHeldGhostHero(){ - heldGhost = null; - } public class roseRecharge extends ArtifactBuff { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java index 639a1c8d7..bffd8017b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java @@ -28,7 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; @@ -320,7 +320,7 @@ public class InterlevelScene extends PixelScene { private void descend() throws IOException { if (Dungeon.hero == null) { - DriedRose.clearHeldGhostHero(); + Mob.clearHeldAllies(); Dungeon.init(); if (noStory) { Dungeon.chapters.add( WndStory.ID_SEWERS ); @@ -328,7 +328,7 @@ public class InterlevelScene extends PixelScene { } GameLog.wipe(); } else { - DriedRose.holdGhostHero( Dungeon.level ); + Mob.holdAllies( Dungeon.level ); Dungeon.saveAll(); } @@ -343,8 +343,8 @@ public class InterlevelScene extends PixelScene { } private void fall() throws IOException { - - DriedRose.holdGhostHero( Dungeon.level ); + + Mob.holdAllies( Dungeon.level ); Buff.affect( Dungeon.hero, Chasm.Falling.class ); Dungeon.saveAll(); @@ -361,7 +361,7 @@ public class InterlevelScene extends PixelScene { private void ascend() throws IOException { - DriedRose.holdGhostHero( Dungeon.level ); + Mob.holdAllies( Dungeon.level ); Dungeon.saveAll(); Dungeon.depth--; @@ -371,7 +371,7 @@ public class InterlevelScene extends PixelScene { private void returnTo() throws IOException { - DriedRose.holdGhostHero( Dungeon.level ); + Mob.holdAllies( Dungeon.level ); Dungeon.saveAll(); Dungeon.depth = returnDepth; @@ -381,7 +381,7 @@ public class InterlevelScene extends PixelScene { private void restore() throws IOException { - DriedRose.clearHeldGhostHero(); + Mob.clearHeldAllies(); GameLog.wipe(); @@ -397,7 +397,7 @@ public class InterlevelScene extends PixelScene { private void resurrect() throws IOException { - DriedRose.holdGhostHero( Dungeon.level ); + Mob.holdAllies( Dungeon.level ); if (Dungeon.level.locked) { Dungeon.hero.resurrect( Dungeon.depth ); @@ -411,8 +411,8 @@ public class InterlevelScene extends PixelScene { } private void reset() throws IOException { - - DriedRose.holdGhostHero( Dungeon.level ); + + Mob.holdAllies( Dungeon.level ); SpecialRoom.resetPitRoom(Dungeon.depth+1);