Jump to content
L2jOne

L2-One Project

Recommended Posts

2 horas atrás, DAVIROBERTO disse:

qual e o java que  esse server uza?

Boa noite tudo que vocÊ precisa estar no tópico principal basta da uma lida. Ele utiliza java dk 11

Share this post


Link to post
Share on other sites
3 horas atrás, Caio Conceição disse:

Erro ocorre ao tentar logar com personagem hero (ADM) e outros peonagens..

image.png.e9c267161856f205aeec05b1fba4c277.png

Estou ciente desse erro acontece porque você não tem uma subbase completa.

  • Thanks 1

Share this post


Link to post
Share on other sites

No mod auction manager tem um pequeno bug, eu não sei se sua intenção e remover esse mod que por sinal acho muito legal, mas se eu colocar dois itens para vender ambos com o valor de 2kkk e alguém compara os dois um dos valores é perdido já que extrapola o limite.

aproveitando: é possível criar instancias de áreas ? intuito e preservar áreas de farm original fazendo eventos etc.. 

  • I love it 1

Share this post


Link to post
Share on other sites
2 horas atrás, Caio Conceição disse:

No mod auction manager tem um pequeno bug, eu não sei se sua intenção e remover esse mod que por sinal acho muito legal, mas se eu colocar dois itens para vender ambos com o valor de 2kkk e alguém compara os dois um dos valores é perdido já que extrapola o limite.

aproveitando: é possível criar instancias de áreas ? intuito e preservar áreas de farm original fazendo eventos etc.. 

Muito obrigado pelo report. Sobre as instâncias tenho que estudar um pouco mais sobre isso, a um tempo atrás eu dei uma pesquisada sobre isso no H5, contém muitas instancias que podem ser aproveitadas no interlude isso é um desenvolvimento para um futuro breve, pois to visando um projeto para PVP no momento.

Share this post


Link to post
Share on other sites
14 minutos atrás, L2jOne disse:

Muito obrigado pelo report. Sobre as instâncias tenho que estudar um pouco mais sobre isso, a um tempo atrás eu dei uma pesquisada sobre isso no H5, contém muitas instancias que podem ser aproveitadas no interlude isso é um desenvolvimento para um futuro breve, pois to visando um projeto para PVP no momento.

Vai adicionar o dressme?

Share this post


Link to post
Share on other sites
22 horas atrás, L2jOne disse:

Muito obrigado pelo report. Sobre as instâncias tenho que estudar um pouco mais sobre isso, a um tempo atrás eu dei uma pesquisada sobre isso no H5, contém muitas instancias que podem ser aproveitadas no interlude isso é um desenvolvimento para um futuro breve, pois to visando um projeto para PVP no momento.

sei que você ta visando pvp, mas agregaria mais se adotasse o mid ou low rate para testes ? sendo que usamos mais recursos disponíveis 

quando fala pvp estamos falando de quantos x ? eu entendo que melhorando a sorce para um mid ou low atende a todos os modelos. me ajuda a entender ?

Outra duvida é quando você disponibilizar as atualizações no GitHub será a sorce inteira ou notifica onde foi feita a alteração ? porque estou modificando então replicar tudo não é o ideal. 😕

 vlww 😉 

Edited by Caio Conceição

Share this post


Link to post
Share on other sites

Tbm acho. O ideal é focar em low rate, pois assim temos mais coisas funcionando. E aí, automaticamente, atende High Rate. De qualquer maneira, parabéns pela iniciativa!

Edited by Gryphon
  • Like 1

Share this post


Link to post
Share on other sites
6 horas atrás, L2jOne disse:

Você poderia lista os bugs que achou para eu ajeitar eles, fico muito grato.

num dos logs apresenta uma skill na qual os mobs usam, nao sei por qual motivo esta apresentando erro !

no outro é sobre boss mortos parece que nao atualiza na database.

É possessível bugar mobs na parede eles não tentam contornar !

Share this post


Link to post
Share on other sites
2 horas atrás, Caio Conceição disse:

num dos logs apresenta uma skill na qual os mobs usam, nao sei por qual motivo esta apresentando erro !

no outro é sobre boss mortos parece que nao atualiza na database.

É possessível bugar mobs na parede eles não tentam contornar !

Esse erro de skill é por causa do evento devo ter esquecido algo, sobre o Boss tenho que olhar.

Share this post


Link to post
Share on other sites
5 horas atrás, L2jOne disse:

Esse erro de skill é por causa do evento devo ter esquecido algo, sobre o Boss tenho que olhar.

Pt > 2 quando o lider leva dc ou ele da /leave a pt desfaz por inteira.

  • I love it 1

Share this post


Link to post
Share on other sites
4 horas atrás, Caio Conceição disse:

Pt > 2 quando o lider leva dc ou ele da /leave a pt desfaz por inteira.

Provavelmente isso seja normal, aCis é baseada em l2off então tem que olhar isso é realmente um bug.

Share this post


Link to post
Share on other sites
17 horas atrás, L2jOne disse:

Provavelmente isso seja normal, aCis é baseada em l2off então tem que olhar isso é realmente um bug.

Bom eu notei isso, mas já to acostumado pois na maioria dos servers q eu joguei era assim. se o lider sai ou cai a party é desfeita completamente. Por isso eu nem notei esse problema como um bug.

  • Thanks 1

Share this post


Link to post
Share on other sites
1 hora atrás, ShadowBR disse:

Bom eu notei isso, mas já to acostumado pois na maioria dos servers q eu joguei era assim. se o lider sai ou cai a party é desfeita completamente. Por isso eu nem notei esse problema como um bug.

Spoiler
package net.sf.l2j.gameserver.model.group;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;

import net.sf.l2j.commons.concurrent.ThreadPool;
import net.sf.l2j.commons.math.MathUtil;
import net.sf.l2j.commons.random.Rnd;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.data.manager.DimensionalRiftManager;
import net.sf.l2j.gameserver.data.manager.MonsterHunterManager;
import net.sf.l2j.gameserver.data.manager.DuelManager;
import net.sf.l2j.gameserver.data.manager.FestivalOfDarknessManager;
import net.sf.l2j.gameserver.enums.LootRule;
import net.sf.l2j.gameserver.enums.MessageType;
import net.sf.l2j.gameserver.model.WorldObject;
import net.sf.l2j.gameserver.model.actor.Attackable;
import net.sf.l2j.gameserver.model.actor.Creature;
import net.sf.l2j.gameserver.model.actor.Player;
import net.sf.l2j.gameserver.model.actor.instance.Servitor;
import net.sf.l2j.gameserver.model.actor.npc.RewardInfo;
import net.sf.l2j.gameserver.model.actor.player.BlockList;
import net.sf.l2j.gameserver.model.holder.IntIntHolder;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.model.partymatching.PartyMatchRoom;
import net.sf.l2j.gameserver.model.partymatching.PartyMatchRoomList;
import net.sf.l2j.gameserver.model.rift.DimensionalRift;
import net.sf.l2j.gameserver.model.rift.MonsterHunter; //edit
import net.sf.l2j.gameserver.network.SystemMessageId;
import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
import net.sf.l2j.gameserver.network.serverpackets.ExCloseMPCC;
import net.sf.l2j.gameserver.network.serverpackets.ExOpenMPCC;
import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
import net.sf.l2j.gameserver.network.serverpackets.PartyMemberPosition;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowAdd;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowAll;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowDelete;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowDeleteAll;
import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;

