com.l2jfree.gameserver.model.entity.CCHSiege.java Source code

Java tutorial

Introduction

Here is the source code for com.l2jfree.gameserver.model.entity.CCHSiege.java

Source

/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jfree.gameserver.model.entity;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Calendar;
import java.util.Set;

import javolution.util.FastList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.l2jfree.Config;
import com.l2jfree.L2DatabaseFactory;
import com.l2jfree.gameserver.datatables.ClanTable;
import com.l2jfree.gameserver.gameobjects.L2Npc;
import com.l2jfree.gameserver.gameobjects.L2Object;
import com.l2jfree.gameserver.gameobjects.L2Player;
import com.l2jfree.gameserver.instancemanager.CCHManager;
import com.l2jfree.gameserver.instancemanager.ClanHallManager;
import com.l2jfree.gameserver.instancemanager.ContestableHideoutGuardManager;
import com.l2jfree.gameserver.instancemanager.SiegeManager;
import com.l2jfree.gameserver.model.clan.L2Clan;
import com.l2jfree.gameserver.model.clan.L2SiegeClan;
import com.l2jfree.gameserver.model.clan.L2SiegeClan.SiegeClanType;
import com.l2jfree.gameserver.model.entity.Siege.TeleportWhoType;
import com.l2jfree.gameserver.model.mapregion.TeleportWhereType;
import com.l2jfree.gameserver.model.world.L2World;
import com.l2jfree.gameserver.model.zone.L2SiegeZone;
import com.l2jfree.gameserver.model.zone.L2Zone;
import com.l2jfree.gameserver.network.SystemMessageId;
import com.l2jfree.gameserver.network.packets.server.SiegeInfo;
import com.l2jfree.gameserver.network.packets.server.SystemMessage;
import com.l2jfree.gameserver.threadmanager.ExclusiveTask;
import com.l2jfree.gameserver.util.Broadcast;
import com.l2jfree.util.L2FastSet;

/**
 * Clan hall siege, without unnecessary clutter.
 * @author Savormix
 */
public final class CCHSiege extends AbstractSiege {
    private final static Log _log = LogFactory.getLog(CCHSiege.class);

    private final ClanHall _hideout;
    private final ContestableHideoutGuardManager _guardManager;
    private final Set<L2SiegeClan> _attackerClans;

    private boolean _isInProgress;
    private boolean _isRegistrationOver;
    private Calendar _siegeEndDate;
    private int _oldOwner; // 0 - NPC, > 0 - clan

    public CCHSiege(ClanHall hideout) {
        _hideout = hideout;
        _guardManager = new ContestableHideoutGuardManager(hideout);
        _attackerClans = new L2FastSet<L2SiegeClan>().setShared(true);
        _isInProgress = false;
        _oldOwner = hideout.getOwnerId();
        startAutoTask();
    }

    public final ContestableHideoutGuardManager getGuardManager() {
        return _guardManager;
    }

    public void announceToPlayer(String message, boolean inAreaOnly) {
        // Get all players
        for (L2Player player : L2World.getInstance().getAllPlayers())
            if (!inAreaOnly || (inAreaOnly && checkIfInZone(player.getX(), player.getY(), player.getZ())))
                player.sendMessage(message);
    }

    public void announceToPlayer(SystemMessage sm, boolean inAreaOnly) {
        for (L2Player player : L2World.getInstance().getAllPlayers())
            if (!inAreaOnly || (inAreaOnly && checkIfInZone(player.getX(), player.getY(), player.getZ())))
                player.sendPacket(sm);
    }

    public void announceToParticipants(SystemMessage sm) {
        for (L2SiegeClan siegeclan : _attackerClans)
            ClanTable.getInstance().getClan(siegeclan.getClanId()).broadcastToOnlineMembers(sm);
    }

