v0.9.0: adjusted ballisticas and webs:

- webs and doors are now 'soft solid' terrain (solid, but can be stepped through)
- ballisticas can now ignore soft solid terrain, instead of just doors
- webs are now flammable
This commit is contained in:
Evan Debenham 2020-09-13 16:40:32 -04:00
parent 1d36642068
commit 61268df037
11 changed files with 35 additions and 25 deletions

View File

@ -52,6 +52,7 @@ public class Web extends Blob {
volume += off[cell];
l.solid[cell] = off[cell] > 0 || (Terrain.flags[l.map[cell]] & Terrain.SOLID) != 0;
l.flamable[cell] = off[cell] > 0 || (Terrain.flags[l.map[cell]] & Terrain.FLAMABLE) != 0;
}
}
}
@ -60,6 +61,7 @@ public class Web extends Blob {
public void seed(Level level, int cell, int amount) {
super.seed(level, cell, amount);
level.solid[cell] = cur[cell] > 0 || (Terrain.flags[level.map[cell]] & Terrain.SOLID) != 0;
level.flamable[cell] = cur[cell] > 0 || (Terrain.flags[level.map[cell]] & Terrain.FLAMABLE) != 0;
}
//affects characters as they step on it. See Level.OccupyCell and Level.PressCell
@ -80,6 +82,7 @@ public class Web extends Blob {
if (cur == null) return;
Level l = Dungeon.level;
l.solid[cell] = cur[cell] > 0 || (Terrain.flags[l.map[cell]] & Terrain.SOLID) != 0;
l.flamable[cell] = cur[cell] > 0 || (Terrain.flags[l.map[cell]] & Terrain.FLAMABLE) != 0;
}
@Override

View File

@ -86,7 +86,7 @@ public class Eye extends Mob {
protected boolean canAttack( Char enemy ) {
if (beamCooldown == 0) {
Ballistica aim = new Ballistica(pos, enemy.pos, Ballistica.STOP_TERRAIN);
Ballistica aim = new Ballistica(pos, enemy.pos, Ballistica.STOP_SOLID);
if (enemy.invisible == 0 && !isCharmedBy(enemy) && fieldOfView[enemy.pos] && aim.subPath(1, aim.dist).contains(enemy.pos)){
beam = aim;
@ -106,7 +106,7 @@ public class Eye extends Mob {
sprite.idle();
}
if (beam == null && beamTarget != -1) {
beam = new Ballistica(pos, beamTarget, Ballistica.STOP_TERRAIN);
beam = new Ballistica(pos, beamTarget, Ballistica.STOP_SOLID);
sprite.turnTo(pos, beamTarget);
}
if (beamCooldown > 0)
@ -128,7 +128,7 @@ public class Eye extends Mob {
spend( attackDelay() );
beam = new Ballistica(pos, beamTarget, Ballistica.STOP_TERRAIN);
beam = new Ballistica(pos, beamTarget, Ballistica.STOP_SOLID);
if (Dungeon.level.heroFOV[pos] || Dungeon.level.heroFOV[beam.collisionPos] ) {
sprite.zap( beam.collisionPos );
return false;

View File

@ -205,11 +205,11 @@ public class RipperDemon extends Mob {
targetPos = enemy.pos + PathFinder.CIRCLE8[(closestIdx+4)%8];
}
Ballistica b = new Ballistica(pos, targetPos, Ballistica.STOP_TARGET | Ballistica.STOP_TERRAIN);
Ballistica b = new Ballistica(pos, targetPos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID);
//try aiming directly at hero if aiming near them doesn't work
if (b.collisionPos != targetPos && targetPos != enemy.pos){
targetPos = enemy.pos;
b = new Ballistica(pos, targetPos, Ballistica.STOP_TARGET | Ballistica.STOP_TERRAIN);
b = new Ballistica(pos, targetPos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID);
}
if (b.collisionPos == targetPos){
//get ready to leap

View File

@ -171,7 +171,7 @@ public class Spinner extends Mob {
int webPos = b.path.get( collisionIndex+1 );
//ensure we aren't shooting the web through walls
int projectilePos = new Ballistica( pos, webPos, Ballistica.STOP_TARGET | Ballistica.STOP_TERRAIN).collisionPos;
int projectilePos = new Ballistica( pos, webPos, Ballistica.STOP_TARGET | Ballistica.STOP_SOLID).collisionPos;
if (projectilePos == webPos && Dungeon.level.passable[webPos]){
return webPos;

View File

@ -82,12 +82,12 @@ public class PotionOfDragonsBreath extends ExoticPotion {
curUser.sprite.zap(cell);
Sample.INSTANCE.play( Assets.Sounds.BURNING );
final Ballistica bolt = new Ballistica(curUser.pos, cell, Ballistica.STOP_TERRAIN | Ballistica.IGNORE_DOORS);
final Ballistica bolt = new Ballistica(curUser.pos, cell, Ballistica.STOP_SOLID | Ballistica.IGNORE_SOFT_SOLID);
int maxDist = 6;
int dist = Math.min(bolt.dist, maxDist);
final ConeAOE cone = new ConeAOE(bolt, 6, 60, Ballistica.STOP_TERRAIN | Ballistica.STOP_TARGET | Ballistica.IGNORE_DOORS );
final ConeAOE cone = new ConeAOE(bolt, 6, 60, Ballistica.STOP_SOLID | Ballistica.STOP_TARGET | Ballistica.IGNORE_SOFT_SOLID);
//cast to cells at the tip, rather than all cells, better performance.
for (Ballistica ray : cone.rays){

View File

@ -48,7 +48,7 @@ public class WandOfCorrosion extends Wand {
{
image = ItemSpriteSheet.WAND_CORROSION;
collisionProperties = Ballistica.STOP_TARGET | Ballistica.STOP_TERRAIN;
collisionProperties = Ballistica.STOP_TARGET | Ballistica.STOP_SOLID;
}
@Override

View File

@ -85,7 +85,6 @@ public class WandOfDisintegration extends DamageWand {
if (Dungeon.level.solid[c]) {
terrainPassed++;
if (web != null) web.clear(c);
}
if (Dungeon.level.flamable[c]) {

View File

@ -52,7 +52,7 @@ public class WandOfFireblast extends DamageWand {
{
image = ItemSpriteSheet.WAND_FIREBOLT;
collisionProperties = Ballistica.STOP_TERRAIN | Ballistica.IGNORE_DOORS;
collisionProperties = Ballistica.STOP_SOLID | Ballistica.IGNORE_SOFT_SOLID;
}
//1x/2x/3x damage

View File

@ -58,7 +58,7 @@ public class WandOfRegrowth extends Wand {
{
image = ItemSpriteSheet.WAND_REGROWTH;
collisionProperties = Ballistica.STOP_TERRAIN;
collisionProperties = Ballistica.STOP_SOLID;
}
private int totChrgUsed = 0;

View File

@ -635,6 +635,7 @@ public abstract class Level implements Bundlable {
if (w != null && w.volume > 0){
for (int i=0; i < length(); i++) {
solid[i] = solid[i] || w.cur[i] > 0;
flamable[i] = flamable[i] || w.cur[i] > 0;
}
}
@ -674,6 +675,10 @@ public abstract class Level implements Bundlable {
public void destroy( int pos ) {
set( pos, Terrain.EMBERS );
Blob web = blobs.get(Web.class);
if (web != null){
web.clear(pos);
}
}
public void cleanWalls() {

View File

@ -24,7 +24,6 @@ package com.shatteredpixel.shatteredpixeldungeon.mechanics;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import java.util.ArrayList;
import java.util.List;
@ -41,12 +40,12 @@ public class Ballistica {
//parameters to specify the colliding cell
public static final int STOP_TARGET = 1; //ballistica will stop at the target cell
public static final int STOP_CHARS = 2; //ballistica will stop on first char hit
public static final int STOP_TERRAIN = 4; //ballistica will stop on solid terrain
public static final int IGNORE_DOORS = 8; //ballistica will ignore doors instead of colliding
public static final int STOP_SOLID = 4; //ballistica will stop on solid terrain
public static final int IGNORE_SOFT_SOLID = 8; //ballistica will ignore soft solid terrain, such as doors and webs
public static final int PROJECTILE = STOP_TARGET | STOP_CHARS | STOP_TERRAIN;
public static final int PROJECTILE = STOP_TARGET | STOP_CHARS | STOP_SOLID;
public static final int MAGIC_BOLT = STOP_CHARS | STOP_TERRAIN;
public static final int MAGIC_BOLT = STOP_CHARS | STOP_SOLID;
public static final int WONT_STOP = 0;
@ -56,8 +55,8 @@ public class Ballistica {
build(from, to,
(params & STOP_TARGET) > 0,
(params & STOP_CHARS) > 0,
(params & STOP_TERRAIN) > 0,
(params & IGNORE_DOORS) > 0);
(params & STOP_SOLID) > 0,
(params & IGNORE_SOFT_SOLID) > 0);
if (collisionPos != null) {
dist = path.indexOf(collisionPos);
@ -70,7 +69,7 @@ public class Ballistica {
}
}
private void build( int from, int to, boolean stopTarget, boolean stopChars, boolean stopTerrain, boolean ignoreDoors ) {
private void build( int from, int to, boolean stopTarget, boolean stopChars, boolean stopTerrain, boolean ignoreSoftSolid ) {
int w = Dungeon.level.width();
int x0 = from % w;
@ -121,12 +120,16 @@ public class Ballistica {
path.add(cell);
if ((stopTerrain && cell != sourcePos && Dungeon.level.solid[cell])
|| (cell != sourcePos && stopChars && Actor.findChar( cell ) != null)
|| (cell == to && stopTarget)){
if (!ignoreDoors || Dungeon.level.map[cell] != Terrain.DOOR) {
collide(cell); //only collide if this isn't a door, or we aren't ignoring doors
if (stopTerrain && cell != sourcePos && Dungeon.level.solid[cell]) {
if (ignoreSoftSolid && (Dungeon.level.passable[cell] || Dungeon.level.avoid[cell])) {
//do nothing
} else {
collide(cell);
}
} else if (cell != sourcePos && stopChars && Actor.findChar( cell ) != null) {
collide(cell);
} else if (cell == to && stopTarget){
collide(cell);
}
cell += stepA;