v0.8.0: fixed various bugs:

- Ghouls rarely moving into chasms as they get up
- Golem teleportation not being blocked by antimagic
- piranhas playing no death animation if they die on land
- ripper demons failing to move off their leap target in many cases
- various freeze/crash bugs with Yog-Dzewa
- player not be able to place items into their main bag if a sub bag is full
- DM-300 rarely spawning ontop of the exit stairs
- rare levelgen hanging bug when placing enemies
- spawner warning playing on floor 26
- rare crash bug involving DM-300
- rare crash bug involving update notification
- typo in bright fist's description
This commit is contained in:
Evan Debenham 2020-03-26 14:18:16 -04:00
parent 54db0a7c6c
commit aa263b6f0a
14 changed files with 63 additions and 44 deletions

View File

@ -277,7 +277,7 @@ public class Ghoul extends Mob {
ArrayList<Integer> candidates = new ArrayList<>(); ArrayList<Integer> candidates = new ArrayList<>();
for (int n : PathFinder.NEIGHBOURS8) { for (int n : PathFinder.NEIGHBOURS8) {
int cell = ghoul.pos + n; int cell = ghoul.pos + n;
if ((Dungeon.level.passable[cell] || Dungeon.level.avoid[cell]) && Actor.findChar( cell ) == null) { if (Dungeon.level.passable[cell] && Actor.findChar( cell ) == null) {
candidates.add( cell ); candidates.add( cell );
} }
} }

View File

@ -24,9 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
@ -135,6 +133,10 @@ public class Golem extends Mob {
} }
} }
if (enemy.buff(MagicImmune.class) != null){
bestPos = enemy.pos;
}
if (bestPos != enemy.pos){ if (bestPos != enemy.pos){
ScrollOfTeleportation.appear(enemy, bestPos); ScrollOfTeleportation.appear(enemy, bestPos);
if (enemy instanceof Hero){ if (enemy instanceof Hero){

View File

@ -65,7 +65,6 @@ public class Piranha extends Mob {
if (!Dungeon.level.water[pos]) { if (!Dungeon.level.water[pos]) {
die( null ); die( null );
sprite.killAndErase();
return true; return true;
} else { } else {
return super.act(); return super.act();

View File

@ -146,18 +146,22 @@ public class RipperDemon extends Mob {
Sample.INSTANCE.play(Assets.SND_HIT); Sample.INSTANCE.play(Assets.SND_HIT);
} }
//bounce to a random safe pos(if possible) //bounce to a random safe pos(if possible)
int bouncepos = leapPos; int bouncepos = -1;
for (int i : PathFinder.NEIGHBOURS8){ for (int i : PathFinder.NEIGHBOURS8){
if (Dungeon.level.trueDistance(pos, leapPos+i) < Dungeon.level.trueDistance(pos, bouncepos) if ((bouncepos == -1 || Dungeon.level.trueDistance(pos, leapPos+i) < Dungeon.level.trueDistance(pos, bouncepos))
&& Actor.findChar(leapPos+i) == null && Dungeon.level.passable[leapPos+i]){ && Actor.findChar(leapPos+i) == null && Dungeon.level.passable[leapPos+i]){
bouncepos = leapPos+i; bouncepos = leapPos+i;
} }
} }
if (bouncepos != -1) {
pos = bouncepos; pos = bouncepos;
Actor.addDelayed(new Pushing(RipperDemon.this, leapPos, bouncepos), -1); Actor.addDelayed(new Pushing(RipperDemon.this, leapPos, bouncepos), -1);
} else { } else {
pos = leapPos; pos = leapPos;
} }
} else {
pos = leapPos;
}
leapPos = -1; leapPos = -1;
Dungeon.level.occupyCell(RipperDemon.this); Dungeon.level.occupyCell(RipperDemon.this);

View File

@ -239,6 +239,8 @@ public class YogDzewa extends Mob {
if (findFist() != null){ if (findFist() != null){
summonCooldown += MIN_SUMMON_CD - phase; summonCooldown += MIN_SUMMON_CD - phase;
} }
} else {
break;
} }
} }

View File

@ -475,7 +475,7 @@ public abstract class YogFist extends Mob {
super.damage(dmg, src); super.damage(dmg, src);
if (isAlive() && beforeHP > HT/2 && HP < HT/2){ if (isAlive() && beforeHP > HT/2 && HP < HT/2){
HP = HT/2; HP = HT/2;
Buff.prolong( enemy, Blindness.class, 30f ); Buff.prolong( Dungeon.hero, Blindness.class, 30f );
int i; int i;
do { do {
i = Random.Int(Dungeon.level.length()); i = Random.Int(Dungeon.level.length());
@ -485,7 +485,7 @@ public abstract class YogFist extends Mob {
GameScene.flash(0xFFFFFF); GameScene.flash(0xFFFFFF);
GLog.w( Messages.get( this, "teleport" )); GLog.w( Messages.get( this, "teleport" ));
} else if (!isAlive()){ } else if (!isAlive()){
Buff.prolong( enemy, Blindness.class, 50f ); Buff.prolong( Dungeon.hero, Blindness.class, 50f );
GameScene.flash(0xFFFFFF); GameScene.flash(0xFFFFFF);
} }
} }

View File

@ -178,7 +178,9 @@ public class Item implements Bundlable {
for (Item item:items) { for (Item item:items) {
if (item instanceof Bag && ((Bag)item).grab( this )) { if (item instanceof Bag && ((Bag)item).grab( this )) {
return collect( (Bag)item ); if (collect( (Bag)item )){
return true;
}
} }
} }
@ -206,7 +208,7 @@ public class Item implements Bundlable {
} else { } else {
GLog.n( Messages.get(Item.class, "pack_full", name()) ); GLog.n( Messages.get(Item.class, "pack_full", container.name()) );
return false; return false;
} }

View File

@ -209,13 +209,6 @@ public class NewCavesBossLevel extends Level {
public void seal() { public void seal() {
super.seal(); super.seal();
NewDM300 boss = new NewDM300();
boss.state = boss.WANDERING;
do {
boss.pos = pointToCell(Random.element(mainArena.getPoints()));
} while (!openSpace[boss.pos] || map[boss.pos] == Terrain.EMPTY_SP);
GameScene.add( boss );
set( entrance, Terrain.WALL ); set( entrance, Terrain.WALL );
GameScene.updateMap( entrance ); GameScene.updateMap( entrance );
Dungeon.observe(); Dungeon.observe();
@ -224,6 +217,13 @@ public class NewCavesBossLevel extends Level {
Camera.main.shake( 3, 0.7f ); Camera.main.shake( 3, 0.7f );
Sample.INSTANCE.play( Assets.SND_ROCKS ); Sample.INSTANCE.play( Assets.SND_ROCKS );
NewDM300 boss = new NewDM300();
boss.state = boss.WANDERING;
do {
boss.pos = pointToCell(Random.element(mainArena.getPoints()));
} while (!openSpace[boss.pos] || map[boss.pos] == Terrain.EMPTY_SP);
GameScene.add( boss );
for (int i : pylonPositions) { for (int i : pylonPositions) {
Pylon pylon = new Pylon(); Pylon pylon = new Pylon();
pylon.pos = i; pylon.pos = i;

View File

@ -191,24 +191,33 @@ public abstract class RegularLevel extends Level {
} }
roomToSpawn = stdRoomIter.next(); roomToSpawn = stdRoomIter.next();
int tries = 30;
do { do {
mob.pos = pointToCell(roomToSpawn.random()); mob.pos = pointToCell(roomToSpawn.random());
} while (findMob(mob.pos) != null || !passable[mob.pos] || mob.pos == exit); tries--;
} while (tries >= 0 && (findMob(mob.pos) != null || !passable[mob.pos] || mob.pos == exit));
if (tries >= 0) {
mobsToSpawn--; mobsToSpawn--;
mobs.add(mob); mobs.add(mob);
//add a second mob to this room
if (mobsToSpawn > 0 && Random.Int(4) == 0){ if (mobsToSpawn > 0 && Random.Int(4) == 0){
mob = createMob(); mob = createMob();
tries = 30;
do { do {
mob.pos = pointToCell(roomToSpawn.random()); mob.pos = pointToCell(roomToSpawn.random());
} while (findMob(mob.pos) != null || !passable[mob.pos] || mob.pos == exit); tries--;
} while (tries >= 0 && findMob(mob.pos) != null || !passable[mob.pos] || mob.pos == exit);
if (tries >= 0) {
mobsToSpawn--; mobsToSpawn--;
mobs.add(mob); mobs.add(mob);
} }
} }
}
}
for (Mob m : mobs){ for (Mob m : mobs){
if (map[m.pos] == Terrain.HIGH_GRASS || map[m.pos] == Terrain.FURROWED_GRASS) { if (map[m.pos] == Terrain.HIGH_GRASS || map[m.pos] == Terrain.FURROWED_GRASS) {

View File

@ -444,7 +444,7 @@ public class GameScene extends PixelScene {
} }
int spawnersAbove = Statistics.spawnersAlive; int spawnersAbove = Statistics.spawnersAlive;
if (spawnersAbove > 0) { if (spawnersAbove > 0 && Dungeon.depth <= 25) {
for (Mob m : Dungeon.level.mobs) { for (Mob m : Dungeon.level.mobs) {
if (m instanceof DemonSpawner && ((DemonSpawner) m).spawnRecorded) { if (m instanceof DemonSpawner && ((DemonSpawner) m).spawnRecorded) {
spawnersAbove--; spawnersAbove--;

View File

@ -128,12 +128,11 @@ public class DM300Sprite extends MobSprite {
public void update() { public void update() {
super.update(); super.update();
if (superchargeSparks != null){
superchargeSparks.visible = visible;
if (ch instanceof NewDM300){ if (ch instanceof NewDM300){
superchargeSparks.on = ((NewDM300) ch).isSupercharged(); superchargeSparks.on = ((NewDM300) ch).isSupercharged();
} }
if (superchargeSparks != null){
superchargeSparks.visible = visible;
} }
} }

View File

@ -31,8 +31,6 @@ import com.watabou.noosa.Game;
public class UpdateNotification extends StyledButton { public class UpdateNotification extends StyledButton {
private static AvailableUpdateData update;
public UpdateNotification(){ public UpdateNotification(){
super( Chrome.Type.GREY_BUTTON_TR, Messages.get(UpdateNotification.class, "title") ); super( Chrome.Type.GREY_BUTTON_TR, Messages.get(UpdateNotification.class, "title") );
textColor( Window.SHPX_COLOR ); textColor( Window.SHPX_COLOR );
@ -56,17 +54,21 @@ public class UpdateNotification extends StyledButton {
@Override @Override
protected void onClick() { protected void onClick() {
update = Updates.updateData(); if (Updates.updateAvailable()){
ShatteredPixelDungeon.scene().addToFront( new WndUpdate() ); ShatteredPixelDungeon.scene().addToFront( new WndUpdate( Updates.updateData() ) );
}
} }
public static class WndUpdate extends WndOptions { public static class WndUpdate extends WndOptions {
public WndUpdate(){ private AvailableUpdateData update;
public WndUpdate( AvailableUpdateData update ){
super( super(
update.versionName == null ? Messages.get(WndUpdate.class,"title") : Messages.get(WndUpdate.class,"versioned_title", update.versionName), update.versionName == null ? Messages.get(WndUpdate.class,"title") : Messages.get(WndUpdate.class,"versioned_title", update.versionName),
update.desc == null ? Messages.get(WndUpdate.class,"desc") : update.desc, update.desc == null ? Messages.get(WndUpdate.class,"desc") : update.desc,
Messages.get(WndUpdate.class,"button")); Messages.get(WndUpdate.class,"button"));
this.update = update;
} }
@Override @Override

View File

@ -773,7 +773,7 @@ actors.mobs.yogfist$rusted.name=rusted fist
actors.mobs.yogfist$rusted.desc=This fist is formed out of living metal. It is a towering mass of shifting metal that has powerful melee attacks, and can cripple its targets at range. Because of its tremendous mass, the fist will take any damage dealt to it over time, instead of immediately.\n\nThe fist is inflexible however, and cannot move into tight passageways. Additionally, while it make take damage slowly, the deferred damage will continue to increase if the fist is hit multiple times. actors.mobs.yogfist$rusted.desc=This fist is formed out of living metal. It is a towering mass of shifting metal that has powerful melee attacks, and can cripple its targets at range. Because of its tremendous mass, the fist will take any damage dealt to it over time, instead of immediately.\n\nThe fist is inflexible however, and cannot move into tight passageways. Additionally, while it make take damage slowly, the deferred damage will continue to increase if the fist is hit multiple times.
actors.mobs.yogfist$bright.name=bright fist actors.mobs.yogfist$bright.name=bright fist
actors.mobs.yogfist$bright.teleport=The fist teleports away in a flash of light that seriously blinds you! actors.mobs.yogfist$bright.teleport=The fist teleports away in a flash of light that seriously blinds you!
actors.mobs.yogfist$bright.desc=This fist is formed out of pure light energy. It is capable of shooting powerful rays of searing light every turn! These beams will temporarily blind you in addition to dealing heavy damage. The fist is also capable of briefly engulphing the arena in blinding light in order to escape!\n\nThe fist has no special abilities which it can use in melee range however. actors.mobs.yogfist$bright.desc=This fist is formed out of pure light energy. It is capable of shooting powerful rays of searing light every turn! These beams will temporarily blind you in addition to dealing heavy damage. The fist is also capable of briefly engulfing the arena in blinding light in order to escape!\n\nThe fist has no special abilities which it can use in melee range however.
actors.mobs.yogfist$dark.name=dark fist actors.mobs.yogfist$dark.name=dark fist
actors.mobs.yogfist$dark.teleport=The fist teleports away in a blast of darkness that extinguishes your light source! actors.mobs.yogfist$dark.teleport=The fist teleports away in a blast of darkness that extinguishes your light source!
actors.mobs.yogfist$dark.desc=This fist is formed out of pure dark energy. It is capable of shooting powerful blasts of dark magic every turn! These blasts will weaken your light source in addition to dealing heavy damage. The fist is also capable of briefly engulfing the arena in darkness in order to escape!\n\nThe fist has no special abilities which it can use in melee range however. actors.mobs.yogfist$dark.desc=This fist is formed out of pure dark energy. It is capable of shooting powerful blasts of dark magic every turn! These blasts will weaken your light source in addition to dealing heavy damage. The fist is also capable of briefly engulfing the arena in darkness in order to escape!\n\nThe fist has no special abilities which it can use in melee range however.

View File

@ -1649,7 +1649,7 @@ items.honeypot.desc=This large honeypot is only really lined with honey, instead
items.honeypot$shatteredpot.name=shattered honeypot items.honeypot$shatteredpot.name=shattered honeypot
items.honeypot$shatteredpot.desc=The pot has been shattered, only the sticky honey that lines its walls is holding it together, and it is slowly coming apart.\n\nDespite its broken state, the bee still seems to want to protect the pot. items.honeypot$shatteredpot.desc=The pot has been shattered, only the sticky honey that lines its walls is holding it together, and it is slowly coming apart.\n\nDespite its broken state, the bee still seems to want to protect the pot.
items.item.pack_full=Your pack is too full for the %s. items.item.pack_full=Your %s is full.
items.item.prompt=Choose direction of throw items.item.prompt=Choose direction of throw
items.item.ac_drop=DROP items.item.ac_drop=DROP
items.item.ac_throw=THROW items.item.ac_throw=THROW