    private int calculateRepChange(L2Clan winner, L2Clan loser) {
        int result = 300;
        if (!Config.ALT_CCH_REPUTATION || winner == null || loser == null)
            return result;
        // absolutely custom
        if (winner.getReputationScore() < loser.getReputationScore())
            result *= 1.2;
        else
            result *= 0.8;
        if (winner.getLevel() < loser.getLevel())
            result *= 1.4;
        else
            result *= 0.75;
        if (winner.getOnlineMembersList().size() < loser.getOnlineMembersList().size())
            result *= 1.05;
        else
            result *= 0.9;
        return result;
    }

    public void startSiege() {
        if (!getIsInProgress()) {
            if (_attackerClans.size() <= 0) {
                announceToPlayer(SystemMessageId.CLANHALL_WAR_CANCELLED.getSystemMessage(), true);
                saveCastleSiege();
                return;
            }

            _isInProgress = true; // Flag so that same siege instance cannot be started again
            loadSiegeClan(); // Load siege clan from db
            updatePlayerSiegeStateFlags(false);
            teleportPlayer(Siege.TeleportWhoType.All, TeleportWhereType.Town);
            _hideout.spawnDoor(); // Spawn door
            _guardManager.spawnSiegeGuards(); // Spawn siege guard
            getZone().updateSiegeStatus();

            // Schedule a task to prepare auto siege end
            _siegeEndDate = Calendar.getInstance();
            _siegeEndDate.add(Calendar.MINUTE, 60);
            _endSiegeTask.schedule(1000);

            if (Config.USE_MISSING_CCH_MESSAGES)
                announceToPlayer(SystemMessageId.CLANHALL_SIEGE_BEGUN.getSystemMessage(), true);
            _oldOwner = _hideout.getOwnerId();
        }
    }

    public void endSiege(L2Clan bossKiller) {
        if (getIsInProgress()) {
            if (Config.USE_MISSING_CCH_MESSAGES)
                announceToPlayer(SystemMessageId.CLANHALL_SIEGE_ENDED.getSystemMessage(), true);
            if (bossKiller != null)
                ClanHallManager.getInstance().setOwner(_hideout.getId(), bossKiller);
            else
                ClanHallManager.getInstance().setFree(_hideout.getId());
            //_hideout.setOwner(bossKiller);
            SystemMessage sm;

            if (_oldOwner > 0) {
                if (_hideout.getOwnerId() <= 0) {
                    L2Clan c = ClanTable.getInstance().getClan(_oldOwner);
                    c.setReputationScore(c.getReputationScore() - calculateRepChange(null, c), true);
                    c.broadcastToOnlineMembers(
                            SystemMessageId.CLAN_LOST_CONTESTED_CLAN_HALL_AND_300_POINTS.getSystemMessage());
                } else if (_hideout.getOwnerId() != _oldOwner) {
                    L2Clan old = ClanTable.getInstance().getClan(_oldOwner);
                    L2Clan owner = _hideout.getOwnerClan();
                    int pts = calculateRepChange(owner, old);
                    old.setReputationScore(old.getReputationScore() - pts, true);
                    sm = new SystemMessage(
                            SystemMessageId.OPPOSING_CLAN_CAPTURED_CLAN_HALL_AND_YOUR_CLAN_LOSES_S1_POINTS);
                    sm.addNumber(pts);
                    old.broadcastToOnlineMembers(sm);
                    owner.setReputationScore(owner.getReputationScore() + pts, true);
                    sm = new SystemMessage(
                            SystemMessageId.CLAN_CAPTURED_CONTESTED_CLAN_HALL_AND_S1_POINTS_DEDUCTED_FROM_OPPONENT);
                    sm.addNumber(pts);
                    owner.broadcastToOnlineMembers(sm);
                }
            } else if (_hideout.getOwnerId() > 0) {
                L2Clan c = _hideout.getOwnerClan();
                int pts = calculateRepChange(c, null);
                c.setReputationScore(c.getReputationScore() + pts, true);
                sm = new SystemMessage(SystemMessageId.CLAN_ACQUIRED_CONTESTED_CLAN_HALL_AND_S1_REPUTATION_POINTS);
                sm.addNumber(pts);
                c.broadcastToOnlineMembers(sm);
            }

            removeFlags(); // Removes all flags. Note: Remove flag before teleporting players
            teleportPlayer(Siege.TeleportWhoType.Attacker, TeleportWhereType.Town); // Teleport to the second closest town
            teleportPlayer(Siege.TeleportWhoType.DefenderNotOwner, TeleportWhereType.Town); // Teleport to the second closest town
            teleportPlayer(Siege.TeleportWhoType.Spectator, TeleportWhereType.Town); // Teleport to the second closest town
            _isInProgress = false; // Flag so that siege instance can be started
            updatePlayerSiegeStateFlags(true);
            getZone().updateSiegeStatus();
            saveCastleSiege(); // Save castle specific data
            clearSiegeClan(); // Clear siege clan from db
            loadSiegeClan();
            _guardManager.despawnSiegeGuards(); // Remove all spawned siege guard from this hall
            _hideout.spawnDoor(); // Respawn door to hideout
        }
    }

