v0.7.4: intelligent allies now follow the hero between depths

This commit is contained in:
Evan Debenham 2019-06-11 01:05:35 -04:00
parent 9bab7dfd5e
commit 911f71e59e
4 changed files with 67 additions and 44 deletions

View File

@ -345,7 +345,7 @@ public class Dungeon {
PathFinder.setMapSize(level.width(), level.height()); PathFinder.setMapSize(level.width(), level.height());
Dungeon.level = level; Dungeon.level = level;
DriedRose.restoreGhostHero( level, pos ); Mob.restoreAllies( level, pos );
Actor.init(); Actor.init();
Actor respawner = level.respawner(); Actor respawner = level.respawner();

View File

@ -46,12 +46,14 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Surprise;
import com.shatteredpixel.shatteredpixeldungeon.effects.Wound; import com.shatteredpixel.shatteredpixeldungeon.effects.Wound;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; 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.artifacts.TimekeepersHourglass;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring; import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression; import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Lucky; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Lucky;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; 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.levels.features.Chasm;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.plants.Swiftthistle; import com.shatteredpixel.shatteredpixeldungeon.plants.Swiftthistle;
@ -59,9 +61,11 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
import com.watabou.utils.GameMath; import com.watabou.utils.GameMath;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
public abstract class Mob extends Char { public abstract class Mob extends Char {
@ -886,5 +890,55 @@ public abstract class Mob extends Char {
return true; return true;
} }
} }
private static ArrayList<Mob> 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<Integer> 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();
}
} }

View File

@ -92,6 +92,7 @@ public class DriedRose extends Artifact {
public int droppedPetals = 0; public int droppedPetals = 0;
public static final String AC_SUMMON = "SUMMON"; public static final String AC_SUMMON = "SUMMON";
public static final String AC_DIRECT = "DIRECT";
public static final String AC_OUTFIT = "OUTFIT"; public static final String AC_OUTFIT = "OUTFIT";
@Override @Override
@ -260,38 +261,6 @@ public class DriedRose extends Artifact {
if (bundle.contains(WEAPON)) weapon = (MeleeWeapon)bundle.get( WEAPON ); if (bundle.contains(WEAPON)) weapon = (MeleeWeapon)bundle.get( WEAPON );
if (bundle.contains(ARMOR)) armor = (Armor)bundle.get( ARMOR ); 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 { public class roseRecharge extends ArtifactBuff {

View File

@ -28,7 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; 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.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
@ -320,7 +320,7 @@ public class InterlevelScene extends PixelScene {
private void descend() throws IOException { private void descend() throws IOException {
if (Dungeon.hero == null) { if (Dungeon.hero == null) {
DriedRose.clearHeldGhostHero(); Mob.clearHeldAllies();
Dungeon.init(); Dungeon.init();
if (noStory) { if (noStory) {
Dungeon.chapters.add( WndStory.ID_SEWERS ); Dungeon.chapters.add( WndStory.ID_SEWERS );
@ -328,7 +328,7 @@ public class InterlevelScene extends PixelScene {
} }
GameLog.wipe(); GameLog.wipe();
} else { } else {
DriedRose.holdGhostHero( Dungeon.level ); Mob.holdAllies( Dungeon.level );
Dungeon.saveAll(); Dungeon.saveAll();
} }
@ -343,8 +343,8 @@ public class InterlevelScene extends PixelScene {
} }
private void fall() throws IOException { private void fall() throws IOException {
DriedRose.holdGhostHero( Dungeon.level ); Mob.holdAllies( Dungeon.level );
Buff.affect( Dungeon.hero, Chasm.Falling.class ); Buff.affect( Dungeon.hero, Chasm.Falling.class );
Dungeon.saveAll(); Dungeon.saveAll();
@ -361,7 +361,7 @@ public class InterlevelScene extends PixelScene {
private void ascend() throws IOException { private void ascend() throws IOException {
DriedRose.holdGhostHero( Dungeon.level ); Mob.holdAllies( Dungeon.level );
Dungeon.saveAll(); Dungeon.saveAll();
Dungeon.depth--; Dungeon.depth--;
@ -371,7 +371,7 @@ public class InterlevelScene extends PixelScene {
private void returnTo() throws IOException { private void returnTo() throws IOException {
DriedRose.holdGhostHero( Dungeon.level ); Mob.holdAllies( Dungeon.level );
Dungeon.saveAll(); Dungeon.saveAll();
Dungeon.depth = returnDepth; Dungeon.depth = returnDepth;
@ -381,7 +381,7 @@ public class InterlevelScene extends PixelScene {
private void restore() throws IOException { private void restore() throws IOException {
DriedRose.clearHeldGhostHero(); Mob.clearHeldAllies();
GameLog.wipe(); GameLog.wipe();
@ -397,7 +397,7 @@ public class InterlevelScene extends PixelScene {
private void resurrect() throws IOException { private void resurrect() throws IOException {
DriedRose.holdGhostHero( Dungeon.level ); Mob.holdAllies( Dungeon.level );
if (Dungeon.level.locked) { if (Dungeon.level.locked) {
Dungeon.hero.resurrect( Dungeon.depth ); Dungeon.hero.resurrect( Dungeon.depth );
@ -411,8 +411,8 @@ public class InterlevelScene extends PixelScene {
} }
private void reset() throws IOException { private void reset() throws IOException {
DriedRose.holdGhostHero( Dungeon.level ); Mob.holdAllies( Dungeon.level );
SpecialRoom.resetPitRoom(Dungeon.depth+1); SpecialRoom.resetPitRoom(Dungeon.depth+1);