浏览代码

BETA: Fixing memory leak:
* Custom skills are used only by players, not by every L2Character!
* Improved !RequestMagicSkillUse to retrieve skills with less map calls (OOP).
* Using lazy initialization, even if map is for player only, players with no custom skills shouldn't instantiate it.
* Removed deprecated method related to class name.
* Using hierarchy in !PcItemTemplate to inherit !ItemHolder fields and methods.
* Using !ArrayList instead of !FastList in !SkillList, there is no need for concurrent or thread safe operations.
* Removed removeSkill(L2Skill) from L2Character.
* Overridden addSkill(L2Skill) in L2PcInstance to keep player related code in player class.
* Fixing issue with custom skills not being displayed by client when skill level doesn't exist in client.
* Using custom display level to properly display custom skills.
* XML skill parameter: displayLevel (same use as displayId).
* Video: http://youtu.be/9wHGkqd5PPc

Zoey76 12 年之前
父节点
当前提交
8095a1ac65

+ 0 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/CharTemplateTable.java

@@ -55,7 +55,6 @@ public final class CharTemplateTable
 				set = new StatsSet();
 				cId = rset.getInt("ClassId");
 				set.set("classId", cId);
-				set.set("className", rset.getString("className"));
 				set.set("raceId", rset.getInt("raceId"));
 				set.set("baseSTR", rset.getInt("STR"));
 				set.set("baseCON", rset.getInt("CON"));

+ 4 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/ChanceSkillList.java

@@ -194,8 +194,8 @@ public class ChanceSkillList extends FastMap<IChanceSkillTrigger, ChanceConditio
 				
 				ISkillHandler handler = SkillHandler.getInstance().getHandler(skill.getSkillType());
 				
-				_owner.broadcastPacket(new MagicSkillLaunched(_owner, skill.getDisplayId(), skill.getLevel(), targets));
-				_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, skill.getDisplayId(), skill.getLevel(), 0, 0));
+				_owner.broadcastPacket(new MagicSkillLaunched(_owner, skill.getDisplayId(), skill.getDisplayLevel(), targets));
+				_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, skill.getDisplayId(), skill.getDisplayLevel(), 0, 0));
 				
 				// Launch the magic skill and calculate its effects
 				// TODO: once core will support all possible effects, use effects (not handler)
@@ -252,8 +252,8 @@ public class ChanceSkillList extends FastMap<IChanceSkillTrigger, ChanceConditio
 			
 			ISkillHandler handler = SkillHandler.getInstance().getHandler(triggered.getSkillType());
 			
-			_owner.broadcastPacket(new MagicSkillLaunched(_owner, triggered.getDisplayId(), triggered.getLevel(), targets));
-			_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, triggered.getDisplayId(), triggered.getLevel(), 0, 0));
+			_owner.broadcastPacket(new MagicSkillLaunched(_owner, triggered.getDisplayId(), triggered.getDisplayLevel(), targets));
+			_owner.broadcastPacket(new MagicSkillUse(_owner, firstTarget, triggered.getDisplayId(), triggered.getDisplayLevel(), 0, 0));
 			
 			// Launch the magic skill and calculate its effects
 			// TODO: once core will support all possible effects, use effects (not handler)

+ 10 - 104
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -200,17 +200,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 	/** Table of Calculators containing all used calculator */
 	private Calculator[] _calculators;
 	
-	/**
-	 * Map containing all skills of this character.
-	 */
+	/** Map containing all skills of this character. */
 	private final FastMap<Integer, L2Skill> _skills = new FastMap<>();
 	
-	/**
-	 * Map containing all custom skills of this character.
-	 */
-	private final FastMap<Integer, SkillHolder> _customSkills = new FastMap<>();
-	
-	/** FastMap containing the active chance skills on this character */
+	/** Map containing the active chance skills on this character */
 	private volatile ChanceSkillList _chanceSkills;
 	
 	/** Current force buff this caster is casting to a target */
@@ -403,7 +396,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		initCharStatus();
 		
 		_skills.shared();
-		_customSkills.shared();
 		
 		// Set its template to the new L2Character
 		_template = template;
@@ -425,16 +417,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 				_skills.putAll(template.getSkills());
 			}
 			
