package l2p.gameserver.network.s2c;
import java.util.ArrayList;
import java.util.List;
import l2p.gameserver.enums.CompassZoneType;
import l2p.gameserver.enums.Relation;
import l2p.gameserver.enums.TeamType;
import l2p.gameserver.managers.games.HandysBlockCheckerManager;
import l2p.gameserver.managers.games.HandysBlockCheckerManager.ArenaParticipantsHolder;
import l2p.gameserver.model.Party;
import l2p.gameserver.model.Playable;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.clan.Clan;
import l2p.gameserver.model.entity.events.GlobalEvent;
import l2p.gameserver.network.components.ServerPackets;
public class RelationChanged extends L2GameServerPacket
{
public static final byte SEND_ONE = (byte) 0x00;
public static final byte SEND_DEFAULT = (byte) 0x01;
public static final byte SEND_MULTI = (byte) 0x04;
private RelationData _single;
private List<RelationData> _multi;
private byte _mask = (byte) 0x00;
public static class RelationData
{
int _objId;
int _relation;
int _autoAttackable;
int _karma;
int _pvpFlag;
}
public RelationChanged()
{
_mask |= SEND_MULTI;
_multi = new ArrayList<>();
}
public RelationChanged(Playable playable, boolean autoAttackable, int relation)
{
_mask |= SEND_ONE;
_single = new RelationData();
_single._objId = playable.getObjectId();
_single._relation = relation;
_single._autoAttackable = autoAttackable ? 1 : 0;
_single._karma = playable.getKarma();
_single._pvpFlag = playable.getPvpFlag();
}
public void add(RelationData data)
{
_multi.add(data);
}
@Override
protected void writeImpl()
{
writeId(ServerPackets.RELATION_CHANGED);
writeC(_mask);
if (_multi == null || _multi.isEmpty())
{
writeRelation(_single);
}
else
{
writeH(_multi.size());
_multi.forEach(data -> writeRelation(data));
}
}
private void writeRelation(RelationData data)
{
writeD(data._objId);
if ((_mask & SEND_DEFAULT) == 0)
{
writeQ(data._relation);
writeC(data._autoAttackable);
writeD(data._karma);
writeC(data._pvpFlag);
}
}
/**
* @param targetPlayable игрок, отношение к которому изменилось
* @param activeChar игрок, которому будет отослан пакет с результатом
*/
public static L2GameServerPacket update(Player sendTo, Playable targetPlayable, Player activeChar)
{
if (sendTo == null || targetPlayable == null || activeChar == null)
return null;
Player targetPlayer = targetPlayable.getPlayer();
int relation = targetPlayer == null ? 0 : getRelation(targetPlayer, activeChar);
return new RelationChanged(targetPlayable, targetPlayable.isTargetable() && targetPlayable.isAutoAttackable(activeChar, null), relation);
}
public static int getRelation(Player player, Player target)
{
int result = 0;
if (CompassZoneType.PVP.checkMask(player.getZoneMask()))
result |= Relation.BATTLE_ZONE.getMask();
if (player.getPvpFlag() != 0)
result |= Relation.PVP.getMask();
if (player.getKarma() < 0)
result |= Relation.PK.getMask();
Clan clan1 = player.getClan();
Clan clan2 = target.getClan();
if (clan1 != null)
{
result |= Relation.CLAN_MEMBER.getMask();
if (player.isClanLeader())
result |= Relation.CLAN_LEADER.getMask();
if (clan1 == clan2)
result |= Relation.CLAN_MATE.getMask();
if (clan1.getAllianceId() != 0)
{
result |= Relation.ALLY_MEMBER.getMask();
if (clan1.getAlliance().getLeader() == clan1 && player.isClanLeader())
result |= Relation.ALLY_LEADER.getMask();
}
}
if (clan1 != null && clan2 != null)
{
if (target.getChaosFestivalMode() < 2 && player.getChaosFestivalMode() < 2)
{
if (clan2.isAtWarWith(clan1))
{
result |= Relation.CLAN_WAR_1_SIDED.getMask();
if (clan1.isAtWarWith(clan2))
result |= Relation.CLAN_WAR_2_SIDED.getMask();
}
}
}
Party party = player.getParty();
if (party != null)
{
if (party == target.getParty())
result |= Relation.HAS_PARTY.getMask();
result |= Relation.PARTY_MEMBER.getMask();
if (party.isLeader(player))
result |= Relation.PARTY_LEADER.getMask();
}
if (player.getBlockCheckerArena() != -1)
{
ArenaParticipantsHolder holder = HandysBlockCheckerManager.getInstance().getHolder(player.getBlockCheckerArena());
int team = holder.getPlayerTeam(player);
if (team == 0)
{
result |= Relation.BLOCK_CHECKER_RED.getMask();
result |= Relation.PVP_RED.getMask();
}
else if (team == 1)
{
result |= Relation.BLOCK_CHECKER_BLUE.getMask();
result |= Relation.PVP_BLUE.getMask();
}
}
if (player.getPvPEventMode() > 0)
{
int mode = player.getPvPEventMode();
TeamType team = player.getTeam();
if (mode == 2)
{
if (team == TeamType.RED)
result |= Relation.PVP_RED.getMask();
else if (team == TeamType.BLUE)
result |= Relation.PVP_BLUE.getMask();
}
else
{
if (team != TeamType.NONE)
result |= Relation.PVP_RED.getMask();
}
}
for (GlobalEvent e : player.getEvents())
result = e.getRelation(player, target, result);
return result;
}
}