Package lineage2.gameserver.model

Source Code of lineage2.gameserver.model.Party$ChangeLootCheck

/*
* 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
*/
package lineage2.gameserver.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;

import lineage2.commons.collections.LazyArrayList;
import lineage2.commons.threading.RunnableImpl;
import lineage2.commons.util.Rnd;
import lineage2.gameserver.Config;
import lineage2.gameserver.ThreadPoolManager;
import lineage2.gameserver.cache.Msg;
import lineage2.gameserver.instancemanager.ReflectionManager;
import lineage2.gameserver.instancemanager.WorldStatisticsManager;
import lineage2.gameserver.model.base.Experience;
import lineage2.gameserver.model.entity.Reflection;
import lineage2.gameserver.model.instances.MonsterInstance;
import lineage2.gameserver.model.instances.NpcInstance;
import lineage2.gameserver.model.items.ItemInstance;
import lineage2.gameserver.model.worldstatistics.CategoryType;
import lineage2.gameserver.network.serverpackets.ExAskModifyPartyLooting;
import lineage2.gameserver.network.serverpackets.ExMPCCClose;
import lineage2.gameserver.network.serverpackets.ExMPCCOpen;
import lineage2.gameserver.network.serverpackets.ExPartyPetWindowAdd;
import lineage2.gameserver.network.serverpackets.ExPartyPetWindowDelete;
import lineage2.gameserver.network.serverpackets.ExSetPartyLooting;
import lineage2.gameserver.network.serverpackets.ExTacticalSign;
import lineage2.gameserver.network.serverpackets.GetItem;
import lineage2.gameserver.network.serverpackets.L2GameServerPacket;
import lineage2.gameserver.network.serverpackets.PartyMemberPosition;
import lineage2.gameserver.network.serverpackets.PartySmallWindowAdd;
import lineage2.gameserver.network.serverpackets.PartySmallWindowAll;
import lineage2.gameserver.network.serverpackets.PartySmallWindowDelete;
import lineage2.gameserver.network.serverpackets.PartySmallWindowDeleteAll;
import lineage2.gameserver.network.serverpackets.PartySpelled;
import lineage2.gameserver.network.serverpackets.RelationChanged;
import lineage2.gameserver.network.serverpackets.SystemMessage;
import lineage2.gameserver.network.serverpackets.SystemMessage2;
import lineage2.gameserver.network.serverpackets.components.IStaticPacket;
import lineage2.gameserver.taskmanager.LazyPrecisionTaskManager;
import lineage2.gameserver.templates.item.ItemTemplate;
import lineage2.gameserver.utils.ItemFunctions;
import lineage2.gameserver.utils.Location;
import lineage2.gameserver.utils.Log;

