v0.3.0: reworked the ballistica system
This commit is contained in:
parent
9c1cfc095f
commit
99f853c190
|
@ -64,19 +64,14 @@ public class Eye extends Mob {
|
|||
return 10;
|
||||
}
|
||||
|
||||
private int hitCell;
|
||||
private Ballistica beam;
|
||||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
|
||||
hitCell = Ballistica.cast( pos, enemy.pos, true, false );
|
||||
beam = new Ballistica( pos, enemy.pos, Ballistica.STOP_TERRAIN);
|
||||
|
||||
for (int i=1; i < Ballistica.distance; i++) {
|
||||
if (Ballistica.trace[i] == enemy.pos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return beam.subPath(1, beam.dist).contains(enemy.pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,14 +91,14 @@ public class Eye extends Mob {
|
|||
|
||||
boolean rayVisible = false;
|
||||
|
||||
for (int i=0; i < Ballistica.distance; i++) {
|
||||
if (Dungeon.visible[Ballistica.trace[i]]) {
|
||||
for (int i : beam.subPath(0, beam.dist)) {
|
||||
if (Dungeon.visible[i]) {
|
||||
rayVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rayVisible) {
|
||||
sprite.attack( hitCell );
|
||||
sprite.attack( beam.collisionPos );
|
||||
return false;
|
||||
} else {
|
||||
attack( enemy );
|
||||
|
@ -114,9 +109,7 @@ public class Eye extends Mob {
|
|||
@Override
|
||||
public boolean attack( Char enemy ) {
|
||||
|
||||
for (int i=1; i < Ballistica.distance; i++) {
|
||||
|
||||
int pos = Ballistica.trace[i];
|
||||
for (int pos : beam.subPath(1, beam.dist)) {
|
||||
|
||||
Char ch = Actor.findChar( pos );
|
||||
if (ch == null) {
|
||||
|
|
|
@ -66,7 +66,7 @@ public class Goo extends Mob {
|
|||
pumpedUp = 0;
|
||||
for (int i = 0; i < Level.NEIGHBOURS9DIST2.length; i++) {
|
||||
int j = pos + Level.NEIGHBOURS9DIST2[i];
|
||||
if (j >= 0 && j <= 1023 && Level.passable[j])
|
||||
if (Level.insideMap(j) && Level.passable[j])
|
||||
CellEmitter.get(j).burst(ElmoParticle.FACTORY, 10);
|
||||
}
|
||||
Sample.INSTANCE.play( Assets.SND_BURNING );
|
||||
|
@ -122,7 +122,7 @@ public class Goo extends Mob {
|
|||
((GooSprite)sprite).pumpUp();
|
||||
for (int i = 0; i < Level.NEIGHBOURS9DIST2.length; i++) {
|
||||
int j = pos + Level.NEIGHBOURS9DIST2[i];
|
||||
if (j >= 0 && j <= 1023 && Level.passable[j])
|
||||
if (Level.insideMap(j) && Level.passable[j])
|
||||
GameScene.add(Blob.seed(j, 2, GooWarn.class));
|
||||
}
|
||||
pumpedUp++;
|
||||
|
|
|
@ -68,7 +68,8 @@ public class Scorpio extends Mob {
|
|||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return !Level.adjacent( pos, enemy.pos ) && Ballistica.cast( pos, enemy.pos, false, true ) == enemy.pos;
|
||||
Ballistica attack = new Ballistica( pos, enemy.pos, Ballistica.PROJECTILE);
|
||||
return !Level.adjacent( pos, enemy.pos ) && attack.collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,7 +72,7 @@ public class Shaman extends Mob implements Callback {
|
|||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return Ballistica.cast( pos, enemy.pos, false, true ) == enemy.pos;
|
||||
return new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT).collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -92,11 +92,12 @@ public class Succubus extends Mob {
|
|||
|
||||
private void blink( int target ) {
|
||||
|
||||
int cell = Ballistica.cast( pos, target, true, true );
|
||||
Ballistica route = new Ballistica( pos, target, Ballistica.PROJECTILE);
|
||||
int cell = route.collisionPos;
|
||||
|
||||
if (Actor.findChar( cell ) != null && Ballistica.distance > 1) {
|
||||
cell = Ballistica.trace[Ballistica.distance - 2];
|
||||
}
|
||||
//can't occupy the same cell as another char, so move back one.
|
||||
if (Actor.findChar( cell ) != null && cell != this.pos)
|
||||
cell = route.path.get(route.dist-1);
|
||||
|
||||
WandOfBlink.appear( this, cell );
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ public class Tengu extends Mob {
|
|||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return Ballistica.cast( pos, enemy.pos, false, true ) == enemy.pos;
|
||||
return new Ballistica( pos, enemy.pos, Ballistica.PROJECTILE).collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,7 +74,7 @@ public class Warlock extends Mob implements Callback {
|
|||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return Ballistica.cast( pos, enemy.pos, false, true ) == enemy.pos;
|
||||
return new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT).collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
protected boolean doAttack( Char enemy ) {
|
||||
|
|
|
@ -326,7 +326,7 @@ public class Yog extends Mob {
|
|||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
return Ballistica.cast( pos, enemy.pos, false, true ) == enemy.pos;
|
||||
return new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT).collisionPos == enemy.pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -467,7 +467,8 @@ public class Ghost extends NPC {
|
|||
|
||||
@Override
|
||||
protected boolean canAttack( Char enemy ) {
|
||||
if (!Level.adjacent(pos, enemy.pos) && Ballistica.cast( pos, enemy.pos, false, true ) == enemy.pos){
|
||||
Ballistica attack = new Ballistica( pos, enemy.pos, Ballistica.PROJECTILE );
|
||||
if (!Level.adjacent(pos, enemy.pos) && attack.collisionPos == enemy.pos){
|
||||
combo++;
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -452,7 +452,7 @@ public class Item implements Bundlable {
|
|||
|
||||
public void cast( final Hero user, int dst ) {
|
||||
|
||||
final int cell = Ballistica.cast( user.pos, dst, false, true );
|
||||
final int cell = new Ballistica( user.pos, dst, Ballistica.PROJECTILE ).collisionPos;
|
||||
user.sprite.zap( cell );
|
||||
user.busy();
|
||||
|
||||
|
|
|
@ -83,10 +83,13 @@ public class WarriorArmor extends ClassArmor {
|
|||
public void onSelect( Integer target ) {
|
||||
if (target != null && target != curUser.pos) {
|
||||
|
||||
int cell = Ballistica.cast( curUser.pos, target, false, true );
|
||||
if (Actor.findChar( cell ) != null && cell != curUser.pos) {
|
||||
cell = Ballistica.trace[Ballistica.distance - 2];
|
||||
}
|
||||
Ballistica route = new Ballistica(curUser.pos, target, Ballistica.PROJECTILE);
|
||||
int cell = route.collisionPos;
|
||||
|
||||
//can't occupy the same cell as another char, so move back one.
|
||||
if (Actor.findChar( cell ) != null && cell != curUser.pos)
|
||||
cell = route.path.get(route.dist-1);
|
||||
|
||||
|
||||
curUser.HP -= (curUser.HP / 3);
|
||||
if (curUser.subClass == HeroSubClass.BERSERKER && curUser.HP <= curUser.HT * Fury.LEVEL) {
|
||||
|
|
|
@ -70,7 +70,7 @@ public abstract class Wand extends KindOfWeapon {
|
|||
|
||||
private int usagesToKnow = USAGES_TO_KNOW;
|
||||
|
||||
protected boolean hitChars = true;
|
||||
protected int collisionProperties = Ballistica.MAGIC_BOLT;
|
||||
|
||||
|
||||
{
|
||||
|
@ -125,7 +125,7 @@ public abstract class Wand extends KindOfWeapon {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void onZap( int cell );
|
||||
protected abstract void onZap( Ballistica attack );
|
||||
|
||||
@Override
|
||||
public boolean collect( Bag container ) {
|
||||
|
@ -260,8 +260,8 @@ public abstract class Wand extends KindOfWeapon {
|
|||
MAX = (tier * tier - tier + 10) / 2 + level;
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.blueLight( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.blueLight( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,8 @@ public abstract class Wand extends KindOfWeapon {
|
|||
|
||||
final Wand curWand = (Wand)Wand.curItem;
|
||||
|
||||
final int cell = Ballistica.cast( curUser.pos, target, true, curWand.hitChars );
|
||||
final Ballistica shot = new Ballistica( curUser.pos, target, curWand.collisionProperties);
|
||||
int cell = shot.collisionPos;
|
||||
|
||||
if (target == curUser.pos || cell == curUser.pos) {
|
||||
GLog.i( TXT_SELF_TARGET );
|
||||
|
@ -354,17 +355,19 @@ public abstract class Wand extends KindOfWeapon {
|
|||
|
||||
curUser.sprite.zap(cell);
|
||||
|
||||
//targets the enemy hit for char-hitting wands, or the cell aimed at for other wands.
|
||||
QuickSlotButton.target(Actor.findChar(curWand.hitChars ? cell : target));
|
||||
//attempts to target the cell aimed at if something is there, otherwise targets the collision pos.
|
||||
if (Actor.findChar(target) != null)
|
||||
QuickSlotButton.target(Actor.findChar(target));
|
||||
else
|
||||
QuickSlotButton.target(Actor.findChar(cell));
|
||||
|
||||
if (curWand.curCharges > 0) {
|
||||
|
||||
curUser.busy();
|
||||
|
||||
curWand.fx( cell, new Callback() {
|
||||
@Override
|
||||
curWand.fx( shot, new Callback() {
|
||||
public void call() {
|
||||
curWand.onZap( cell );
|
||||
curWand.onZap( shot );
|
||||
curWand.wandUsed();
|
||||
}
|
||||
} );
|
||||
|
|
|
@ -19,6 +19,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
|
@ -36,8 +37,8 @@ public class WandOfAmok extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
Char ch = Actor.findChar( cell );
|
||||
protected void onZap( Ballistica bolt) {
|
||||
Char ch = Actor.findChar( bolt.collisionPos );
|
||||
if (ch != null) {
|
||||
|
||||
if (ch == Dungeon.hero) {
|
||||
|
@ -53,8 +54,9 @@ public class WandOfAmok extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.purpleLight( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.purpleLight( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -42,20 +42,18 @@ public class WandOfAvalanche extends Wand {
|
|||
|
||||
{
|
||||
name = "Wand of Avalanche";
|
||||
hitChars = false;
|
||||
collisionProperties = Ballistica.STOP_TERRAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
Sample.INSTANCE.play( Assets.SND_ROCKS );
|
||||
|
||||
int level = level();
|
||||
|
||||
Ballistica.distance = Math.min( Ballistica.distance, 8 + level );
|
||||
|
||||
int size = 1 + level / 3;
|
||||
PathFinder.buildDistanceMap( cell, BArray.not( Level.solid, null ), size );
|
||||
PathFinder.buildDistanceMap( bolt.collisionPos, BArray.not( Level.solid, null ), size );
|
||||
|
||||
for (int i=0; i < Level.LENGTH; i++) {
|
||||
|
||||
|
@ -86,8 +84,9 @@ public class WandOfAvalanche extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.earth( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.earth( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -35,24 +35,25 @@ public class WandOfBlink extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
int level = level();
|
||||
|
||||
if (Ballistica.distance > level + 4) {
|
||||
//TODO: don't care about this atm as this wand is marked for death, should correct this logic if I end up keeping it.
|
||||
/*if (Ballistica.distance > level + 4) {
|
||||
cell = Ballistica.trace[level + 3];
|
||||
} else if (Actor.findChar( cell ) != null && Ballistica.distance > 1) {
|
||||
cell = Ballistica.trace[Ballistica.distance - 2];
|
||||
}
|
||||
}*/
|
||||
|
||||
curUser.sprite.visible = true;
|
||||
appear( Dungeon.hero, cell );
|
||||
appear( Dungeon.hero, bolt.collisionPos );
|
||||
Dungeon.observe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.whiteLight( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.whiteLight( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
curUser.sprite.visible = false;
|
||||
}
|
||||
|
|
|
@ -37,24 +37,21 @@ public class WandOfDisintegration extends Wand {
|
|||
|
||||
{
|
||||
name = "Wand of Disintegration";
|
||||
hitChars = false;
|
||||
collisionProperties = Ballistica.STOP_TERRAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica beam ) {
|
||||
|
||||
boolean terrainAffected = false;
|
||||
|
||||
int level = level();
|
||||
|
||||
int maxDistance = distance();
|
||||
Ballistica.distance = Math.min( Ballistica.distance, maxDistance );
|
||||
int maxDistance = Math.min(distance(), beam.dist);
|
||||
|
||||
ArrayList<Char> chars = new ArrayList<Char>();
|
||||
|
||||
for (int i=1; i < Ballistica.distance; i++) {
|
||||
|
||||
int c = Ballistica.trace[i];
|
||||
for (int c : beam.subPath(1, maxDistance)) {
|
||||
|
||||
Char ch;
|
||||
if ((ch = Actor.findChar( c )) != null) {
|
||||
|
@ -98,9 +95,9 @@ public class WandOfDisintegration extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
protected void fx( Ballistica beam, Callback callback ) {
|
||||
|
||||
cell = Ballistica.trace[Math.min( Ballistica.distance, distance() ) - 1];
|
||||
int cell = beam.path.get(Math.min(beam.dist, distance()));
|
||||
curUser.sprite.parent.add( new DeathRay( curUser.sprite.center(), DungeonTilemap.tileCenterToWorld( cell ) ) );
|
||||
callback.call();
|
||||
}
|
||||
|
|
|
@ -44,17 +44,18 @@ public class WandOfFirebolt extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
int level = level();
|
||||
|
||||
for (int i=1; i < Ballistica.distance - 1; i++) {
|
||||
int c = Ballistica.trace[i];
|
||||
for (int c : bolt.subPath(0, bolt.dist)) {
|
||||
if (Level.flamable[c]) {
|
||||
GameScene.add( Blob.seed( c, 1, Fire.class ) );
|
||||
}
|
||||
}
|
||||
|
||||
int cell = bolt.collisionPos;
|
||||
|
||||
GameScene.add( Blob.seed( cell, 1, Fire.class ) );
|
||||
|
||||
Char ch = Actor.findChar( cell );
|
||||
|
@ -72,8 +73,9 @@ public class WandOfFirebolt extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.fire( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.fire( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -42,15 +42,17 @@ public class WandOfFlock extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
int level = level();
|
||||
|
||||
int n = level + 2;
|
||||
|
||||
//TODO: don't care about this atm as this wand is marked for death, should correct this logic if I end up keeping it
|
||||
/**
|
||||
if (Actor.findChar( cell ) != null && Ballistica.distance > 2) {
|
||||
cell = Ballistica.trace[Ballistica.distance - 2];
|
||||
}
|
||||
}*/
|
||||
|
||||
boolean[] passable = BArray.or( Level.passable, Level.avoid, null );
|
||||
for (Actor actor : Actor.all()) {
|
||||
|
@ -59,6 +61,8 @@ public class WandOfFlock extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
int cell = bolt.collisionPos;
|
||||
|
||||
PathFinder.buildDistanceMap( cell, passable, n );
|
||||
int dist = 0;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions;
|
||||
|
@ -47,7 +48,7 @@ public class WandOfLightning extends Wand {
|
|||
private int nPoints;
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
// Everything is processed in fx() method
|
||||
if (!curUser.isAlive()) {
|
||||
Dungeon.fail( Utils.format( ResultDescriptions.ITEM, name ) );
|
||||
|
@ -87,11 +88,13 @@ public class WandOfLightning extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
|
||||
nPoints = 0;
|
||||
points[nPoints++] = Dungeon.hero.pos;
|
||||
|
||||
int cell = bolt.collisionPos;
|
||||
|
||||
Char ch = Actor.findChar( cell );
|
||||
if (ch != null) {
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
|
@ -66,9 +67,9 @@ public class WandOfMagicMissile extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
Char ch = Actor.findChar( cell );
|
||||
Char ch = Actor.findChar( bolt.collisionPos );
|
||||
if (ch != null) {
|
||||
|
||||
int level = level();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
|
@ -34,8 +35,8 @@ public class WandOfPoison extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
Char ch = Actor.findChar( cell );
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
Char ch = Actor.findChar( bolt.collisionPos );
|
||||
if (ch != null) {
|
||||
|
||||
Buff.affect( ch, Poison.class ).set( Poison.durationFactor( ch ) * (5 + level()) );
|
||||
|
@ -47,8 +48,9 @@ public class WandOfPoison extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.poison( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.poison( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -37,28 +37,27 @@ public class WandOfRegrowth extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
for (int i=1; i < Ballistica.distance-1; i++) {
|
||||
int p = Ballistica.trace[i];
|
||||
int c = Dungeon.level.map[p];
|
||||
for (int i : bolt.subPath(1, bolt.dist)) {
|
||||
int c = Dungeon.level.map[i];
|
||||
if (c == Terrain.EMPTY ||
|
||||
c == Terrain.EMBERS ||
|
||||
c == Terrain.EMPTY_DECO) {
|
||||
|
||||
Level.set( p, Terrain.GRASS );
|
||||
Level.set( i, Terrain.GRASS );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int c = Dungeon.level.map[cell];
|
||||
int c = Dungeon.level.map[bolt.collisionPos];
|
||||
if (c == Terrain.EMPTY ||
|
||||
c == Terrain.EMBERS ||
|
||||
c == Terrain.EMPTY_DECO ||
|
||||
c == Terrain.GRASS ||
|
||||
c == Terrain.HIGH_GRASS) {
|
||||
|
||||
GameScene.add( Blob.seed( cell, (level() + 2) * 20, Regrowth.class ) );
|
||||
GameScene.add( Blob.seed( bolt.collisionPos, (level() + 2) * 20, Regrowth.class ) );
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -67,8 +66,9 @@ public class WandOfRegrowth extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.foliage( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.foliage( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
|
@ -34,8 +35,8 @@ public class WandOfSlowness extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
Char ch = Actor.findChar( cell );
|
||||
protected void onZap( Ballistica bolt) {
|
||||
Char ch = Actor.findChar( bolt.collisionPos );
|
||||
if (ch != null) {
|
||||
|
||||
Buff.affect( ch, Slow.class, Slow.duration( ch ) / 3 + level() );
|
||||
|
@ -47,8 +48,9 @@ public class WandOfSlowness extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.slowness( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.slowness( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -17,25 +17,17 @@
|
|||
*/
|
||||
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Shopkeeper;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Heap.Type;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.watabou.utils.Callback;
|
||||
|
||||
|
@ -45,12 +37,14 @@ public class WandOfTelekinesis extends Wand {
|
|||
|
||||
{
|
||||
name = "Wand of Telekinesis";
|
||||
hitChars = false;
|
||||
collisionProperties = Ballistica.STOP_TERRAIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
//TODO: this whole wand is getting reworked anyway, so screw trying to correct this logic, just rewrite.
|
||||
/*
|
||||
boolean mapUpdated = false;
|
||||
|
||||
int maxDistance = level() + 4;
|
||||
|
@ -131,6 +125,7 @@ public class WandOfTelekinesis extends Wand {
|
|||
if (mapUpdated) {
|
||||
Dungeon.observe();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void transport( Heap heap ) {
|
||||
|
@ -160,8 +155,9 @@ public class WandOfTelekinesis extends Wand {
|
|||
heap.sprite.drop();
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.force( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.force( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
|
@ -35,9 +36,9 @@ public class WandOfTeleportation extends Wand {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onZap( int cell ) {
|
||||
protected void onZap( Ballistica bolt ) {
|
||||
|
||||
Char ch = Actor.findChar( cell );
|
||||
Char ch = Actor.findChar( bolt.collisionPos );
|
||||
|
||||
if (ch == curUser) {
|
||||
|
||||
|
@ -74,8 +75,9 @@ public class WandOfTeleportation extends Wand {
|
|||
}
|
||||
}
|
||||
|
||||
protected void fx( int cell, Callback callback ) {
|
||||
MagicMissile.coldLight( curUser.sprite.parent, curUser.pos, cell, callback );
|
||||
@Override
|
||||
protected void fx( Ballistica bolt, Callback callback ) {
|
||||
MagicMissile.coldLight( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback );
|
||||
Sample.INSTANCE.play( Assets.SND_ZAP );
|
||||
}
|
||||
|
||||
|
|
|
@ -100,8 +100,7 @@ public abstract class Level implements Bundlable {
|
|||
public static final int[] NEIGHBOURS8 = {+1, -1, +WIDTH, -WIDTH, +1+WIDTH, +1-WIDTH, -1+WIDTH, -1-WIDTH};
|
||||
public static final int[] NEIGHBOURS9 = {0, +1, -1, +WIDTH, -WIDTH, +1+WIDTH, +1-WIDTH, -1+WIDTH, -1-WIDTH};
|
||||
|
||||
//Note that use of these without checking values is unsafe, mobs can be within 2 tiles of the
|
||||
//edge of the map, unsafe use in that cause will cause an array out of bounds exception.
|
||||
//make sure to check insideMap() when using these, as there's a risk something may be outside the map
|
||||
public static final int[] NEIGHBOURS8DIST2 = {+2+2*WIDTH, +1+2*WIDTH, 2*WIDTH, -1+2*WIDTH, -2+2*WIDTH,
|
||||
+2+WIDTH, +1+WIDTH, +WIDTH, -1+WIDTH, -2+WIDTH,
|
||||
+2, +1, -1, -2,
|
||||
|
@ -972,6 +971,16 @@ public abstract class Level implements Bundlable {
|
|||
return diff == 1 || diff == WIDTH || diff == WIDTH + 1 || diff == WIDTH - 1;
|
||||
}
|
||||
|
||||
//returns true if the input is a valid tile within the level
|
||||
public static boolean insideMap( int tile ){
|
||||
//outside map array
|
||||
return !((tile <= -1 || tile >= LENGTH) ||
|
||||
//top and bottom row
|
||||
(tile <= 31 || tile >= LENGTH - WIDTH) ||
|
||||
//left and right column
|
||||
(tile % WIDTH == 0 || tile % WIDTH == 31));
|
||||
}
|
||||
|
||||
public String tileName( int tile ) {
|
||||
|
||||
if (tile >= Terrain.WATER_TILES) {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2014 Oleg Dolya
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2015 Evan Debenham
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,13 +23,43 @@ package com.shatteredpixel.shatteredpixeldungeon.mechanics;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Ballistica {
|
||||
|
||||
public static int[] trace = new int[Math.max( Level.WIDTH, Level.HEIGHT )];
|
||||
public static int distance;
|
||||
//note that the path is the FULL path of the projectile, including tiles after collision.
|
||||
//make sure to generate a subPath for the common case of going source to collision.
|
||||
public ArrayList<Integer> path = new ArrayList<>();
|
||||
public Integer sourcePos = null;
|
||||
public Integer collisionPos = null;
|
||||
public Integer dist = 0;
|
||||
|
||||
public static int cast( int from, int to, boolean magic, boolean hitChars ) {
|
||||
//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 terrain(LOS blocking, impassable, etc.)
|
||||
|
||||
public static final int PROJECTILE = STOP_TARGET | STOP_CHARS | STOP_TERRAIN;
|
||||
|
||||
//TODO: consider if we want thrown items to use this, or just have them all be projectileWeapons
|
||||
public static final int THROWN_ITEM = STOP_TARGET | STOP_TERRAIN;
|
||||
|
||||
public static final int MAGIC_BOLT = STOP_CHARS | STOP_TERRAIN;
|
||||
|
||||
public static final int WONT_STOP = 0;
|
||||
|
||||
|
||||
public Ballistica( int from, int to, int params ){
|
||||
sourcePos = from;
|
||||
build(from, to, (params & STOP_TARGET) > 0, (params & STOP_CHARS) > 0, (params & STOP_TERRAIN) > 0);
|
||||
if (collisionPos != null)
|
||||
dist = path.indexOf( collisionPos );
|
||||
else
|
||||
collisionPos = path.get( dist=path.size()-1 );
|
||||
}
|
||||
|
||||
private void build( int from, int to, boolean stopTarget, boolean stopChars, boolean stopTerrain ) {
|
||||
int w = Level.WIDTH;
|
||||
|
||||
int x0 = from % w;
|
||||
|
@ -64,13 +97,23 @@ public class Ballistica {
|
|||
|
||||
}
|
||||
|
||||
distance = 1;
|
||||
trace[0] = from;
|
||||
|
||||
int cell = from;
|
||||
|
||||
int err = dA / 2;
|
||||
while (cell != to || magic) {
|
||||
while (Level.insideMap(cell)) {
|
||||
|
||||
//if we're in a wall, collide with the previous cell along the path.
|
||||
if (stopTerrain && !Level.passable[cell] && !Level.avoid[cell]) {
|
||||
collide(path.get(path.size()-1));
|
||||
}
|
||||
|
||||
path.add(cell);
|
||||
|
||||
if ((stopTerrain && Level.losBlocking[cell])
|
||||
|| (cell != sourcePos && stopChars && Actor.findChar( cell ) != null)
|
||||
|| (cell == to && stopTarget)){
|
||||
collide(cell);
|
||||
}
|
||||
|
||||
cell += stepA;
|
||||
|
||||
|
@ -79,20 +122,23 @@ public class Ballistica {
|
|||
err = err - dA;
|
||||
cell = cell + stepB;
|
||||
}
|
||||
|
||||
trace[distance++] = cell;
|
||||
|
||||
if (!Level.passable[cell] && !Level.avoid[cell]) {
|
||||
return trace[--distance - 1];
|
||||
}
|
||||
|
||||
if (Level.losBlocking[cell] || (hitChars && Actor.findChar( cell ) != null)) {
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
trace[distance++] = cell;
|
||||
//we only want to record the first position collision occurs at.
|
||||
private void collide(int cell){
|
||||
if (collisionPos == null)
|
||||
collisionPos = cell;
|
||||
}
|
||||
|
||||
return to;
|
||||
//returns a segment of the path from start to end, inclusive.
|
||||
//if there is an error, returns an empty arraylist instead.
|
||||
public List<Integer> subPath(int start, int end){
|
||||
try {
|
||||
end = Math.max( end, path.size()-1);
|
||||
return path.subList(start, end+1);
|
||||
} catch (Exception e){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user