1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012 |
- /*
- * 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 net.sf.l2j.gameserver.model.entity;
- import java.util.Calendar;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javolution.util.FastList;
- import net.sf.l2j.gameserver.ThreadPoolManager;
- import net.sf.l2j.gameserver.ai.CtrlIntention;
- import net.sf.l2j.gameserver.instancemanager.DuelManager;
- import net.sf.l2j.gameserver.model.L2Effect;
- import net.sf.l2j.gameserver.model.actor.L2Character;
- import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
- import net.sf.l2j.gameserver.network.SystemMessageId;
- import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
- import net.sf.l2j.gameserver.network.serverpackets.ExDuelEnd;
- import net.sf.l2j.gameserver.network.serverpackets.ExDuelReady;
- import net.sf.l2j.gameserver.network.serverpackets.ExDuelStart;
- import net.sf.l2j.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
- import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
- import net.sf.l2j.gameserver.network.serverpackets.PlaySound;
- import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
- import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
- public class Duel
- {
- protected static final Logger _log = Logger.getLogger(Duel.class.getName());
-
- public static final int DUELSTATE_NODUEL = 0;
- public static final int DUELSTATE_DUELLING = 1;
- public static final int DUELSTATE_DEAD = 2;
- public static final int DUELSTATE_WINNER = 3;
- public static final int DUELSTATE_INTERRUPTED = 4;
-
- // =========================================================
- // Data Field
- private int _duelId;
- private L2PcInstance _playerA;
- private L2PcInstance _playerB;
- private boolean _partyDuel;
- private Calendar _duelEndTime;
- private int _surrenderRequest = 0;
- private int _countdown = 4;
- private boolean _finished = false;
-
- private FastList<PlayerCondition> _playerConditions;
-
- public static enum DuelResultEnum
- {
- Continue,
- Team1Win,
- Team2Win,
- Team1Surrender,
- Team2Surrender,
- Canceled,
- Timeout
- }
-
- // =========================================================
- // Constructor
- public Duel(L2PcInstance playerA, L2PcInstance playerB, int partyDuel, int duelId)
- {
- _duelId = duelId;
- _playerA = playerA;
- _playerB = playerB;
- _partyDuel = partyDuel == 1 ? true : false;
-
- _duelEndTime = Calendar.getInstance();
- if (_partyDuel)
- _duelEndTime.add(Calendar.SECOND, 300);
- else
- _duelEndTime.add(Calendar.SECOND, 120);
-
- _playerConditions = new FastList<PlayerCondition>();
-
- setFinished(false);
-
- if (_partyDuel)
- {
- // increase countdown so that start task can teleport players
- _countdown++;
- // inform players that they will be portet shortly
- SystemMessage sm = new SystemMessage(SystemMessageId.IN_A_MOMENT_YOU_WILL_BE_TRANSPORTED_TO_THE_SITE_WHERE_THE_DUEL_WILL_TAKE_PLACE);
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- }
- // Schedule duel start
- ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleStartDuelTask(this), 3000);
- }
-
- // ===============================================================
- // Nested Class
-
- public class PlayerCondition
- {
- private L2PcInstance _player;
- private double _hp;
- private double _mp;
- private double _cp;
- private boolean _paDuel;
- private int _x, _y, _z;
- private FastList<L2Effect> _debuffs;
-
- public PlayerCondition(L2PcInstance player, boolean partyDuel)
- {
- if (player == null)
- return;
- _player = player;
- _hp = _player.getCurrentHp();
- _mp = _player.getCurrentMp();
- _cp = _player.getCurrentCp();
- _paDuel = partyDuel;
-
- if (_paDuel)
- {
- _x = _player.getX();
- _y = _player.getY();
- _z = _player.getZ();
- }
- }
-
- public void restoreCondition()
- {
- if (_player == null)
- return;
- _player.setCurrentHp(_hp);
- _player.setCurrentMp(_mp);
- _player.setCurrentCp(_cp);
-
- if (_paDuel)
- {
- teleportBack();
- }
- if (_debuffs != null) // Debuff removal
- {
- for (L2Effect temp : _debuffs)
- if (temp != null)
- temp.exit();
- }
- }
-
- public void registerDebuff(L2Effect debuff)
- {
- if (_debuffs == null)
- _debuffs = new FastList<L2Effect>();
-
- _debuffs.add(debuff);
- }
-
- public void teleportBack()
- {
- if (_paDuel)
- _player.teleToLocation(_x, _y, _z);
- }
-
- public L2PcInstance getPlayer()
- {
- return _player;
- }
- }
-
- // ===============================================================
- // Schedule task
- public class ScheduleDuelTask implements Runnable
- {
- private Duel _duel;
-
- public ScheduleDuelTask(Duel duel)
- {
- _duel = duel;
- }
-
- public void run()
- {
- try
- {
- DuelResultEnum status = _duel.checkEndDuelCondition();
-
- if (status == DuelResultEnum.Canceled)
- {
- // do not schedule duel end if it was interrupted
- setFinished(true);
- _duel.endDuel(status);
- }
- else if (status != DuelResultEnum.Continue)
- {
- setFinished(true);
- playKneelAnimation();
- ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleEndDuelTask(_duel, status), 5000);
- }
- else
- ThreadPoolManager.getInstance().scheduleGeneral(this, 1000);
- }
- catch (Exception e)
- {
- _log.log(Level.SEVERE, "", e);
- }
- }
- }
-
- public class ScheduleStartDuelTask implements Runnable
- {
- private Duel _duel;
-
- public ScheduleStartDuelTask(Duel duel)
- {
- _duel = duel;
- }
-
- public void run()
- {
- try
- {
- // start/continue countdown
- int count = _duel.countdown();
-
- if (count == 4)
- {
- // players need to be teleportet first
- //TODO: stadia manager needs a function to return an unused stadium for duels
- // currently only teleports to the same stadium
- _duel.teleportPlayers(-102495, -209023, -3326);
-
- // give players 20 seconds to complete teleport and get ready (its ought to be 30 on offical..)
- ThreadPoolManager.getInstance().scheduleGeneral(this, 20000);
- }
- else if (count > 0) // duel not started yet - continue countdown
- {
- ThreadPoolManager.getInstance().scheduleGeneral(this, 1000);
- }
- else
- _duel.startDuel();
- }
- catch (Exception e)
- {
- _log.log(Level.SEVERE, "", e);
- }
- }
- }
-
- public class ScheduleEndDuelTask implements Runnable
- {
- private Duel _duel;
- private DuelResultEnum _result;
-
- public ScheduleEndDuelTask(Duel duel, DuelResultEnum result)
- {
- _duel = duel;
- _result = result;
- }
-
- public void run()
- {
- try
- {
- _duel.endDuel(_result);
- }
- catch (Exception e)
- {
- _log.log(Level.SEVERE, "", e);
- }
- }
- }
-
- // ========================================================
- // Method - Private
-
- /**
- * Stops all players from attacking.
- * Used for duel timeout / interrupt.
- *
- */
- private void stopFighting()
- {
- ActionFailed af = ActionFailed.STATIC_PACKET;
- if (_partyDuel)
- {
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- temp.abortCast();
- temp.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
- temp.setTarget(null);
- temp.sendPacket(af);
- }
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- temp.abortCast();
- temp.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
- temp.setTarget(null);
- temp.sendPacket(af);
- }
- }
- else
- {
- _playerA.abortCast();
- _playerB.abortCast();
- _playerA.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
- _playerA.setTarget(null);
- _playerB.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
- _playerB.setTarget(null);
- _playerA.sendPacket(af);
- _playerB.sendPacket(af);
- }
- }
-
- // ========================================================
- // Method - Public
-
- /**
- * Check if a player engaged in pvp combat (only for 1on1 duels)
- * @return returns true if a duelist is engaged in Pvp combat
- */
- public boolean isDuelistInPvp(boolean sendMessage)
- {
- if (_partyDuel)
- {
- // Party duels take place in arenas - should be no other players there
- return false;
- }
- else if (_playerA.getPvpFlag() != 0 || _playerB.getPvpFlag() != 0)
- {
- if (sendMessage)
- {
- String engagedInPvP = "The duel was canceled because a duelist engaged in PvP combat.";
- _playerA.sendMessage(engagedInPvP);
- _playerB.sendMessage(engagedInPvP);
- }
- return true;
- }
- return false;
- }
-
- /**
- * Starts the duel
- *
- */
- public void startDuel()
- {
- // Save player Conditions
- savePlayerConditions();
-
- if (_playerA == null || _playerB == null || _playerA.isInDuel() || _playerB.isInDuel())
- {
- // clean up
- _playerConditions.clear();
- _playerConditions = null;
- DuelManager.getInstance().removeDuel(this);
- return;
- }
-
- if (_partyDuel)
- {
- // set isInDuel() state
- // cancel all active trades, just in case? xD
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- temp.cancelActiveTrade();
- temp.setIsInDuel(_duelId);
- temp.setTeam(1);
- temp.broadcastUserInfo();
- broadcastToTeam2(new ExDuelUpdateUserInfo(temp));
- }
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- temp.cancelActiveTrade();
- temp.setIsInDuel(_duelId);
- temp.setTeam(2);
- temp.broadcastUserInfo();
- broadcastToTeam1(new ExDuelUpdateUserInfo(temp));
- }
-
- // Send duel Start packets
- ExDuelReady ready = new ExDuelReady(1);
- ExDuelStart start = new ExDuelStart(1);
-
- broadcastToTeam1(ready);
- broadcastToTeam2(ready);
- broadcastToTeam1(start);
- broadcastToTeam2(start);
- }
- else
- {
- // set isInDuel() state
- _playerA.setIsInDuel(_duelId);
- _playerA.setTeam(1);
- _playerB.setIsInDuel(_duelId);
- _playerB.setTeam(2);
-
- // Send duel Start packets
- ExDuelReady ready = new ExDuelReady(0);
- ExDuelStart start = new ExDuelStart(0);
-
- broadcastToTeam1(ready);
- broadcastToTeam2(ready);
- broadcastToTeam1(start);
- broadcastToTeam2(start);
- broadcastToTeam1(new ExDuelUpdateUserInfo(_playerB));
- broadcastToTeam2(new ExDuelUpdateUserInfo(_playerA));
- _playerA.broadcastUserInfo();
- _playerB.broadcastUserInfo();
- }
-
- // play sound
- PlaySound ps = new PlaySound(1, "B04_S01", 0, 0, 0, 0, 0);
- broadcastToTeam1(ps);
- broadcastToTeam2(ps);
-
- // start duelling task
- ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleDuelTask(this), 1000);
- }
-
- /**
- * Save the current player condition: hp, mp, cp, location
- *
- */
- public void savePlayerConditions()
- {
- if (_partyDuel)
- {
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- _playerConditions.add(new PlayerCondition(temp, _partyDuel));
- }
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- _playerConditions.add(new PlayerCondition(temp, _partyDuel));
- }
- }
- else
- {
- _playerConditions.add(new PlayerCondition(_playerA, _partyDuel));
- _playerConditions.add(new PlayerCondition(_playerB, _partyDuel));
- }
- }
-
- /**
- * Restore player conditions
- * @param was the duel canceled?
- */
- public void restorePlayerConditions(boolean abnormalDuelEnd)
- {
- // update isInDuel() state for all players
- if (_partyDuel)
- {
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- temp.setIsInDuel(0);
- temp.setTeam(0);
- temp.broadcastUserInfo();
- }
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- temp.setIsInDuel(0);
- temp.setTeam(0);
- temp.broadcastUserInfo();
- }
- }
- else
- {
- _playerA.setIsInDuel(0);
- _playerA.setTeam(0);
- _playerA.broadcastUserInfo();
- _playerB.setIsInDuel(0);
- _playerB.setTeam(0);
- _playerB.broadcastUserInfo();
- }
-
- // if it is an abnormal DuelEnd do not restore hp, mp, cp
- if (abnormalDuelEnd)
- return;
-
- // restore player conditions
- for (FastList.Node<PlayerCondition> e = _playerConditions.head(), end = _playerConditions.tail(); (e = e.getNext()) != end;)
- {
- e.getValue().restoreCondition();
- }
- }
-
- /**
- * Get the duel id
- * @return id
- */
- public int getId()
- {
- return _duelId;
- }
-
- /**
- * Returns the remaining time
- * @return remaining time
- */
- public int getRemainingTime()
- {
- return (int) (_duelEndTime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
- }
-
- /**
- * Get the player that requestet the duel
- * @return duel requester
- */
- public L2PcInstance getPlayerA()
- {
- return _playerA;
- }
-
- /**
- * Get the player that was challenged
- * @return challenged player
- */
- public L2PcInstance getPlayerB()
- {
- return _playerB;
- }
-
- /**
- * Returns whether this is a party duel or not
- * @return is party duel
- */
- public boolean isPartyDuel()
- {
- return _partyDuel;
- }
-
- public void setFinished(boolean mode)
- {
- _finished = mode;
- }
-
- public boolean getFinished()
- {
- return _finished;
- }
-
- /**
- * teleport all players to the given coordinates
- * @param x
- * @param y
- * @param z
- */
- public void teleportPlayers(int x, int y, int z)
- {
- //TODO: adjust the values if needed... or implement something better (especially using more then 1 arena)
- if (!_partyDuel)
- return;
- int offset = 0;
-
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- temp.teleToLocation(x + offset - 180, y - 150, z);
- offset += 40;
- }
- offset = 0;
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- temp.teleToLocation(x + offset - 180, y + 150, z);
- offset += 40;
- }
- }
-
- /**
- * Broadcast a packet to the challanger team
- *
- */
- public void broadcastToTeam1(L2GameServerPacket packet)
- {
- if (_playerA == null)
- return;
-
- if (_partyDuel && _playerA.getParty() != null)
- {
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- temp.sendPacket(packet);
- }
- else
- _playerA.sendPacket(packet);
- }
-
- /**
- * Broadcast a packet to the challenged team
- *
- */
- public void broadcastToTeam2(L2GameServerPacket packet)
- {
- if (_playerB == null)
- return;
-
- if (_partyDuel && _playerB.getParty() != null)
- {
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- temp.sendPacket(packet);
- }
- else
- _playerB.sendPacket(packet);
- }
-
- /**
- * Get the duel winner
- * @return winner
- */
- public L2PcInstance getWinner()
- {
- if (!getFinished() || _playerA == null || _playerB == null)
- return null;
- if (_playerA.getDuelState() == DUELSTATE_WINNER)
- return _playerA;
- if (_playerB.getDuelState() == DUELSTATE_WINNER)
- return _playerB;
- return null;
- }
-
- /**
- * Get the duel looser
- * @return looser
- */
- public L2PcInstance getLooser()
- {
- if (!getFinished() || _playerA == null || _playerB == null)
- return null;
- if (_playerA.getDuelState() == DUELSTATE_WINNER)
- return _playerB;
- else if (_playerA.getDuelState() == DUELSTATE_WINNER)
- return _playerA;
- return null;
- }
-
- /**
- * Playback the bow animation for all loosers
- *
- */
- public void playKneelAnimation()
- {
- L2PcInstance looser = getLooser();
-
- if (looser == null)
- return;
-
- if (_partyDuel && looser.getParty() != null)
- {
- for (L2PcInstance temp : looser.getParty().getPartyMembers())
- temp.broadcastPacket(new SocialAction(temp.getObjectId(), 7));
- }
- else
- looser.broadcastPacket(new SocialAction(looser.getObjectId(), 7));
- }
-
- /**
- * Do the countdown and send message to players if necessary
- * @return current count
- */
- public int countdown()
- {
- _countdown--;
-
- if (_countdown > 3)
- return _countdown;
-
- // Broadcast countdown to duelists
- SystemMessage sm = null;
- if (_countdown > 0)
- {
- sm = new SystemMessage(SystemMessageId.THE_DUEL_WILL_BEGIN_IN_S1_SECONDS);
- sm.addNumber(_countdown);
- }
- else
- sm = new SystemMessage(SystemMessageId.LET_THE_DUEL_BEGIN);
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
-
- return _countdown;
- }
-
- /**
- * The duel has reached a state in which it can no longer continue
- * @param duel result
- */
- public void endDuel(DuelResultEnum result)
- {
- if (_playerA == null || _playerB == null)
- {
- //clean up
- _playerConditions.clear();
- _playerConditions = null;
- DuelManager.getInstance().removeDuel(this);
- return;
- }
-
- // inform players of the result
- SystemMessage sm = null;
- switch (result)
- {
- case Team1Win:
- restorePlayerConditions(false);
- // send SystemMessage
- if (_partyDuel)
- sm = new SystemMessage(SystemMessageId.C1_PARTY_HAS_WON_THE_DUEL);
- else
- sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_DUEL);
- sm.addString(_playerA.getName());
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- break;
- case Team2Win:
- restorePlayerConditions(false);
- // send SystemMessage
- if (_partyDuel)
- sm = new SystemMessage(SystemMessageId.C1_PARTY_HAS_WON_THE_DUEL);
- else
- sm = new SystemMessage(SystemMessageId.C1_HAS_WON_THE_DUEL);
- sm.addString(_playerB.getName());
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- break;
- case Team1Surrender:
- restorePlayerConditions(false);
- // send SystemMessage
- if (_partyDuel)
- sm = new SystemMessage(SystemMessageId.SINCE_C1_PARTY_WITHDREW_FROM_THE_DUEL_S2_PARTY_HAS_WON);
- else
- sm = new SystemMessage(SystemMessageId.SINCE_C1_WITHDREW_FROM_THE_DUEL_S2_HAS_WON);
- sm.addString(_playerA.getName());
- sm.addString(_playerB.getName());
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- break;
- case Team2Surrender:
- restorePlayerConditions(false);
- // send SystemMessage
- if (_partyDuel)
- sm = new SystemMessage(SystemMessageId.SINCE_C1_PARTY_WITHDREW_FROM_THE_DUEL_S2_PARTY_HAS_WON);
- else
- sm = new SystemMessage(SystemMessageId.SINCE_C1_WITHDREW_FROM_THE_DUEL_S2_HAS_WON);
- sm.addString(_playerB.getName());
- sm.addString(_playerA.getName());
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- break;
- case Canceled:
- stopFighting();
- // dont restore hp, mp, cp
- restorePlayerConditions(true);
- //TODO: is there no other message for a canceled duel?
- // send SystemMessage
- sm = new SystemMessage(SystemMessageId.THE_DUEL_HAS_ENDED_IN_A_TIE);
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- break;
- case Timeout:
- stopFighting();
- // hp,mp,cp seem to be restored in a timeout too...
- restorePlayerConditions(false);
- // send SystemMessage
- sm = new SystemMessage(SystemMessageId.THE_DUEL_HAS_ENDED_IN_A_TIE);
-
- broadcastToTeam1(sm);
- broadcastToTeam2(sm);
- break;
- }
-
- // Send end duel packet
- ExDuelEnd duelEnd = null;
- if (_partyDuel)
- duelEnd = new ExDuelEnd(1);
- else
- duelEnd = new ExDuelEnd(0);
-
- broadcastToTeam1(duelEnd);
- broadcastToTeam2(duelEnd);
-
- //clean up
- _playerConditions.clear();
- _playerConditions = null;
- DuelManager.getInstance().removeDuel(this);
- }
-
- /**
- * Did a situation occur in which the duel has to be ended?
- * @return DuelResultEnum duel status
- */
- public DuelResultEnum checkEndDuelCondition()
- {
- // one of the players might leave during duel
- if (_playerA == null || _playerB == null)
- return DuelResultEnum.Canceled;
-
- // got a duel surrender request?
- if (_surrenderRequest != 0)
- {
- if (_surrenderRequest == 1)
- return DuelResultEnum.Team1Surrender;
- else
- return DuelResultEnum.Team2Surrender;
- }
- // duel timed out
- else if (getRemainingTime() <= 0)
- {
- return DuelResultEnum.Timeout;
- }
- // Has a player been declared winner yet?
- else if (_playerA.getDuelState() == DUELSTATE_WINNER)
- {
- // If there is a Winner already there should be no more fighting going on
- stopFighting();
- return DuelResultEnum.Team1Win;
- }
- else if (_playerB.getDuelState() == DUELSTATE_WINNER)
- {
- // If there is a Winner already there should be no more fighting going on
- stopFighting();
- return DuelResultEnum.Team2Win;
- }
-
- // More end duel conditions for 1on1 duels
- else if (!_partyDuel)
- {
- // Duel was interrupted e.g.: player was attacked by mobs / other players
- if (_playerA.getDuelState() == DUELSTATE_INTERRUPTED || _playerB.getDuelState() == DUELSTATE_INTERRUPTED)
- return DuelResultEnum.Canceled;
-
- // Are the players too far apart?
- if (!_playerA.isInsideRadius(_playerB, 1600, false, false))
- return DuelResultEnum.Canceled;
-
- // Did one of the players engage in PvP combat?
- if (isDuelistInPvp(true))
- return DuelResultEnum.Canceled;
-
- // is one of the players in a Siege, Peace or PvP zone?
- if (_playerA.isInsideZone(L2Character.ZONE_PEACE) || _playerB.isInsideZone(L2Character.ZONE_PEACE) || _playerA.isInsideZone(L2Character.ZONE_SIEGE) || _playerB.isInsideZone(L2Character.ZONE_SIEGE)
- || _playerA.isInsideZone(L2Character.ZONE_PVP) || _playerB.isInsideZone(L2Character.ZONE_PVP))
- return DuelResultEnum.Canceled;
- }
-
- return DuelResultEnum.Continue;
- }
-
- /**
- * Register a surrender request
- * @param surrendering player
- */
- public void doSurrender(L2PcInstance player)
- {
- // already recived a surrender request
- if (_surrenderRequest != 0)
- return;
-
- // stop the fight
- stopFighting();
-
- // TODO: Can every party member cancel a party duel? or only the party leaders?
- if (_partyDuel)
- {
- if (_playerA.getParty().getPartyMembers().contains(player))
- {
- _surrenderRequest = 1;
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- temp.setDuelState(DUELSTATE_DEAD);
- }
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- temp.setDuelState(DUELSTATE_WINNER);
- }
- }
- else if (_playerB.getParty().getPartyMembers().contains(player))
- {
- _surrenderRequest = 2;
- for (L2PcInstance temp : _playerB.getParty().getPartyMembers())
- {
- temp.setDuelState(DUELSTATE_DEAD);
- }
- for (L2PcInstance temp : _playerA.getParty().getPartyMembers())
- {
- temp.setDuelState(DUELSTATE_WINNER);
- }
-
- }
- }
- else
- {
- if (player == _playerA)
- {
- _surrenderRequest = 1;
- _playerA.setDuelState(DUELSTATE_DEAD);
- _playerB.setDuelState(DUELSTATE_WINNER);
- }
- else if (player == _playerB)
- {
- _surrenderRequest = 2;
- _playerB.setDuelState(DUELSTATE_DEAD);
- _playerA.setDuelState(DUELSTATE_WINNER);
- }
- }
- }
-
- /**
- * This function is called whenever a player was defeated in a duel
- * @param dieing player
- */
- public void onPlayerDefeat(L2PcInstance player)
- {
- // Set player as defeated
- player.setDuelState(DUELSTATE_DEAD);
-
- if (_partyDuel)
- {
- boolean teamdefeated = true;
- for (L2PcInstance temp : player.getParty().getPartyMembers())
- {
- if (temp.getDuelState() == DUELSTATE_DUELLING)
- {
- teamdefeated = false;
- break;
- }
- }
-
- if (teamdefeated)
- {
- L2PcInstance winner = _playerA;
- if (_playerA.getParty().getPartyMembers().contains(player))
- winner = _playerB;
-
- for (L2PcInstance temp : winner.getParty().getPartyMembers())
- {
- temp.setDuelState(DUELSTATE_WINNER);
- }
- }
- }
- else
- {
- if (player != _playerA && player != _playerB)
- _log.warning("Error in onPlayerDefeat(): player is not part of this 1vs1 duel");
-
- if (_playerA == player)
- _playerB.setDuelState(DUELSTATE_WINNER);
- else
- _playerA.setDuelState(DUELSTATE_WINNER);
- }
- }
-
- /**
- * This function is called whenever a player leaves a party
- * @param leaving player
- */
- public void onRemoveFromParty(L2PcInstance player)
- {
- // if it isnt a party duel ignore this
- if (!_partyDuel)
- return;
-
- // this player is leaving his party during party duel
- // if hes either playerA or playerB cancel the duel and port the players back
- if (player == _playerA || player == _playerB)
- {
- for (FastList.Node<PlayerCondition> e = _playerConditions.head(), end = _playerConditions.tail(); (e = e.getNext()) != end;)
- {
- e.getValue().teleportBack();
- e.getValue().getPlayer().setIsInDuel(0);
- }
-
- _playerA = null;
- _playerB = null;
- }
- else
- // teleport the player back & delete his PlayerCondition record
- {
- for (FastList.Node<PlayerCondition> e = _playerConditions.head(), end = _playerConditions.tail(); (e = e.getNext()) != end;)
- {
- if (e.getValue().getPlayer() == player)
- {
- e.getValue().teleportBack();
- _playerConditions.remove(e.getValue());
- break;
- }
- }
- player.setIsInDuel(0);
- }
- }
-
- public void onBuff(L2PcInstance player, L2Effect debuff)
- {
- for (FastList.Node<PlayerCondition> e = _playerConditions.head(), end = _playerConditions.tail(); (e = e.getNext()) != end;)
- {
- if (e.getValue().getPlayer() == player)
- {
- e.getValue().registerDebuff(debuff);
- return;
- }
- }
- }
- }
|