v0.8.0: fixes/tweaks:

- Buying shop items now only triggers when hero walks onto them. This is for consistency with other item types
- Mimics are now alerted when they receive a debuff
- Teleportation now only plays sfx/vfx if the hero sees it
- Fixed logic for updating openSpace array when terrain changes
- Added a limit to how large chars and items are prioritized over cells
- Adjusted hero to appear behind mobs by default
- Fixed cases where movement keys would remain held incorrectly
- Improved vfx for falling enemies and items
- Fixed golem particle vfx lasting longer than intended in some cases
This commit is contained in:
Evan Debenham 2020-01-06 20:12:30 -05:00
parent 70c45d3709
commit 2925e445b8
9 changed files with 82 additions and 29 deletions

View File

@ -651,7 +651,7 @@ public class Hero extends Char {
private boolean actBuy( HeroAction.Buy action ) { private boolean actBuy( HeroAction.Buy action ) {
int dst = action.dst; int dst = action.dst;
if (pos == dst || Dungeon.level.adjacent( pos, dst )) { if (pos == dst) {
ready(); ready();

View File

@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Challenges;
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.Buff;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
@ -90,6 +91,16 @@ public class Mimic extends Mob {
} }
} }
@Override
public void add(Buff buff) {
super.add(buff);
if (buff.type == Buff.buffType.NEGATIVE && alignment == Alignment.NEUTRAL){
alignment = Alignment.ENEMY;
stopHiding();
if (sprite != null) sprite.idle();
}
}
@Override @Override
public String name() { public String name() {
if (alignment == Alignment.NEUTRAL){ if (alignment == Alignment.NEUTRAL){

View File

@ -222,6 +222,10 @@ public class ScrollOfTeleportation extends Scroll {
ch.sprite.interruptMotion(); ch.sprite.interruptMotion();
if (Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[ch.pos]){
Sample.INSTANCE.play(Assets.SND_TELEPORT);
}
ch.move( pos ); ch.move( pos );
if (ch.pos == pos) ch.sprite.place( pos ); if (ch.pos == pos) ch.sprite.place( pos );
@ -230,8 +234,9 @@ public class ScrollOfTeleportation extends Scroll {
ch.sprite.parent.add( new AlphaTweener( ch.sprite, 1, 0.4f ) ); ch.sprite.parent.add( new AlphaTweener( ch.sprite, 1, 0.4f ) );
} }
if (Dungeon.level.heroFOV[pos] || ch == Dungeon.hero ) {
ch.sprite.emitter().start(Speck.factory(Speck.LIGHT), 0.2f, 3); ch.sprite.emitter().start(Speck.factory(Speck.LIGHT), 0.2f, 3);
Sample.INSTANCE.play( Assets.SND_TELEPORT ); }
} }
@Override @Override

View File

@ -693,18 +693,27 @@ public abstract class Level implements Bundlable {
level.pit[cell] = (flags & Terrain.PIT) != 0; level.pit[cell] = (flags & Terrain.PIT) != 0;
level.water[cell] = terrain == Terrain.WATER; level.water[cell] = terrain == Terrain.WATER;
for (int i : PathFinder.NEIGHBOURS9){
level.openSpace[cell+i] = !level.solid[cell+i] &&
(!level.solid[cell+i-1] || !level.solid[cell+i+1]) &&
(!level.solid[cell+i-level.width()] || !level.solid[cell+i+level.width()]);
}
SmokeScreen s = (SmokeScreen)level.blobs.get(SmokeScreen.class); SmokeScreen s = (SmokeScreen)level.blobs.get(SmokeScreen.class);
if (s != null && s.volume > 0){ if (s != null && s.volume > 0){
level.losBlocking[cell] = level.losBlocking[cell] || s.cur[cell] > 0; level.losBlocking[cell] = level.losBlocking[cell] || s.cur[cell] > 0;
} }
//TODO update openSpace here too for (int i : PathFinder.NEIGHBOURS9){
i = cell + i;
if (level.solid[i]){
level.openSpace[i] = false;
} else {
for (int j = 1; j < PathFinder.CIRCLE8.length; j += 2){
if (level.solid[i+PathFinder.CIRCLE8[j]]) {
level.openSpace[i] = false;
} else if (!level.solid[i+PathFinder.CIRCLE8[(j+1)%8]]
&& !level.solid[i+PathFinder.CIRCLE8[(j+2)%8]]){
level.openSpace[i] = true;
break;
}
}
}
}
} }
public Heap drop( Item item, int cell ) { public Heap drop( Item item, int cell ) {

View File

@ -82,19 +82,29 @@ public class CellSelector extends ScrollArea {
} else { } else {
PointF p = Camera.main.screenToCamera( (int) event.current.x, (int) event.current.y ); PointF p = Camera.main.screenToCamera( (int) event.current.x, (int) event.current.y );
//Prioritizes a mob sprite if it and a tile overlap, so long as the mob sprite isn't more than 4 pixels into a tile the mob doesn't occupy.
//The extra check prevents large mobs from blocking the player from clicking adjacent tiles
for (Char mob : Dungeon.level.mobs.toArray(new Mob[0])){ for (Char mob : Dungeon.level.mobs.toArray(new Mob[0])){
if (mob.sprite != null && mob.sprite.overlapsPoint( p.x, p.y )){ if (mob.sprite != null && mob.sprite.overlapsPoint( p.x, p.y )){
PointF c = DungeonTilemap.tileCenterToWorld(mob.pos);
if (Math.abs(p.x - c.x) <= 12 && Math.abs(p.y - c.y) <= 12) {
select(mob.pos); select(mob.pos);
return; return;
} }
} }
}
//Does the same but for heaps
for (Heap heap : Dungeon.level.heaps.valueList()){ for (Heap heap : Dungeon.level.heaps.valueList()){
if (heap.sprite != null && heap.sprite.overlapsPoint( p.x, p.y)){ if (heap.sprite != null && heap.sprite.overlapsPoint( p.x, p.y)){
PointF c = DungeonTilemap.tileCenterToWorld(heap.pos);
if (Math.abs(p.x - c.x) <= 12 && Math.abs(p.y - c.y) <= 12) {
select(heap.pos); select(heap.pos);
return; return;
} }
} }
}
select( ((DungeonTilemap)target).screenToTile( select( ((DungeonTilemap)target).screenToTile(
(int) event.current.x, (int) event.current.x,

View File

@ -246,6 +246,11 @@ public class GameScene extends PixelScene {
mobs = new Group(); mobs = new Group();
add( mobs ); add( mobs );
hero = new HeroSprite();
hero.place( Dungeon.hero.pos );
hero.updateArmor();
mobs.add( hero );
for (Mob mob : Dungeon.level.mobs) { for (Mob mob : Dungeon.level.mobs) {
addMobSprite( mob ); addMobSprite( mob );
if (Statistics.amuletObtained) { if (Statistics.amuletObtained) {
@ -296,11 +301,6 @@ public class GameScene extends PixelScene {
add( emoicons ); add( emoicons );
hero = new HeroSprite();
hero.place( Dungeon.hero.pos );
hero.updateArmor();
mobs.add( hero );
add( cellSelector = new CellSelector( tiles ) ); add( cellSelector = new CellSelector( tiles ) );
pane = new StatusPane(); pane = new StatusPane();
@ -967,6 +967,7 @@ public class GameScene extends PixelScene {
} }
private static boolean cancelCellSelector() { private static boolean cancelCellSelector() {
cellSelector.resetKeyHold();
if (cellSelector.listener != null && cellSelector.listener != defaultCellListener) { if (cellSelector.listener != null && cellSelector.listener != defaultCellListener) {
cellSelector.cancel(); cellSelector.cancel();
return true; return true;

View File

@ -21,23 +21,19 @@
package com.shatteredpixel.shatteredpixeldungeon.sprites; package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.watabou.noosa.Game; import com.watabou.noosa.Game;
public class DiscardedItemSprite extends ItemSprite { public class DiscardedItemSprite extends ItemSprite {
public DiscardedItemSprite() {
super();
originToCenter();
angularSpeed = 720;
}
@Override @Override
public void drop() { public void drop() {
scale.set( 1 ); scale.set( 1 );
am = 1; am = 1;
if (emitter != null) emitter.killAndErase(); if (emitter != null) emitter.killAndErase();
origin.set( width/2, height - DungeonTilemap.SIZE/2);
angularSpeed = 720;
} }
@Override @Override
@ -45,7 +41,8 @@ public class DiscardedItemSprite extends ItemSprite {
super.update(); super.update();
scale.set( scale.x * 0.9f ); scale.set( scale.x -= Game.elapsed );
y += 12 * Game.elapsed;
if ((am -= Game.elapsed) <= 0) { if ((am -= Game.elapsed) <= 0) {
remove(); remove();
} }

View File

@ -78,6 +78,15 @@ public class GolemSprite extends MobSprite {
} }
} }
@Override
public void kill() {
super.kill();
if (teleParticles != null) {
teleParticles.on = false;
}
}
public void teleParticles(boolean value){ public void teleParticles(boolean value){
if (teleParticles != null) teleParticles.on = value; if (teleParticles != null) teleParticles.on = value;
} }

View File

@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.watabou.noosa.Game;
import com.watabou.noosa.tweeners.AlphaTweener; import com.watabou.noosa.tweeners.AlphaTweener;
import com.watabou.noosa.tweeners.ScaleTweener; import com.watabou.noosa.tweeners.ScaleTweener;
import com.watabou.utils.PointF; import com.watabou.utils.PointF;
@ -59,6 +60,15 @@ public class MobSprite extends CharSprite {
origin.set( width / 2, height - DungeonTilemap.SIZE / 2 ); origin.set( width / 2, height - DungeonTilemap.SIZE / 2 );
angularSpeed = Random.Int( 2 ) == 0 ? -720 : 720; angularSpeed = Random.Int( 2 ) == 0 ? -720 : 720;
am = 1;
if (emo != null){
emo.killAndErase();
}
if (health != null){
health.killAndErase();
}
parent.add( new ScaleTweener( this, new PointF( 0, 0 ), FALL_TIME ) { parent.add( new ScaleTweener( this, new PointF( 0, 0 ), FALL_TIME ) {
@Override @Override
@ -69,6 +79,7 @@ public class MobSprite extends CharSprite {
@Override @Override
protected void updateValues( float progress ) { protected void updateValues( float progress ) {
super.updateValues( progress ); super.updateValues( progress );
y += 12 * Game.elapsed;
am = 1 - progress; am = 1 - progress;
} }
} ); } );