-			if (!_skills.isEmpty())
+			for (L2Skill skill : _skills.values())
 			{
-				for (L2Skill skill : getAllSkills())
-				{
-					if (skill.getDisplayId() != skill.getId())
-					{
-						_customSkills.put(Integer.valueOf(skill.getDisplayId()), new SkillHolder(skill));
-					}
-					addStatFuncs(skill.getStatFuncs(null, this));
-				}
+				addStatFuncs(skill.getStatFuncs(null, this));
 			}
 		}
 		else
@@ -451,16 +436,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 				{
 					_skills.putAll(((L2NpcTemplate) template).getSkills());
 				}
-				if (!_skills.isEmpty())
+				
+				for (L2Skill skill : _skills.values())
 				{
-					for (L2Skill skill : getAllSkills())
-					{
-						if (skill.getDisplayId() != skill.getId())
-						{
-							_customSkills.put(Integer.valueOf(skill.getDisplayId()), new SkillHolder(skill));
-						}
-						addStatFuncs(skill.getStatFuncs(null, this));
-					}
+					addStatFuncs(skill.getStatFuncs(null, this));
 				}
 			}
 			
@@ -1758,17 +1737,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		// Get the Identifier of the skill
 		int magicId = skill.getId();
 		
-		// Get the Display Identifier for a skill that client can't display
-		int displayId = skill.getDisplayId();
-		
-		// Get the level of the skill
-		int level = skill.getLevel();
-		
-		if (level < 1)
-		{
-			level = 1;
-		}
-		
 		// Get the Base Casting Time of the Skills.
 		int skillTime = (skill.getHitTime() + skill.getCoolTime());
 		
@@ -1940,7 +1908,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		
 		// Send a Server->Client packet MagicSkillUser with target, displayId, level, skillTime, reuseDelay
 		// to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
-		broadcastPacket(new MagicSkillUse(this, target, displayId, level, skillTime, reuseDelay));
+		broadcastPacket(new MagicSkillUse(this, target, skill.getDisplayId(), skill.getDisplayLevel(), skillTime, reuseDelay));
 		
 		// Send a system message USE_S1 to the L2Character
 		if (isPlayer())