public class Party extends AbstractGroup
{
	private static final double[] BONUS_EXP_SP =
	{
		1,
		1,
		1.30,
		1.39,
		1.50,
		1.54,
		1.58,
		1.63,
		1.67,
		1.71
	};
	
	private static final int PARTY_POSITION_BROADCAST = 12000;
	
	private final List<Player> _members = new CopyOnWriteArrayList<>();
	private final LootRule _lootRule;
	
	private boolean _pendingInvitation;
	private long _pendingInviteTimeout;
	private int _itemLastLoot;
	
	private CommandChannel _commandChannel;
	private DimensionalRift _rift;
	
	private MonsterHunter _hunter;//edit
	
	private Future<?> _positionBroadcastTask;
	protected PartyMemberPosition _positionPacket;
	
	public Party(Player leader, Player target, LootRule lootRule)
	{
		super(leader);
		
		_members.add(leader);
		_members.add(target);
		
		leader.setParty(this);
		target.setParty(this);
		
		_lootRule = lootRule;
		
		recalculateLevel();
		
		// Send new member party window for all members.
		target.sendPacket(new PartySmallWindowAll(target, this));
		leader.sendPacket(new PartySmallWindowAdd(target, this));
		
		// Send messages.
		target.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_JOINED_S1_PARTY).addCharName(leader));
		leader.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_JOINED_PARTY).addCharName(target));
		
		// Update icons.
		for (Player member : _members)
		{
			member.updateEffectIcons(true);
			member.broadcastUserInfo();
		}
		
		_positionBroadcastTask = ThreadPool.scheduleAtFixedRate(new PositionBroadcast(), PARTY_POSITION_BROADCAST / 2, PARTY_POSITION_BROADCAST);
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if (!(obj instanceof Party))
			return false;
		
		if (obj == this)
			return true;
		
		return isLeader(((Party) obj).getLeader());
	}
	
	@Override
	public final List<Player> getMembers()
	{
		return _members;
	}
	
	@Override
	public int getMembersCount()
	{
		return _members.size();
	}
	
	@Override
	public boolean containsPlayer(WorldObject player)
	{
		return _members.contains(player);
	}
	
	@Override
	public void broadcastPacket(final L2GameServerPacket packet)
	{
		for (Player member : _members)
			member.sendPacket(packet);
	}
	
	@Override
	public void broadcastCreatureSay(final CreatureSay msg, final Player broadcaster)
	{
		for (Player member : _members)
		{
			if (!BlockList.isBlocked(member, broadcaster))
				member.sendPacket(msg);
		}
	}
	
	@Override
	public void recalculateLevel()
	{
		int newLevel = 0;
		for (Player member : _members)
		{
			if (member.getLevel() > newLevel)
				newLevel = member.getLevel();
		}
		setLevel(newLevel);
	}
	
	@Override
	public void disband()
	{
		
		
		MonsterHunterManager.getInstance().onPartyEdit(this); //edit
		// Cancel current rift session.
		DimensionalRiftManager.getInstance().onPartyEdit(this);
		
		// Cancel party duel based on leader, as it will affect all players anyway.
		DuelManager.getInstance().onPartyEdit(getLeader());
		
		// Delete the CommandChannel, or remove Party from it.
		if (_commandChannel != null)
		{
			broadcastPacket(ExCloseMPCC.STATIC_PACKET);
			
			if (_commandChannel.isLeader(getLeader()))
				_commandChannel.disband();
			else
				_commandChannel.removeParty(this);
		}
		
		for (Player member : _members)
		{
			member.setParty(null);
			member.sendPacket(PartySmallWindowDeleteAll.STATIC_PACKET);
			
			if (member.isFestivalParticipant())
				FestivalOfDarknessManager.getInstance().updateParticipants(member, this);
			
			if (member.getFusionSkill() != null)
				member.abortCast();
			
			for (Creature character : member.getKnownType(Creature.class))
				if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == member)
					character.abortCast();
				
			member.sendPacket(SystemMessageId.PARTY_DISPERSED);
		}
		_members.clear();
		
		if (_positionBroadcastTask != null)
		{
			_positionBroadcastTask.cancel(false);
			_positionBroadcastTask = null;
		}
	}
	
	/**
	 * Check if another player can start invitation process.
	 * @return boolean if party waits for invitation respond.
	 */
	public boolean getPendingInvitation()
	{
		return _pendingInvitation;
	}
	
	/**
	 * Set invitation process flag and store time for expiration happens when player join or decline to join.
	 * @param val : set the invitation process flag to that value.
	 */
	public void setPendingInvitation(boolean val)
	{
		_pendingInvitation = val;
		_pendingInviteTimeout = System.currentTimeMillis() + Player.REQUEST_TIMEOUT * 1000;
	}
	
	/**
	 * Check if player invitation is expired.
	 * @return boolean if time is expired.
	 * @see net.sf.l2j.gameserver.model.actor.Player#isRequestExpired()
	 */
	public boolean isInvitationRequestExpired()
	{
		return _pendingInviteTimeout <= System.currentTimeMillis();
	}
	
	/**
	 * Get a random member from this party.
	 * @param itemId : the ID of the item for which the member must have inventory space.
	 * @param target : the object of which the member must be within a certain range (must not be null).
	 * @return a random member from this party or {@code null} if none of the members have inventory space for the specified item.
	 */
	private Player getRandomMember(int itemId, Creature target)
	{
		final List<Player> availableMembers = new ArrayList<>();
		for (Player member : _members)
		{
			if (member.getInventory().validateCapacityByItemId(itemId) && MathUtil.checkIfInRange(Config.PARTY_RANGE, target, member, true))
				availableMembers.add(member);
		}
		return (availableMembers.isEmpty()) ? null : Rnd.get(availableMembers);
	}
	
	/**
	 * Get the next item looter for this party.
	 * @param itemId : the ID of the item for which the member must have inventory space.
	 * @param target : the object of which the member must be within a certain range (must not be null).
	 * @return the next looter from this party or {@code null} if none of the members have inventory space for the specified item.
	 */
	private Player getNextLooter(int itemId, Creature target)
	{
		for (int i = 0; i < getMembersCount(); i++)
		{
			if (++_itemLastLoot >= getMembersCount())
				_itemLastLoot = 0;
			
			final Player member = _members.get(_itemLastLoot);
			if (member.getInventory().validateCapacityByItemId(itemId) && MathUtil.checkIfInRange(Config.PARTY_RANGE, target, member, true))
				return member;
		}
		return null;
	}
	
	/**
	 * @param player : the potential, initial looter.
	 * @param itemId : the ID of the item for which the member must have inventory space.
	 * @param spoil : a boolean used for spoil process.
	 * @param target : the object of which the member must be within a certain range (must not be null).
	 * @return the next Player looter.
	 */
	private Player getActualLooter(Player player, int itemId, boolean spoil, Creature target)
	{
		Player looter = player;
		
		switch (_lootRule)
		{
			case ITEM_RANDOM:
				if (!spoil)
					looter = getRandomMember(itemId, target);
				break;
			
			case ITEM_RANDOM_SPOIL:
				looter = getRandomMember(itemId, target);
				break;
			
			case ITEM_ORDER:
				if (!spoil)
					looter = getNextLooter(itemId, target);
				break;
			
			case ITEM_ORDER_SPOIL:
				looter = getNextLooter(itemId, target);
				break;
		}
		
		return (looter == null) ? player : looter;
	}
	
	public void broadcastNewLeaderStatus()
	{
		final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_BECOME_A_PARTY_LEADER).addCharName(getLeader());
		for (Player member : _members)
		{
			member.sendPacket(PartySmallWindowDeleteAll.STATIC_PACKET);
			member.sendPacket(new PartySmallWindowAll(member, this));
			member.broadcastUserInfo();
			member.sendPacket(sm);
		}
	}
	
	/**
	 * Send a packet to all other players of the Party, except the player.
	 * @param player : this player won't receive the packet.
	 * @param msg : the packet to send.
	 */
	public void broadcastToPartyMembers(Player player, L2GameServerPacket msg)
	{
		for (Player member : _members)
		{
			if (member != null && !member.equals(player))
				member.sendPacket(msg);
		}
	}
	
	/**
	 * Add a new member to the party.
	 * @param player : the player to add to the party.
	 */
	public void addPartyMember(Player player)
	{
		if (player == null || _members.contains(player))
			return;
		
		// Send new member party window for all members.
		player.sendPacket(new PartySmallWindowAll(player, this));
		broadcastPacket(new PartySmallWindowAdd(player, this));
		
		// Send messages.
		player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_JOINED_S1_PARTY).addCharName(getLeader()));
		broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_JOINED_PARTY).addCharName(player));
		
		// Cancel current rift session.
		DimensionalRiftManager.getInstance().onPartyEdit(this);
		
		
		MonsterHunterManager.getInstance().onPartyEdit(this); //edit
		
		// Cancel party duel based on leader, as it will affect all players anyway.
		DuelManager.getInstance().onPartyEdit(getLeader());
		
		// Add player to party.
		_members.add(player);
		
		// Add party to player.
		player.setParty(this);
		
		// Adjust party level.
		if (player.getLevel() > getLevel())
			setLevel(player.getLevel());
		
		// Update icons.
		for (Player member : _members)
		{
			member.updateEffectIcons(true);
			member.broadcastUserInfo();
		}
		
		if (_commandChannel != null)
			player.sendPacket(ExOpenMPCC.STATIC_PACKET);
	}
	
	/**
	 * Removes a party member using its name.
	 * @param name : player the player to remove from the party.
	 * @param type : the message type {@link MessageType}.
	 */
	public void removePartyMember(String name, MessageType type)
	{
		removePartyMember(getPlayerByName(name), type);
	}
	
	/**
	 * Removes a party member instance.
	 * @param player : the player to remove from the party.
	 * @param type : the message type {@link MessageType}.
	 */
	public void removePartyMember(Player player, MessageType type)
	{
		if (player == null || !_members.contains(player))
			return;
		
		if (_members.size() == 2 && isLeader(player) || _members.size() == 2  ) {
			disband();
		}
		
			else if(isLeader(player) && _members.size() < 2) {
				setLeader(_members.get(1));
				_members.remove(player);
			}
		else
		{
			// Cancel current rift session.
			DimensionalRiftManager.getInstance().onPartyEdit(this);
			
			MonsterHunterManager.getInstance().onPartyEdit(this); //edit
			
			// Cancel party duel based on leader, as it will affect all players anyway.
			DuelManager.getInstance().onPartyEdit(getLeader());
			
			_members.remove(player);
			recalculateLevel();
			
			if (player.isFestivalParticipant())
				FestivalOfDarknessManager.getInstance().updateParticipants(player, this);
			
			if (player.getFusionSkill() != null)
				player.abortCast();
			
			for (Creature character : player.getKnownType(Creature.class))
				if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == player)
					character.abortCast();
				
			if (type == MessageType.EXPELLED)
			{
				player.sendPacket(SystemMessageId.HAVE_BEEN_EXPELLED_FROM_PARTY);
				broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_WAS_EXPELLED_FROM_PARTY).addCharName(player));
			}
			else if (type == MessageType.LEFT || type == MessageType.DISCONNECTED)
			{
				player.sendPacket(SystemMessageId.YOU_LEFT_PARTY);
				broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_LEFT_PARTY).addCharName(player));
			}
			
			player.setParty(null);
			player.sendPacket(PartySmallWindowDeleteAll.STATIC_PACKET);
			
			broadcastPacket(new PartySmallWindowDelete(player));
			
			if (_commandChannel != null)
				player.sendPacket(ExCloseMPCC.STATIC_PACKET);
		}
	}
	
	/**
	 * Change the party leader. If CommandChannel leader was the previous leader, change it too.
	 * @param name : the name of the player newly promoted to leader.
	 */
	public void changePartyLeader(String name)
	{
		final Player player = getPlayerByName(name);
		if (player == null || player.isInDuel())
			return;
		
		// Can't set leader if not part of the party.
		if (!_members.contains(player))
		{
			player.sendPacket(SystemMessageId.YOU_CAN_TRANSFER_RIGHTS_ONLY_TO_ANOTHER_PARTY_MEMBER);
			return;
		}
		
		// If already leader, abort.
		if (isLeader(player))
		{
			player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFER_RIGHTS_TO_YOURSELF);
			return;
		}
		
		// Refresh channel leader, if any.
		if (_commandChannel != null && _commandChannel.isLeader(getLeader()))
		{
			_commandChannel.setLeader(player);
			_commandChannel.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.COMMAND_CHANNEL_LEADER_NOW_S1).addCharName(player));
		}
		
		// Update this party leader and broadcast the update.
		setLeader(player);
		broadcastNewLeaderStatus();
		
		if (player.isInPartyMatchRoom())
		{
			final PartyMatchRoom room = PartyMatchRoomList.getInstance().getPlayerRoom(player);
			room.changeLeader(player);
		}
	}
	
	/**
	 * @param name : the name of the player to search.
	 * @return a party member by its name.
	 */
	private Player getPlayerByName(String name)
	{
		for (Player member : _members)
		{
			if (member.getName().equalsIgnoreCase(name))
				return member;
		}
		return null;
	}
	
	/**
	 * Distribute item(s) to one party member, based on party LootRule.
	 * @param player : the initial looter.
	 * @param item : the looted item to distribute.
	 */
	public void distributeItem(Player player, ItemInstance item)
	{
		if (item.getItemId() == 57)
		{
			distributeAdena(player, item.getCount(), player);
			item.destroyMe("Party", player, null);
			return;
		}
		
		final Player target = getActualLooter(player, item.getItemId(), false, player);
		if (target == null)
			return;
		
		// Send messages to other party members about reward.
		if (item.getCount() > 1)
			broadcastToPartyMembers(target, SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S3_S2).addCharName(target).addItemName(item).addItemNumber(item.getCount()));
		else if (item.getEnchantLevel() > 0)
			broadcastToPartyMembers(target, SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S2_S3).addCharName(target).addNumber(item.getEnchantLevel()).addItemName(item));
		else
			broadcastToPartyMembers(target, SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S2).addCharName(target).addItemName(item));
		
		target.addItem("Party", item, player, true);
	}
	
	/**
	 * Distribute item(s) to one party member, based on party LootRule.
	 * @param player : the initial looter.
	 * @param item : the looted item to distribute.
	 * @param spoil : true if the item comes from a spoil process.
	 * @param target : the looted character.
	 */
	public void distributeItem(Player player, IntIntHolder item, boolean spoil, Attackable target)
	{
		if (item == null)
			return;
		
		if (item.getId() == 57)
		{
			distributeAdena(player, item.getValue(), target);
			return;
		}
		
		final Player looter = getActualLooter(player, item.getId(), spoil, target);
		if (looter == null)
			return;
		
		looter.addItem(spoil ? "Sweep" : "Party", item.getId(), item.getValue(), player, true);
		
		// Send messages to other party members about reward.
		SystemMessage msg;
		if (item.getValue() > 1)
		{
			msg = (spoil) ? SystemMessage.getSystemMessage(SystemMessageId.S1_SWEEPED_UP_S3_S2) : SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S3_S2);
			msg.addCharName(looter);
			msg.addItemName(item.getId());
			msg.addItemNumber(item.getValue());
		}
		else
		{
			msg = (spoil) ? SystemMessage.getSystemMessage(SystemMessageId.S1_SWEEPED_UP_S2) : SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S2);
			msg.addCharName(looter);
			msg.addItemName(item.getId());
		}
		broadcastToPartyMembers(looter, msg);
	}
	
	/**
	 * Distribute adena to party members, according distance.
	 * @param player : The player who picked.
	 * @param adena : Amount of adenas.
	 * @param target : Target used for distance checks.
	 */
	public void distributeAdena(Player player, int adena, Creature target)
	{
		List<Player> toReward = new ArrayList<>(_members.size());
		for (Player member : _members)
		{
			if (!MathUtil.checkIfInRange(Config.PARTY_RANGE, target, member, true) || member.getAdena() == Integer.MAX_VALUE)
				continue;
			
			toReward.add(member);
		}
		
		// Avoid divisions by 0.
		if (toReward.isEmpty())
			return;
		
		final int count = adena / toReward.size();
		for (Player member : toReward)
			member.addAdena("Party", count, player, true);
	}
	
	/**
	 * Distribute Experience and SP rewards to party members in the known area of the last attacker.<BR>
	 * <BR>
	 * <B><U> Actions</U> :</B><BR>
	 * <ul>
	 * <li>Get the owner of the Summon (if necessary).</li>
	 * <li>Calculate the Experience and SP reward distribution rate.</li>
	 * <li>Add Experience and SP to the player.</li>
	 * </ul>
	 * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T GIVE rewards to Pet</B></FONT><BR>
	 * <BR>
	 * Exception are Pets that leech from the owner's XP; they get the exp indirectly, via the owner's exp gain.<BR>
	 * @param xpReward : The Experience reward to distribute.
	 * @param spReward : The SP reward to distribute.
	 * @param rewardedMembers : The list of Player to reward.
	 * @param topLvl : The maximum level.
	 * @param rewards : The list of players and summons.
	 */
	public void distributeXpAndSp(long xpReward, int spReward, List<Player> rewardedMembers, int topLvl, Map<Creature, RewardInfo> rewards)
	{
		final List<Player> validMembers = new ArrayList<>();
		
		if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("level"))
		{
			for (Player member : rewardedMembers)
			{
				if (topLvl - member.getLevel() <= Config.PARTY_XP_CUTOFF_LEVEL)
					validMembers.add(member);
			}
		}
		else if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("percentage"))
		{
			int sqLevelSum = 0;
			for (Player member : rewardedMembers)
				sqLevelSum += (member.getLevel() * member.getLevel());
			
			for (Player member : rewardedMembers)
			{
				int sqLevel = member.getLevel() * member.getLevel();
				if (sqLevel * 100 >= sqLevelSum * Config.PARTY_XP_CUTOFF_PERCENT)
					validMembers.add(member);
			}
		}
		else if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("auto"))
		{
			int sqLevelSum = 0;
			for (Player member : rewardedMembers)
				sqLevelSum += (member.getLevel() * member.getLevel());
			
			// Have to use range 1 to 9, since we -1 it : 0 can't be a good number (would lead to a IOOBE). Since 0 and 1 got same values, it's not a problem.
			final int partySize = MathUtil.limit(rewardedMembers.size(), 1, 9);
			
			for (Player member : rewardedMembers)
			{
				int sqLevel = member.getLevel() * member.getLevel();
				if (sqLevel >= sqLevelSum * (1 - 1 / (1 + BONUS_EXP_SP[partySize] - BONUS_EXP_SP[partySize - 1])))
					validMembers.add(member);
			}
		}
		
		// Since validMembers can also hold CommandChannel members, we have to restrict the value.
		final double partyRate = BONUS_EXP_SP[Math.min(validMembers.size(), 9)];
		
		xpReward *= partyRate * Config.RATE_PARTY_XP;
		spReward *= partyRate * Config.RATE_PARTY_SP;
		
		int sqLevelSum = 0;
		for (Player member : validMembers)
			sqLevelSum += member.getLevel() * member.getLevel();
		
		// Go through the players that must be rewarded.
		for (Player member : rewardedMembers)
		{
			if (member.isDead())
				continue;
			
			// Calculate and add the EXP and SP reward to the member.
			if (validMembers.contains(member))
			{
				// The servitor penalty.
				final float penalty = member.hasServitor() ? ((Servitor) member.getSummon()).getExpPenalty() : 0;
				
				final double sqLevel = member.getLevel() * member.getLevel();
				final double preCalculation = (sqLevel / sqLevelSum) * (1 - penalty);
				
				final long xp = Math.round(xpReward * preCalculation);
				final int sp = (int) (spReward * preCalculation);
				
				// Set new karma.
				member.updateKarmaLoss(xp);
				
				// Add the XP/SP points to the requested party member.
				member.addExpAndSp(xp, sp, rewards);
			}
			else
				member.addExpAndSp(0, 0);
		}
	}
	
	public LootRule getLootRule()
	{
		return _lootRule;
	}
	
	public boolean isInCommandChannel()
	{
		return _commandChannel != null;
	}
	
	public CommandChannel getCommandChannel()
	{
		return _commandChannel;
	}
	
	public void setCommandChannel(CommandChannel channel)
	{
		_commandChannel = channel;
	}
	
	public boolean isInDimensionalRift()
	{
		return _rift != null;
	}
	
	public DimensionalRift getDimensionalRift()
	{
		return _rift;
	}
	
	public void setDimensionalRift(DimensionalRift rift)
	{
		_rift = rift;
	}
	
	 //edit
	public boolean isInMonsterHunter()
	{
		return _hunter != null;
	}
	
	public MonsterHunter getMonsterHunter()
	{
		return _hunter;
	}
	
	public void setMonsterHunter(MonsterHunter hunter)
	{
		_hunter = hunter;
	}
	 //edit
	
	/**
	 * @return true if the entire party is currently dead.
	 */
	public boolean wipedOut()
	{
		for (Player member : _members)
		{
			if (!member.isDead())
				return false;
		}
		return true;
	}
	
	protected class PositionBroadcast implements Runnable
	{
		@Override
		public void run()
		{
			if (_positionPacket == null)
				_positionPacket = new PartyMemberPosition(Party.this);
			else
				_positionPacket.reuse(Party.this);
			
			broadcastPacket(_positionPacket);
		}
	}
}

 

