Показать контент
/**
* This class contains all RewardInfo of the L2Attackable against the any
* attacker L2Character, based on amount of damage done.<BR>
* <BR>
* <B><U> Data</U> :</B><BR>
* <BR>
* <li>attacker : The attaker L2Character concerned by this RewardInfo of
* this L2Attackable</li> <li>dmg : Total amount of damage done by the
* attacker to this L2Attackable (summon + own)</li>
*/
protected final class RewardInfo
{
protected L2Character _attacker;
protected int _dmg = 0;
public RewardInfo(L2Character pAttacker, int pDmg)
{
this._attacker = pAttacker;
this._dmg = pDmg;
}
public void addDamage(int pDmg)
{
this._dmg += pDmg;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj instanceof RewardInfo)
return (((RewardInfo) obj)._attacker == _attacker);
return false;
}
@Override
public int hashCode()
{
return this._attacker.getObjectId();
}
}
Hide
Показать контент
protected void calculateRewards(L2Character lastAttacker)
{
if (getAggroListRP().isEmpty())
return;
if (Config.DROP_LASTATTACKERISMAXDAMAGER && getAggroListRP().size() > 1)
{
int maxDamage = 0;
L2PcInstance attacker = null;
for (Map.Entry<L2Character, AggroInfo> entry : getAggroListRP().entrySet())
{
if (entry.getKey() != null && entry.getKey().getActingPlayer() != null && entry.getValue()._damage > maxDamage)
{
maxDamage = entry.getValue()._damage;
attacker = entry.getKey().getActingPlayer();
}
}
if (attacker != null)
lastAttacker = attacker;
}
// Manage Base, Quests and Sweep drops of the L2Attackable
doItemDrop(lastAttacker);
// Manage drop of Special Events created by GM for a defined period
doEventDrop(lastAttacker);
if (!getMustRewardExpSP())
return;
try
{
// Creates an empty list of rewards
final Map<Integer, RewardInfo> rewards = new FastMap<Integer, RewardInfo>();
int rewardCount = 0;
int damage;
L2Character attacker, ddealer;
RewardInfo reward;
// Go through the _aggroList of the L2Attackable
for (AggroInfo info : getAggroListRP().values())
{
if (info == null)
continue;
// Get the L2Character corresponding to this attacker
attacker = info._attacker;
// Get damages done by this attacker
damage = info._damage;
// Prevent unwanted behavior
if (damage > 1 && attacker != null)
{
// Check if ddealer isn't too far from this (killed monster)
if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE, this, attacker, true))
continue;
ddealer = attacker.getActingPlayer();
// Calculate real damages (Summoners should get own damage plus summon's damage)
reward = rewards.get(ddealer.getObjectId());
if (reward == null)
{
reward = new RewardInfo(ddealer, damage);
rewardCount++;
}
else
reward.addDamage(damage);
rewards.put(ddealer.getObjectId(), reward);
}
}
if (!rewards.isEmpty())
{
final FastTable<L2Party> parties = new FastTable<L2Party>();
final FastTable<L2PcInstance> rewardedMembers = new FastTable<L2PcInstance>();
L2Party attackerParty;
double exp,sp;
int levelDiff, partyDmg, partyLvl, partyLevelSum;
RewardInfo reward2;
double[] tmp;
for (RewardInfo reward_f : rewards.values())
{
reward = reward_f;
if (reward == null)
continue;
// Attacker to be rewarded
attacker = reward._attacker;
// Total amount of damage done
damage = reward._dmg;
// If the attacker is a Pet, get the party of the owner
attackerParty = attacker.getParty();
// We must avoid "over damage", if any
if (damage > getMaxHp())
damage = getMaxHp();
// If there's NO party in progress
if (attackerParty == null)
{
if (!(attacker instanceof L2PcInstance)) continue;
L2PcInstance player = attacker.getActingPlayer();
levelDiff = player.getLevel() - getLevel();
tmp = calculateExpAndSp(levelDiff, damage);
exp = tmp[0];
sp = tmp[1];
if (isOverhit() && player == getOverhitAttacker().getActingPlayer())
{
long overHitExp = calculateOverhitExp((long)exp);
SystemMessage sms = new SystemMessage(SystemMessageId.OVER_HIT);
sms.addNumber((int)overHitExp);
player.sendPacket(sms);
exp += overHitExp;
}
if (!attacker.isDead())
{
long addexp = Math.round(attacker.calcStat(Stats.EXPSP_RATE, exp, null, null));
int addsp = (int) attacker.calcStat(Stats.EXPSP_RATE, sp, null, null);
if (attacker instanceof L2PcInstance && !(this instanceof L2ChestInstance))
{
// Soul Mastery skill
int soulMasteryLevel = attacker.getSkillLevel(L2Skill.SKILL_SOUL_MASTERY);
if (soulMasteryLevel > 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(L2Skill.SKILL_SOUL_MASTERY, soulMasteryLevel);
if (skill.getExpNeeded() <= addexp)
((L2PcInstance) attacker).absorbSoulFromNpc(skill, this);
}
}
if (Config.ENABLE_VITALITY)
{
if (!isChampion() || (isChampion() && Config.CHAMPION_ENABLE_VITALITY))
{
player.addVitExpAndSp(addexp, addsp, this);
//_log.info("calculateVitalityPoints partyDmg="+damage);
player.calculateVitalityPoints(this, damage);
}
else
player.addExpAndSp(addexp, addsp, this);
}
else
player.addExpAndSp(addexp, addsp, this);
}
}
else
{
if (parties.contains(attackerParty))
continue;
parties.add(attackerParty);
rewardedMembers.clear();
//share with party members
partyDmg = 0;
partyLvl = attackerParty.getLevel();
partyLevelSum = 0;
// Go through all L2PcInstance in the party
List<L2PcInstance> groupMembers = attackerParty.getPartyMembers();
for (L2PcInstance pl : groupMembers)
{
if (pl == null || pl.isDead())
continue;
// Check if ddealer isn't too far from this (killed monster)
if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE, this, pl, true))
continue;
// Get the RewardInfo of this L2PcInstance from L2Attackable rewards
reward2 = rewards.get(pl.getObjectId());
if (reward2 != null)
partyDmg += reward2._dmg; // Add L2PcInstance damages to party damages
rewardedMembers.add(pl);
partyLevelSum += pl.getLevel();
}
partyDmg = Math.min(partyDmg, getMaxHp());
int newLevel = 0;
for (L2Character member : rewardedMembers)
{
if (member.getLevel() > newLevel)
newLevel = member.getLevel();
}
// Calculate the level difference between Party and L2Attackable
levelDiff = partyLvl - getLevel();
// Calculate Exp and SP rewards
tmp = calculateExpAndSp(levelDiff, partyDmg);
double partyMul = (double) partyDmg / getMaxHp();
exp = tmp[0] * partyMul;
sp = tmp[1] * partyMul;
// Check for an over-hit enabled strike
// (When in party, the over-hit exp bonus is given to the whole party and splitted proportionally through the party members)
if (isOverhit() && attacker.getActingPlayer() == getOverhitAttacker().getActingPlayer())
{
L2PcInstance player = (L2PcInstance) attacker;
if (isOverhit() && attacker == getOverhitAttacker())
{
player.sendPacket(SystemMessageId.OVER_HIT);
exp += calculateOverhitExp((long)exp);
}
}
// Distribute Experience and SP rewards to L2PcInstance Party members in the known area of the last attacker
if (partyDmg > 0)
attackerParty.distributeXpAndSp((long)exp, (int)sp, rewardedMembers, this, partyDmg, partyLevelSum, isChampion());
}
}
rewardedMembers.clear();
parties.clear();
rewards.clear();
}
}
catch (Exception e)
{
_log.warn("", e);
}
}
Hide
сами разберетесь?