@@ -6036,15 +6004,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 	public L2Skill addSkill(L2Skill newSkill)
 	{
 		L2Skill oldSkill = null;
-		
 		if (newSkill != null)
 		{
 			// Replace oldSkill by newSkill or Add the newSkill
 			oldSkill = _skills.put(newSkill.getId(), newSkill);
-			if (newSkill.getDisplayId() != newSkill.getId())
-			{
-				_customSkills.put(Integer.valueOf(newSkill.getDisplayId()), new SkillHolder(newSkill));
-			}
 			// If an old skill has been replaced, remove all its Func objects
 			if (oldSkill != null)
 			{
@@ -6069,47 +6032,13 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			
 			// Add passive effects if there are any.
 			newSkill.getEffectsPassive(this);
-			
-			/*
-			 * if (!newSkill.isChance() && newSkill.triggerAnotherSkill() ) { L2Skill bestowed = SkillTable.getInstance().getInfo(newSkill.getTriggeredId(), newSkill.getTriggeredLevel()); addSkill(bestowed); //bestowed skills are invisible for player. Visible for gm's looking thru gm window. //those
-			 * skills should always be chance or passive, to prevent hlapex. } if(newSkill.isChance() && newSkill.triggerAnotherSkill()) { L2Skill triggeredSkill = SkillTable.getInstance().getInfo(newSkill.getTriggeredId(),newSkill.getTriggeredLevel()); addSkill(triggeredSkill); }
-			 */
 		}
-		
 		return oldSkill;
 	}
 	
-	/**
-	 * Remove a skill from the L2Character and its Func objects from calculator set of the L2Character.<br>
-	 * <B><U>Concept</U>:</B><br>
-	 * All skills own by a L2Character are identified in <B>_skills</B><br>
-	 * <B><U>Actions</U>:</B>
-	 * <ul>
-	 * <li>Remove the skill from the L2Character _skills</li>
-	 * <li>Remove all its Func objects from the L2Character calculator set</li>
-	 * </ul>
-	 * @param skill The L2Skill to remove from the L2Character
-	 * @return The L2Skill removed
-	 */
-	public L2Skill removeSkill(L2Skill skill)
-	{
-		if (skill == null)
-		{
-			return null;
-		}
-		
-		return removeSkill(skill.getId(), true);
-	}
-	
 	public L2Skill removeSkill(L2Skill skill, boolean cancelEffect)
 	{
-		if (skill == null)
-		{
-			return null;
-		}
-		
-		// Remove the skill from the L2Character _skills
-		return removeSkill(skill.getId(), cancelEffect);
+		return (skill != null) ? removeSkill(skill.getId(), cancelEffect) : null;
 	}
 	
 	public L2Skill removeSkill(int skillId)
@@ -6124,10 +6053,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		// Remove all its Func objects from the L2Character calculator set
 		if (oldSkill != null)
 		{
-			if (oldSkill.getDisplayId() != oldSkill.getId())
-			{
-				_customSkills.remove(Integer.valueOf(oldSkill.getDisplayId()));
-			}
 			// this is just a fail-safe againts buggers and gm dummies...
 			if ((oldSkill.triggerAnotherSkill()) && (oldSkill.getTriggeredId() > 0))
 			{
@@ -6281,14 +6206,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 		return _skills;
 	}
 	
-	/**
-	 * @return all the custom skills (skills with different display Id than skill Id).
-	 */
-	public final Map<Integer, SkillHolder> getCustomSkills()
-	{
-		return _customSkills;
-	}
-	
 	public ChanceSkillList getChanceSkills()
 	{
 		return _chanceSkills;
@@ -6457,21 +6374,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
 			return;
 		}
 		
-		// Get the display identifier of the skill
-		int magicId = skill.getDisplayId();
-		
-		// Get the level of the skill
-		int level = getSkillLevel(skill.getId());
-		
-		if (level < 1)
-		{
-			level = 1;
-		}
-		
 		// Send a Server->Client packet MagicSkillLaunched to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
 		if (!skill.isStatic())
 		{
-			broadcastPacket(new MagicSkillLaunched(this, magicId, level, targets));
+			broadcastPacket(new MagicSkillLaunched(this, skill.getDisplayId(), skill.getDisplayLevel(), targets));
 		}
 		
 		mut.phase = 2;

+ 66 - 31
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -825,11 +825,6 @@ public final class L2PcInstance extends L2Playable
 	private double _mpUpdateDecCheck = .0;
 	private double _mpUpdateInterval = .0;
 	
-	// not used any more
-	// private boolean _isRidingFenrirWolf = false;
-	// private boolean _isRidingWFenrirWolf = false;
-	// private boolean _isRidingGreatSnowWolf = false;
-	
 	private boolean _isRidingStrider = false;
 	private boolean _isFlyingMounted = false;
 	
@@ -858,6 +853,9 @@ public final class L2PcInstance extends L2Playable
 	
 	private long _notMoveUntil = 0;
 	
+	/** Map containing all custom skills of this player. */
+	private Map<Integer, L2Skill> _customSkills = null;
+	
 	public void setPvpFlagLasts(long time)
 	{
 		_pvpFlagLasts = time;
@@ -2441,12 +2439,12 @@ public final class L2PcInstance extends L2Playable
 				_curWeightPenalty = newWeightPenalty;
 				if ((newWeightPenalty > 0) && !_dietMode)
 				{
-					super.addSkill(SkillTable.getInstance().getInfo(4270, newWeightPenalty));
+					addSkill(SkillTable.getInstance().getInfo(4270, newWeightPenalty));
 					setIsOverloaded(getCurrentLoad() > maxLoad);
 				}
 				else
 				{
-					super.removeSkill(getKnownSkill(4270));
+					removeSkill(getKnownSkill(4270), false, true);
 					setIsOverloaded(false);
 				}
 				sendPacket(new UserInfo(this));
@@ -2508,11 +2506,11 @@ public final class L2PcInstance extends L2Playable
 			_expertiseWeaponPenalty = weaponPenalty;
 			if (_expertiseWeaponPenalty > 0)
 			{
-				super.addSkill(SkillTable.getInstance().getInfo(FrequentSkill.WEAPON_GRADE_PENALTY.getId(), _expertiseWeaponPenalty));
+				addSkill(SkillTable.getInstance().getInfo(FrequentSkill.WEAPON_GRADE_PENALTY.getId(), _expertiseWeaponPenalty));
 			}
 			else
 			{
-				super.removeSkill(getKnownSkill(FrequentSkill.WEAPON_GRADE_PENALTY.getId()));
+				removeSkill(getKnownSkill(FrequentSkill.WEAPON_GRADE_PENALTY.getId()), false, true);
 			}
 			changed = true;
 		}
@@ -2533,11 +2531,11 @@ public final class L2PcInstance extends L2Playable
 			_expertiseArmorPenalty = armorPenalty;
 			if (_expertiseArmorPenalty > 0)
 			{
-				super.addSkill(SkillTable.getInstance().getInfo(FrequentSkill.ARMOR_GRADE_PENALTY.getId(), _expertiseArmorPenalty));
+				addSkill(SkillTable.getInstance().getInfo(FrequentSkill.ARMOR_GRADE_PENALTY.getId(), _expertiseArmorPenalty));
 			}
 			else
 			{
-				super.removeSkill(getKnownSkill(FrequentSkill.ARMOR_GRADE_PENALTY.getId()));
+				removeSkill(getKnownSkill(FrequentSkill.ARMOR_GRADE_PENALTY.getId()), false, true);
 			}
 			changed = true;
 		}
@@ -8447,6 +8445,13 @@ public final class L2PcInstance extends L2Playable
 		return _isIn7sDungeon;
 	}
 	
