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 fcbcaee17..5d3b06d18 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 @@ -72,6 +72,7 @@ import com.watabou.utils.Reflection; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; public abstract class Mob extends Char { @@ -1053,8 +1054,12 @@ public abstract class Mob extends Char { private static ArrayList heldAllies = new ArrayList<>(); - + public static void holdAllies( Level level ){ + holdAllies(level, Dungeon.hero.pos); + } + + public static void holdAllies( Level level, int holdFromPos ){ heldAllies.clear(); for (Mob mob : level.mobs.toArray( new Mob[0] )) { //preserve the ghost no matter where they are @@ -1066,14 +1071,18 @@ public abstract class Mob extends Char { //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){ + && Dungeon.level.distance(holdFromPos, mob.pos) <= 5){ level.mobs.remove( mob ); heldAllies.add(mob); } } } - + public static void restoreAllies( Level level, int pos ){ + restoreAllies(level, pos, -1); + } + + public static void restoreAllies( Level level, int pos, int gravitatePos ){ if (!heldAllies.isEmpty()){ ArrayList candidatePositions = new ArrayList<>(); @@ -1082,7 +1091,19 @@ public abstract class Mob extends Char { candidatePositions.add(i+pos); } } - Collections.shuffle(candidatePositions); + + //gravitate pos sets a preferred location for allies to be closer to + if (gravitatePos == -1) { + Collections.shuffle(candidatePositions); + } else { + Collections.sort(candidatePositions, new Comparator() { + @Override + public int compare(Integer t1, Integer t2) { + return Dungeon.level.distance(gravitatePos, t1) - + Dungeon.level.distance(gravitatePos, t2); + } + }); + } for (Mob ally : heldAllies) { level.mobs.add(ally); @@ -1093,6 +1114,7 @@ public abstract class Mob extends Char { } else { ally.pos = pos; } + if (ally.sprite != null) ally.sprite.place(ally.pos); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java index 35e0fafef..da835339b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java @@ -270,14 +270,10 @@ public class NewCityBossLevel extends Level { public void seal() { super.seal(); - for (Mob m : mobs){ - //bring the first ally with you - if (m.alignment == Char.Alignment.ALLY && !m.properties().contains(Char.Property.IMMOVABLE)){ - m.pos = Dungeon.hero.pos + (Random.Int(2) == 0 ? +1 : -1); - m.sprite.place(m.pos); - break; - } - } + //moves intelligent allies with the hero, preferring closer pos to entrance door + int doorPos = pointToCell(new Point(arena.left + arena.width()/2, arena.bottom)); + Mob.holdAllies(this, doorPos); + Mob.restoreAllies(this, Dungeon.hero.pos, doorPos); DwarfKing boss = new DwarfKing(); boss.state = boss.WANDERING; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java index fb568cb2d..b157ebada 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonBossLevel.java @@ -383,15 +383,11 @@ public class PrisonBossLevel extends Level { seal(); set(pointToCell(tenguCellDoor), Terrain.LOCKED_DOOR); GameScene.updateMap(pointToCell(tenguCellDoor)); - - for (Mob m : mobs){ - //bring the first ally with you - if (m.alignment == Char.Alignment.ALLY && !m.properties().contains(Char.Property.IMMOVABLE)){ - m.pos = pointToCell(tenguCellDoor); //they should immediately walk out of the door - m.sprite.place(m.pos); - break; - } - } + + //moves intelligent allies with the hero, preferring closer pos to cell door + int doorPos = pointToCell(tenguCellDoor); + Mob.holdAllies(this, doorPos); + Mob.restoreAllies(this, Dungeon.hero.pos, doorPos); tengu.state = tengu.HUNTING; tengu.pos = tenguPos;