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") );
}