+	@Override
+	public L2Skill addSkill(L2Skill newSkill)
+	{
+		addCustomSkill(newSkill);
+		return super.addSkill(newSkill);
+	}
+	
 	/**
 	 * Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance and save update in the character_skills table of the database. <B><U> Concept</U> :</B> All skills own by a L2PcInstance are identified in <B>_skills</B> <B><U> Actions</U> :</B> <li>Replace
 	 * oldSkill by newSkill or Add the newSkill</li> <li>If an old skill has been replaced, remove all its Func objects of L2Character calculator set</li> <li>Add Func objects of newSkill to the calculator set of the L2Character</li>
@@ -8457,8 +8462,7 @@ public final class L2PcInstance extends L2Playable
 	public L2Skill addSkill(L2Skill newSkill, boolean store)
 	{
 		// Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance
-		L2Skill oldSkill = super.addSkill(newSkill);
-		
+		final L2Skill oldSkill = addSkill(newSkill);
 		// Add or update a L2PcInstance skill in the character_skills table of the database
 		if (store)
 		{
@@ -8470,20 +8474,14 @@ public final class L2PcInstance extends L2Playable
 	@Override
 	public L2Skill removeSkill(L2Skill skill, boolean store)
 	{
-		if (store)
-		{
-			return removeSkill(skill);
-		}
-		return super.removeSkill(skill, true);
+		removeCustomSkill(skill);
+		return store ? removeSkill(skill) : super.removeSkill(skill, true);
 	}
 	
 	public L2Skill removeSkill(L2Skill skill, boolean store, boolean cancelEffect)
 	{
-		if (store)
-		{
-			return removeSkill(skill);
-		}
-		return super.removeSkill(skill, cancelEffect);
+		removeCustomSkill(skill);
+		return store ? removeSkill(skill) : super.removeSkill(skill, cancelEffect);
 	}
 	
 	/**
@@ -8492,11 +8490,11 @@ public final class L2PcInstance extends L2Playable
 	 * @param skill The L2Skill to remove from the L2Character
 	 * @return The L2Skill removed
 	 */
-	@Override
 	public L2Skill removeSkill(L2Skill skill)
 	{
+		removeCustomSkill(skill);
 		// Remove a skill from the L2Character and its Func objects from calculator set of the L2Character
-		final L2Skill oldSkill = super.removeSkill(skill);
+		final L2Skill oldSkill = super.removeSkill(skill, true);
 		if (oldSkill != null)
 		{
 			try (Connection con = L2DatabaseFactory.getInstance().getConnection();
@@ -8610,7 +8608,7 @@ public final class L2PcInstance extends L2Playable
 				}
 				
 				// Add the L2Skill object to the L2Character _skills and its Func objects to the calculator set of the L2Character
-				super.addSkill(skill);
+				addSkill(skill);
 				
 				if (Config.SKILL_CHECK_ENABLE && (!canOverrideCond(PcCondOverride.SKILL_CONDITIONS) || Config.SKILL_CHECK_GM))
 				{
@@ -10773,14 +10771,14 @@ public final class L2PcInstance extends L2Playable
 		{
 			for (L2Skill skill : SkillTreesData.getInstance().getHeroSkillTree().values())
 			{
-				addSkill(skill, false); // Dont Save Hero skills to database
+				addSkill(skill, false); // Don't persist hero skills into database
 			}
 		}
 		else
 		{
 			for (L2Skill skill : SkillTreesData.getInstance().getHeroSkillTree().values())
 			{
-				super.removeSkill(skill); // Just Remove skills from nonHero characters
+				removeSkill(skill, false, true); // Just remove skills from non-hero players
 			}
 		}
 		_hero = hero;
@@ -10944,7 +10942,7 @@ public final class L2PcInstance extends L2Playable
 		{
 			for (L2Skill skill : nobleSkillTree)
 			{
-				super.removeSkill(skill);
+				removeSkill(skill, false, true);
 			}
 		}
 		
@@ -11039,7 +11037,7 @@ public final class L2PcInstance extends L2Playable
 				}
 			}
 			
-			sl.addSkill(s.getDisplayId(), s.getLevel(), s.isPassive(), isDisabled, isEnchantable);
+			sl.addSkill(s.getDisplayId(), s.getDisplayLevel(), s.isPassive(), isDisabled, isEnchantable);
 		}
 		
 		sendPacket(sl);
