Selaa lähdekoodia

BETA: Minor rework of L2Attackable:
* Fields should be at the begin of the class.
* Constructor should be after the fields.
* Merging conditions in useMagic(..) method, shortening the code.
* OOP rework of calculateRewards(..) method, more could be done.
* Fixes issue with summons not over-hitting and not giving extra XP on over-hit.

Reported by: MELERIX

Zoey76 12 vuotta sitten
vanhempi
sitoutus
67071c716f

+ 122 - 204
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Attackable.java

@@ -18,11 +18,13 @@
  */
 package com.l2jserver.gameserver.model.actor;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 
-import javolution.util.FastList;
 import javolution.util.FastMap;
 
 import com.l2jserver.Config;
@@ -40,7 +42,6 @@ import com.l2jserver.gameserver.datatables.EventDroplist.DateDrop;
 import com.l2jserver.gameserver.datatables.HerbDropTable;
 import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.datatables.ManorData;
-import com.l2jserver.gameserver.datatables.SkillTable;
 import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager;
 import com.l2jserver.gameserver.instancemanager.WalkingManager;
 import com.l2jserver.gameserver.model.L2CharPosition;
@@ -52,7 +53,6 @@ import com.l2jserver.gameserver.model.L2Party;
 import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
 import com.l2jserver.gameserver.model.actor.knownlist.AttackableKnownList;
 import com.l2jserver.gameserver.model.actor.status.AttackableStatus;
@@ -79,6 +79,38 @@ public class L2Attackable extends L2Npc
 	private boolean _isRaid = false;
 	private boolean _isRaidMinion = false;
 	private boolean _champion = false;