Eu ajustei segundo o que achei certo, baseado no index quando a pt for > 2 ele pega o primeiro e transforma em lider

Edited by Caio Conceição

Share this post


Link to post
Share on other sites
21 horas atrás, Caio Conceição disse:
  Mostrar conteúdo oculto

package net.sf.l2j.gameserver.model.group;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;

import net.sf.l2j.commons.concurrent.ThreadPool;
import net.sf.l2j.commons.math.MathUtil;
import net.sf.l2j.commons.random.Rnd;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.data.manager.DimensionalRiftManager;
import net.sf.l2j.gameserver.data.manager.MonsterHunterManager;
import net.sf.l2j.gameserver.data.manager.DuelManager;
import net.sf.l2j.gameserver.data.manager.FestivalOfDarknessManager;
import net.sf.l2j.gameserver.enums.LootRule;
import net.sf.l2j.gameserver.enums.MessageType;
import net.sf.l2j.gameserver.model.WorldObject;
import net.sf.l2j.gameserver.model.actor.Attackable;
import net.sf.l2j.gameserver.model.actor.Creature;
import net.sf.l2j.gameserver.model.actor.Player;
import net.sf.l2j.gameserver.model.actor.instance.Servitor;
import net.sf.l2j.gameserver.model.actor.npc.RewardInfo;
import net.sf.l2j.gameserver.model.actor.player.BlockList;
import net.sf.l2j.gameserver.model.holder.IntIntHolder;
import net.sf.l2j.gameserver.model.item.instance.ItemInstance;
import net.sf.l2j.gameserver.model.partymatching.PartyMatchRoom;
import net.sf.l2j.gameserver.model.partymatching.PartyMatchRoomList;
import net.sf.l2j.gameserver.model.rift.DimensionalRift;
import net.sf.l2j.gameserver.model.rift.MonsterHunter; //edit
import net.sf.l2j.gameserver.network.SystemMessageId;
import net.sf.l2j.gameserver.network.serverpackets.CreatureSay;
import net.sf.l2j.gameserver.network.serverpackets.ExCloseMPCC;
import net.sf.l2j.gameserver.network.serverpackets.ExOpenMPCC;
import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
import net.sf.l2j.gameserver.network.serverpackets.PartyMemberPosition;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowAdd;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowAll;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowDelete;
import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowDeleteAll;
import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;