    public void updatePlayerSiegeStateFlags(boolean clear) {
        L2Clan clan;
        for (L2SiegeClan siegeclan : _attackerClans) {
            if (siegeclan == null)
                continue;
            clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
            for (L2Player member : clan.getOnlineMembers(0)) {
                if (clear)
                    member.setSiegeState((byte) 0);
                // TODO: not so sure about this part
                else if (_hideout.getOwnerId() == siegeclan.getClanId())
                    member.setSiegeState((byte) 2);
                else
                    member.setSiegeState((byte) 1);
                member.revalidateZone(true);
                member.broadcastUserInfo();
            }
        }
    }

    /** Return true if object is inside the zone */
    public boolean checkIfInZone(L2Object object) {
        return checkIfInZone(object.getX(), object.getY(), object.getZ());
    }

    /** Return true if object is inside the zone */
    public boolean checkIfInZone(int x, int y, int z) {
        return (getIsInProgress() && (_hideout.checkIfInZone(x, y, z) || getZone().isInsideZone(x, y)));
    }

    public void clearSiegeClan() {
        Connection con = null;
        try {
            con = L2DatabaseFactory.getInstance().getConnection();
            PreparedStatement statement = con.prepareStatement("DELETE FROM siege_clans WHERE castle_id=?");
            statement.setInt(1, _hideout.getId());
            statement.executeUpdate();
            statement.close();

            if (_hideout.getOwnerId() > 0) {
                statement = con.prepareStatement("DELETE FROM siege_clans WHERE clan_id=? AND castle_id >= 20");
                statement.setInt(1, _hideout.getOwnerId());
                statement.executeUpdate();
                statement.close();
            }

            _attackerClans.clear();
        } catch (Exception e) {
            _log.error("Failed clearing registered clan list!", e);
        } finally {
            L2DatabaseFactory.close(con);
        }
    }

    public FastList<L2Player> getAttackersInZone() {
        FastList<L2Player> players = new FastList<L2Player>();
        L2Clan clan;
        for (L2SiegeClan siegeclan : _attackerClans) {
            clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
            for (L2Player player : clan.getOnlineMembers(0))
                if (checkIfInZone(player.getX(), player.getY(), player.getZ()))
                    players.add(player);
        }
        return players;
    }

    public FastList<L2Player> getPlayersInZone() {
        FastList<L2Player> players = new FastList<L2Player>();

        for (L2Player player : L2World.getInstance().getAllPlayers()) {
            // quick check from player states, which don't include siege number however
            if (!player.isInsideZone(L2Zone.FLAG_SIEGE))
                continue;
            if (checkIfInZone(player.getX(), player.getY(), player.getZ()))
                players.add(player);
        }

        return players;
    }

    public FastList<L2Player> getSpectatorsInZone() {
        FastList<L2Player> players = new FastList<L2Player>();

        for (L2Player player : L2World.getInstance().getAllPlayers()) {
            // quick check from player states, which don't include siege number however
            if (!player.isInsideZone(L2Zone.FLAG_SIEGE) || player.getSiegeState() != 0)
                continue;
            if (checkIfInZone(player.getX(), player.getY(), player.getZ()))
                players.add(player);
        }

        return players;
    }

