/*
* This file is part of aion-unique <aion-unique.org>.
*
* aion-unique 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.
*
* aion-unique 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 aion-unique. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.gameserver.services;
import javolution.util.FastMap;
import org.apache.log4j.Logger;
import com.aionemu.gameserver.model.DuelResult;
import com.aionemu.gameserver.model.gameobjects.Creature;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.gameobjects.player.RequestResponseHandler;
import com.aionemu.gameserver.network.aion.serverpackets.SM_DUEL;
import com.aionemu.gameserver.network.aion.serverpackets.SM_QUESTION_WINDOW;
import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
import com.aionemu.gameserver.skillengine.model.SkillTargetSlot;
import com.aionemu.gameserver.utils.PacketSendUtility;
import com.aionemu.gameserver.world.World;
import com.google.inject.Inject;
/**
* @author Simple
* @author Sphinx :)
*/
public class DuelService
{
@Inject
World world;
private static Logger log = Logger.getLogger(DuelService.class);
private FastMap<Integer, Integer> duels = new FastMap<Integer, Integer>();
/**
* Send the duel request to the owner
*
* @param requester
* the player who requested the duel
* @param responder
* the player who respond to duel request
*/
public void onDuelRequest(Player requester, Player responder)
{
/**
* Check if requester isn't already in a duel and responder is same race
*/
if(requester.isEnemyPlayer(responder) || isDueling(requester.getObjectId()))
return;
RequestResponseHandler rrh = new RequestResponseHandler(requester){
@Override
public void denyRequest(Creature requester, Player responder)
{
rejectDuelRequest((Player) requester, responder);
}
@Override
public void acceptRequest(Creature requester, Player responder)
{
startDuel((Player) requester, responder);
}
};
responder.getResponseRequester().putRequest(SM_QUESTION_WINDOW.STR_DUEL_DO_YOU_ACCEPT_DUEL, rrh);
PacketSendUtility.sendPacket(responder, new SM_QUESTION_WINDOW(SM_QUESTION_WINDOW.STR_DUEL_DO_YOU_ACCEPT_DUEL,
0, requester.getName()));
PacketSendUtility.sendPacket(responder, SM_SYSTEM_MESSAGE.DUEL_ASKED_BY(requester.getName()));
}
/**
* Asks confirmation for the duel request
*
* @param requester
* the player whose the duel was requested
* @param responder
* the player whose the duel was responded
*/
public void confirmDuelWith(Player requester, Player responder)
{
/**
* Check if requester isn't already in a duel and responder is same race
*/
if(requester.isEnemyPlayer(responder))
return;
RequestResponseHandler rrh = new RequestResponseHandler(responder){
@Override
public void denyRequest(Creature requester, Player responder)
{
log.debug("[Duel] Player " + responder.getName() + " confirmed his duel with " + requester.getName());
}
@Override
public void acceptRequest(Creature requester, Player responder)
{
cancelDuelRequest(responder, (Player) requester);
}
};
requester.getResponseRequester().putRequest(SM_QUESTION_WINDOW.STR_DUEL_DO_YOU_CONFIRM_DUEL, rrh);
PacketSendUtility.sendPacket(requester, new SM_QUESTION_WINDOW(SM_QUESTION_WINDOW.STR_DUEL_DO_YOU_CONFIRM_DUEL,
0, responder.getName()));
PacketSendUtility.sendPacket(requester, SM_SYSTEM_MESSAGE.DUEL_ASKED_TO(responder.getName()));
}
/**
* Rejects the duel request
*
* @param requester
* the duel requester
* @param responder
* the duel responder
*/
private void rejectDuelRequest(Player requester, Player responder)
{
log.debug("[Duel] Player " + responder.getName() + " rejected duel request from " + requester.getName());
PacketSendUtility.sendPacket(requester, SM_SYSTEM_MESSAGE.DUEL_REJECTED_BY(responder.getName()));
PacketSendUtility.sendPacket(responder, SM_SYSTEM_MESSAGE.DUEL_REJECT_DUEL_OF(requester.getName()));
}
/**
* Cancels the duel request
*
* @param target
* the duel target
* @param requester
*/
private void cancelDuelRequest(Player owner, Player target)
{
log.debug("[Duel] Player " + owner.getName() + " cancelled his duel request with " + target.getName());
PacketSendUtility.sendPacket(target, SM_SYSTEM_MESSAGE.DUEL_CANCEL_DUEL_BY(owner.getName()));
PacketSendUtility.sendPacket(owner, SM_SYSTEM_MESSAGE.DUEL_CANCEL_DUEL_WITH(target.getName()));
}
/**
* Starts the duel
*
* @param requester
* the player to start duel with
* @param responder
* the other player
*/
private void startDuel(Player requester, Player responder)
{
PacketSendUtility.sendPacket(requester, SM_DUEL.SM_DUEL_STARTED(responder.getObjectId()));
PacketSendUtility.sendPacket(responder, SM_DUEL.SM_DUEL_STARTED(requester.getObjectId()));
createDuel(requester.getObjectId(), responder.getObjectId());
}
/**
* This method will make the selected player lose the duel
*
* @param player
*/
public void loseDuel(Player player)
{
if(!isDueling(player.getObjectId()))
return;
/**
* all debuffs are removed from looser
*/
player.getEffectController().removeAbnormalEffectsByTargetSlot(SkillTargetSlot.DEBUFF);
int opponnentId = duels.get(player.getObjectId());
Player opponent = world.findPlayer(opponnentId);
if(opponent != null)
{
/**
* all debuffs are removed from winner, but buffs will remain
*/
opponent.getEffectController().removeAbnormalEffectsByTargetSlot(SkillTargetSlot.DEBUFF);
PacketSendUtility.sendPacket(opponent, SM_DUEL.SM_DUEL_RESULT(DuelResult.DUEL_WON, player.getName()));
PacketSendUtility.sendPacket(player, SM_DUEL.SM_DUEL_RESULT(DuelResult.DUEL_LOST, opponent.getName()));
}
else
{
log.warn("CHECKPOINT : duel opponent is already out of world");
}
removeDuel(player.getObjectId(), opponnentId);
}
/**
* @param player
* @param lastAttacker
*/
public void onDie(Player player)
{
loseDuel(player);
player.getLifeStats().setCurrentHp(1);
player.getLifeStats().triggerHpMpRestoreTask();
}
/**
* @param playerObjId
* @return true of player is dueling
*/
public boolean isDueling(int playerObjId)
{
return (duels.containsKey(playerObjId) && duels.containsValue(playerObjId));
}
/**
* @param playerObjId
* @param targetObjId
* @return true of player is dueling
*/
public boolean isDueling(int playerObjId, int targetObjId)
{
return duels.containsKey(playerObjId) && duels.get(playerObjId) == targetObjId;
}
/**
* @param requesterObjId
* @param responderObjId
*/
private void createDuel(int requesterObjId, int responderObjId)
{
duels.put(requesterObjId, responderObjId);
duels.put(responderObjId, requesterObjId);
}
/**
* @param requesterObjId
* @param responderObjId
*/
private void removeDuel(int requesterObjId, int responderObjId)
{
duels.remove(requesterObjId);
duels.remove(responderObjId);
}
}