public void count_cmd() throws CivException {
    Player player = getPlayer();

    HashMap<String, Integer> amounts = new HashMap<String, Integer>();
    int total = CommonCustomMob.customMobs.size();
    for (CommonCustomMob mob : CommonCustomMob.customMobs.values()) {
      Integer count = amounts.get(mob.getClass().getSimpleName());
      if (count == null) {
        count = 0;
      }

      amounts.put(mob.getClass().getSimpleName(), count + 1);
    }

    CivMessage.sendHeading(player, "Custom Mob Counts");
    CivMessage.send(
        player,
        CivColor.LightGray
            + "Red mobs are over their count limit for this area and should no longer spawn.");
    for (String mob : amounts.keySet()) {
      int count = amounts.get(mob);

      LinkedList<Entity> entities =
          EntityProximity.getNearbyEntities(
              null, player.getLocation(), MobSpawnerTimer.MOB_AREA, EntityCreature.class);
      if (entities.size() > MobSpawnerTimer.MOB_AREA_LIMIT) {
        CivMessage.send(player, CivColor.Red + mob + ": " + CivColor.Rose + count);
      } else {
        CivMessage.send(player, CivColor.Green + mob + ": " + CivColor.LightGreen + count);
      }
    }
    CivMessage.send(player, CivColor.Green + "Total Mobs:" + CivColor.LightGreen + total);
  }
  @Override
  public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {

    if (!(sender instanceof Player)) {
      CivMessage.sendError(sender, "Only a player can execute this command.");
      return false;
    }

    Player player = (Player) sender;
    player.setHealth(0);

    CivMessage.send(sender, CivColor.Yellow + CivColor.BOLD + "You couldn't take it anymore.");

    return true;
  }
  public void disable_cmd() throws CivException {
    Player player = getPlayer();
    String name = getNamedString(1, "Enter a mob name");

    switch (name.toLowerCase()) {
      case "yobo":
        CommonCustomMob.disabledMobs.add(CustomMobType.YOBO.toString());
        break;
      case "angryyobo":
        CommonCustomMob.disabledMobs.add(CustomMobType.ANGRYYOBO.toString());
        break;
      case "savage":
        CommonCustomMob.disabledMobs.add(CustomMobType.SAVAGE.toString());
        break;
      case "ruffian":
        CommonCustomMob.disabledMobs.add(CustomMobType.RUFFIAN.toString());
        break;
      case "behemoth":
        CommonCustomMob.disabledMobs.add(CustomMobType.BEHEMOTH.toString());
        break;
      default:
        throw new CivException("Invalid mob. Make sure it is spelled right!");
    }
    CivMessage.sendSuccess(player, "Disabled " + name);
  }
  @Override
  public void repairStructure() throws CivException {
    double cost = getRepairCost();

    if (!this.isValidWall()) {
      throw new CivException(
          "This wall is no longer valid and cannot be repaired. Walls can no longer overlap with protected structure blocks, demolish this wall instead.");
    }

    if (!getTown().getTreasury().hasEnough(cost)) {
      throw new CivException(
          "Your town cannot not afford the " + cost + " coins to build a " + getDisplayName());
    }

    setHitpoints(this.getMaxHitPoints());
    bindStructureBlocks();

    for (WallBlock wb : this.wallBlocks.values()) {
      BlockCoord bcoord = wb.getCoord();
      ItemManager.setTypeId(bcoord.getBlock(), wb.getTypeId());
      ItemManager.setData(bcoord.getBlock(), wb.getData());
    }

    save();
    getTown().getTreasury().withdraw(cost);
    CivMessage.sendTown(
        getTown(),
        CivColor.Yellow + "The town has repaired a " + getDisplayName() + " at " + getCorner());
  }
  @Override
  public void processUndo() throws CivException {

    double refund = 0.0;
    for (WallBlock wb : wallBlocks.values()) {

      Material material = ItemManager.getMaterial(wb.getOldId());
      if (CivSettings.restrictedUndoBlocks.contains(material)) {
        continue;
      }

      ItemManager.setTypeId(wb.getCoord().getBlock(), wb.getOldId());
      ItemManager.setData(wb.getCoord().getBlock(), wb.getOldData());
      refund += COST_PER_SEGMENT;
      try {
        wb.delete();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }

    refund /= HEIGHT;
    refund = Math.round(refund);
    this.getTown().getTreasury().deposit(refund);
    CivMessage.sendTown(
        this.getTown(), CivColor.Yellow + "Refunded " + refund + " coins from wall construction.");
    try {
      this.delete();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  public void killall_cmd() throws CivException {
    Player player = getPlayer();
    String name = getNamedString(1, "Enter a mob name");

    LinkedList<CommonCustomMob> removeUs = new LinkedList<CommonCustomMob>();
    for (CommonCustomMob mob : CommonCustomMob.customMobs.values()) {
      if (mob.getType().toString().equalsIgnoreCase(name)) {
        removeUs.add(mob);
      }
    }

    int count = 0;
    for (CommonCustomMob mob : removeUs) {
      CommonCustomMob.customMobs.remove(mob.entity.getUniqueID());
      mob.entity.getBukkitEntity().remove();
      count++;
    }
    CivMessage.sendSuccess(player, "Removed " + count + " mobs of type " + name);
  }
  public void onHit() {
    // launchExplodeFirework(loc);

    int radius = (int) yield;
    HashSet<Buildable> structuresHit = new HashSet<Buildable>();

    for (int x = -radius; x < radius; x++) {
      for (int z = -radius; z < radius; z++) {
        for (int y = -radius; y < radius; y++) {

          Block b = loc.getBlock().getRelative(x, y, z);
          if (ItemManager.getId(b) == CivData.BEDROCK) {
            continue;
          }

          if (loc.distance(b.getLocation()) <= yield) {
            bcoord.setFromLocation(b.getLocation());
            StructureBlock sb = CivGlobal.getStructureBlock(bcoord);
            CampBlock cb = CivGlobal.getCampBlock(bcoord);

            if (sb == null && cb == null) {
              explodeBlock(b);
              continue;
            }

            if (sb != null) {

              if (!sb.isDamageable()) {
                continue;
              }

              if (sb.getOwner() instanceof TownHall) {
                TownHall th = (TownHall) sb.getOwner();
                if (th.getControlPoints().containsKey(bcoord)) {
                  continue;
                }
              }

              if (!sb.getOwner().isDestroyed()) {
                if (!structuresHit.contains(sb.getOwner())) {

                  structuresHit.add(sb.getOwner());

                  if (sb.getOwner() instanceof TownHall) {
                    TownHall th = (TownHall) sb.getOwner();

                    if (th.getHitpoints() == 0) {
                      explodeBlock(b);
                    } else {
                      th.onCannonDamage(cannon.getDamage());
                    }
                  } else {
                    Player player = null;
                    try {
                      player = CivGlobal.getPlayer(whoFired);
                    } catch (CivException e) {
                    }

                    if (!sb.getCiv().getDiplomacyManager().atWarWith(whoFired.getCiv())) {
                      if (player != null) {
                        CivMessage.sendError(
                            player,
                            "Cannot damage structures in civilizations we're not at war with.");
                        return;
                      }
                    }

                    sb.getOwner()
                        .onDamage(cannon.getDamage(), b.getWorld(), player, sb.getCoord(), sb);
                    CivMessage.sendCiv(
                        sb.getCiv(),
                        CivColor.Yellow
                            + "Our "
                            + sb.getOwner().getDisplayName()
                            + " at ("
                            + sb.getOwner().getCenterLocation().getX()
                            + ","
                            + sb.getOwner().getCenterLocation().getY()
                            + ","
                            + sb.getOwner().getCenterLocation().getZ()
                            + ")"
                            + " was hit by a cannon! ("
                            + sb.getOwner().getHitpoints()
                            + "/"
                            + sb.getOwner().getMaxHitPoints()
                            + ")");
                  }

                  CivMessage.sendCiv(
                      whoFired.getCiv(),
                      CivColor.LightGreen
                          + "We've hit "
                          + sb.getOwner().getTown().getName()
                          + "'s "
                          + sb.getOwner().getDisplayName()
                          + " with a cannon!"
                          + " ("
                          + sb.getOwner().getHitpoints()
                          + "/"
                          + sb.getOwner().getMaxHitPoints()
                          + ")");
                }
              } else {

                if (!IronCannon.cannonBlocks.containsKey(bcoord)) {
                  explodeBlock(b);
                }
              }
              continue;
            }
          }
        }
      }
    }

    /* Instantly kill any players caught in the blast. */
    LinkedList<Entity> players =
        EntityProximity.getNearbyEntities(null, loc, yield, EntityPlayer.class);
    for (Entity e : players) {
      Player player = (Player) e;
      player.damage(playerDamage);
      if (player.isDead()) {
        CivMessage.global(
            CivColor.LightGray
                + whoFired.getName()
                + " obliterated "
                + player.getName()
                + " with a cannon blast!");
      }
    }
  }
  @Override
  public void onMarkerPlacement(Player player, Location next, ArrayList<Location> locs)
      throws CivException {
    BlockCoord first = new BlockCoord(next);
    BlockCoord second = null;

    CultureChunk cc = CivGlobal.getCultureChunk(next);
    if (cc == null || cc.getTown().getCiv() != this.getTown().getCiv()) {
      throw new CivException("Cannot build here, you need to build inside your culture.");
    }

    if (locs.size() <= 1) {
      CivMessage.send(
          player,
          CivColor.LightGray + "First location placed, place another to start building a wall.");
      return;
    }

    // Validate our locations
    if (locs.get(0).distance(locs.get(1)) > Wall.MAX_SEGMENT) {
      throw new CivException(
          "Can only build a wall in "
              + Wall.MAX_SEGMENT
              + " block segments, pick a closer location");
    }

    second = new BlockCoord(locs.get(0));
    locs.clear();
    MarkerPlacementManager.removeFromPlacementMode(player, false);

    Location secondLoc = second.getLocation();
    // Setting to a new block coord so we can increment in buildWallSegment without changing the
    // corner.
    this.setCorner(new BlockCoord(secondLoc));
    this.setComplete(true);
    this.save();

    // We should now be able to draw a line between these two block points.
    HashMap<String, SimpleBlock> simpleBlocks = new HashMap<String, SimpleBlock>();
    int verticalSegments = this.buildWallSegment(player, first, second, 0, simpleBlocks, 0);

    // Pay the piper
    double cost = verticalSegments * COST_PER_SEGMENT;
    if (!this.getTown().getTreasury().hasEnough(cost)) {

      for (WallBlock wb : this.wallBlocks.values()) {
        try {
          wb.delete();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      }
      this.wallBlocks.clear();

      throw new CivException(
          "Cannot build, not enough coins to pay "
              + cost
              + " coins for wall of length "
              + verticalSegments
              + " blocks.");
    }

    this.getTown().getTreasury().withdraw(cost);

    CivMessage.sendTown(
        this.getTown(),
        CivColor.Yellow + "Paid " + cost + " coins for " + verticalSegments + " wall segments.");

    // build the blocks
    for (SimpleBlock sb : simpleBlocks.values()) {
      BlockCoord bcoord = new BlockCoord(sb);
      ItemManager.setTypeId(bcoord.getBlock(), sb.getType());
      ItemManager.setData(bcoord.getBlock(), sb.getData());
    }

    // Add wall to town and global tables
    this.getTown().addStructure(this);
    CivGlobal.addStructure(this);
    this.getTown().lastBuildableBuilt = this;
  }