    public void killedFlag(L2Npc flag) {
        if (flag == null)
            return;
        for (L2SiegeClan clan : _attackerClans)
            if (clan.removeFlag(flag))
                return;
    }

    public void listRegisterClan(L2Player player) {
        player.sendPacket(new SiegeInfo(_hideout));
    }

    public void registerAttacker(L2Player player, boolean force) {
        if ((force && player.getClan() != null) || checkIfCanRegister(player))
            saveSiegeClan(player.getClan(), false); // Save to database
    }

    private void removeSiegeClan(int clanId) {
        if (clanId <= 0)
            return;

        Connection con = null;
        try {
            con = L2DatabaseFactory.getInstance().getConnection(con);
            PreparedStatement statement = con
                    .prepareStatement("DELETE FROM siege_clans WHERE castle_id=? and clan_id=?");
            statement.setInt(1, _hideout.getId());
            statement.setInt(2, clanId);
            statement.execute();
            statement.close();

            loadSiegeClan();
        } catch (Exception e) {
            _log.error(e.getMessage(), e);
        } finally {
            L2DatabaseFactory.close(con);
        }
    }

    /**
     * Remove clan from siege<BR><BR>
     * @param player The L2Player of player/clan being removed
     */
    public void removeSiegeClan(L2Clan clan) {
        if (clan == null || clan.getHasHideout() == _hideout.getId()
                || !CCHManager.getInstance().checkIsRegistered(clan, _hideout.getId()))
            return;
        removeSiegeClan(clan.getClanId());
    }

    /**
     * Remove clan from siege<BR><BR>
     * @param player The L2Player of player/clan being removed
     */
    public void removeSiegeClan(L2Player player) {
        removeSiegeClan(player.getClan());
    }

    public void startAutoTask() {
        correctSiegeDateTime();

        _log.info("Contest/Siege of " + _hideout.getName() + ": " + getSiegeDate().getTime());

        loadSiegeClan();

        // Schedule siege auto start
        _startSiegeTask.schedule(1000);
    }

    /**
     * Teleport players
     */
    public void teleportPlayer(TeleportWhoType teleportWho, TeleportWhereType teleportWhere) {
        FastList<L2Player> players;
        switch (teleportWho) {
        case Attacker:
            players = getAttackersInZone();
            break;
        case Spectator:
            players = getSpectatorsInZone();
            break;
        default:
            players = getPlayersInZone();
        }

        for (L2Player player : players) {
            if (player.isGM() || player.isInJail())
                continue;
            player.teleToLocation(teleportWhere);
        }
    }

    private void addAttacker(int clanId) {
        _attackerClans.add(new L2SiegeClan(clanId, SiegeClanType.ATTACKER));
    }

    private boolean checkIfCanRegister(L2Player player) {
        L2Clan clan = player.getClan();
        if (clan == null || clan.getLevel() < Config.SIEGE_CLAN_MIN_LEVEL) {
            if (Config.SIEGE_CLAN_MIN_LEVEL == 5) //default retail
                player.sendPacket(SystemMessageId.ONLY_CLAN_LEVEL_5_ABOVE_MAY_SIEGE);
            else
                player.sendMessage("Only clans with Level " + Config.SIEGE_CLAN_MIN_LEVEL
                        + " and higher may register for a castle siege.");
            return false;
        } else if (_isRegistrationOver) {
            player.sendPacket(SystemMessageId.REGISTRATION_CLOSED);
            return false;
        } else if (getIsInProgress()) {
            player.sendPacket(SystemMessageId.NOT_SIEGE_REGISTRATION_TIME2);
            return false;
        } else if (clan.getHasHideout() > 0) {
            player.sendPacket(SystemMessageId.CLAN_OWNING_CLANHALL_MAY_NOT_SIEGE_CLANHALL);
            return false;
        } else if (checkIfAlreadyRegisteredForSameDay(player.getClan())) {
            player.sendPacket(
                    SystemMessageId.APPLICATION_DENIED_BECAUSE_ALREADY_SUBMITTED_A_REQUEST_FOR_ANOTHER_SIEGE_BATTLE);
            return false;
        } else {
            if (CCHManager.getInstance().checkIsRegistered(player.getClan())) {
                player.sendPacket(SystemMessageId.ALREADY_REQUESTED_SIEGE_BATTLE);
                return false;
            }
        }

        if (_attackerClans.size() >= Config.SIEGE_MAX_ATTACKER) {
            player.sendPacket(SystemMessageId.ATTACKER_SIDE_FULL);
            return false;
        }

        return true;
    }