public class Party extends AbstractGroup
{
	private static final double[] BONUS_EXP_SP =
	{
		1,
		1,
		1.30,
		1.39,
		1.50,
		1.54,
		1.58,
		1.63,
		1.67,
		1.71
	};
	
	private static final int PARTY_POSITION_BROADCAST = 12000;
	
	private final List<Player> _members = new CopyOnWriteArrayList<>();
	private final LootRule _lootRule;
	
	private boolean _pendingInvitation;
	private long _pendingInviteTimeout;
	private int _itemLastLoot;
	
	private CommandChannel _commandChannel;
	private DimensionalRift _rift;
	
	private MonsterHunter _hunter;//edit
	
	private Future<?> _positionBroadcastTask;
	protected PartyMemberPosition _positionPacket;
	
	public Party(Player leader, Player target, LootRule lootRule)
	{
		super(leader);
		
		_members.add(leader);
		_members.add(target);
		
		leader.setParty(this);
		target.setParty(this);
		
		_lootRule = lootRule;
		
		recalculateLevel();
		
		// Send new member party window for all members.
		target.sendPacket(new PartySmallWindowAll(target, this));
		leader.sendPacket(new PartySmallWindowAdd(target, this));
		
		// Send messages.
		target.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_JOINED_S1_PARTY).addCharName(leader));
		leader.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_JOINED_PARTY).addCharName(target));
		
		// Update icons.
		for (Player member : _members)
		{
			member.updateEffectIcons(true);
			member.broadcastUserInfo();
		}
		
		_positionBroadcastTask = ThreadPool.scheduleAtFixedRate(new PositionBroadcast(), PARTY_POSITION_BROADCAST / 2, PARTY_POSITION_BROADCAST);
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if (!(obj instanceof Party))
			return false;
		
		if (obj == this)
			return true;
		
		return isLeader(((Party) obj).getLeader());
	}
	
	@Override
	public final List<Player> getMembers()
	{
		return _members;
	}
	
	@Override
	public int getMembersCount()
	{
		return _members.size();
	}
	
	@Override
	public boolean containsPlayer(WorldObject player)
	{
		return _members.contains(player);
	}
	
	@Override
	public void broadcastPacket(final L2GameServerPacket packet)
	{
		for (Player member : _members)
			member.sendPacket(packet);
	}
	
	@Override
	public void broadcastCreatureSay(final CreatureSay msg, final Player broadcaster)
	{
		for (Player member : _members)
		{
			if (!BlockList.isBlocked(member, broadcaster))
				member.sendPacket(msg);
		}
	}
	
	@Override
	public void recalculateLevel()
	{
		int newLevel = 0;
		for (Player member : _members)
		{
			if (member.getLevel() > newLevel)
				newLevel = member.getLevel();
		}
		setLevel(newLevel);
	}
	
	@Override
	public void disband()
	{
		
		
		MonsterHunterManager.getInstance().onPartyEdit(this); //edit
		// Cancel current rift session.
		DimensionalRiftManager.getInstance().onPartyEdit(this);
		
		// Cancel party duel based on leader, as it will affect all players anyway.
		DuelManager.getInstance().onPartyEdit(getLeader());
		
		// Delete the CommandChannel, or remove Party from it.
		if (_commandChannel != null)
		{
			broadcastPacket(ExCloseMPCC.STATIC_PACKET);
			
			if (_commandChannel.isLeader(getLeader()))
				_commandChannel.disband();
			else
				_commandChannel.removeParty(this);
		}
		
		for (Player member : _members)
		{
			member.setParty(null);
			member.sendPacket(PartySmallWindowDeleteAll.STATIC_PACKET);
			
			if (member.isFestivalParticipant())
				FestivalOfDarknessManager.getInstance().updateParticipants(member, this);
			
			if (member.getFusionSkill() != null)
				member.abortCast();
			
			for (Creature character : member.getKnownType(Creature.class))
				if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == member)
					character.abortCast();
				
			member.sendPacket(SystemMessageId.PARTY_DISPERSED);
		}
		_members.clear();
		
		if (_positionBroadcastTask != null)
		{
			_positionBroadcastTask.cancel(false);
			_positionBroadcastTask = null;
		}
	}
	
	/**
	 * Check if another player can start invitation process.
	 * @return boolean if party waits for invitation respond.
	 */
	public boolean getPendingInvitation()
	{
		return _pendingInvitation;
	}
	
	/**
	 * Set invitation process flag and store time for expiration happens when player join or decline to join.
	 * @param val : set the invitation process flag to that value.
	 */
	public void setPendingInvitation(boolean val)
	{
		_pendingInvitation = val;
		_pendingInviteTimeout = System.currentTimeMillis() + Player.REQUEST_TIMEOUT * 1000;
	}
	
	/**
	 * Check if player invitation is expired.
	 * @return boolean if time is expired.
	 * @see net.sf.l2j.gameserver.model.actor.Player#isRequestExpired()
	 */
	public boolean isInvitationRequestExpired()
	{
		return _pendingInviteTimeout <= System.currentTimeMillis();
	}
	
	/**
	 * Get a random member from this party.
	 * @param itemId : the ID of the item for which the member must have inventory space.
	 * @param target : the object of which the member must be within a certain range (must not be null).
	 * @return a random member from this party or {@code null} if none of the members have inventory space for the specified item.
	 */
	private Player getRandomMember(int itemId, Creature target)
	{
		final List<Player> availableMembers = new ArrayList<>();
		for (Player member : _members)
		{
			if (member.getInventory().validateCapacityByItemId(itemId) && MathUtil.checkIfInRange(Config.PARTY_RANGE, target, member, true))
				availableMembers.add(member);
		}
		return (availableMembers.isEmpty()) ? null : Rnd.get(availableMembers);
	}
	
	/**
	 * Get the next item looter for this party.
	 * @param itemId : the ID of the item for which the member must have inventory space.
	 * @param target : the object of which the member must be within a certain range (must not be null).
	 * @return the next looter from this party or {@code null} if none of the members have inventory space for the specified item.
	 */
	private Player getNextLooter(int itemId, Creature target)
	{
		for (int i = 0; i < getMembersCount(); i++)
		{
			if (++_itemLastLoot >= getMembersCount())
				_itemLastLoot = 0;
			
			final Player member = _members.get(_itemLastLoot);
			if (member.getInventory().validateCapacityByItemId(itemId) && MathUtil.checkIfInRange(Config.PARTY_RANGE, target, member, true))
				return member;
		}
		return null;
	}
	
	/**
	 * @param player : the potential, initial looter.
	 * @param itemId : the ID of the item for which the member must have inventory space.
	 * @param spoil : a boolean used for spoil process.
	 * @param target : the object of which the member must be within a certain range (must not be null).
	 * @return the next Player looter.
	 */
	private Player getActualLooter(Player player, int itemId, boolean spoil, Creature target)
	{
		Player looter = player;
		
		switch (_lootRule)
		{
			case ITEM_RANDOM:
				if (!spoil)
					looter = getRandomMember(itemId, target);
				break;
			
			case ITEM_RANDOM_SPOIL:
				looter = getRandomMember(itemId, target);
				break;
			
			case ITEM_ORDER:
				if (!spoil)
					looter = getNextLooter(itemId, target);
				break;
			
			case ITEM_ORDER_SPOIL:
				looter = getNextLooter(itemId, target);
				break;
		}
		
		return (looter == null) ? player : looter;
	}
	
	public void broadcastNewLeaderStatus()
	{
		final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_BECOME_A_PARTY_LEADER).addCharName(getLeader());
		for (Player member : _members)
		{
			member.sendPacket(PartySmallWindowDeleteAll.STATIC_PACKET);
			member.sendPacket(new PartySmallWindowAll(member, this));
			member.broadcastUserInfo();
			member.sendPacket(sm);
		}
	}
	
	/**
	 * Send a packet to all other players of the Party, except the player.
	 * @param player : this player won't receive the packet.
	 * @param msg : the packet to send.
	 */
	public void broadcastToPartyMembers(Player player, L2GameServerPacket msg)
	{
		for (Player member : _members)
		{
			if (member != null && !member.equals(player))
				member.sendPacket(msg);
		}
	}
	
	/**
	 * Add a new member to the party.
	 * @param player : the player to add to the party.
	 */
	public void addPartyMember(Player player)
	{
		if (player == null || _members.contains(player))
			return;
		
		// Send new member party window for all members.
		player.sendPacket(new PartySmallWindowAll(player, this));
		broadcastPacket(new PartySmallWindowAdd(player, this));
		
		// Send messages.
		player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_JOINED_S1_PARTY).addCharName(getLeader()));
		broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_JOINED_PARTY).addCharName(player));
		
		// Cancel current rift session.
		DimensionalRiftManager.getInstance().onPartyEdit(this);
		
		
		MonsterHunterManager.getInstance().onPartyEdit(this); //edit
		
		// Cancel party duel based on leader, as it will affect all players anyway.
		DuelManager.getInstance().onPartyEdit(getLeader());
		
		// Add player to party.
		_members.add(player);
		
		// Add party to player.
		player.setParty(this);
		
		// Adjust party level.
		if (player.getLevel() > getLevel())
			setLevel(player.getLevel());
		
		// Update icons.
		for (Player member : _members)
		{
			member.updateEffectIcons(true);
			member.broadcastUserInfo();
		}
		
		if (_commandChannel != null)
			player.sendPacket(ExOpenMPCC.STATIC_PACKET);
	}
	
	/**
	 * Removes a party member using its name.
	 * @param name : player the player to remove from the party.
	 * @param type : the message type {@link MessageType}.
	 */
	public void removePartyMember(String name, MessageType type)
	{
		removePartyMember(getPlayerByName(name), type);
	}
	
	/**
	 * Removes a party member instance.
	 * @param player : the player to remove from the party.
	 * @param type : the message type {@link MessageType}.
	 */
	public void removePartyMember(Player player, MessageType type)
	{
		if (player == null || !_members.contains(player))
			return;
		
		if (_members.size() == 2 && isLeader(player) || _members.size() == 2  ) {
			disband();
		}
		
			else if(isLeader(player) && _members.size() < 2) {
				setLeader(_members.get(1));
				_members.remove(player);
			}
		else
		{
			// Cancel current rift session.
			DimensionalRiftManager.getInstance().onPartyEdit(this);
			
			MonsterHunterManager.getInstance().onPartyEdit(this); //edit
			
			// Cancel party duel based on leader, as it will affect all players anyway.
			DuelManager.getInstance().onPartyEdit(getLeader());
			
			_members.remove(player);
			recalculateLevel();
			
			if (player.isFestivalParticipant())
				FestivalOfDarknessManager.getInstance().updateParticipants(player, this);
			
			if (player.getFusionSkill() != null)
				player.abortCast();
			
			for (Creature character : player.getKnownType(Creature.class))
				if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == player)
					character.abortCast();
				
			if (type == MessageType.EXPELLED)
			{
				player.sendPacket(SystemMessageId.HAVE_BEEN_EXPELLED_FROM_PARTY);
				broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_WAS_EXPELLED_FROM_PARTY).addCharName(player));
			}
			else if (type == MessageType.LEFT || type == MessageType.DISCONNECTED)
			{
				player.sendPacket(SystemMessageId.YOU_LEFT_PARTY);
				broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_LEFT_PARTY).addCharName(player));
			}
			
			player.setParty(null);
			player.sendPacket(PartySmallWindowDeleteAll.STATIC_PACKET);
			
			broadcastPacket(new PartySmallWindowDelete(player));
			
			if (_commandChannel != null)
				player.sendPacket(ExCloseMPCC.STATIC_PACKET);
		}
	}
	
	/**
	 * Change the party leader. If CommandChannel leader was the previous leader, change it too.
	 * @param name : the name of the player newly promoted to leader.
	 */
	public void changePartyLeader(String name)
	{
		final Player player = getPlayerByName(name);
		if (player == null || player.isInDuel())
			return;
		
		// Can't set leader if not part of the party.
		if (!_members.contains(player))
		{
			player.sendPacket(SystemMessageId.YOU_CAN_TRANSFER_RIGHTS_ONLY_TO_ANOTHER_PARTY_MEMBER);
			return;
		}
		
		// If already leader, abort.
		if (isLeader(player))
		{
			player.sendPacket(SystemMessageId.YOU_CANNOT_TRANSFER_RIGHTS_TO_YOURSELF);
			return;
		}
		
		// Refresh channel leader, if any.
		if (_commandChannel != null && _commandChannel.isLeader(getLeader()))
		{
			_commandChannel.setLeader(player);
			_commandChannel.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.COMMAND_CHANNEL_LEADER_NOW_S1).addCharName(player));
		}
		
		// Update this party leader and broadcast the update.
		setLeader(player);
		broadcastNewLeaderStatus();
		
		if (player.isInPartyMatchRoom())
		{
			final PartyMatchRoom room = PartyMatchRoomList.getInstance().getPlayerRoom(player);
			room.changeLeader(player);
		}
	}
	
	/**
	 * @param name : the name of the player to search.
	 * @return a party member by its name.
	 */
	private Player getPlayerByName(String name)
	{
		for (Player member : _members)
		{
			if (member.getName().equalsIgnoreCase(name))
				return member;
		}
		return null;
	}
	
	/**
	 * Distribute item(s) to one party member, based on party LootRule.
	 * @param player : the initial looter.
	 * @param item : the looted item to distribute.
	 */
	public void distributeItem(Player player, ItemInstance item)
	{
		if (item.getItemId() == 57)
		{
			distributeAdena(player, item.getCount(), player);
			item.destroyMe("Party", player, null);
			return;
		}
		
		final Player target = getActualLooter(player, item.getItemId(), false, player);
		if (target == null)
			return;
		
		// Send messages to other party members about reward.
		if (item.getCount() > 1)
			broadcastToPartyMembers(target, SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S3_S2).addCharName(target).addItemName(item).addItemNumber(item.getCount()));
		else if (item.getEnchantLevel() > 0)
			broadcastToPartyMembers(target, SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S2_S3).addCharName(target).addNumber(item.getEnchantLevel()).addItemName(item));
		else
			broadcastToPartyMembers(target, SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S2).addCharName(target).addItemName(item));
		
		target.addItem("Party", item, player, true);
	}
	
	/**
	 * Distribute item(s) to one party member, based on party LootRule.
	 * @param player : the initial looter.
	 * @param item : the looted item to distribute.
	 * @param spoil : true if the item comes from a spoil process.
	 * @param target : the looted character.
	 */
	public void distributeItem(Player player, IntIntHolder item, boolean spoil, Attackable target)
	{
		if (item == null)
			return;
		
		if (item.getId() == 57)
		{
			distributeAdena(player, item.getValue(), target);
			return;
		}
		
		final Player looter = getActualLooter(player, item.getId(), spoil, target);
		if (looter == null)
			return;
		
		looter.addItem(spoil ? "Sweep" : "Party", item.getId(), item.getValue(), player, true);
		
		// Send messages to other party members about reward.
		SystemMessage msg;
		if (item.getValue() > 1)
		{
			msg = (spoil) ? SystemMessage.getSystemMessage(SystemMessageId.S1_SWEEPED_UP_S3_S2) : SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S3_S2);
			msg.addCharName(looter);
			msg.addItemName(item.getId());
			msg.addItemNumber(item.getValue());
		}
		else
		{
			msg = (spoil) ? SystemMessage.getSystemMessage(SystemMessageId.S1_SWEEPED_UP_S2) : SystemMessage.getSystemMessage(SystemMessageId.S1_OBTAINED_S2);
			msg.addCharName(looter);
			msg.addItemName(item.getId());
		}
		broadcastToPartyMembers(looter, msg);
	}
	
	/**
	 * Distribute adena to party members, according distance.
	 * @param player : The player who picked.
	 * @param adena : Amount of adenas.
	 * @param target : Target used for distance checks.
	 */
	public void distributeAdena(Player player, int adena, Creature target)
	{
		List<Player> toReward = new ArrayList<>(_members.size());
		for (Player member : _members)
		{
			if (!MathUtil.checkIfInRange(Config.PARTY_RANGE, target, member, true) || member.getAdena() == Integer.MAX_VALUE)
				continue;
			
			toReward.add(member);
		}
		
		// Avoid divisions by 0.
		if (toReward.isEmpty())
			return;
		
		final int count = adena / toReward.size();
		for (Player member : toReward)
			member.addAdena("Party", count, player, true);
	}
	
	/**
	 * Distribute Experience and SP rewards to party members in the known area of the last attacker.<BR>
	 * <BR>
	 * <B><U> Actions</U> :</B><BR>
	 * <ul>
	 * <li>Get the owner of the Summon (if necessary).</li>
	 * <li>Calculate the Experience and SP reward distribution rate.</li>
	 * <li>Add Experience and SP to the player.</li>
	 * </ul>
	 * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T GIVE rewards to Pet</B></FONT><BR>
	 * <BR>
	 * Exception are Pets that leech from the owner's XP; they get the exp indirectly, via the owner's exp gain.<BR>
	 * @param xpReward : The Experience reward to distribute.
	 * @param spReward : The SP reward to distribute.
	 * @param rewardedMembers : The list of Player to reward.
	 * @param topLvl : The maximum level.
	 * @param rewards : The list of players and summons.
	 */
	public void distributeXpAndSp(long xpReward, int spReward, List<Player> rewardedMembers, int topLvl, Map<Creature, RewardInfo> rewards)
	{
		final List<Player> validMembers = new ArrayList<>();
		
		if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("level"))
		{
			for (Player member : rewardedMembers)
			{
				if (topLvl - member.getLevel() <= Config.PARTY_XP_CUTOFF_LEVEL)
					validMembers.add(member);
			}
		}
		else if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("percentage"))
		{
			int sqLevelSum = 0;
			for (Player member : rewardedMembers)
				sqLevelSum += (member.getLevel() * member.getLevel());
			
			for (Player member : rewardedMembers)
			{
				int sqLevel = member.getLevel() * member.getLevel();
				if (sqLevel * 100 >= sqLevelSum * Config.PARTY_XP_CUTOFF_PERCENT)
					validMembers.add(member);
			}
		}
		else if (Config.PARTY_XP_CUTOFF_METHOD.equalsIgnoreCase("auto"))
		{
			int sqLevelSum = 0;
			for (Player member : rewardedMembers)
				sqLevelSum += (member.getLevel() * member.getLevel());
			
			// Have to use range 1 to 9, since we -1 it : 0 can't be a good number (would lead to a IOOBE). Since 0 and 1 got same values, it's not a problem.
			final int partySize = MathUtil.limit(rewardedMembers.size(), 1, 9);
			
			for (Player member : rewardedMembers)
			{
				int sqLevel = member.getLevel() * member.getLevel();
				if (sqLevel >= sqLevelSum * (1 - 1 / (1 + BONUS_EXP_SP[partySize] - BONUS_EXP_SP[partySize - 1])))
					validMembers.add(member);
			}
		}
		
		// Since validMembers can also hold CommandChannel members, we have to restrict the value.
		final double partyRate = BONUS_EXP_SP[Math.min(validMembers.size(), 9)];
		
		xpReward *= partyRate * Config.RATE_PARTY_XP;
		spReward *= partyRate * Config.RATE_PARTY_SP;
		
		int sqLevelSum = 0;
		for (Player member : validMembers)
			sqLevelSum += member.getLevel() * member.getLevel();
		
		// Go through the players that must be rewarded.
		for (Player member : rewardedMembers)
		{
			if (member.isDead())
				continue;
			
			// Calculate and add the EXP and SP reward to the member.
			if (validMembers.contains(member))
			{
				// The servitor penalty.
				final float penalty = member.hasServitor() ? ((Servitor) member.getSummon()).getExpPenalty() : 0;
				
				final double sqLevel = member.getLevel() * member.getLevel();
				final double preCalculation = (sqLevel / sqLevelSum) * (1 - penalty);
				
				final long xp = Math.round(xpReward * preCalculation);
				final int sp = (int) (spReward * preCalculation);
				
				// Set new karma.
				member.updateKarmaLoss(xp);
				
				// Add the XP/SP points to the requested party member.
				member.addExpAndSp(xp, sp, rewards);
			}
			else
				member.addExpAndSp(0, 0);
		}
	}
	
	public LootRule getLootRule()
	{
		return _lootRule;
	}
	
	public boolean isInCommandChannel()
	{
		return _commandChannel != null;
	}
	
	public CommandChannel getCommandChannel()
	{
		return _commandChannel;
	}
	
	public void setCommandChannel(CommandChannel channel)
	{
		_commandChannel = channel;
	}
	
	public boolean isInDimensionalRift()
	{
		return _rift != null;
	}
	
	public DimensionalRift getDimensionalRift()
	{
		return _rift;
	}
	
	public void setDimensionalRift(DimensionalRift rift)
	{
		_rift = rift;
	}
	
	 //edit
	public boolean isInMonsterHunter()
	{
		return _hunter != null;
	}
	
	public MonsterHunter getMonsterHunter()
	{
		return _hunter;
	}
	
	public void setMonsterHunter(MonsterHunter hunter)
	{
		_hunter = hunter;
	}
	 //edit
	
	/**
	 * @return true if the entire party is currently dead.
	 */
	public boolean wipedOut()
	{
		for (Player member : _members)
		{
			if (!member.isDead())
				return false;
		}
		return true;
	}
	
	protected class PositionBroadcast implements Runnable
	{
		@Override
		public void run()
		{
			if (_positionPacket == null)
				_positionPacket = new PartyMemberPosition(Party.this);
			else
				_positionPacket.reuse(Party.this);
			
			broadcastPacket(_positionPacket);
		}
	}
}

 

