protected void wandEffect(final int cell) { setKnown(); QuickSlot.target(curItem, Actor.findChar(cell)); if (curCharges > 0) { getCurUser().busy(); fx( cell, new Callback() { @Override public void call() { onZap(cell); wandUsed(); } }); Invisibility.dispel(getCurUser()); } else { getCurUser().spendAndNext(TIME_TO_ZAP); GLog.w(TXT_FIZZLES); levelKnown = true; if (Random.Int(5) == 0) { identify(); } updateQuickslot(); } }
private void hit(Char ch, int damage) { if (damage < 1) { return; } affected.add(ch); ch.damage( Level.water[ch.pos] && !ch.flying ? (int) (damage * 2) : damage, LightningTrap.LIGHTNING); ch.sprite.centerEmitter().burst(SparkParticle.FACTORY, 3); ch.sprite.flash(); points[nPoints++] = ch.pos; HashSet<Char> ns = new HashSet<Char>(); for (int i = 0; i < Level.NEIGHBOURS8.length; i++) { Char n = Actor.findChar(ch.pos + Level.NEIGHBOURS8[i]); if (n != null && !affected.contains(n)) { ns.add(n); } } if (ns.size() > 0) { hit(Random.element(ns), Random.Int(damage / 2, damage)); } }
@Override public boolean attack(Char enemy) { for (int i = 1; i < Ballistica.distance; i++) { int pos = Ballistica.trace[i]; Char ch = Actor.findChar(pos); if (ch == null) { continue; } if (hit(this, ch, true)) { ch.damage(Random.NormalIntRange(14, 20), this); if (Dungeon.visible[pos]) { ch.getSprite().flash(); CellEmitter.center(pos).burst(PurpleParticle.BURST, Random.IntRange(1, 2)); } if (!ch.isAlive() && ch == Dungeon.hero) { Dungeon.fail( Utils.format(ResultDescriptions.MOB, Utils.indefinite(getName()), Dungeon.depth)); GLog.n(TXT_DEATHGAZE_KILLED, getName()); } } else { ch.getSprite().showStatus(CharSprite.NEUTRAL, ch.defenseVerb()); } } return true; }
private void jump() { timeToJump = JUMP_DELAY; for (int i = 0; i < 4; i++) { int trapPos; do { trapPos = Random.Int(Level.LENGTH); } while (!Level.fieldOfView[trapPos] || !Level.passable[trapPos]); if (Dungeon.level.map[trapPos] == Terrain.INACTIVE_TRAP) { Level.set(trapPos, Terrain.POISON_TRAP); GameScene.updateMap(trapPos); ScrollOfMagicMapping.discover(trapPos); } } int newPos; do { newPos = Random.Int(Level.LENGTH); } while (!Level.fieldOfView[newPos] || !Level.passable[newPos] || (enemy != null && Level.adjacent(newPos, enemy.pos)) || Actor.findChar(newPos) != null); sprite.move(pos, newPos); move(newPos); if (Dungeon.visible[newPos]) { CellEmitter.get(newPos).burst(Speck.factory(Speck.WOOL), 6); Sample.INSTANCE.play(Assets.SND_PUFF); } spend(1 / speed()); }
public boolean handle(int cell) { if (cell == -1) { return false; } Char ch; Heap heap; if (Dungeon.level.map[cell] == Terrain.ALCHEMY && cell != pos) { curAction = new HeroAction.Cook(cell); } else if (Level.fieldOfView[cell] && (ch = Actor.findChar(cell)) instanceof Mob) { if (ch instanceof NPC) { curAction = new HeroAction.Interact((NPC) ch); } else { curAction = new HeroAction.Attack(ch); } } else if ((heap = Dungeon.level.heaps.get(cell)) != null) { switch (heap.type) { case HEAP: curAction = new HeroAction.PickUp(cell); break; case FOR_SALE: curAction = heap.size() == 1 && heap.peek().price() > 0 ? new HeroAction.Buy(cell) : new HeroAction.PickUp(cell); break; default: curAction = new HeroAction.OpenChest(cell); } } else if (Dungeon.level.map[cell] == Terrain.LOCKED_DOOR || Dungeon.level.map[cell] == Terrain.LOCKED_EXIT) { curAction = new HeroAction.Unlock(cell); } else if (cell == Dungeon.level.exit) { curAction = new HeroAction.Descend(cell); } else if (cell == Dungeon.level.entrance) { curAction = new HeroAction.Ascend(cell); } else { curAction = new HeroAction.Move(cell); lastAction = null; } return act(); }
@Override protected void onZap(int cell) { Char ch = Actor.findChar(cell); if (ch != null) { Buff.affect(ch, Poison.class).set(Poison.durationFactor(ch) * (5 + level())); } else { GLog.i(Game.getVar(R.string.WandOfPoison_Info1)); } }
private boolean getCloser(final int target) { if (rooted) { return false; } int step = -1; if (Level.adjacent(pos, target)) { if (Actor.findChar(target) == null) { if (Level.pit[target] && !flying && !Chasm.jumpConfirmed) { Chasm.heroJump(this); interrupt(); return false; } if (Level.passable[target] || Level.avoid[target]) { step = target; } } } else { int len = Level.LENGTH; boolean[] p = Level.passable; boolean[] v = Dungeon.level.visited; boolean[] m = Dungeon.level.mapped; boolean[] passable = new boolean[len]; for (int i = 0; i < len; i++) { passable[i] = p[i] && (v[i] || m[i]); } step = Dungeon.findPath(this, pos, target, passable, Level.fieldOfView); } if (step != -1) { int oldPos = pos; move(step); sprite.move(oldPos, pos); spend(1 / speed()); return true; } else { return false; } }
@Override protected void evolve() { for (int i = 0; i < LENGTH; i++) { int offv = cur[i] > 0 ? cur[i] - 1 : 0; off[i] = offv; if (offv > 0) { volume += offv; Char ch = Actor.findChar(i); if (ch != null) { Buff.prolong(ch, Roots.class, TICK); } } } }
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) { 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); }