@Override
 public void activate() {
   for (int i : Level.NEIGHBOURS9DIST2) {
     if (Level.insideMap(pos + i) && !Level.solid[pos + i]) {
       if (Level.pit[pos + i] || Level.water[pos + i])
         GameScene.add(Blob.seed(pos + i, 1, Fire.class));
       else GameScene.add(Blob.seed(pos + i, 5, Fire.class));
       CellEmitter.get(pos + i).burst(FlameParticle.FACTORY, 5);
     }
   }
   Sample.INSTANCE.play(Assets.SND_BURNING);
 }
  @Override
  public void execute(Hero hero, String action) {
    if (action.equals(AC_READ)) {

      if (hero.buff(Blindness.class) != null)
        GLog.w("You cannot read from the book while blinded.");
      else if (!isEquipped(hero)) GLog.i("You need to equip your spellbook to do that.");
      else if (charge == 0) GLog.i("Your spellbook is out of energy for now.");
      else if (cursed) GLog.i("Your cannot read from a cursed spellbook.");
      else {
        charge--;

        Scroll scroll;
        do {
          scroll = (Scroll) Generator.random(Generator.Category.SCROLL);
        } while (scroll == null
            ||
            // gotta reduce the rate on these scrolls or that'll be all the item does.
            ((scroll instanceof ScrollOfIdentify
                    || scroll instanceof ScrollOfRemoveCurse
                    || scroll instanceof ScrollOfMagicMapping)
                && Random.Int(2) == 0));

        scroll.ownedByBook = true;
        scroll.execute(hero, AC_READ);
      }

    } else if (action.equals(AC_ADD)) {
      GameScene.selectItem(itemSelector, mode, inventoryTitle);
    } else super.execute(hero, action);
  }
  @Override
  public boolean act() {
    if (Dungeon.level.map[target.pos] == Terrain.GRASS) {
      Dungeon.level.set(target.pos, Terrain.EMBERS);
      GameScene.updateMap(target.pos);
    }

    spend(TICK);
    left -= TICK;
    if (left <= 0) detach();

    return true;
  }
  @Override
  public void activate() {

    for (Mob mob : Dungeon.level.mobs) {
      mob.beckon(pos);
    }

    if (Dungeon.visible[pos]) {
      GLog.w("The trap emits a piercing sound that echoes throughout the dungeon!");
      CellEmitter.center(pos).start(Speck.factory(Speck.SCREAM), 0.3f, 3);
    }

    Sample.INSTANCE.play(Assets.SND_ALERT);

    for (int i = 0; i < (Dungeon.depth - 5) / 5; i++) {
      Guardian guardian = new Guardian();
      guardian.state = guardian.WANDERING;
      guardian.pos = Dungeon.level.randomRespawnCell();
      GameScene.add(guardian);
      guardian.beckon(Dungeon.hero.pos);
    }
  }
 @Override
 protected void onZap(Ballistica bolt) {
   Blob venomGas = Blob.seed(bolt.collisionPos, 50 + 10 * level, VenomGas.class);
   ((VenomGas) venomGas).setStrength(level + 1);
   GameScene.add(venomGas);
 }