/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public class Party implements PlayerGroup
{
  /**
   * Field MAX_SIZE. (value is 7)
   */
  public static final int MAX_SIZE = 7;
  /**
   * Field ITEM_LOOTER. (value is 0)
   */
  public static final int ITEM_LOOTER = 0;
  /**
   * Field ITEM_RANDOM. (value is 1)
   */
  public static final int ITEM_RANDOM = 1;
  /**
   * Field ITEM_RANDOM_SPOIL. (value is 2)
   */
  public static final int ITEM_RANDOM_SPOIL = 2;
  /**
   * Field ITEM_ORDER. (value is 3)
   */
  public static final int ITEM_ORDER = 3;
  /**
   * Field ITEM_ORDER_SPOIL. (value is 4)
   */
  public static final int ITEM_ORDER_SPOIL = 4;
  /**
   * Field _members.
   */
  final List<Player> _members = new CopyOnWriteArrayList<>();
  /**
   * Field _tacticalSigns.
   */
  private static Map<Integer, GameObject> _tacticalSigns = new HashMap<>(4);
  /**
   * Field _partyLvl.
   */
  private int _partyLvl = 0;
  /**
   * Field _itemDistribution.
   */
  private int _itemDistribution = 0;
  /**
   * Field _itemOrder.
   */
  private int _itemOrder = 0;
  /**
   * Field _reflection.
   */
  private Reflection _reflection;
  /**
   * Field _commandChannel.
   */
  private CommandChannel _commandChannel;
  /**
   * Field _rateExp.
   */
  public double _rateExp;
  /**
   * Field _rateSp.
   */
  public double _rateSp;
  /**
   * Field _rateDrop.
   */
  public double _rateDrop;
  /**
   * Field _rateAdena.
   */
  public double _rateAdena;
  /**
   * Field _rateSpoil.
   */
  public double _rateSpoil;
  /**
   * Field positionTask.
   */
  private ScheduledFuture<?> positionTask;
  /**
   * Field _requestChangeLoot.
   */
  private int _requestChangeLoot = -1;
  /**
   * Field _requestChangeLootTimer.
   */
  long _requestChangeLootTimer = 0;
  /**
   * Field _changeLootAnswers.
   */
  private Set<Integer> _changeLootAnswers = null;
  /**
   * Field LOOT_SYSSTRINGS.
   */
  private static final int[] LOOT_SYSSTRINGS =
  {
    487,
    488,
    798,
    799,
    800
  };
  /**
   * Field _checkTask.
   */
  private Future<?> _checkTask = null;
 
  /**
   * Constructor for Party.
   * @param leader Player
   * @param itemDistribution int
   */
  public Party(Player leader, int itemDistribution)
  {
    _itemDistribution = itemDistribution;
    _members.add(leader);
    _partyLvl = leader.getLevel();
    _rateExp = leader.getBonus().getRateXp();
    _rateSp = leader.getBonus().getRateSp();
    _rateAdena = leader.getBonus().getDropAdena();
    _rateDrop = leader.getBonus().getDropItems();
    _rateSpoil = leader.getBonus().getDropSpoil();
  }
 
  /**
   * Method getMemberCount.
   * @return int
   */
  public int getMemberCount()
  {
    return _members.size();
  }
 
  /**
   * Method getMemberCountInRange.
   * @param player Player
   * @param range int
   * @return int
   */
  public int getMemberCountInRange(Player player, int range)
  {
    int count = 0;
    for (Player member : _members)
    {
      if ((member == player) || member.isInRangeZ(player, range))
      {
        count++;
      }
    }
    return count;
  }
 
  /**
   * Method getPartyMembers.
   * @return List<Player>
   */
  public List<Player> getPartyMembers()
  {
    return _members;
  }
 
  /**
   * Method getPartyMembersObjIds.
   * @return List<Integer>
   */
  public List<Integer> getPartyMembersObjIds()
  {
    List<Integer> result = new ArrayList<>(_members.size());
    for (Player member : _members)
    {
      result.add(member.getObjectId());
    }
    return result;
  }
 
  /**
   * Method getPartyMembersWithPets.
   * @return List<Playable>
   */
  public List<Playable> getPartyMembersWithPets()
  {
    List<Playable> result = new ArrayList<>();
    for (Player member : _members)
    {
      result.add(member);
      for (Summon summon : member.getSummonList())
      {
        result.add(summon);
      }
    }
    return result;
  }
 
  /**
   * Method isLeader.
   * @param player Player
   * @return boolean
   */
  public boolean isLeader(Player player)
  {
    return getPartyLeader() == player;
  }
 
  /**
   * Method getPartyLeader.
   * @return Player
   */
  public Player getPartyLeader()
  {
    synchronized (_members)
    {
      if (_members.size() == 0)
      {
        return null;
      }
      return _members.get(0);
    }
  }
 
  /**
   * Method broadCast.
   * @param msg IStaticPacket[]
   * @see lineage2.gameserver.model.PlayerGroup#broadCast(IStaticPacket[])
   */
  @Override
  public void broadCast(IStaticPacket... msg)
  {
    for (Player member : _members)
    {
      member.sendPacket(msg);
    }
  }
 
  /**
   * Method broadcastMessageToPartyMembers.
   * @param msg String
   */
  public void broadcastMessageToPartyMembers(String msg)
  {
    broadCast(new SystemMessage(msg));
  }
 
  /**
   * Method broadcastToPartyMembers.
   * @param exclude Player
   * @param msg L2GameServerPacket
   */
  public void broadcastToPartyMembers(Player exclude, L2GameServerPacket msg)
  {
    for (Player member : _members)
    {
      if (exclude != member)
      {
        member.sendPacket(msg);
      }
    }
  }
 
  /**
   * Method broadcastToPartyMembersInRange.
   * @param player Player
   * @param msg L2GameServerPacket
   * @param range int
   */
  public void broadcastToPartyMembersInRange(Player player, L2GameServerPacket msg, int range)
  {
    for (Player member : _members)
    {
      if (player.isInRangeZ(member, range))
      {
        member.sendPacket(msg);
      }
    }
  }
 
  /**
   * Method containsMember.
   * @param player Player
   * @return boolean
   */
  public boolean containsMember(Player player)
  {
    return _members.contains(player);
  }
 
  /**
   * Method addPartyMember.
   * @param player Player
   * @return boolean
   */
  public boolean addPartyMember(Player player)
  {
    Player leader = getPartyLeader();
    if (leader == null)
    {
      return false;
    }
    synchronized (_members)
    {
      if (_members.isEmpty())
      {
        return false;
      }
      if (_members.contains(player))
      {
        return false;
      }
      if (_members.size() == MAX_SIZE)
      {
        return false;
      }
      _members.add(player);
    }
    if (_requestChangeLoot != -1)
    {
      finishLootRequest(false);
    }
    player.setParty(this);
    player.getListeners().onPartyInvite();
    List<L2GameServerPacket> addInfo = new ArrayList<>(4 + (_members.size() * 4));
    List<L2GameServerPacket> pplayer = new ArrayList<>(20);
    pplayer.add(new PartySmallWindowAll(this, player));
    pplayer.add(new SystemMessage(SystemMessage.YOU_HAVE_JOINED_S1S_PARTY).addName(leader));
    addInfo.add(new SystemMessage(SystemMessage.S1_HAS_JOINED_THE_PARTY).addName(player));
    addInfo.add(new PartySpelled(player, true));
    for (Summon summon : player.getSummonList())
    {
      addInfo.add(new ExPartyPetWindowAdd(summon));
      addInfo.add(new PartySpelled(summon, true));
    }
    PartyMemberPosition pmp = new PartyMemberPosition();
    List<L2GameServerPacket> pmember;
    for (Player member : _members)
    {
      if (member != player)
      {
        pmember = new ArrayList<>(addInfo.size() + 4);
        pmember.addAll(addInfo);
        if (_members.size() == 2)
        {
          pmember.add(new PartySmallWindowAll(this, member));
        }
        else
        {
          pmember.add(new PartySmallWindowAdd(member, player, getLootDistribution()));
        }
        pmember.add(new PartyMemberPosition().add(player));
        pmember.add(RelationChanged.update(member, player, member));
        member.sendPacket(pmember);
        pplayer.add(new PartySpelled(member, true));
        for (Summon summon : member.getSummonList())
        {
          pplayer.add(new PartySpelled(summon, true));
        }
        pplayer.add(RelationChanged.update(player, member, player));
        pmp.add(member);
      }
    }
    pplayer.add(pmp);
    if (isInCommandChannel())
    {
      pplayer.add(ExMPCCOpen.STATIC);
    }
    player.sendPacket(pplayer);
    for (Map.Entry<Integer, GameObject> entry : _tacticalSigns.entrySet())
    {
      player.sendPacket(new ExTacticalSign(entry.getValue().getObjectId(), entry.getKey()));
    }
    startUpdatePositionTask();
    recalculatePartyData();
    for (Player member : _members)
    {
      member.setStartingTimeInParty(System.currentTimeMillis());
      if (_members.size() == 7)
        member.setStartingTimeInFullParty(System.currentTimeMillis());
    }
    return true;
  }
 
  /**
   * Method dissolveParty.
   */
  public void dissolveParty()
  {
    for (Player p : _members)
    {
      removeTacticalSigns(p);
      p.sendPacket(PartySmallWindowDeleteAll.STATIC);
      p.setParty(null);
    }
    synchronized (_members)
    {
      _members.clear();
    }
    setCommandChannel(null);
    stopUpdatePositionTask();
  }
 
  /**
   * Method removePartyMember.
   * @param player Player
   * @param kick boolean
   * @return boolean
   */
  public boolean removePartyMember(Player player, boolean kick)
  {
    boolean isLeader = isLeader(player);
    boolean dissolve = false;
    synchronized (_members)
    {
      if (_members.size() == 7)
        WorldStatisticsManager.getInstance().updateStat(player, CategoryType.TIME_IN_FULLPARTY, (System.currentTimeMillis() - player.getStartingTimeInFullParty()) / 1000);
      if (!_members.remove(player))
      {
        return false;
      }
      dissolve = _members.size() == 1;
    }
    removeTacticalSigns(player);
    player.getListeners().onPartyLeave();
    player.setParty(null);
    WorldStatisticsManager.getInstance().updateStat(player, CategoryType.TIME_IN_PARTY, (System.currentTimeMillis() - player.getStartingTimeInParty()) / 1000);
    recalculatePartyData();
    List<L2GameServerPacket> pplayer = new ArrayList<>(4 + (_members.size() * 2));
    if (isInCommandChannel())
    {
      pplayer.add(ExMPCCClose.STATIC);
    }
    if (kick)
    {
      pplayer.add(Msg.YOU_HAVE_BEEN_EXPELLED_FROM_THE_PARTY);
    }
    else
    {
      pplayer.add(Msg.YOU_HAVE_WITHDRAWN_FROM_THE_PARTY);
    }
    pplayer.add(PartySmallWindowDeleteAll.STATIC);
    List<L2GameServerPacket> outsInfo = new ArrayList<>(6);
    for (Summon summon : player.getSummonList())
    {
      outsInfo.add(new ExPartyPetWindowDelete(summon));
    }
    outsInfo.add(new PartySmallWindowDelete(player));
    if (kick)
    {
      outsInfo.add(new SystemMessage(SystemMessage.S1_WAS_EXPELLED_FROM_THE_PARTY).addName(player));
    }
    else
    {
      outsInfo.add(new SystemMessage(SystemMessage.S1_HAS_LEFT_THE_PARTY).addName(player));
    }
    List<L2GameServerPacket> pmember;
    for (Player member : _members)
    {
      pmember = new ArrayList<>(2 + outsInfo.size());
      pmember.addAll(outsInfo);
      pmember.add(RelationChanged.update(member, player, member));
      member.sendPacket(pmember);
      pplayer.add(RelationChanged.update(player, member, player));
    }
    player.sendPacket(pplayer);
    Reflection reflection = getReflection();
    if ((reflection != null) && (player.getReflection() == reflection) && (reflection.getReturnLoc() != null))
    {
      player.teleToLocation(reflection.getReturnLoc(), ReflectionManager.DEFAULT);
    }
    Player leader = getPartyLeader();
    if (dissolve)
    {
      if (isInCommandChannel())
      {
        _commandChannel.removeParty(this);
      }
      else if (reflection != null)
      {
        if ((reflection.getInstancedZone() != null) && reflection.getInstancedZone().isCollapseOnPartyDismiss())
        {
          if (reflection.getParty() == this)
          {
            reflection.startCollapseTimer(reflection.getInstancedZone().getTimerOnCollapse() * 1000);
          }
          if ((leader != null) && (leader.getReflection() == reflection))
          {
            leader.broadcastPacket(new SystemMessage(SystemMessage.THIS_DUNGEON_WILL_EXPIRE_IN_S1_MINUTES).addNumber(1));
          }
        }
      }
      WorldStatisticsManager.getInstance().updateStat(leader, CategoryType.TIME_IN_PARTY, (System.currentTimeMillis() - leader.getStartingTimeInParty()) / 1000);
      if (leader.getStartingTimeInFullParty() != 0)
        WorldStatisticsManager.getInstance().updateStat(leader, CategoryType.TIME_IN_FULLPARTY, (System.currentTimeMillis() - leader.getStartingTimeInFullParty()) / 1000);
      dissolveParty();
    }
    else
    {
      if (isInCommandChannel() && (_commandChannel.getChannelLeader() == player))
      {
        _commandChannel.setChannelLeader(leader);
      }
      if (isLeader)
      {
        updateLeaderInfo();
      }
    }
    if (_checkTask != null)
    {
      _checkTask.cancel(true);
      _checkTask = null;
    }
    return true;
  }
 
  /**
   * Method changePartyLeader.
   * @param player Player
   * @return boolean
   */
  public boolean changePartyLeader(Player player)
  {
    Player leader = getPartyLeader();
    synchronized (_members)
    {
      int index = _members.indexOf(player);
      if (index == -1)
      {
        return false;
      }
      _members.set(0, player);
      _members.set(index, leader);
    }
    updateLeaderInfo();
    if (isInCommandChannel() && (_commandChannel.getChannelLeader() == leader))
    {
      _commandChannel.setChannelLeader(player);
    }
    return true;
  }
 
  /**
   * Method updateLeaderInfo.
   */
  private void updateLeaderInfo()
  {
    Player leader = getPartyLeader();
    if (leader == null)
    {
      return;
    }
    SystemMessage msg = new SystemMessage(SystemMessage.S1_HAS_BECOME_A_PARTY_LEADER).addName(leader);
    for (Player member : _members)
    {
      member.sendPacket(PartySmallWindowDeleteAll.STATIC, new PartySmallWindowAll(this, member), msg);
    }
    for (Player member : _members)
    {
      broadcastToPartyMembers(member, new PartySpelled(member, true));
      for (Summon summon : member.getSummonList())
      {
        broadCast(new ExPartyPetWindowAdd(summon));
      }
    }
  }
 
  /**
   * Method getPlayerByName.
   * @param name String
   * @return Player
   */
  public Player getPlayerByName(String name)
  {
    for (Player member : _members)
    {
      if (name.equalsIgnoreCase(member.getName()))
      {
        return member;
      }
    }
    return null;
  }
 
  /**
   * Method distributeItem.
   * @param player Player
   * @param item ItemInstance
   * @param fromNpc NpcInstance
   */
  public void distributeItem(Player player, ItemInstance item, NpcInstance fromNpc)
  {
    switch (item.getItemId())
    {
      case ItemTemplate.ITEM_ID_ADENA:
        distributeAdena(player, item, fromNpc);
        break;
      default:
        distributeItem0(player, item, fromNpc);
        break;
    }
  }
 
  /**
   * Method distributeItem0.
   * @param player Player
   * @param item ItemInstance
   * @param fromNpc NpcInstance
   */
  private void distributeItem0(Player player, ItemInstance item, NpcInstance fromNpc)
  {
    Player target = null;
    List<Player> ret = null;
    switch (_itemDistribution)
    {
      case ITEM_RANDOM:
      case ITEM_RANDOM_SPOIL:
        ret = new ArrayList<>(_members.size());
        for (Player member : _members)
        {
          if (member.isInRangeZ(player, Config.ALT_PARTY_DISTRIBUTION_RANGE) && !member.isDead() && member.getInventory().validateCapacity(item) && member.getInventory().validateWeight(item))
          {
            ret.add(member);
          }
        }
        target = ret.isEmpty() ? null : ret.get(Rnd.get(ret.size()));
        break;
      case ITEM_ORDER:
      case ITEM_ORDER_SPOIL:
        synchronized (_members)
        {
          ret = new CopyOnWriteArrayList<>(_members);
          while ((target == null) && !ret.isEmpty())
          {
            int looter = _itemOrder;
            _itemOrder++;
            if (_itemOrder > (ret.size() - 1))
            {
              _itemOrder = 0;
            }
            Player looterPlayer = looter < ret.size() ? ret.get(looter) : null;
            if (looterPlayer != null)
            {
              if (!looterPlayer.isDead() && looterPlayer.isInRangeZ(player, Config.ALT_PARTY_DISTRIBUTION_RANGE) && ItemFunctions.canAddItem(looterPlayer, item))
              {
                target = looterPlayer;
              }
              else
              {
                ret.remove(looterPlayer);
              }
            }
          }
        }
        if (target == null)
        {
          return;
        }
        break;
      case ITEM_LOOTER:
      default:
        target = player;
        break;
    }
    if (target == null)
    {
      target = player;
    }
    if (target.pickupItem(item, Log.PartyPickup))
    {
      if (fromNpc == null)
      {
        player.broadcastPacket(new GetItem(item, player.getObjectId()));
      }
      player.broadcastPickUpMsg(item);
      item.pickupMe();
      broadcastToPartyMembers(target, SystemMessage2.obtainItemsBy(item, target));
    }
    else
    {
      item.dropToTheGround(player, fromNpc);
    }
  }
 
  /**
   * Method distributeAdena.
   * @param player Player
   * @param item ItemInstance
   * @param fromNpc NpcInstance
   */
  private void distributeAdena(Player player, ItemInstance item, NpcInstance fromNpc)
  {
    if (player == null)
    {
      return;
    }
    List<Player> membersInRange = new ArrayList<>();
    if (item.getCount() < _members.size())
    {
      membersInRange.add(player);
    }
    else
    {
      for (Player member : _members)
      {
        if (!member.isDead() && ((member == player) || player.isInRangeZ(member, Config.ALT_PARTY_DISTRIBUTION_RANGE)) && ItemFunctions.canAddItem(player, item))
        {
          membersInRange.add(member);
        }
      }
    }
    if (membersInRange.isEmpty())
    {
      membersInRange.add(player);
    }
    long totalAdena = item.getCount();
    long amount = totalAdena / membersInRange.size();
    long ost = totalAdena % membersInRange.size();
    for (Player member : membersInRange)
    {
      long count = member.equals(player) ? amount + ost : amount;
      member.getInventory().addAdena(count);
      member.sendPacket(SystemMessage2.obtainItems(ItemTemplate.ITEM_ID_ADENA, count, 0));
    }
    if (fromNpc == null)
    {
      player.broadcastPacket(new GetItem(item, player.getObjectId()));
    }
    item.pickupMe();
  }
 
  /**
   * Method distributeXpAndSp.
   * @param xpReward double
   * @param spReward double
   * @param rewardedMembers List<Player>
   * @param lastAttacker Creature
   * @param monster MonsterInstance
   */
  public void distributeXpAndSp(double xpReward, double spReward, List<Player> rewardedMembers, Creature lastAttacker, MonsterInstance monster)
  {
    recalculatePartyData();
    List<Player> mtr = new ArrayList<>();
    int partyLevel = lastAttacker.getLevel();
    int partyLvlSum = 0;
    for (Player member : rewardedMembers)
    {
      if (!monster.isInRangeZ(member, Config.ALT_PARTY_DISTRIBUTION_RANGE))
      {
        continue;
      }
      partyLevel = Math.max(partyLevel, member.getLevel());
    }
    for (Player member : rewardedMembers)
    {
      if (!monster.isInRangeZ(member, Config.ALT_PARTY_DISTRIBUTION_RANGE))
      {
        continue;
      }
      if (member.getLevel() <= (partyLevel - 15))
      {
        continue;
      }
      partyLvlSum += member.getLevel();
      mtr.add(member);
    }
    if (mtr.isEmpty())
    {
      return;
    }
    double bonus = Config.ALT_PARTY_BONUS[mtr.size() - 1];
    double XP = xpReward * bonus;
    double SP = spReward * bonus;
    for (Player member : mtr)
    {
      double lvlPenalty = Experience.penaltyModifier(monster.calculateLevelDiffForDrop(member.getLevel()), 9);
      int lvlDiff = partyLevel - member.getLevel();
      if ((lvlDiff >= 10) && (lvlDiff <= 14))
      {
        lvlPenalty *= 0.3D;
      }
      double memberXp = (XP * lvlPenalty * member.getLevel()) / partyLvlSum;
      double memberSp = (SP * lvlPenalty * member.getLevel()) / partyLvlSum;
      memberXp = Math.min(memberXp, xpReward);
      memberSp = Math.min(memberSp, spReward);
      member.addExpAndCheckBonus(monster, (long) memberXp, (long) memberSp, memberXp / xpReward);
    }
    recalculatePartyData();
  }
 
  /**
   * Method recalculatePartyData.
   */
  public void recalculatePartyData()
  {
    _partyLvl = 0;
    double rateExp = 0.;
    double rateSp = 0.;
    double rateDrop = 0.;
    double rateAdena = 0.;
    double rateSpoil = 0.;
    double minRateExp = Double.MAX_VALUE;
    double minRateSp = Double.MAX_VALUE;
    double minRateDrop = Double.MAX_VALUE;
    double minRateAdena = Double.MAX_VALUE;
    double minRateSpoil = Double.MAX_VALUE;
    int count = 0;
    for (Player member : _members)
    {
      int level = member.getLevel();
      _partyLvl = Math.max(_partyLvl, level);
      count++;
      rateExp += member.getBonus().getRateXp();
      rateSp += member.getBonus().getRateSp();
      rateDrop += member.getBonus().getDropItems();
      rateAdena += member.getBonus().getDropAdena();
      rateSpoil += member.getBonus().getDropSpoil();
      minRateExp = Math.min(minRateExp, member.getBonus().getRateXp());
      minRateSp = Math.min(minRateSp, member.getBonus().getRateSp());
      minRateDrop = Math.min(minRateDrop, member.getBonus().getDropItems());
      minRateAdena = Math.min(minRateAdena, member.getBonus().getDropAdena());
      minRateSpoil = Math.min(minRateSpoil, member.getBonus().getDropSpoil());
    }
    _rateExp = Config.RATE_PARTY_MIN ? minRateExp : rateExp / count;
    _rateSp = Config.RATE_PARTY_MIN ? minRateSp : rateSp / count;
    _rateDrop = Config.RATE_PARTY_MIN ? minRateDrop : rateDrop / count;
    _rateAdena = Config.RATE_PARTY_MIN ? minRateAdena : rateAdena / count;
    _rateSpoil = Config.RATE_PARTY_MIN ? minRateSpoil : rateSpoil / count;
  }
 
  /**
   * Method getLevel.
   * @return int
   */
  public int getLevel()
  {
    return _partyLvl;
  }
 
  /**
   * Method getLootDistribution.
   * @return int
   */
  public int getLootDistribution()
  {
    return _itemDistribution;
  }
 
  /**
   * Method isDistributeSpoilLoot.
   * @return boolean
   */
  public boolean isDistributeSpoilLoot()
  {
    boolean rv = false;
    if ((_itemDistribution == ITEM_RANDOM_SPOIL) || (_itemDistribution == ITEM_ORDER_SPOIL))
    {
      rv = true;
    }
    return rv;
  }
 
  /**
   * Method isInReflection.
   * @return boolean
   */
  public boolean isInReflection()
  {
    if (_reflection != null)
    {
      return true;
    }
    if (_commandChannel != null)
    {
      return _commandChannel.isInReflection();
    }
    return false;
  }
 
  /**
   * Method setReflection.
   * @param reflection Reflection
   */
  public void setReflection(Reflection reflection)
  {
    _reflection = reflection;
  }
 
  /**
   * Method getReflection.
   * @return Reflection
   */
  public Reflection getReflection()
  {
    if (_reflection != null)
    {
      return _reflection;
    }
    if (_commandChannel != null)
    {
      return _commandChannel.getReflection();
    }
    return null;
  }
 
  /**
   * Method isInCommandChannel.
   * @return boolean
   */
  public boolean isInCommandChannel()
  {
    return _commandChannel != null;
  }
 
  /**
   * Method getCommandChannel.
   * @return CommandChannel
   */
  public CommandChannel getCommandChannel()
  {
    return _commandChannel;
  }
 
  /**
   * Method setCommandChannel.
   * @param channel CommandChannel
   */
  public void setCommandChannel(CommandChannel channel)
  {
    _commandChannel = channel;
  }
 
  /**
   * Method Teleport.
   * @param x int
   * @param y int
   * @param z int
   */
  public void Teleport(int x, int y, int z)
  {
    TeleportParty(getPartyMembers(), new Location(x, y, z));
  }
 
  /**
   * Method Teleport.
   * @param dest Location
   */
  public void Teleport(Location dest)
  {
    TeleportParty(getPartyMembers(), dest);
  }
 
  /**
   * Method Teleport.
   * @param territory Territory
   */
  public void Teleport(Territory territory)
  {
    RandomTeleportParty(getPartyMembers(), territory);
  }
 
  /**
   * Method Teleport.
   * @param territory Territory
   * @param dest Location
   */
  public void Teleport(Territory territory, Location dest)
  {
    TeleportParty(getPartyMembers(), territory, dest);
  }
 
  /**
   * Method TeleportParty.
   * @param members List<Player>
   * @param dest Location
   */
  public static void TeleportParty(List<Player> members, Location dest)
  {
    for (Player _member : members)
    {
      if (_member == null)
      {
        continue;
      }
      _member.teleToLocation(dest);
    }
  }
 
  /**
   * Method TeleportParty.
   * @param members List<Player>
   * @param territory Territory
   * @param dest Location
   */
  public static void TeleportParty(List<Player> members, Territory territory, Location dest)
  {
    if (!territory.isInside(dest.x, dest.y))
    {
      Log.add("TeleportParty: dest is out of territory", "errors");
      Thread.dumpStack();
      return;
    }
    int base_x = members.get(0).getX();
    int base_y = members.get(0).getY();
    for (Player _member : members)
    {
      if (_member == null)
      {
        continue;
      }
      int diff_x = _member.getX() - base_x;
      int diff_y = _member.getY() - base_y;
      Location loc = new Location(dest.x + diff_x, dest.y + diff_y, dest.z);
      while (!territory.isInside(loc.x, loc.y))
      {
        diff_x = loc.x - dest.x;
        diff_y = loc.y - dest.y;
        if (diff_x != 0)
        {
          loc.x -= diff_x / Math.abs(diff_x);
        }
        if (diff_y != 0)
        {
          loc.y -= diff_y / Math.abs(diff_y);
        }
      }
      _member.teleToLocation(loc);
    }
  }
 
  /**
   * Method RandomTeleportParty.
   * @param members List<Player>
   * @param territory Territory
   */
  public static void RandomTeleportParty(List<Player> members, Territory territory)
  {
    for (Player member : members)
    {
      member.teleToLocation(Territory.getRandomLoc(territory, member.getGeoIndex()));
    }
  }
 
  /**
   * Method startUpdatePositionTask.
   */
  private void startUpdatePositionTask()
  {
    if (positionTask == null)
    {
      positionTask = LazyPrecisionTaskManager.getInstance().scheduleAtFixedRate(new UpdatePositionTask(), 1000, 1000);
    }
  }
 
  /**
   * Method stopUpdatePositionTask.
   */
  private void stopUpdatePositionTask()
  {
    if (positionTask != null)
    {
      positionTask.cancel(false);
    }
  }
 
  /**
   * @author Mobius
   */
  private class UpdatePositionTask extends RunnableImpl
  {
    /**
     * Constructor for UpdatePositionTask.
     */
    public UpdatePositionTask()
    {
      // TODO Auto-generated constructor stub
    }
   
    /**
     * Method runImpl.
     */
    @Override
    public void runImpl()
    {
      LazyArrayList<Player> update = LazyArrayList.newInstance();
      for (Player member : _members)
      {
        Location loc = member.getLastPartyPosition();
        if ((loc == null) || (member.getDistance(loc) > 256))
        {
          member.setLastPartyPosition(member.getLoc());
          update.add(member);
        }
      }
      if (!update.isEmpty())
      {
        for (Player member : _members)
        {
          PartyMemberPosition pmp = new PartyMemberPosition();
          for (Player m : update)
          {
            if (m != member)
            {
              pmp.add(m);
            }
          }
          if (pmp.size() > 0)
          {
            member.sendPacket(pmp);
          }
        }
      }
      LazyArrayList.recycle(update);
    }
  }
 
  /**
   * Method requestLootChange.
   * @param type byte
   */
  public void requestLootChange(byte type)
  {
    if (_requestChangeLoot != -1)
    {
      if (System.currentTimeMillis() > _requestChangeLootTimer)
      {
        finishLootRequest(false);
      }
      else
      {
        return;
      }
    }
    _requestChangeLoot = type;
    int additionalTime = 45000;
    _requestChangeLootTimer = System.currentTimeMillis() + additionalTime;
    _changeLootAnswers = new CopyOnWriteArraySet<>();
    _checkTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new ChangeLootCheck(), additionalTime + 1000, 5000);
    broadcastToPartyMembers(getPartyLeader(), new ExAskModifyPartyLooting(getPartyLeader().getName(), type));
    SystemMessage sm = new SystemMessage(SystemMessage.REQUESTING_APPROVAL_CHANGE_PARTY_LOOT_S1);
    sm.addSystemString(LOOT_SYSSTRINGS[type]);
    getPartyLeader().sendPacket(sm);
  }
 
  /**
   * Method answerLootChangeRequest.
   * @param member Player
   * @param answer boolean
   */
  public synchronized void answerLootChangeRequest(Player member, boolean answer)
  {
    if (_requestChangeLoot == -1)
    {
      return;
    }
    if (_changeLootAnswers.contains(member.getObjectId()))
    {
      return;
    }
    if (!answer)
    {
      finishLootRequest(false);
      return;
    }
    _changeLootAnswers.add(member.getObjectId());
    if (_changeLootAnswers.size() >= (getMemberCount() - 1))
    {
      finishLootRequest(true);
    }
  }
 
  /**
   * Method finishLootRequest.
   * @param success boolean
   */
  synchronized void finishLootRequest(boolean success)
  {
    if (_requestChangeLoot == -1)
    {
      return;
    }
    if (_checkTask != null)
    {
      _checkTask.cancel(false);
      _checkTask = null;
    }
    if (success)
    {
      broadCast(new ExSetPartyLooting(1, _requestChangeLoot));
      _itemDistribution = _requestChangeLoot;
      SystemMessage sm = new SystemMessage(SystemMessage.PARTY_LOOT_CHANGED_S1);
      sm.addSystemString(LOOT_SYSSTRINGS[_requestChangeLoot]);
      broadCast(sm);
    }
    else
    {
      broadCast(new ExSetPartyLooting(0, (byte) 0));
      broadCast(new SystemMessage(SystemMessage.PARTY_LOOT_CHANGE_CANCELLED));
    }
    _changeLootAnswers = null;
    _requestChangeLoot = -1;
    _requestChangeLootTimer = 0;
  }
 
  /**
   * @author Mobius
   */
  private class ChangeLootCheck extends RunnableImpl
  {
    /**
     * Constructor for ChangeLootCheck.
     */
    public ChangeLootCheck()
    {
      // TODO Auto-generated constructor stub
    }
   
    /**
     * Method runImpl.
     */
    @Override
    public void runImpl()
    {
      if (System.currentTimeMillis() > _requestChangeLootTimer)
      {
        finishLootRequest(false);
      }
    }
  }
 
  /**
   * Method iterator.
   * @return Iterator<Player> * @see java.lang.Iterable#iterator()
   */
  @Override
  public Iterator<Player> iterator()
  {
    return _members.iterator();
  }
 
  /**
   * Method getTacticalSignsList.
   * @return Map<Integer,GameObject>
   */
  public Map<Integer, GameObject> getTacticalSignsList()
  {
    return _tacticalSigns;
  }
 
  /**
   * Method removeTacticalSigns.
   * @param player Player
   */
  public void removeTacticalSigns(Player player)
  {
    for (Map.Entry<Integer, GameObject> entry : _tacticalSigns.entrySet())
    {
      player.sendPacket(new ExTacticalSign(entry.getValue().getObjectId(), 0));
    }
  }
}
TOP

Related Classes of lineage2.gameserver.model.Party$ChangeLootCheck

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
geview');