    public boolean checkIfAlreadyRegisteredForSameDay(L2Clan clan) {
        for (Siege siege : SiegeManager.getInstance().getSieges()) {
            if (siege.getSiegeDate().get(Calendar.DAY_OF_WEEK) == getSiegeDate().get(Calendar.DAY_OF_WEEK)) {
                if (siege.checkIsAttacker(clan))
                    return true;
                if (siege.checkIsDefender(clan))
                    return true;
                if (siege.checkIsDefenderWaiting(clan))
                    return true;
            }
        }
        for (CCHSiege siege : CCHManager.getInstance().getSieges()) {
            if (siege.getSiegeDate().get(Calendar.DAY_OF_WEEK) == getSiegeDate().get(Calendar.DAY_OF_WEEK)) {
                if (siege.checkIsAttacker(clan))
                    return true;
                if (siege.checkIsDefender(clan))
                    return true;
            }
        }
        return false;
    }

    public void correctSiegeDateTime() {
        if (getSiegeDate().getTimeInMillis() < System.currentTimeMillis()) {
            // Since siege has past reschedule it to the next one
            // This is usually caused by server being down
            setNextSiegeDate();
            saveSiegeDate();
        }
    }

    private void loadSiegeClan() {
        Connection con = null;
        try {
            _attackerClans.clear();

            // Add hideout owner as attacker
            if (_hideout.getOwnerId() > 0)
                addAttacker(_hideout.getOwnerId());

            con = L2DatabaseFactory.getInstance().getConnection(con);

            PreparedStatement statement = con.prepareStatement("SELECT clan_id FROM siege_clans where castle_id=?");
            statement.setInt(1, _hideout.getId());
            ResultSet rs = statement.executeQuery();
            while (rs.next())
                addAttacker(rs.getInt("clan_id"));

            statement.close();
        } catch (Exception e) {
            _log.error("Couldn't load contest clan list from the db!", e);
        } finally {
            L2DatabaseFactory.close(con);
        }
    }

    private void removeFlags() {
        for (L2SiegeClan sc : _attackerClans)
            if (sc != null)
                sc.removeFlags();
    }

    private void saveCastleSiege() {
        setNextSiegeDate(); // Set the next set date for a week from now
        // Schedule Time registration end
        getTimeRegistrationOverDate().setTimeInMillis(Calendar.getInstance().getTimeInMillis());
        getTimeRegistrationOverDate().add(Calendar.DAY_OF_MONTH, 1);
        _hideout.setIsTimeRegistrationOver(false);

        saveSiegeDate(); // Save the new date
        startAutoTask(); // Prepare auto start siege and end registration
    }

    public void saveSiegeDate() {
        if (_startSiegeTask.isScheduled())
            _startSiegeTask.schedule(1000);

        Connection con = null;
        try {
            con = L2DatabaseFactory.getInstance().getConnection(con);
            PreparedStatement statement = con.prepareStatement(
                    "UPDATE clanhall_sieges SET siegeDate=?,regTimeEnd=?,regTimeOver=? WHERE hallId=?");
            statement.setLong(1, getSiegeDate().getTimeInMillis());
            statement.setLong(2, getTimeRegistrationOverDate().getTimeInMillis());
            statement.setString(3, String.valueOf(getIsTimeRegistrationOver()));
            statement.setInt(4, _hideout.getId());
            statement.execute();
            statement.close();
        } catch (Exception e) {
            _log.error("Exception: saveSiegeDate(): " + e.getMessage(), e);
        } finally {
            L2DatabaseFactory.close(con);
        }
    }