Eu ajustei segundo o que achei certo, baseado no index quando a pt for > 2 ele pega o primeiro e transforma em lider

pode compartilhar a DIFF? seria interessante acrescentar isso. 😃

Share this post


Link to post
Share on other sites
5 horas atrás, ShadowBR disse:

pode compartilhar a DIFF? seria interessante acrescentar isso. 😃

eu gostaria de aprender a mexer com essa questão de versão e atualização, posso comparar minhas alterações e adicionar o + e o - manualmente como sempre fiz ahahahah...

Pessoal Divine Inspiration adicionando mesmo estando setado para não adicionar (ser necessário o book e o sp).

Atual:

# Spellbook is needed to learn Divine Inspiration. Default: True
DivineInspirationSpBookNeeded = True

 

Share this post


Link to post
Share on other sites

report: WindowsCount, ao delimitar uma quantidade de box quando excede ele continua dando kick mesmo que a quantidade de tela seja inferior ao proposto, sera que estou errando em algo ?

Citar

#=============================================================
#                        Game Guard
#=============================================================
# Allow Guard Protection System
AllowGuardSystem = True

# Installing client HWID
# 1 = HWID HDD
# 2 = HWID MAC
# 3 = HWID CPU
UseClientHWID = 2
WindowsCount = 2
KickWithEmptyHWID = true
KickWithLastErrorHWID = true

