All pastes #727757 Raw Edit

Etwas

public text v1 · immutable
·published 2007-10-06 10:42 UTC
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();
}