@Override
    public void run() {
      L2RaidBossInstance raidboss = null;

      if (bossId == 25328)
        raidboss = DayNightSpawnManager.getInstance().handleBoss(_spawns.get(bossId));
      else raidboss = (L2RaidBossInstance) _spawns.get(bossId).doSpawn();

      if (raidboss != null) {
        raidboss.setRaidStatus(StatusEnum.ALIVE);

        final StatsSet info = new StatsSet();
        info.set("currentHP", raidboss.getCurrentHp());
        info.set("currentMP", raidboss.getCurrentMp());
        info.set("respawnTime", 0L);

        _storedInfo.put(bossId, info);

        _log.info("RaidBoss: " + raidboss.getName() + " has spawned.");

        _bosses.put(bossId, raidboss);
      }

      _schedules.remove(bossId);
    }
  private void updateDb() {
    try (Connection con = L2DatabaseFactory.getInstance().getConnection()) {
      PreparedStatement statement =
          con.prepareStatement(
              "UPDATE raidboss_spawnlist SET respawn_time = ?, currentHP = ?, currentMP = ? WHERE boss_id = ?");

      for (Integer bossId : _storedInfo.keySet()) {
        if (bossId == null) continue;

        final L2RaidBossInstance boss = _bosses.get(bossId);
        if (boss == null) continue;

        if (boss.getRaidStatus().equals(StatusEnum.ALIVE)) updateStatus(boss, false);

        final StatsSet info = _storedInfo.get(bossId);
        if (info == null) continue;

        try {
          statement.setLong(1, info.getLong("respawnTime"));
          statement.setDouble(2, info.getDouble("currentHP"));
          statement.setDouble(3, info.getDouble("currentMP"));
          statement.setInt(4, bossId);
          statement.executeUpdate();
          statement.clearParameters();
        } catch (SQLException e) {
          _log.log(
              Level.WARNING,
              "RaidBossSpawnManager: Couldnt update raidboss_spawnlist table " + e.getMessage(),
              e);
        }
      }
      statement.close();
    } catch (SQLException e) {
      _log.log(
          Level.WARNING,
          "SQL error while updating RaidBoss spawn to database: " + e.getMessage(),
          e);
    }
  }
  public void notifySpawnNightBoss(L2RaidBossInstance raidboss) {
    final StatsSet info = new StatsSet();
    info.set("currentHP", raidboss.getCurrentHp());
    info.set("currentMP", raidboss.getCurrentMp());
    info.set("respawnTime", 0L);

    raidboss.setRaidStatus(StatusEnum.ALIVE);

    _storedInfo.put(raidboss.getNpcId(), info);
    _bosses.put(raidboss.getNpcId(), raidboss);

    _log.info("RaidBossSpawnManager: Spawning Night Raid Boss " + raidboss.getName());
  }
  public void addNewSpawn(
      L2Spawn spawnDat, long respawnTime, double currentHP, double currentMP, boolean storeInDb) {
    if (spawnDat == null) return;

    final int bossId = spawnDat.getNpcId();
    if (_spawns.containsKey(bossId)) return;

    final long time = Calendar.getInstance().getTimeInMillis();

    SpawnTable.getInstance().addNewSpawn(spawnDat, false);

    if (respawnTime == 0L || (time > respawnTime)) {
      L2RaidBossInstance raidboss = null;

      if (bossId == 25328) raidboss = DayNightSpawnManager.getInstance().handleBoss(spawnDat);
      else raidboss = (L2RaidBossInstance) spawnDat.doSpawn();

      if (raidboss != null) {
        currentHP = (currentHP == 0) ? raidboss.getMaxHp() : currentHP;
        currentMP = (currentMP == 0) ? raidboss.getMaxMp() : currentMP;

        raidboss.setCurrentHp(currentHP);
        raidboss.setCurrentMp(currentMP);
        raidboss.setRaidStatus(StatusEnum.ALIVE);

        _bosses.put(bossId, raidboss);

        final StatsSet info = new StatsSet();
        info.set("currentHP", currentHP);
        info.set("currentMP", currentMP);
        info.set("respawnTime", 0L);

        _storedInfo.put(bossId, info);
      }
    } else {
      long spawnTime = respawnTime - Calendar.getInstance().getTimeInMillis();
      _schedules.put(
          bossId,
          ThreadPoolManager.getInstance().scheduleGeneral(new spawnSchedule(bossId), spawnTime));
    }

    _spawns.put(bossId, spawnDat);

    if (storeInDb) {
      try (Connection con = L2DatabaseFactory.getInstance().getConnection()) {
        PreparedStatement statement =
            con.prepareStatement(
                "INSERT INTO raidboss_spawnlist (boss_id,loc_x,loc_y,loc_z,heading,respawn_time,currentHp,currentMp) values(?,?,?,?,?,?,?,?)");
        statement.setInt(1, spawnDat.getNpcId());
        statement.setInt(2, spawnDat.getLocx());
        statement.setInt(3, spawnDat.getLocy());
        statement.setInt(4, spawnDat.getLocz());
        statement.setInt(5, spawnDat.getHeading());
        statement.setLong(6, respawnTime);
        statement.setDouble(7, currentHP);
        statement.setDouble(8, currentMP);
        statement.execute();
        statement.close();
      } catch (Exception e) {
        // problem with storing spawn
        _log.log(
            Level.WARNING,
            "RaidBossSpawnManager: Could not store raidboss #"
                + bossId
                + " in the DB:"
                + e.getMessage(),
            e);
      }
    }
  }
  public void updateStatus(L2RaidBossInstance boss, boolean isBossDead) {
    if (!_storedInfo.containsKey(boss.getNpcId())) return;

    final StatsSet info = _storedInfo.get(boss.getNpcId());

    if (isBossDead) {
      boss.setRaidStatus(StatusEnum.DEAD);

      // getRespawnMinDelay() is used as fixed timer, while getRespawnMaxDelay() is used as random
      // timer.
      final int respawnDelay =
          boss.getSpawn().getRespawnMinDelay()
              + Rnd.get(
                  -boss.getSpawn().getRespawnMaxDelay(), boss.getSpawn().getRespawnMaxDelay());
      final long respawnTime = Calendar.getInstance().getTimeInMillis() + (respawnDelay * 3600000);

      info.set("currentHP", boss.getMaxHp());
      info.set("currentMP", boss.getMaxMp());
      info.set("respawnTime", respawnTime);

      if (!_schedules.containsKey(boss.getNpcId())) {
        final Calendar time = Calendar.getInstance();
        time.setTimeInMillis(respawnTime);
        _log.info(
            "RaidBoss: "
                + boss.getName()
                + " - "
                + Util.formatDate(time.getTime(), "d MMM yyyy HH:mm")
                + " ("
                + respawnDelay
                + "h).");

        _schedules.put(
            boss.getNpcId(),
            ThreadPoolManager.getInstance()
                .scheduleGeneral(new spawnSchedule(boss.getNpcId()), respawnDelay * 3600000));
        updateDb();
      }
    } else {
      boss.setRaidStatus(StatusEnum.ALIVE);

      info.set("currentHP", boss.getCurrentHp());
      info.set("currentMP", boss.getCurrentMp());
      info.set("respawnTime", 0L);
    }

    _storedInfo.put(boss.getNpcId(), info);
  }