rendered paste body/* 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 2, 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package de.dc.l2j.gameserver.object.duel;
import java.util.Calendar;
import java.util.logging.Logger;
import de.dc.l2j.gameserver.character.ai.CtrlIntention;
import de.dc.l2j.gameserver.character.player.L2PcInstance;
import de.dc.l2j.gameserver.instancemanager.EventDuelManager;
import de.dc.l2j.gameserver.network.enums.SystemMessageId;
import de.dc.l2j.gameserver.network.server.ActionFailed;
import de.dc.l2j.gameserver.network.server.ExDuelEnd;
import de.dc.l2j.gameserver.network.server.ExDuelReady;
import de.dc.l2j.gameserver.network.server.ExDuelStart;
import de.dc.l2j.gameserver.network.server.ExDuelUpdateUserInfo;
import de.dc.l2j.gameserver.network.server.L2GameServerPacket;
import de.dc.l2j.gameserver.network.server.PlaySound;
import de.dc.l2j.gameserver.network.server.SystemMessage;
import de.dc.l2j.gameserver.network.server.ValidateLocation;
import de.dc.l2j.gameserver.object.L2Party;
import de.dc.l2j.gameserver.system.ThreadPoolManager;
/**
*
* @author Noctarius
*/
public abstract class L2EventDuel
{
protected static final Logger _log = Logger.getLogger(L2EventDuel.class.getName());
private class DuelTimeoutTask implements Runnable
{
L2EventDuel _duel;
public DuelTimeoutTask(L2EventDuel duel)
{
_duel = duel;
}
public void run()
{
_duel.onDuelTimeout();
}
}
private class DuelStartTask implements Runnable
{
L2EventDuel _duel;
public DuelStartTask(L2EventDuel duel)
{
_duel = duel;
_duel.setDuelState(DuelState.Prepare);
}
public void run()
{
int waitTime = _duel.onDuelPrepare();
if (waitTime > 0)
{
ThreadPoolManager.getInstance().scheduleGeneral(this, waitTime);
}
else
{
broadcastPacket(new SystemMessage(SystemMessageId.LET_THE_DUEL_BEGIN));
_duel.setDuelState(DuelState.Start);
_duel.onDuelStart();
}
}
}
public enum DuelState
{
NoDuel,
Prepare,
Start,
Duelling,
Winner,
Surrender,
Draw
}
protected enum DuelType
{
Deathmatch,
Training,
TVT
}
private Integer _duelId;
protected DuelType _duelType;
protected DuelState _duelState;
protected Calendar _duelEndTime;
protected boolean _partyDuel = false;
protected boolean _canSurrender = true;
protected boolean _willSurrender = true;
protected boolean _canDisqualify = true;
protected L2PcInstance _playerA;
protected L2PcInstance _playerB;
protected int _eventTime = 3;
public L2EventDuel(L2PcInstance playerA, L2PcInstance playerB, boolean partyDuel)
{
_playerA = playerA;
_playerB = playerB;
_partyDuel = partyDuel;
_duelId = EventDuelManager.getInstance().getNextDuelId();
_duelState = DuelState.NoDuel;
// Hole die eigentlichen Typewerte
setWillSurrender();
setCanSurrender();
setCanDisqualify();
ThreadPoolManager.getInstance().scheduleGeneral(new DuelStartTask(this), 100);
}
/*------------------------------------------------------------
*| Public functions area
*|
*------------------------------------------------------------
*/
public final Integer getDuelId()
{
return _duelId;
}
public final boolean isPartyDuel()
{
return _partyDuel;
}
public final DuelState getDuelState()
{
return _duelState;
}
public final L2PcInstance playerA()
{
return _playerA;
}
public final L2PcInstance playerB()
{
return _playerB;
}
public final void broadcastToOpponentTeam(L2PcInstance player, L2GameServerPacket packet)
{
if (_partyDuel)
{
L2PcInstance partyLeader = getPlayersPartyLeader(player);
if (partyLeader == null)
return;
for (L2PcInstance opPlayer : getOpponent(partyLeader).getParty().getPartyMembers())
{
opPlayer.sendPacket(packet);
}
}
else
getOpponent(player).sendPacket(packet);
}
public final int getRemainingTime()
{
return (int)(_duelEndTime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis());
}
public final void setEventTime(int time)
{
_eventTime = time;
}
public final synchronized void changePartyLeader(L2PcInstance oldLeader, L2PcInstance newLeader)
{
ExDuelEnd duelEnd = new ExDuelEnd(0);
ActionFailed af = new ActionFailed();
oldLeader.abortCast();
oldLeader.abortAttack();
oldLeader.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
oldLeader.setTarget(null);
oldLeader.sendPacket(af);
oldLeader.sendPacket(duelEnd);
if (oldLeader == _playerA)
_playerA = newLeader;
else
_playerB = newLeader;
}
public final synchronized void removeFromDuel(L2PcInstance player)
{
if (isPartyDuel())
{
ExDuelEnd duelEnd = new ExDuelEnd(0);
ActionFailed af = new ActionFailed();
player.setIsInDuel(null);
player.abortCast();
player.abortAttack();
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
player.setTarget(null);
player.sendPacket(af);
player.sendPacket(duelEnd);
}
else
{
onDuelEnd(getOpponent(player), player);
}
}
public final L2PcInstance getOpponent(L2PcInstance player)
{
if (player == _playerA)
return _playerB;
return _playerA;
}
public final L2PcInstance getPlayersPartyLeader(L2PcInstance player)
{
if (!isPartyDuel())
return player;
int partyLeaderId = player.getParty().getPartyLeaderOID();
for (L2PcInstance leader : player.getParty().getPartyMembers())
{
if (leader.getObjectId() == partyLeaderId)
return leader;
}
// Wird hoffentlich nie erreicht
return null;
}
/*------------------------------------------------------------
*| Public event-functions area
*|
*------------------------------------------------------------
*/
public int onDuelPrepare()
{
return 0;
}
public void onDuelStart()
{
if (_eventTime > -1)
{
_duelEndTime = Calendar.getInstance();
_duelEndTime.add(Calendar.MINUTE, _eventTime);
ThreadPoolManager.getInstance().scheduleGeneral(new DuelTimeoutTask(this), _duelEndTime.getTimeInMillis());
}
_duelState = DuelState.Duelling;
// Teams setzen
setTeams();
// Send duel Start packets
ExDuelReady ready = new ExDuelReady(_partyDuel ? 1 : 0);
broadcastPacket(ready);
ExDuelStart start = new ExDuelStart(_partyDuel ? 1 : 0);
broadcastPacket(start);
PlaySound ps = new PlaySound(1, "B04_S01", 0, 0, 0, 0, 0);
broadcastPacket(ps);
// Zeigt die Statusanzeige des Gegners
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
broadcastPacket(new ExDuelUpdateUserInfo(player));
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
broadcastPacket(new ExDuelUpdateUserInfo(player));
}
}
else
{
_playerA.sendPacket(new ExDuelUpdateUserInfo(_playerB));
_playerB.sendPacket(new ExDuelUpdateUserInfo(_playerA));
}
}
public void onDuelTimeout()
{
L2PcInstance winner = getWinner();
onDuelEnd(winner, getOpponent(winner));
sendWinnerMessages();
}
public void onDuelSurrender(L2PcInstance survivor)
{
if (_canSurrender)
{
_duelState = DuelState.Surrender;
sendSurrenderMessages(getOpponent(survivor), survivor);
onDuelEnd(getOpponent(survivor), survivor);
}
else
return;
}
public boolean onDuelDefeat(L2PcInstance player)
{
boolean surrender = false;
if (isPartyDuel())
{
L2PcInstance partyLeader = getPlayersPartyLeader(player);
if (partyLeader == null)
return false;
if (allPartyMemberDead(partyLeader.getParty()) && _willSurrender)
surrender = true;
if (allPartyMemberDead(partyLeader.getParty()))
{
onDuelEnd(getOpponent(partyLeader), partyLeader);
sendWinnerMessages();
}
}
else
{
if (!isPartyDuel() && _willSurrender)
surrender = true;
onDuelEnd(getOpponent(player), player);
sendWinnerMessages();
}
return surrender;
}
public void onDuelDraw()
{
_duelState = DuelState.Draw;
broadcastPacket(new SystemMessage(SystemMessageId.THE_DUEL_HAS_ENDED_IN_A_TIE));
onDuelEnd(_playerA, _playerB);
}
public void onDuelEnd(L2PcInstance winner, L2PcInstance loser)
{
_duelState = DuelState.Winner;
stopFighting();
EventDuelManager.getInstance().removeDuel(this);
}
public void onDuelDisqualification(L2PcInstance disqulified)
{
if (_canDisqualify)
{
stopFighting();
sendDisqualificationMessages(getOpponent(disqulified), disqulified);
onDuelEnd(getOpponent(disqulified), disqulified);
}
else
return;
}
public void onDuelDelete()
{
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
if (player != null)
{
player.cancelActiveTrade();
player.setTeam(0);
player.setIsInDuel(null);
player.enableAllSkills();
player.getStatus().startHpMpRegeneration();
player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
player.sendPacket(new ActionFailed());
player.broadcastUserInfo();
player.broadcastStatusUpdate();
player.sendPacket(new ValidateLocation(player));
}
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
if (player != null)
{
player.cancelActiveTrade();
player.setTeam(0);
player.setIsInDuel(null);
player.enableAllSkills();
player.getStatus().startHpMpRegeneration();
player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
player.sendPacket(new ActionFailed());
player.broadcastUserInfo();
player.broadcastStatusUpdate();
player.sendPacket(new ValidateLocation(player));
}
}
}
else
{
_playerA.setTeam(0);
_playerA.setIsInDuel(null);
_playerA.enableAllSkills();
_playerA.getStatus().startHpMpRegeneration();
_playerA.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
_playerA.sendPacket(new ActionFailed());
_playerA.broadcastStatusUpdate();
_playerA.broadcastUserInfo();
_playerA.sendPacket(new ValidateLocation(_playerA));
_playerB.setTeam(0);
_playerB.setIsInDuel(null);
_playerB.enableAllSkills();
_playerB.getStatus().startHpMpRegeneration();
_playerB.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
_playerB.sendPacket(new ActionFailed());
_playerB.broadcastStatusUpdate();
_playerB.broadcastUserInfo();
_playerB.sendPacket(new ValidateLocation(_playerB));
}
}
/*------------------------------------------------------------
*| Protected functions area
*|
*------------------------------------------------------------
*/
protected final void setDuelState(DuelState duelState)
{
_duelState = duelState;
}
protected final void sendDisqualificationMessages(L2PcInstance winner, L2PcInstance loser)
{
SystemMessage msg;
// Setze entsprechende Winner Message
if (isPartyDuel())
msg = new SystemMessage(SystemMessageId.S1S_WAS_DISQUALIFIED_SO_S2S_HAS_WON);
else
msg = new SystemMessage(SystemMessageId.S1_WAS_DISQUALIFIED_SO_S2_HAS_WON);
// Namen zur Nachricht hinzufügen
msg.addString(loser.getName());
msg.addString(winner.getName());
// Broadcast Message
broadcastPacket(msg);
}
protected final void sendSurrenderMessages(L2PcInstance winner, L2PcInstance loser)
{
SystemMessage msg;
// Setze entsprechende Winner Message
if (isPartyDuel())
msg = new SystemMessage(SystemMessageId.SINCE_S1S_PARTY_WITHDREW_FROM_THE_DUEL_S1S_PARTY_HAS_WON);
else
msg = new SystemMessage(SystemMessageId.SINCE_S1_WITHDREW_FROM_THE_DUEL_S2_HAS_WON);
// Namen zur Nachricht hinzufügen
msg.addString(loser.getName());
msg.addString(winner.getName());
// Broadcast Message
broadcastPacket(msg);
}
protected final L2PcInstance getWinner()
{
double hpPartyA = 0;
double hpPartyB = 0;
// Berechne übrige HP beider Parteien
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
if (player != null)
{
hpPartyA += player.getCurrentHp();
}
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
if (player != null)
{
hpPartyB += player.getCurrentHp();
}
}
}
else
{
hpPartyA = _playerA.getCurrentHp();
hpPartyB = _playerB.getCurrentHp();
}
if (hpPartyA > hpPartyB)
return _playerA;
return _playerB;
}
protected final void sendWinnerMessages()
{
SystemMessage msg;
// Setze entsprechende Winner Message
if (isPartyDuel())
msg = new SystemMessage(SystemMessageId.S1S_PARTY_HAS_WON_THE_DUEL);
else
msg = new SystemMessage(SystemMessageId.S1_HAS_WON_THE_DUEL);
// Füge Spielername der Message hinzu
if (getWinner() == _playerA)
msg.addString(_playerA.getName());
else
msg.addString(_playerB.getName());
// Broadcast Message
broadcastPacket(msg);
}
protected final void broadcastPacket(L2GameServerPacket packet)
{
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
if (player != null)
{
player.sendPacket(packet);
}
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
if (player != null)
{
player.sendPacket(packet);
}
}
}
else
{
_playerA.sendPacket(packet);
_playerB.sendPacket(packet);
}
}
protected final void broadcastPacket(SystemMessage msg)
{
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
if (player != null)
{
player.sendSystemMessage(msg);
}
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
if (player != null)
{
player.sendSystemMessage(msg);
}
}
}
else
{
_playerA.sendSystemMessage(msg);
_playerB.sendSystemMessage(msg);
}
}
protected final void stopFighting()
{
ExDuelEnd duelEnd;
if (isPartyDuel())
duelEnd = new ExDuelEnd(1);
else
duelEnd = new ExDuelEnd(0);
ActionFailed af = new ActionFailed();
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
if (player != null)
{
player.sendPacket(af);
player.abortCast();
player.abortAttack();
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
player.setTarget(null);
player.sendPacket(duelEnd);
}
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
if (player != null)
{
player.sendPacket(af);
player.abortCast();
player.abortAttack();
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
player.setTarget(null);
player.sendPacket(duelEnd);
}
}
}
else
{
_playerA.sendPacket(af);
_playerB.sendPacket(af);
_playerA.abortCast();
_playerB.abortCast();
_playerA.abortAttack();
_playerB.abortAttack();
_playerA.sendPacket(duelEnd);
_playerB.sendPacket(duelEnd);
_playerA.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
_playerB.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
_playerA.setTarget(null);
_playerB.setTarget(null);
}
}
protected final boolean allPartyMemberDead(L2Party party)
{
for (L2PcInstance player : party.getPartyMembers())
{
if (player != null && !player.isDead())
return false;
}
return true;
}
protected final void setTeams()
{
if (isPartyDuel())
{
for (L2PcInstance player : _playerA.getParty().getPartyMembers())
{
if (player != null)
{
player.cancelActiveTrade();
player.setTeam(1);
player.setIsInDuel(this);
player.broadcastStatusUpdate();
player.broadcastUserInfo();
}
}
for (L2PcInstance player : _playerB.getParty().getPartyMembers())
{
if (player != null)
{
player.cancelActiveTrade();
player.setTeam(2);
player.setIsInDuel(this);
player.broadcastStatusUpdate();
player.broadcastUserInfo();
}
}
}
else
{
_playerA.setTeam(1);
_playerA.setIsInDuel(this);
_playerA.broadcastStatusUpdate();
_playerA.broadcastUserInfo();
_playerB.setTeam(2);
_playerB.setIsInDuel(this);
_playerB.broadcastStatusUpdate();
_playerB.broadcastUserInfo();
}
}
/*------------------------------------------------------------
*| Protected abstract functions area
*|
*------------------------------------------------------------
*/
protected abstract void setWillSurrender();
protected abstract void setCanSurrender();
protected abstract void setCanDisqualify();
protected abstract void setDuelType();
}