@@ -11344,7 +11342,7 @@ public final class L2PcInstance extends L2Playable
 			// 9. Resend a class change animation effect to broadcast to all nearby players.
 			for (L2Skill oldSkill : getAllSkills())
 			{
-				super.removeSkill(oldSkill);
+				removeSkill(oldSkill, false, true);
 			}
 			
 			stopAllEffectsExceptThoseThatLastThroughDeath();
@@ -16098,6 +16096,43 @@ public final class L2PcInstance extends L2Playable
 		}
 	}
 	
+	/**
+	 * @param skillId the display skill Id
+	 * @return the custom skill
+	 */
+	public final L2Skill getCustomSkill(int skillId)
+	{
+		return (_customSkills != null) ? _customSkills.get(skillId) : null;
+	}
+	
+	/**
+	 * Add a skill level to the custom skills map.
+	 * @param skill the skill to add
+	 */
+	private final void addCustomSkill(L2Skill skill)
+	{
+		if ((skill != null) && (skill.getDisplayId() != skill.getId()))
+		{
+			if (_customSkills == null)
+			{
+				_customSkills = new FastMap<Integer, L2Skill>().shared();
+			}
+			_customSkills.put(skill.getDisplayId(), skill);
+		}
+	}
+	
+	/**
+	 * Remove a skill level from the custom skill map.
+	 * @param skill the skill to remove
+	 */
+	private final void removeCustomSkill(L2Skill skill)
+	{
+		if ((skill != null) && (_customSkills != null) && (skill.getDisplayId() != skill.getId()))
+		{
+			_customSkills.remove(skill.getDisplayId());
+		}
+	}
+	
 	// LISTENERS
 	/**
 	 * Fires all the equipment listeners, if any.<br>

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PetInstance.java

@@ -1387,7 +1387,7 @@ public class L2PetInstance extends L2Summon
 				}
 				else
 				{
-					super.removeSkill(getKnownSkill(4270));
+					removeSkill(getKnownSkill(4270), true);
 					setIsOverloaded(false);
 				}
 			}

+ 0 - 13
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/templates/L2PcTemplate.java

@@ -23,7 +23,6 @@ import java.util.List;
 import com.l2jserver.gameserver.datatables.InitialEquipmentData;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.base.ClassId;
-import com.l2jserver.gameserver.model.base.ClassInfo;
 import com.l2jserver.gameserver.model.base.Race;
 import com.l2jserver.gameserver.model.items.PcItemTemplate;
 
@@ -34,7 +33,6 @@ public class L2PcTemplate extends L2CharTemplate
 {
 	private final ClassId _classId;
 	private final Race _race;
-	private final String _className;
 	
 	private final int _spawnX;
 	private final int _spawnY;
@@ -63,7 +61,6 @@ public class L2PcTemplate extends L2CharTemplate
 		super(set);
 		_classId = ClassId.getClassId(set.getInteger("classId"));
 		_race = Race.values()[set.getInteger("raceId")];
-		_className = set.getString("className");
 		
 		_spawnX = set.getInteger("spawnX");
 		_spawnY = set.getInteger("spawnY");
@@ -104,16 +101,6 @@ public class L2PcTemplate extends L2CharTemplate
 		return _race;
 	}
 	
-	/**
-	 * @return the template server side class name.
-	 * @deprecated replaced by {@link ClassInfo#getClassName()}
-	 */
-	@Deprecated
-	public String getClassName()
-	{
-		return _className;
-	}
-	
 	/**
 	 * @return the template X spawn coordinate.
 	 */