KickWithLastErrorHWID = false ---> foi feito a tentativa mas ai não tem mais kick 

  • I love it 1

Share this post


Link to post
Share on other sites
19 horas atrás, Caio Conceição disse:

eu gostaria de aprender a mexer com essa questão de versão e atualização, posso comparar minhas alterações e adicionar o + e o - manualmente como sempre fiz ahahahah...

Pessoal Divine Inspiration adicionando mesmo estando setado para não adicionar (ser necessário o book e o sp).

Atual:

# Spellbook is needed to learn Divine Inspiration. Default: True
DivineInspirationSpBookNeeded = True

 

Tem uma opção no eclipse que te permite criar a diff, basta ir no arquivo que vc alterou e clicar com o botão direito, ir em TEAM e depois em Create Patch. Ele ira comparar a sua versão com a versão do GIT e então extraira o seu DIFF.

image.thumb.png.f24edea193bb4d8eb43900c59e97e770.png

Share this post


Link to post
Share on other sites
3 horas atrás, ShadowBR disse:

Tem uma opção no eclipse que te permite criar a diff, basta ir no arquivo que vc alterou e clicar com o botão direito, ir em TEAM e depois em Create Patch. Ele ira comparar a sua versão com a versão do GIT e então extraira o seu DIFF.

image.thumb.png.f24edea193bb4d8eb43900c59e97e770.png