    private void saveSiegeClan(L2Clan clan, boolean isUpdateRegistration) {
        if (clan.getHasCastle() > 0)
            return;

        Connection con = null;
        try {
            con = L2DatabaseFactory.getInstance().getConnection(con);
            PreparedStatement statement;
            if (!isUpdateRegistration) {
                statement = con.prepareStatement(
                        "INSERT INTO siege_clans (clan_id,castle_id,type,castle_owner) VALUES (?,?,?,0)");
                statement.setInt(1, clan.getClanId());
                statement.setInt(2, _hideout.getId());
                statement.setInt(3, 1);
                statement.execute();
                statement.close();
            } else {
                statement = con
                        .prepareStatement("UPDATE siege_clans SET type = ? WHERE castle_id = ? AND clan_id = ?");
                statement.setInt(1, 1);
                statement.setInt(2, _hideout.getId());
                statement.setInt(3, clan.getClanId());
                statement.execute();
                statement.close();
            }

            addAttacker(clan.getClanId());
            announceToPlayer(clan.getName() + " has been registered to siege " + _hideout.getName(), false);
        } catch (Exception e) {
            _log.error("Could not save contest clan registration!", e);
        } finally {
            L2DatabaseFactory.close(con);
        }
    }

    private void setNextSiegeDate() {
        while (getSiegeDate().getTimeInMillis() < System.currentTimeMillis()) {
            if (getSiegeDate().get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY
                    && getSiegeDate().get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY)
                getSiegeDate().set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
            // set the next siege day to the next weekend
            getSiegeDate().add(Calendar.DAY_OF_MONTH, 7);
            getSiegeDate().set(Calendar.HOUR_OF_DAY, 20);
        }
        _isRegistrationOver = false; // Allow registration for next siege
    }

    public Set<L2Npc> getFlag(L2Clan clan) {
        L2SiegeClan sc = getAttackerClan(clan);
        if (sc != null)
            return sc.getFlag();
        else
            return null;
    }

    public L2Npc getClosestFlag(L2Object obj) {
        if (obj instanceof L2Player && ((L2Player) obj).getClan() != null) {
            L2SiegeClan sc = getAttackerClan(((L2Player) obj).getClan());
            if (sc != null)
                return sc.getClosestFlag(obj);
        }
        return null;
    }

    public final L2SiegeZone getZone() {
        return _hideout.getBattlefield();
    }

    public final boolean getIsTimeRegistrationOver() {
        return _hideout.getIsTimeRegistrationOver();
    }

    public final Calendar getSiegeDate() {
        return _hideout.getSiegeDate();
    }

    public final Calendar getTimeRegistrationOverDate() {
        return _hideout.getTimeRegistrationOverDate();
    }

    public void endTimeRegistration(boolean automatic) {
        _hideout.setIsTimeRegistrationOver(true);
        if (!automatic) {
            saveSiegeDate();
            Broadcast.toAllOnlinePlayers(
                    new SystemMessage(SystemMessageId.S1_ANNOUNCED_SIEGE_TIME).addString(_hideout.getName()));
        }
    }

    public final ClanHall getHideout() {
        return _hideout;
    }

    public final Set<L2SiegeClan> getAttackerClans() {
        return _attackerClans;
    }

    /* (non-Javadoc)
     * @see com.l2jfree.gameserver.model.entity.AbstractSiege#checkIsAttacker(com.l2jfree.gameserver.model.L2Clan)
     */
    @Override
    public boolean checkIsAttacker(L2Clan clan) {
        return getAttackerClan(clan) != null;
    }

    /* (non-Javadoc)
     * @see com.l2jfree.gameserver.model.entity.AbstractSiege#checkIsDefender(com.l2jfree.gameserver.model.L2Clan)
     */
    @Override
    public boolean checkIsDefender(L2Clan clan) {
        return false;
    }