+ 4 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/effects/L2Effect.java

@@ -590,11 +590,11 @@ public abstract class L2Effect implements IChanceSkillTrigger
 		{
 			if (sk.isStatic())
 			{
-				mi.addEffect(sk.getDisplayId(), getLevel(), sk.getBuffDuration() - (getTaskTime() * 1000));
+				mi.addEffect(sk.getDisplayId(), sk.getDisplayLevel(), sk.getBuffDuration() - (getTaskTime() * 1000));
 			}
 			else
 			{
-				mi.addEffect(sk.getDisplayId(), getLevel(), -1);
+				mi.addEffect(sk.getDisplayId(), sk.getDisplayLevel(), -1);
 			}
 		}
 		else if (future != null)
@@ -637,11 +637,11 @@ public abstract class L2Effect implements IChanceSkillTrigger
 		final L2Skill sk = getSkill();
 		if (future != null)
 		{
-			os.addEffect(sk.getDisplayId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
+			os.addEffect(sk.getDisplayId(), sk.getDisplayLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
 		}
 		else if (_abnormalTime == -1)
 		{
-			os.addEffect(sk.getDisplayId(), getLevel(), _abnormalTime);
+			os.addEffect(sk.getDisplayId(), sk.getDisplayLevel(), _abnormalTime);
 		}
 	}
 	

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/model/holders/ItemHolder.java

@@ -22,7 +22,7 @@ package com.l2jserver.gameserver.model.holders;
  * Holder for item id-count.
  * @author UnAfraid
  */
-public final class ItemHolder
+public class ItemHolder
 {
 	private final int _id;
 	private final int _objectId;

+ 5 - 23
L2J_Server_BETA/java/com/l2jserver/gameserver/model/items/PcItemTemplate.java

@@ -19,44 +19,26 @@
 package com.l2jserver.gameserver.model.items;
 
 import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.holders.ItemHolder;
 
 /**
  * @author Zoey76
  */
-public final class PcItemTemplate
+public final class PcItemTemplate extends ItemHolder
 {
-	private final int _itemId;
-	private final long _count;
 	private final boolean _equipped;
 	
 	/**
-	 * @param set the set containing the values for this object.
+	 * @param set the set containing the values for this object
 	 */
 	public PcItemTemplate(StatsSet set)
 	{
-		_itemId = set.getInteger("id");
-		_count = set.getInteger("count");
+		super(set.getInteger("id"), set.getInteger("count"));
 		_equipped = set.getBool("equipped", false);
 	}
 	
 	/**
-	 * @return the item Id.
-	 */
-	public int getItemId()
-	{
-		return _itemId;
-	}
-	
-	/**
-	 * @return the item count.
-	 */
-	public long getCount()
-	{
-		return _count;
-	}
-	
-	/**
-	 * @return {@code true} if the items is equipped upon character creation, {@code false} otherwise.
+	 * @return {@code true} if the items is equipped upon character creation, {@code false} otherwise
 	 */
 	public boolean isEquipped()
 	{

+ 7 - 4
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/L2Skill.java

@@ -105,8 +105,10 @@ public abstract class L2Skill implements IChanceSkillTrigger
 	private final int _id;
 	private final int _level;
 	
-	/** Identifier for a skill that client can't display */
-	private int _displayId;
+	/** Custom skill Id displayed by the client. */
+	private final int _displayId;
+	/** Custom skill level displayed by the client. */
+	private final int _displayLevel;
 	
 	// not needed, just for easier debug
 	private final String _name;
@@ -264,6 +266,7 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		_level = set.getInteger("level");
 		_refId = set.getInteger("referenceId", 0);
 		_displayId = set.getInteger("displayId", _id);
+		_displayLevel = set.getInteger("displayLevel", _level);
 		_name = set.getString("name", "");
 		_operateType = set.getEnum("operateType", L2SkillOpType.class);
 		_magic = set.getInteger("isMagic", 0);
@@ -789,9 +792,9 @@ public abstract class L2Skill implements IChanceSkillTrigger
 		return _displayId;
 	}
 	
-	public void setDisplayId(int id)
+	public int getDisplayLevel()
 	{
-		_displayId = id;
+		return _displayLevel;
 	}
 	
 	public int getTriggeredId()

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/CharacterCreate.java

@@ -291,10 +291,10 @@ public final class CharacterCreate extends L2GameClientPacket
 			L2ItemInstance item;
 			for (PcItemTemplate ie : template.getInitialEquipment())
 			{
-				item = newChar.getInventory().addItem("Init", ie.getItemId(), ie.getCount(), newChar, null);
+				item = newChar.getInventory().addItem("Init", ie.getId(), ie.getCount(), newChar, null);
 				if (item == null)
 				{
-					_log.warning("Could not create item during char creation: itemId " + ie.getItemId() + ", amount " + ie.getCount() + ".");
+					_log.warning("Could not create item during char creation: itemId " + ie.getId() + ", amount " + ie.getCount() + ".");
 					continue;
 				}
 				

+ 43 - 61
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestMagicSkillUse.java

@@ -20,11 +20,9 @@ package com.l2jserver.gameserver.network.clientpackets;
 
 import com.l2jserver.Config;
 import com.l2jserver.gameserver.ai.CtrlIntention;
-import com.l2jserver.gameserver.datatables.SkillTable;
 import com.l2jserver.gameserver.model.L2CharPosition;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.actor.position.PcPosition;
-import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.model.skills.L2SkillType;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
@@ -51,83 +49,67 @@ public final class RequestMagicSkillUse extends L2GameClientPacket
 	protected void runImpl()
 	{
 		// Get the current L2PcInstance of the player
-		final L2PcInstance activeChar = getClient().getActiveChar();
+		final L2PcInstance activeChar = getActiveChar();
 		if (activeChar == null)
 		{
 			return;
 		}
 		
 		// Get the level of the used skill
-		int level = activeChar.getSkillLevel(_magicId);
-		if (level <= 0)
+		L2Skill skill = activeChar.getKnownSkill(_magicId);
+		if (skill == null)
 		{
 			// Player doesn't know this skill, maybe it's the display Id.
-			final SkillHolder customSkill = activeChar.getCustomSkills().get(_magicId);
-			if (customSkill != null)
-			{
-				_magicId = customSkill.getSkillId();
-				level = customSkill.getSkillLvl();
-			}
-			else
+			skill = activeChar.getCustomSkill(_magicId);
+			if (skill == null)
 			{
 				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
+				_log.warning("Skill Id " + _magicId + " not found in player!");
 				return;
 			}
 		}
 		
-		// Get the L2Skill template corresponding to the skillID received from the client
-		L2Skill skill = SkillTable.getInstance().getInfo(_magicId, level);
-		
-		// Check the validity of the skill
-		if (skill != null)
+		// Avoid Use of Skills in AirShip.
+		if (activeChar.isPlayable() && activeChar.isInAirShip())
 		{
-			// Avoid Use of Skills in AirShip.
-			if (activeChar.isPlayable() && activeChar.isInAirShip())
-			{
-				activeChar.sendPacket(SystemMessageId.ACTION_PROHIBITED_WHILE_MOUNTED_OR_ON_AN_AIRSHIP);
-				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
-				return;
-			}
-			
-			if ((activeChar.isTransformed() || activeChar.isInStance()) && !activeChar.containsAllowedTransformSkill(skill.getId()))
-			{
-				activeChar.sendPacket(ActionFailed.STATIC_PACKET);
-				return;
-			}
-			
-			if (Config.DEBUG)
-			{
-				_log.fine("	skill:" + skill.getName() + " level:" + skill.getLevel() + " passive:" + skill.isPassive());
-				_log.fine("	range:" + skill.getCastRange() + " targettype:" + skill.getTargetType() + " power:" + skill.getPower());
-				_log.fine("	reusedelay:" + skill.getReuseDelay() + " hittime:" + skill.getHitTime());
-			}
-			
-			// If Alternate rule Karma punishment is set to true, forbid skill Return to player with Karma
-			if ((skill.getSkillType() == L2SkillType.RECALL) && !Config.ALT_GAME_KARMA_PLAYER_CAN_TELEPORT && (activeChar.getKarma() > 0))
-			{
-				return;
-			}
-			
-			// players mounted on pets cannot use any toggle skills
-			if (skill.isToggle() && activeChar.isMounted())
-			{
-				return;
-			}
-			
-			activeChar.useMagic(skill, _ctrlPressed, _shiftPressed);
-			
-			// Stop if use self-buff (except if on AirShip or Boat).
-			if (((skill.getSkillType() == L2SkillType.BUFF) && (skill.getTargetType() == L2TargetType.SELF)) && (!activeChar.isInAirShip() || !activeChar.isInBoat()))
-			{
-				final PcPosition charPos = activeChar.getPosition();
-				final L2CharPosition stopPos = new L2CharPosition(charPos.getX(), charPos.getY(), charPos.getZ(), charPos.getHeading());
-				activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, stopPos);
-			}
+			activeChar.sendPacket(SystemMessageId.ACTION_PROHIBITED_WHILE_MOUNTED_OR_ON_AN_AIRSHIP);
+			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
+			return;
 		}
-		else
+		
+		if ((activeChar.isTransformed() || activeChar.isInStance()) && !activeChar.containsAllowedTransformSkill(skill.getId()))
 		{
 			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
-			_log.warning("No skill found with id " + _magicId + " and level " + level + " !!");
+			return;
+		}
+		
+		if (activeChar.isDebug())
+		{
+			_log.fine("Skill:" + skill.getName() + " level:" + skill.getLevel() + " passive:" + skill.isPassive());
+			_log.fine("Range:" + skill.getCastRange() + " targettype:" + skill.getTargetType() + " power:" + skill.getPower());
+			_log.fine("Reusedelay:" + skill.getReuseDelay() + " hittime:" + skill.getHitTime());
+		}
+		
+		// If Alternate rule Karma punishment is set to true, forbid skill Return to player with Karma
+		if ((skill.getSkillType() == L2SkillType.RECALL) && !Config.ALT_GAME_KARMA_PLAYER_CAN_TELEPORT && (activeChar.getKarma() > 0))
+		{
+			return;
+		}
+		
+		// players mounted on pets cannot use any toggle skills
+		if (skill.isToggle() && activeChar.isMounted())
+		{
+			return;
+		}
+		
+		activeChar.useMagic(skill, _ctrlPressed, _shiftPressed);
+		
+		// Stop if use self-buff (except if on AirShip or Boat).
+		if (((skill.getSkillType() == L2SkillType.BUFF) && (skill.getTargetType() == L2TargetType.SELF)) && (!activeChar.isInAirShip() || !activeChar.isInBoat()))
+		{
+			final PcPosition charPos = activeChar.getPosition();
+			final L2CharPosition stopPos = new L2CharPosition(charPos.getX(), charPos.getY(), charPos.getZ(), charPos.getHeading());
+			activeChar.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, stopPos);
 		}
 	}
 	

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/GMViewSkillInfo.java

@@ -48,7 +48,7 @@ public class GMViewSkillInfo extends L2GameServerPacket
 		for (L2Skill skill : _skills)
 		{
 			writeD(skill.isPassive() ? 1 : 0);
-			writeD(skill.getLevel());
+			writeD(skill.getDisplayLevel());
 			writeD(skill.getDisplayId());
 			writeC(isDisabled && skill.isClanSkill() ? 1 : 0);
 			writeC(SkillTable.getInstance().isEnchantable(skill.getDisplayId()) ? 1 : 0);

+ 1 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/PledgeSkillList.java

@@ -60,7 +60,7 @@ public class PledgeSkillList extends L2GameServerPacket
 		for (L2Skill sk : _skills)
 		{
 			writeD(sk.getDisplayId());
-			writeD(sk.getLevel());
+			writeD(sk.getDisplayLevel());
 		}
 		for (SubPledgeSkill sk : _subSkills)
 		{

+ 2 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/network/serverpackets/SkillList.java

@@ -18,13 +18,12 @@
  */
 package com.l2jserver.gameserver.network.serverpackets;
 
+import java.util.ArrayList;
 import java.util.List;
 
-import javolution.util.FastList;
-
 public final class SkillList extends L2GameServerPacket
 {
-	private final List<Skill> _skills;
+	private final List<Skill> _skills = new ArrayList<>();
 	
 	static class Skill
 	{
@@ -44,11 +43,6 @@ public final class SkillList extends L2GameServerPacket
 		}
 	}
 	
-	public SkillList()
-	{
-		_skills = new FastList<>();
-	}
-	
 	public void addSkill(int id, int level, boolean passive, boolean disabled, boolean enchanted)
 	{
 		_skills.add(new Skill(id, level, passive, disabled, enchanted));