Infelizmente meu amigo eu não tinha sincronizado o git, e nem vejo muita necessidade em fazer pois parece que meus reportes nao agregam muito ao projeto em si..

boa sorte ae 😉

Share this post


Link to post
Share on other sites
1 hora atrás, Caio Conceição disse:

Infelizmente meu amigo eu não tinha sincronizado o git, e nem vejo muita necessidade em fazer pois parece que meus reportes nao agregam muito ao projeto em si..

boa sorte ae 😉

eu sempre faço, mas nem por isso eu faço commit. O importante dos projetos abertos é sempre vc sincronizar para ter certeza do que vc alterou, pois depois de uma correção da versão original vc iria ter q mudar tudo na unha, agora se vc tiver sincronizado vc usa suas diffs para manter o seu projeto sempre atualizado.

Share this post


Link to post
Share on other sites
12 horas atrás, ShadowBR disse:

eu sempre faço, mas nem por isso eu faço commit. O importante dos projetos abertos é sempre vc sincronizar para ter certeza do que vc alterou, pois depois de uma correção da versão original vc iria ter q mudar tudo na unha, agora se vc tiver sincronizado vc usa suas diffs para manter o seu projeto sempre atualizado.

é tomei um prejuízo poque já ajustei muitas coisas na mao e inclui outras:

eventos de dungeon, npc buffer dando buffs ate um lvl ou para vips ou para clan's que tem castelo, alterações no login server para deixar o sv extranet e conseguir logar do 127.0.0.1, esse problema de pt, agora as divine inspiration...

mas também posso sincronizar e jogar tudo por cima  já que desde então não tivemos atualizações oficiais.

Share this post


Link to post
Share on other sites
2 horas atrás, Caio Conceição disse:

é tomei um prejuízo poque já ajustei muitas coisas na mao e inclui outras:

eventos de dungeon, npc buffer dando buffs ate um lvl ou para vips ou para clan's que tem castelo, alterações no login server para deixar o sv extranet e conseguir logar do 127.0.0.1, esse problema de pt, agora as divine inspiration...

mas também posso sincronizar e jogar tudo por cima  já que desde então não tivemos atualizações oficiais.

pode ser, mas se não me engano se vc jogar tudo por cima o controle de versão entendera q vc alterou tudo e então não vai ter o controle q vc deseja (eu acho q era assim, não lembro exatamente)

Share this post


Link to post
Share on other sites
5 horas atrás, ShadowBR disse:

pode ser, mas se não me engano se vc jogar tudo por cima o controle de versão entendera q vc alterou tudo e então não vai ter o controle q vc deseja (eu acho q era assim, não lembro exatamente)

 

7 horas atrás, Caio Conceição disse:

é tomei um prejuízo poque já ajustei muitas coisas na mao e inclui outras:

eventos de dungeon, npc buffer dando buffs ate um lvl ou para vips ou para clan's que tem castelo, alterações no login server para deixar o sv extranet e conseguir logar do 127.0.0.1, esse problema de pt, agora as divine inspiration...

mas também posso sincronizar e jogar tudo por cima  já que desde então não tivemos atualizações oficiais.

Não se preocupem voltei atividade de novo estou com um computador temporario, pois o outro deu pau, deixo logo um spoiler do que fiz, já atualizei o projeto para JAVA DK 14, atualizei o hikariCP que é o nosso pool de conexão com a DB e corrigi algumas coisas, adicionei uma zona para os eventos, para rodar igual a olympiad. Irei postar o Patch " Diff ", das atualizações.

Edited by L2jOne
  • I love it 1

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.


🛡️ Servidores com Firewall Físico



⚔️ Server Patrocinado



🎁 Ofertas







×
×
  • Create New...