    /* (non-Javadoc)
     * @see com.l2jfree.gameserver.model.entity.AbstractSiege#getAttackerClan(com.l2jfree.gameserver.model.L2Clan)
     */
    @Override
    public L2SiegeClan getAttackerClan(L2Clan clan) {
        if (clan == null)
            return null;
        return getAttackerClan(clan.getClanId());
    }

    private final L2SiegeClan getAttackerClan(int clanId) {
        for (L2SiegeClan sc : _attackerClans)
            if (sc != null && sc.getClanId() == clanId)
                return sc;
        return null;
    }

    /* (non-Javadoc)
     * @see com.l2jfree.gameserver.model.entity.AbstractSiege#getDefenderClan(com.l2jfree.gameserver.model.L2Clan)
     */
    @Override
    public L2SiegeClan getDefenderClan(L2Clan clan) {
        return null;
    }

    /* (non-Javadoc)
     * @see com.l2jfree.gameserver.model.entity.AbstractSiege#getIsInProgress()
     */
    @Override
    public boolean getIsInProgress() {
        return _isInProgress;
    }

    // ===============================================================
    // Schedule task

    private final ExclusiveTask _endSiegeTask = new ExclusiveTask() {
        @Override
        protected void onElapsed() {
            if (!getIsInProgress()) {
                cancel();
                return;
            }

            final long timeRemaining = _siegeEndDate.getTimeInMillis() - System.currentTimeMillis();

            if (timeRemaining <= 0) {
                endSiege(null);
                cancel();
                return;
            }

            if (3600000 > timeRemaining) {
                if (timeRemaining > 120000)
                    announceToPlayer(new SystemMessage(SystemMessageId.S1_MINUTES_REMAINING)
                            .addNumber(Math.round(timeRemaining / 60000)), true);
                else
                    announceToPlayer(new SystemMessage(SystemMessageId.S1_SECONDS_REMAINING)
                            .addNumber(Math.round(timeRemaining / 1000)), true);
            }

            int divider;

            if (timeRemaining > 3600000)
                divider = 3600000; // 1 hour

            else if (timeRemaining > 600000)
                divider = 600000; // 10 min

            else if (timeRemaining > 60000)
                divider = 60000; // 1 min

            else if (timeRemaining > 10000)
                divider = 10000; // 10 sec

            else
                divider = 1000; // 1 sec

            schedule(timeRemaining % divider);
        }
    };

    private final ExclusiveTask _startSiegeTask = new ExclusiveTask() {
        @Override
        protected void onElapsed() {
            if (getIsInProgress()) {
                cancel();
                return;
            }

            if (!getIsTimeRegistrationOver()) {
                long regTimeRemaining = getTimeRegistrationOverDate().getTimeInMillis()
                        - System.currentTimeMillis();

                if (regTimeRemaining > 0) {
                    schedule(regTimeRemaining);
                    return;
                }

                endTimeRegistration(true);
            }

            final long timeRemaining = getSiegeDate().getTimeInMillis() - System.currentTimeMillis();

            if (timeRemaining <= 0) {
                startSiege();
                cancel();
                return;
            }

            if (7200000 > timeRemaining) {
                if (!_isRegistrationOver) {
                    _isRegistrationOver = true;
                    announceToPlayer(SystemMessageId.CLANHALL_WAR_REGISTRATION_PERIOD_ENDED.getSystemMessage(),
                            true);
                }

                if (timeRemaining > 120000)
                    announceToParticipants(new SystemMessage(SystemMessageId.CONTEST_BEGIN_IN_S1_MINUTES)
                            .addNumber((int) Math.round(timeRemaining / 60000.0)));
            }

            int divider;

            if (timeRemaining > 86400000)
                divider = 86400000; // 1 day

            else if (timeRemaining > 3600000)
                divider = 3600000; // 1 hour

            else if (timeRemaining > 600000)
                divider = 600000; // 10 min

            else if (timeRemaining > 60000)
                divider = 60000; // 1 min

            else if (timeRemaining > 10000)
                divider = 10000; // 10 sec

            else
                divider = 1000; // 1 sec

            schedule(timeRemaining % divider);
        }
    };
}