+	private final Map<L2Character, AggroInfo> _aggroList = new FastMap<L2Character, AggroInfo>().shared();
+	private boolean _isReturningToSpawnPoint = false;
+	private boolean _canReturnToSpawnPoint = true;
+	private boolean _seeThroughSilentMove = false;
+	private ItemHolder[] _sweepItems;
+	private ItemHolder[] _harvestItems;
+	private boolean _seeded;
+	private int _seedType = 0;
+	private int _seederObjId = 0;
+	
+	private boolean _overhit;
+	
+	private double _overhitDamage;
+	
+	private L2Character _overhitAttacker;
+	
+	private volatile L2CommandChannel _firstCommandChannelAttacked = null;
+	private CommandChannelTimer _commandChannelTimer = null;
+	private long _commandChannelLastAttack = 0;
+	
+	private boolean _absorbed;
+	
+	private final L2TIntObjectHashMap<AbsorberInfo> _absorbersList = new L2TIntObjectHashMap<>();
+	
+	private boolean _mustGiveExpSp;
+	
+	/** True if a Dwarf has used Spoil on this L2NpcInstance */
+	private boolean _isSpoil = false;
+	
+	private int _isSpoiledBy = 0;
+	
+	protected int _onKillDelay = 5000;
 	
 	/**
 	 * This class contains all AggroInfo of the L2Attackable against the attacker L2Character.
@@ -242,78 +274,6 @@ public class L2Attackable extends L2Npc
 		}
 	}
 	
-	private final FastMap<L2Character, AggroInfo> _aggroList = new FastMap<L2Character, AggroInfo>().shared();
-	
-	public final FastMap<L2Character, AggroInfo> getAggroList()
-	{
-		return _aggroList;
-	}
-	
-	private boolean _isReturningToSpawnPoint = false;
-	
-	public final boolean isReturningToSpawnPoint()
-	{
-		return _isReturningToSpawnPoint;
-	}
-	
-	public final void setisReturningToSpawnPoint(boolean value)
-	{
-		_isReturningToSpawnPoint = value;
-	}
-	
-	private boolean _canReturnToSpawnPoint = true;
-	
-	public final boolean canReturnToSpawnPoint()
-	{
-		return _canReturnToSpawnPoint;
-	}
-	
-	public final void setCanReturnToSpawnPoint(boolean value)
-	{
-		_canReturnToSpawnPoint = value;
-	}
-	
-	private boolean _seeThroughSilentMove = false;
-	
-	public boolean canSeeThroughSilentMove()
-	{
-		return _seeThroughSilentMove;
-	}
-	
-	public void setSeeThroughSilentMove(boolean val)
-	{
-		_seeThroughSilentMove = val;
-	}
-	
-	private ItemHolder[] _sweepItems;
-	private ItemHolder[] _harvestItems;
-	private boolean _seeded;
-	private int _seedType = 0;
-	private int _seederObjId = 0;
-	
-	private boolean _overhit;
-	
-	private double _overhitDamage;
-	
-	private L2Character _overhitAttacker;
-	
-	private volatile L2CommandChannel _firstCommandChannelAttacked = null;
-	private CommandChannelTimer _commandChannelTimer = null;
-	private long _commandChannelLastAttack = 0;
-	
-	private boolean _absorbed;
-	
-	private final L2TIntObjectHashMap<AbsorberInfo> _absorbersList = new L2TIntObjectHashMap<>();
-	
-	private boolean _mustGiveExpSp;
-	
-	/** True if a Dwarf has used Spoil on this L2NpcInstance */
-	private boolean _isSpoil = false;
-	
-	private int _isSpoiledBy = 0;
-	
-	protected int _onKillDelay = 5000;
-	
 	/**
 	 * Constructor of L2Attackable (use L2Character and L2NpcInstance constructor).<br>
 	 * Actions:<br>
@@ -377,63 +337,75 @@ public class L2Attackable extends L2Npc
 		return ai;
 	}
 	
+	public final Map<L2Character, AggroInfo> getAggroList()
+	{
+		return _aggroList;
+	}
+	
+	public final boolean isReturningToSpawnPoint()
+	{
+		return _isReturningToSpawnPoint;
+	}
+	
+	public final void setisReturningToSpawnPoint(boolean value)
+	{
+		_isReturningToSpawnPoint = value;
+	}
+	
+	public final boolean canReturnToSpawnPoint()
+	{
+		return _canReturnToSpawnPoint;
+	}
+	
+	public final void setCanReturnToSpawnPoint(boolean value)
+	{
+		_canReturnToSpawnPoint = value;
+	}
+	
+	public boolean canSeeThroughSilentMove()
+	{
+		return _seeThroughSilentMove;
+	}
+	
+	public void setSeeThroughSilentMove(boolean val)
+	{
+		_seeThroughSilentMove = val;
+	}
+	
+	/**
+	 * Use the skill if minimum checks are pass.
+	 * @param skill the skill
+	 */
 	public void useMagic(L2Skill skill)
 	{
-		if ((skill == null) || isAlikeDead())
-		{
-			return;
-		}
-		
-		if (skill.isPassive())
-		{
-			return;
-		}
-		
-		if (isCastingNow())
-		{
-			return;
-		}
-		
-		if (isSkillDisabled(skill))
-		{
-			return;
-		}
-		
-		if (getCurrentMp() < (getStat().getMpConsume(skill) + getStat().getMpInitialConsume(skill)))
+		if ((skill == null) || isAlikeDead() || skill.isPassive() || isCastingNow() || isSkillDisabled(skill))
 		{
 			return;
 		}
 		
-		if (getCurrentHp() <= skill.getHpConsume())
+		if ((getCurrentMp() < (getStat().getMpConsume(skill) + getStat().getMpInitialConsume(skill))) || (getCurrentHp() <= skill.getHpConsume()))
 		{
 			return;
 		}
 		
 		if (!skill.isStatic())
 		{
-			if (skill.isMagic())
+			if (skill.isMagic() && isMuted())
 			{
-				if (isMuted())
-				{
-					return;
-				}
+				return;
 			}
-			else
+			
+			if (isPhysicalMuted())
 			{
-				if (isPhysicalMuted())
-				{
-					return;
-				}
+				return;
 			}
 		}
 		
-		L2Object target = skill.getFirstOfTargetList(this);
-		if (target == null)
+		final L2Object target = skill.getFirstOfTargetList(this);
+		if (target != null)
 		{
-			return;
+			getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
 		}
-		
-		getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
 	}
 	
 	/**
@@ -604,8 +576,6 @@ public class L2Attackable extends L2Npc
 	@Override
 	protected void calculateRewards(L2Character lastAttacker)
 	{
-		// Creates an empty list of rewards
-		FastMap<L2Character, RewardInfo> rewards = new FastMap<L2Character, RewardInfo>().shared();
 		try
 		{
 			if (getAggroList().isEmpty())
@@ -613,12 +583,11 @@ public class L2Attackable extends L2Npc
 				return;
 			}
 			
+			final Map<L2Character, RewardInfo> rewards = new ConcurrentHashMap<>();
 			int damage;
-			L2Character attacker, ddealer;
-			
-			L2PcInstance maxDealer = null;
+			L2Character maxDealer = null;
 			int maxDamage = 0;
-			
+			L2Character attacker;
 			// While Iterating over This Map Removing Object is Not Allowed
 			// Go through the _aggroList of the L2Attackable
 			for (AggroInfo info : getAggroList().values())
@@ -637,45 +606,29 @@ public class L2Attackable extends L2Npc
 				// Prevent unwanted behavior
 				if (damage > 1)
 				{
-					if ((attacker instanceof L2ServitorInstance) || ((attacker instanceof L2PetInstance) && (((L2PetInstance) attacker).getPetLevelData().getOwnerExpTaken() > 0)))
-					{
-						ddealer = ((L2Summon) attacker).getOwner();
-					}
-					else
-					{
-						ddealer = info.getAttacker();
-					}
-					
-					// Check if ddealer isn't too far from this (killed monster)
-					if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE, this, ddealer, true))
+					// Check if damage dealer isn't too far from this (killed monster)
+					if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE, this, attacker, true))
 					{
 						continue;
 					}
 					
 					// Calculate real damages (Summoners should get own damage plus summon's damage)
-					RewardInfo reward = rewards.get(ddealer);
-					
-					if (reward == null)
+					if (!rewards.containsKey(attacker))
 					{
-						reward = new RewardInfo(ddealer, damage);
+						rewards.put(attacker, new RewardInfo(attacker, damage));
 					}
-					else
+					final RewardInfo reward = rewards.get(attacker);
+					reward.addDamage(damage);
+					if ((attacker.getActingPlayer() != null) && (reward._dmg > maxDamage))
 					{
-						reward.addDamage(damage);
-					}
-					
-					rewards.put(ddealer, reward);
-					
-					if ((ddealer.getActingPlayer() != null) && (reward._dmg > maxDamage))
-					{
-						maxDealer = ddealer.getActingPlayer();
+						maxDealer = attacker;
 						maxDamage = reward._dmg;
 					}
 				}
 			}
 			
 			// Manage Base, Quests and Sweep drops of the L2Attackable
-			doItemDrop((maxDealer != null) && maxDealer.isOnline() ? maxDealer : lastAttacker);
+			doItemDrop((maxDealer != null) && (maxDealer.getActingPlayer() != null) && maxDealer.getActingPlayer().isOnline() ? maxDealer : lastAttacker);
 			
 			// Manage drop of Special Events created by GM for a defined period
 			doEventDrop(lastAttacker);
@@ -700,33 +653,21 @@ public class L2Attackable extends L2Npc
 						continue;
 					}
 					
-					// Penalty applied to the attacker's XP
-					penalty = 0;
-					
 					// 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
-					if (attacker instanceof L2PetInstance)
-					{
-						attackerParty = ((L2PetInstance) attacker).getParty();
-					}
-					else if (attacker instanceof L2PcInstance)
-					{
-						attackerParty = ((L2PcInstance) attacker).getParty();
-					}
-					else
-					{
-						return;
-					}
+					// Get party
+					attackerParty = attacker.getParty();
 					
+					// Penalty applied to the attacker's XP
+					penalty = 0;
 					// If this attacker is a L2PcInstance with a summoned L2ServitorInstance, get Exp Penalty applied for the current summoned L2SummonInstance
-					if ((attacker instanceof L2PcInstance) && (((L2PcInstance) attacker).getSummon() instanceof L2ServitorInstance))
+					if (attacker.isPlayer() && attacker.hasSummon() && attacker.getSummon().isServitor())
 					{
-						penalty = ((L2ServitorInstance) ((L2PcInstance) attacker).getSummon()).getExpPenalty();
+						penalty = ((L2ServitorInstance) attacker.getSummon()).getExpPenalty();
 					}
 					
 					// We must avoid "over damage", if any
@@ -759,14 +700,10 @@ public class L2Attackable extends L2Npc
 							}
 							
 							// Check for an over-hit enabled strike
-							if (attacker instanceof L2PcInstance)
+							if (attacker.isPlayable() && isOverhit() && (attacker == getOverhitAttacker()))
 							{
-								L2PcInstance player = (L2PcInstance) attacker;
-								if (isOverhit() && (attacker == getOverhitAttacker()))
-								{
-									player.sendPacket(SystemMessageId.OVER_HIT);
-									exp += calculateOverhitExp(exp);
-								}
+								attacker.sendPacket(SystemMessageId.OVER_HIT);
+								exp += calculateOverhitExp(exp);
 							}
 							
 							// Distribute the Exp and SP between the L2PcInstance and its L2Summon
@@ -775,12 +712,11 @@ public class L2Attackable extends L2Npc
 								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)
+								if (attacker.isPlayer())
 								{
-									if (((L2PcInstance) attacker).getSkillLevel(467) > 0)
+									final L2Skill skill = attacker.getKnownSkill(L2Skill.SKILL_SOUL_MASTERY);
+									if (skill != null)
 									{
-										L2Skill skill = SkillTable.getInstance().getInfo(467, ((L2PcInstance) attacker).getSkillLevel(467));
-										
 										if (skill.getExpNeeded() <= addexp)
 										{
 											((L2PcInstance) attacker).absorbSoul(skill, this);
@@ -807,19 +743,9 @@ public class L2Attackable extends L2Npc
 						partyLvl = 0;
 						
 						// Get all L2Character that can be rewarded in the party
-						List<L2Playable> rewardedMembers = new FastList<>();
+						final List<L2Playable> rewardedMembers = new ArrayList<>();
 						// Go through all L2PcInstance in the party
-						List<L2PcInstance> groupMembers;
-						
-						if (attackerParty.isInCommandChannel())
-						{
-							groupMembers = attackerParty.getCommandChannel().getMembers();
-						}
-						else
-						{
-							groupMembers = attackerParty.getMembers();
-						}
-						
+						final List<L2PcInstance> groupMembers = attackerParty.isInCommandChannel() ? attackerParty.getCommandChannel().getMembers() : attackerParty.getMembers();
 						for (L2PcInstance pl : groupMembers)
 						{
 							if ((pl == null) || pl.isDead())
@@ -922,15 +848,10 @@ public class L2Attackable extends L2Npc
 						
 						// 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 (attacker instanceof L2PcInstance)
+						if (attacker.isPlayable() && isOverhit() && (attacker == getOverhitAttacker()))
 						{
-							L2PcInstance player = (L2PcInstance) attacker;
-							
-							if (isOverhit() && (attacker == getOverhitAttacker()))
-							{
-								player.sendPacket(SystemMessageId.OVER_HIT);
-								exp += calculateOverhitExp(exp);
-							}
+							attacker.sendPacket(SystemMessageId.OVER_HIT);
+							exp += calculateOverhitExp(exp);
 						}
 						// Distribute Experience and SP rewards to L2PcInstance Party members in the known area of the last attacker
 						if (partyDmg > 0)
@@ -940,7 +861,6 @@ public class L2Attackable extends L2Npc
 					}
 				}
 			}
-			rewards = null;
 		}
 		catch (Exception e)
 		{
@@ -1183,7 +1103,7 @@ public class L2Attackable extends L2Npc
 		L2Character mostHated = null;
 		L2Character secondMostHated = null;
 		int maxHate = 0;
-		List<L2Character> result = new FastList<>();
+		List<L2Character> result = new ArrayList<>();
 		
 		// While iterating over this map removing objects is not allowed
 		// Go through the aggroList of the L2Attackable
@@ -1221,8 +1141,8 @@ public class L2Attackable extends L2Npc
 		{
 			return null;
 		}
-		List<L2Character> result = new FastList<>();
 		
+		List<L2Character> result = new ArrayList<>();
 		for (AggroInfo ai : getAggroList().values())
 		{
 			if (ai == null)
@@ -1809,8 +1729,7 @@ public class L2Attackable extends L2Npc
 				// according to sh1ny, seeded mobs CAN be spoiled and swept.
 				if (isSpoil()/* && !isSeeded() */)
 				{
-					FastList<ItemHolder> sweepList = new FastList<>();
-					
+					List<ItemHolder> sweepList = new ArrayList<>();
 					for (L2DropData drop : cat.getAllDrops())
 					{
 						item = calculateRewardItem(player, drop, levelModifier, true);
@@ -2088,9 +2007,9 @@ public class L2Attackable extends L2Npc
 	/**
 	 * @return a copy of dummy items for the spoil loot.
 	 */
-	public FastList<L2Item> getSpoilLootItems()
+	public List<L2Item> getSpoilLootItems()
 	{
-		final FastList<L2Item> lootItems = new FastList<>();
+		final List<L2Item> lootItems = new ArrayList<>();
 		if (isSweepActive())
 		{
 			for (ItemHolder item : _sweepItems)
@@ -2489,11 +2408,10 @@ public class L2Attackable extends L2Npc
 			count += diff;
 		}
 		
-		FastList<ItemHolder> harvested = new FastList<>();
-		
-		harvested.add(new ItemHolder(ManorData.getInstance().getCropType(_seedType), count * Config.RATE_DROP_MANOR));
-		
-		_harvestItems = harvested.toArray(new ItemHolder[harvested.size()]);
+		_harvestItems = new ItemHolder[]
+		{
+			new ItemHolder(ManorData.getInstance().getCropType(_seedType), count * Config.RATE_DROP_MANOR)
+		};
 	}
 	
 	public int getSeederId()

+ 2 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java

@@ -21,6 +21,7 @@ package com.l2jserver.gameserver.model.itemcontainer;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -838,7 +839,7 @@ public class PcInventory extends Inventory
 	 * @param sendSkillMessage if {@code true} will send a message of skill not available.
 	 * @return {@code true} if the inventory isn't full after taking new items and items weight add to current load doesn't exceed max weight load.
 	 */
-	public boolean checkInventorySlotsAndWeight(FastList<L2Item> itemList, boolean sendMessage, boolean sendSkillMessage)
+	public boolean checkInventorySlotsAndWeight(List<L2Item> itemList, boolean sendMessage, boolean sendSkillMessage)
 	{
 		int lootWeight = 0;
 		int requiredSlots = 0;

+ 1 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/L2Skill.java

@@ -79,6 +79,7 @@ public abstract class L2Skill implements IChanceSkillTrigger
 	public static final int SKILL_EXPERTISE = 239;
 	public static final int SKILL_CRYSTALLIZE = 248;
 	public static final int SKILL_CLAN_LUCK = 390;
+	public static final int SKILL_SOUL_MASTERY = 467;
 	public static final int SKILL_ONYX_BEAST_TRANSFORMATION = 617;
 	public static final int SKILL_CREATE_COMMON = 1320;
 	public static final int SKILL_DIVINE_INSPIRATION = 1405;