Java源码示例:com.watabou.utils.PathFinder
示例1
@Override
protected void activate(int cell) {
for (int i : PathFinder.NEIGHBOURS9){
if (!Dungeon.level.solid[cell + i]
&& !Dungeon.level.pit[cell + i]
&& Actor.findChar(cell + i) == null) {
Sheep sheep = new Sheep();
sheep.lifespan = Random.IntRange(5, 8);
sheep.pos = cell + i;
GameScene.add(sheep);
Dungeon.level.occupyCell(sheep);
CellEmitter.get(sheep.pos).burst(Speck.factory(Speck.WOOL), 4);
}
}
CellEmitter.get(cell).burst(Speck.factory(Speck.WOOL), 4);
Sample.INSTANCE.play(Assets.Sounds.PUFF);
}
示例2
@Override
public void shatter( int cell ) {
if (Dungeon.level.heroFOV[cell]) {
setKnown();
splash( cell );
Sample.INSTANCE.play( Assets.SND_SHATTER );
}
for (int offset : PathFinder.NEIGHBOURS9){
if (!Dungeon.level.solid[cell+offset]) {
GameScene.add(Blob.seed(cell + offset, 2, Fire.class));
}
}
}
示例3
@Override
public void onSelect(Integer target) {
if (target != null && (Dungeon.level.visited[target] || Dungeon.level.mapped[target])){
//chains cannot be used to go where it is impossible to walk to
PathFinder.buildDistanceMap(target, BArray.or(Dungeon.level.passable, Dungeon.level.avoid, null));
if (PathFinder.distance[curUser.pos] == Integer.MAX_VALUE){
GLog.w( Messages.get(EtherealChains.class, "cant_reach") );
return;
}
final Ballistica chain = new Ballistica(curUser.pos, target, Ballistica.STOP_TARGET);
if (Actor.findChar( chain.collisionPos ) != null){
chainEnemy( chain, curUser, Actor.findChar( chain.collisionPos ));
} else {
chainLocation( chain, curUser );
}
throwSound();
Sample.INSTANCE.play( Assets.Sounds.CHAINS );
}
}
示例4
public static int flee( Char ch, int cur, int from, boolean pass[], boolean[] visible ) {
if (ch.flying) {
BArray.or( pass, Level.avoid, passable );
} else {
System.arraycopy( pass, 0, passable, 0, Level.LENGTH );
}
for (Actor actor : Actor.all()) {
if (actor instanceof Char) {
int pos = ((Char)actor).pos;
if (visible[pos]) {
passable[pos] = false;
}
}
}
passable[cur] = true;
return PathFinder.getStepBack( cur, from, passable );
}
示例5
@Override
public int damageRoll() {
int min = 1;
int max = (HP*2 <= HT) ? 12 : 8;
if (pumpedUp > 0) {
pumpedUp = 0;
PathFinder.buildDistanceMap( pos, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE)
CellEmitter.get(i).burst(ElmoParticle.FACTORY, 10);
}
Sample.INSTANCE.play( Assets.SND_BURNING );
return Random.NormalIntRange( min*3, max*3 );
} else {
return Random.NormalIntRange( min, max );
}
}
示例6
public static int findPath( Char ch, int from, int to, boolean pass[], boolean[] visible ) {
if (Level.adjacent( from, to )) {
return Actor.findChar( to ) == null && (pass[to] || Level.avoid[to]) ? to : -1;
}
if (ch.flying || ch.buff( Amok.class ) != null || ch.buff( Rage.class ) != null) {
BArray.or( pass, Level.avoid, passable );
} else {
System.arraycopy( pass, 0, passable, 0, Level.LENGTH );
}
for (Actor actor : Actor.all()) {
if (actor instanceof Char) {
int pos = ((Char)actor).pos;
if (visible[pos]) {
passable[pos] = false;
}
}
}
return PathFinder.getStep( from, to, passable );
}
示例7
@Override
public void activate( Char ch ) {
if (ch instanceof Hero && ((Hero) ch).subClass == HeroSubClass.WARDEN){
Buff.affect(ch, FrostImbue.class, FrostImbue.DURATION*0.3f);
}
PathFinder.buildDistanceMap( pos, BArray.not( Dungeon.level.losBlocking, null ), 1 );
Fire fire = (Fire)Dungeon.level.blobs.get( Fire.class );
for (int i=0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
Freezing.affect( i, fire );
}
}
}
示例8
@Override
public void explode(int cell) {
super.explode(cell);
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
if (Dungeon.level.insideMap(i)
&& Actor.findChar(i) == null
&& !(Dungeon.level.pit[i])) {
Sheep sheep = new Sheep();
sheep.lifespan = Random.NormalIntRange( 8, 16 );
sheep.pos = i;
Dungeon.level.occupyCell(sheep);
GameScene.add(sheep);
CellEmitter.get(i).burst(Speck.factory(Speck.WOOL), 4);
}
}
}
Sample.INSTANCE.play(Assets.SND_PUFF);
}
示例9
@Override
public void onSelect(Integer target) {
if (target != null && (Dungeon.level.visited[target] || Dungeon.level.mapped[target])){
//chains cannot be used to go where it is impossible to walk to
PathFinder.buildDistanceMap(target, BArray.or(Dungeon.level.passable, Dungeon.level.avoid, null));
if (PathFinder.distance[curUser.pos] == Integer.MAX_VALUE){
GLog.w( Messages.get(EtherealChains.class, "cant_reach") );
return;
}
final Ballistica chain = new Ballistica(curUser.pos, target, Ballistica.STOP_TARGET);
if (Actor.findChar( chain.collisionPos ) != null){
chainEnemy( chain, curUser, Actor.findChar( chain.collisionPos ));
} else {
chainLocation( chain, curUser );
}
}
}
示例10
@Override
protected void activate(int cell) {
for (int i : PathFinder.NEIGHBOURS9){
if (!Dungeon.level.solid[cell + i]
&& !Dungeon.level.pit[cell + i]
&& Actor.findChar(cell + i) == null) {
Sheep sheep = new Sheep();
sheep.lifespan = Random.IntRange(5, 8);
sheep.pos = cell + i;
GameScene.add(sheep);
Dungeon.level.occupyCell(sheep);
CellEmitter.get(sheep.pos).burst(Speck.factory(Speck.WOOL), 4);
}
}
CellEmitter.get(cell).burst(Speck.factory(Speck.WOOL), 4);
Sample.INSTANCE.play(Assets.SND_PUFF);
}
示例11
@Override
protected void onZap(Ballistica bolt) {
CorrosiveGas gas = Blob.seed(bolt.collisionPos, 50 + 10 * buffedLvl(), CorrosiveGas.class);
CellEmitter.get(bolt.collisionPos).burst(Speck.factory(Speck.CORROSION), 10 );
gas.setStrength(2 + buffedLvl());
GameScene.add(gas);
Sample.INSTANCE.play(Assets.Sounds.GAS);
for (int i : PathFinder.NEIGHBOURS9) {
Char ch = Actor.findChar(bolt.collisionPos + i);
if (ch != null) {
processSoulMark(ch, chargesPerCast());
}
}
if (Actor.findChar(bolt.collisionPos) == null){
Dungeon.level.pressCell(bolt.collisionPos);
}
}
示例12
@Override
public void die( Object cause ) {
super.die( cause );
Dungeon.level.unseal();
GameScene.bossSlain();
Dungeon.level.drop( new SkeletonKey( Dungeon.depth ), pos ).sprite.drop();
//60% chance of 2 blobs, 30% chance of 3, 10% chance for 4. Average of 2.5
int blobs = Random.chances(new float[]{0, 0, 6, 3, 1});
for (int i = 0; i < blobs; i++){
int ofs;
do {
ofs = PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (!Dungeon.level.passable[pos + ofs]);
Dungeon.level.drop( new GooBlob(), pos + ofs ).sprite.drop( pos );
}
Badges.validateBossSlain();
yell( Messages.get(this, "defeated") );
}
示例13
@Override
public void activate( Char ch ) {
int nSeeds = Random.NormalIntRange(2, 4);
ArrayList<Integer> candidates = new ArrayList<>();
for (int i : PathFinder.NEIGHBOURS8){
if (Dungeon.level.passable[pos+i]
&& pos+i != Dungeon.level.entrance
&& pos+i != Dungeon.level.exit){
candidates.add(pos+i);
}
}
for (int i = 0; i < nSeeds && !candidates.isEmpty(); i++){
Integer c = Random.element(candidates);
Dungeon.level.drop(Generator.random(Generator.Category.SEED), c).sprite.drop(pos);
candidates.remove(c);
}
}
示例14
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);
ally.state = ally.WANDERING;
if (!candidatePositions.isEmpty()){
ally.pos = candidatePositions.remove(0);
} else {
ally.pos = pos;
}
}
}
heldAllies.clear();
}
示例15
@Override
public void activate( Char ch ) {
int nSeeds = Random.NormalIntRange(2, 4);
ArrayList<Integer> candidates = new ArrayList<>();
for (int i : PathFinder.NEIGHBOURS8){
if (Dungeon.level.passable[pos+i]
&& pos+i != Dungeon.level.entrance
&& pos+i != Dungeon.level.exit){
candidates.add(pos+i);
}
}
for (int i = 0; i < nSeeds && !candidates.isEmpty(); i++){
Integer c = Random.element(candidates);
Dungeon.level.drop(Generator.random(Generator.Category.SEED), c).sprite.drop(pos);
candidates.remove(c);
}
}
示例16
@Override
protected void onThrow( int cell ) {
if (Dungeon.level.map[cell] == Terrain.ALCHEMY
|| Dungeon.level.pit[cell]
|| Dungeon.level.traps.get(cell) != null
|| Dungeon.isChallenged(Challenges.NO_HERBALISM)) {
super.onThrow( cell );
} else {
Dungeon.level.plant( this, cell );
if (Dungeon.hero.subClass == HeroSubClass.WARDEN) {
for (int i : PathFinder.NEIGHBOURS8) {
int c = Dungeon.level.map[cell + i];
if ( c == Terrain.EMPTY || c == Terrain.EMPTY_DECO
|| c == Terrain.EMBERS || c == Terrain.GRASS){
Level.set(cell + i, Terrain.FURROWED_GRASS);
GameScene.updateMap(cell + i);
CellEmitter.get( cell + i ).burst( LeafParticle.LEVEL_SPECIFIC, 4 );
}
}
}
}
}
示例17
public void teleportEnemy(){
spend(TICK);
int bestPos = enemy.pos;
for (int i : PathFinder.NEIGHBOURS8){
if (Dungeon.level.passable[pos + i]
&& Actor.findChar(pos+i) == null
&& Dungeon.level.trueDistance(pos+i, enemy.pos) > Dungeon.level.trueDistance(bestPos, enemy.pos)){
bestPos = pos+i;
}
}
if (enemy.buff(MagicImmune.class) != null){
bestPos = enemy.pos;
}
if (bestPos != enemy.pos){
ScrollOfTeleportation.appear(enemy, bestPos);
if (enemy instanceof Hero){
((Hero) enemy).interrupt();
Dungeon.observe();
}
}
enemyTeleCooldown = 20;
}
示例18
public static int autoAim(Char target, Item item){
//first try to directly target
if (item.throwPos(Dungeon.hero, target.pos) == target.pos) {
return target.pos;
}
//Otherwise pick nearby tiles to try and 'angle' the shot, auto-aim basically.
PathFinder.buildDistanceMap( target.pos, BArray.not( new boolean[Dungeon.level.length()], null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE
&& item.throwPos(Dungeon.hero, i) == target.pos)
return i;
}
//couldn't find a cell, give up.
return -1;
}
示例19
private void arc( Char ch ) {
int dist = (Dungeon.level.water[ch.pos] && !ch.flying) ? 2 : 1;
ArrayList<Char> hitThisArc = new ArrayList<>();
PathFinder.buildDistanceMap( ch.pos, BArray.not( Dungeon.level.solid, null ), dist );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE){
Char n = Actor.findChar( i );
if (n == Dungeon.hero && PathFinder.distance[i] > 1)
//the hero is only zapped if they are adjacent
continue;
else if (n != null && !affected.contains( n )) {
hitThisArc.add(n);
}
}
}
affected.addAll(hitThisArc);
for (Char hit : hitThisArc){
arcs.add(new Lightning.Arc(ch.sprite.center(), hit.sprite.center()));
arc(hit);
}
}
示例20
public static PathFinder.Path findPath(Char ch, int to, boolean[] pass, boolean[] vis, boolean chars) {
setupPassable();
if (ch.flying || ch.buff( Amok.class ) != null) {
BArray.or( pass, Dungeon.level.avoid, passable );
} else {
System.arraycopy( pass, 0, passable, 0, Dungeon.level.length() );
}
if (Char.hasProp(ch, Char.Property.LARGE)){
BArray.and( pass, Dungeon.level.openSpace, passable );
}
if (chars) {
for (Char c : Actor.chars()) {
if (vis[c.pos]) {
passable[c.pos] = false;
}
}
}
return PathFinder.find( ch.pos, to, passable );
}
示例21
@Override
protected void affectTarget(Ballistica bolt, Hero hero) {
int cell = bolt.collisionPos;
Splash.at(cell, 0x00AAFF, 10);
for (int i : PathFinder.NEIGHBOURS9){
if (i == 0 || Random.Int(5) != 0){
Dungeon.level.setCellToWater(false, cell+i);
}
}
Char target = Actor.findChar(cell);
if (target != null && target != hero){
//just enough to skip their current turn
Buff.affect(target, Paralysis.class, 0f);
}
}
示例22
public static int findPath( Char ch, int from, int to, boolean pass[], boolean[] visible ) {
if (Level.adjacent( from, to )) {
return Actor.findChar( to ) == null && (pass[to] || Level.avoid[to] && !(ch instanceof Piranha)) ? to : -1;
}
if (ch.flying || ch.buff( Tormented.class ) != null ||
ch.buff( Blinded.class ) != null || ch.buff( Vertigo.class ) != null
) {
BArray.or( pass, Level.avoid, passable );
} else {
System.arraycopy( pass, 0, passable, 0, Level.LENGTH );
}
if (ch instanceof Mob && !(ch instanceof Piranha)) {
BArray.or( passable, Level.illusory, passable );
}
for (Actor actor : Actor.all()) {
if (actor instanceof Char) {
int pos = ((Char)actor).pos;
if (visible[pos] && ((Char) actor).invisible == 0) {
passable[pos] = false;
}
}
}
return PathFinder.getStep( from, to, passable );
}
示例23
@Override
public void activate() {
//use an actor as we want to put this on a slight delay so all chars get a chance to act this turn first.
Actor.add(new Actor() {
{ actPriority = BUFF_PRIO; }
protected boolean act() {
PathFinder.buildDistanceMap( pos, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {
Trap t;
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
if (Dungeon.level.insideMap(i)
&& Actor.findChar(i) == null
&& !(Dungeon.level.pit[i])) {
Sheep sheep = new Sheep();
sheep.lifespan = Random.NormalIntRange( 4, 8 );
sheep.pos = i;
GameScene.add(sheep);
CellEmitter.get(i).burst(Speck.factory(Speck.WOOL), 4);
//before the tile is pressed, directly trigger traps to avoid sfx spam
if ((t = Dungeon.level.traps.get(i)) != null && t.active){
t.disarm();
t.reveal();
t.activate();
}
Dungeon.level.occupyCell(sheep);
}
}
}
Sample.INSTANCE.play(Assets.SND_PUFF);
Actor.remove(this);
return true;
}
});
}
示例24
@Override
protected void onThrow(int cell) {
if (Dungeon.level.pit[cell]){
super.onThrow(cell);
return;
}
Dungeon.level.pressCell(cell);
ArrayList<Char> targets = new ArrayList<>();
if (Actor.findChar(cell) != null) targets.add(Actor.findChar(cell));
for (int i : PathFinder.NEIGHBOURS8){
if (!(Dungeon.level.traps.get(cell+i) instanceof TenguDartTrap)) Dungeon.level.pressCell(cell+i);
if (Actor.findChar(cell + i) != null) targets.add(Actor.findChar(cell + i));
}
for (Char target : targets){
curUser.shoot(target, this);
if (target == Dungeon.hero && !target.isAlive()){
Dungeon.fail(getClass());
GLog.n(Messages.get(this, "ondeath"));
}
}
rangedHit( null, cell );
WandOfBlastWave.BlastWave.blast(cell);
Sample.INSTANCE.play( Assets.Sounds.BLAST );
}
示例25
@Override
public void activate() {
PathFinder.buildDistanceMap( pos, BArray.not( Level.losBlocking, null ), 1 );
Fire fire = (Fire)Dungeon.level.blobs.get( Fire.class );
for (int i=0; i < Level.LENGTH; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
Freezing.affect( i, fire );
}
}
}
示例26
@Override
protected void activate(int cell) {
Sample.INSTANCE.play( Assets.SND_LIGHTNING );
ArrayList<Lightning.Arc> arcs = new ArrayList<>();
int hits = 0;
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
Char n = Actor.findChar(i);
if (n != null) {
arcs.add(new Lightning.Arc(cell, n.sprite.center()));
Buff.prolong(n, Paralysis.class, 1f);
hits++;
}
}
}
CellEmitter.center( cell ).burst( SparkParticle.FACTORY, 3 );
if (hits > 0) {
curUser.sprite.parent.addToFront( new Lightning( arcs, null ) );
curUser.sprite.centerEmitter().burst(EnergyParticle.FACTORY, 10);
Sample.INSTANCE.play( Assets.SND_LIGHTNING );
curUser.belongings.charge(1f + hits);
}
}
示例27
@Override
protected void decorate(Level level, ArrayList<Room> rooms) {
int[] map = level.map;
int w = level.width();
int l = level.length();
for (int i=w + 1; i < l - w - 1; i++) {
if (map[i] == Terrain.EMPTY) {
int count = 0;
for (int j = 0; j < PathFinder.NEIGHBOURS8.length; j++) {
if ((Terrain.flags[map[i + PathFinder.NEIGHBOURS8[j]]] & Terrain.PASSABLE) > 0) {
count++;
}
}
if (Random.Int( 80 ) < count) {
map[i] = Terrain.EMPTY_DECO;
}
} else
if (map[i] == Terrain.WALL &&
map[i-1] != Terrain.WALL_DECO && map[i-w] != Terrain.WALL_DECO &&
Random.Int( 20 ) == 0) {
map[i] = Terrain.WALL_DECO;
}
}
}
示例28
public void move( int step ) {
if (Dungeon.level.adjacent( step, pos ) && buff( Vertigo.class ) != null) {
sprite.interruptMotion();
int newPos = pos + PathFinder.NEIGHBOURS8[Random.Int( 8 )];
if (!(Dungeon.level.passable[newPos] || Dungeon.level.avoid[newPos])
|| (properties.contains(Property.LARGE) && !Dungeon.level.openSpace[pos])
|| Actor.findChar( newPos ) != null)
return;
else {
sprite.move(pos, newPos);
step = newPos;
}
}
if (Dungeon.level.map[pos] == Terrain.OPEN_DOOR) {
Door.leave( pos );
}
pos = step;
if (this != Dungeon.hero) {
sprite.visible = Dungeon.level.heroFOV[pos];
}
Dungeon.level.occupyCell(this );
}
示例29
@Override
public void onSelect( Integer target ) {
if (target != null) {
PathFinder.buildDistanceMap(curUser.pos, Dungeon.level.passable, 8);
if ( PathFinder.distance[target] == Integer.MAX_VALUE ||
!Dungeon.level.heroFOV[target] ||
!(Dungeon.level.passable[target] || Dungeon.level.avoid[target]) ||
Actor.findChar( target ) != null) {
GLog.w( Messages.get(RogueArmor.class, "fov") );
return;
}
curUser.HP -= (curUser.HP / 3);
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) {
if (Dungeon.level.heroFOV[mob.pos] && mob.alignment != Char.Alignment.ALLY) {
Buff.prolong( mob, Blindness.class, 2 );
if (mob.state == mob.HUNTING) mob.state = mob.WANDERING;
mob.sprite.emitter().burst( Speck.factory( Speck.LIGHT ), 4 );
}
}
ScrollOfTeleportation.appear( curUser, target );
CellEmitter.get( target ).burst( Speck.factory( Speck.WOOL ), 10 );
Sample.INSTANCE.play( Assets.SND_PUFF );
Dungeon.level.occupyCell(curUser );
Dungeon.observe();
GameScene.updateFog();
curUser.spendAndNext( Actor.TICK );
}
}
示例30
@Override
public void die( Object cause ) {
super.die( cause );
GameScene.bossSlain();
Dungeon.level.unseal();
//60% chance of 2 shards, 30% chance of 3, 10% chance for 4. Average of 2.5
int shards = Random.chances(new float[]{0, 0, 6, 3, 1});
for (int i = 0; i < shards; i++){
int ofs;
do {
ofs = PathFinder.NEIGHBOURS8[Random.Int(8)];
} while (!Dungeon.level.passable[pos + ofs]);
Dungeon.level.drop( new MetalShard(), pos + ofs ).sprite.drop( pos );
}
Badges.validateBossSlain();
LloydsBeacon beacon = Dungeon.hero.belongings.getItem(LloydsBeacon.class);
if (beacon != null) {
beacon.upgrade();
}
yell( Messages.get(this, "defeated") );
}