Selaa lähdekoodia

BETA: Rework of Servitor summoning to more retail:
* Removed L2SkillSummon
* Implemented new effect Summon
* Implemented onSummon quest hook (Notification when player summons a servitor/pet)
* Fixed bug causing effects ending system messeges to be sent when unsummoning pet/servitor.
* Updated to retail item consuming interval, life time broadcast interval.
* Thanks to: Nos
* Reviewed by: Nos, Adry_85

Rumen Nikiforov 11 vuotta sitten
vanhempi
sitoutus
45ebef66c8

+ 11 - 40
L2J_Server_BETA/java/com/l2jserver/gameserver/datatables/CharSummonTable.java

@@ -29,14 +29,13 @@ import java.util.logging.Logger;
 
 import com.l2jserver.Config;
 import com.l2jserver.L2DatabaseFactory;
-import com.l2jserver.gameserver.idfactory.IdFactory;
 import com.l2jserver.gameserver.model.L2PetData;
 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.templates.L2NpcTemplate;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSummon;
+import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.network.serverpackets.PetItemList;
 
 /**
@@ -194,9 +193,7 @@ public class CharSummonTable
 			ps.setInt(2, skillId);
 			try (ResultSet rs = ps.executeQuery())
 			{
-				L2NpcTemplate summonTemplate;
-				L2ServitorInstance summon;
-				L2SkillSummon skill;
+				L2Skill skill;
 				
 				while (rs.next())
 				{
@@ -204,47 +201,21 @@ public class CharSummonTable
 					int curMp = rs.getInt("curMp");
 					int time = rs.getInt("time");
 					
-					skill = (L2SkillSummon) SkillTable.getInstance().getInfo(skillId, activeChar.getSkillLevel(skillId));
+					skill = SkillTable.getInstance().getInfo(skillId, activeChar.getSkillLevel(skillId));
 					if (skill == null)
 					{
 						removeServitor(activeChar);
 						return;
 					}
 					
-					summonTemplate = NpcData.getInstance().getTemplate(skill.getNpcId());
-					if (summonTemplate == null)
+					skill.applyEffects(activeChar, activeChar);
+					if (activeChar.hasServitor())
 					{
-						_log.warning(getClass().getSimpleName() + ": Summon attemp for nonexisting Skill ID:" + skillId);
-						return;
-					}
-					
-					final int id = IdFactory.getInstance().getNextId();
-					
-					summon = new L2ServitorInstance(id, summonTemplate, activeChar, skill);
-					
-					summon.setName(summonTemplate.getName());
-					summon.setTitle(activeChar.getName());
-					summon.setExpPenalty(skill.getExpPenalty());
-					summon.setSharedElementals(skill.getInheritElementals());
-					summon.setSharedElementalsValue(skill.getElementalSharePercent());
-					
-					if (summon.getLevel() >= ExperienceTable.getInstance().getMaxPetLevel())
-					{
-						summon.getStat().setExp(ExperienceTable.getInstance().getExpForLevel(ExperienceTable.getInstance().getMaxPetLevel() - 1));
-						_log.warning(getClass().getSimpleName() + ": Summon (" + summon.getName() + ") NpcID: " + summon.getId() + " has a level above " + ExperienceTable.getInstance().getMaxPetLevel() + ". Please rectify.");
+						final L2ServitorInstance summon = (L2ServitorInstance) activeChar.getSummon();
+						summon.setCurrentHp(curHp);
+						summon.setCurrentMp(curMp);
+						summon.setLifeTimeRemaining(time);
 					}
-					else
-					{
-						summon.getStat().setExp(ExperienceTable.getInstance().getExpForLevel(summon.getLevel() % ExperienceTable.getInstance().getMaxPetLevel()));
-					}
-					summon.setCurrentHp(curHp);
-					summon.setCurrentMp(curMp);
-					summon.setHeading(activeChar.getHeading());
-					summon.setRunning();
-					activeChar.setPet(summon);
-					summon.setTimeRemaining(time);
-					
-					summon.spawnMe(activeChar.getX() + 20, activeChar.getY() + 20, activeChar.getZ());
 				}
 			}
 		}
@@ -256,7 +227,7 @@ public class CharSummonTable
 	
 	public void saveSummon(L2ServitorInstance summon)
 	{
-		if ((summon == null) || (summon.getTimeRemaining() <= 0))
+		if ((summon == null) || (summon.getLifeTimeRemaining() <= 0))
 		{
 			return;
 		}
@@ -270,7 +241,7 @@ public class CharSummonTable
 			ps.setInt(2, summon.getReferenceSkill());
 			ps.setInt(3, (int) Math.round(summon.getCurrentHp()));
 			ps.setInt(4, (int) Math.round(summon.getCurrentMp()));
-			ps.setInt(5, summon.getTimeRemaining());
+			ps.setInt(5, summon.getLifeTimeRemaining());
 			ps.execute();
 		}
 		catch (Exception e)

+ 2 - 1
L2J_Server_BETA/java/com/l2jserver/gameserver/enums/QuestEventType.java

@@ -43,7 +43,8 @@ public enum QuestEventType
 	ON_NODE_ARRIVED(true), // onNodeArrived action, triggered when NPC, controlled by Walking Manager, arrives to next node
 	ON_SEE_CREATURE(true), // onSeeCreature action, triggered when NPC's known list include the character
 	ON_ROUTE_FINISHED(true), // onRouteFinished action, triggered when NPC, controlled by Walking Manager, arrives to last node
-	ON_NPC_HATE(true);
+	ON_NPC_HATE(true),
+	ON_SUMMON(true);
 	
 	// control whether this event type is allowed for the same npc template in multiple quests
 	// or if the npc must be registered in at most one quest for the specified event

+ 1 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/handler/EffectHandler.java

@@ -65,6 +65,7 @@ public final class EffectHandler implements IHandler<Class<? extends AbstractEff
 	{
 		try
 		{
+			
 			File file = new File(L2ScriptEngineManager.SCRIPT_FOLDER, "handlers/EffectMasterHandler.java");
 			L2ScriptEngineManager.getInstance().executeScript(file);
 		}

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Party.java

@@ -763,10 +763,10 @@ public class L2Party extends AbstractPlayerGroup
 			if (validMembers.contains(member))
 			{
 				// The servitor penalty
-				final float penalty = member.hasServitor() ? ((L2ServitorInstance) member.getSummon()).getExpPenalty() : 0;
+				final float penalty = member.hasServitor() ? ((L2ServitorInstance) member.getSummon()).getExpMultiplier() : 1;
 				
 				final double sqLevel = member.getLevel() * member.getLevel();
-				final double preCalculation = (sqLevel / sqLevelSum) * (1 - penalty);
+				final double preCalculation = (sqLevel / sqLevelSum) * penalty;
 				
 				// Add the XP/SP points to the requested party member
 				long addexp = Math.round(member.calcStat(Stats.EXPSP_RATE, xpReward * preCalculation, null, null));

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

@@ -497,7 +497,7 @@ public class L2Attackable extends L2Npc
 					
 					// Penalty applied to the attacker's XP
 					// If this attacker have servitor, get Exp Penalty applied for the servitor.
-					final float penalty = attacker.hasServitor() ? ((L2ServitorInstance) attacker.getSummon()).getExpPenalty() : 0;
+					final float penalty = attacker.hasServitor() ? ((L2ServitorInstance) attacker.getSummon()).getExpMultiplier() : 1;
 					
 					// If there's NO party in progress
 					if (attackerParty == null)
@@ -521,7 +521,7 @@ public class L2Attackable extends L2Npc
 								sp *= Config.L2JMOD_CHAMPION_REWARDS;
 							}
 							
-							exp *= 1 - penalty;
+							exp *= penalty;
 							
 							// Check for an over-hit enabled strike
 							L2Character overhitAttacker = getOverhitAttacker();

+ 1 - 11
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -113,7 +113,6 @@ import com.l2jserver.gameserver.model.skills.L2SkillType;
 import com.l2jserver.gameserver.model.skills.SkillChannelized;
 import com.l2jserver.gameserver.model.skills.SkillChannelizer;
 import com.l2jserver.gameserver.model.skills.funcs.Func;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSummon;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
 import com.l2jserver.gameserver.model.stats.BaseStats;
 import com.l2jserver.gameserver.model.stats.Calculator;
@@ -2113,7 +2112,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 			if ((requiredItems == null) || (requiredItems.getCount() < skill.getItemConsume()))
 			{
 				// Checked: when a summon skill failed, server show required consume item count
-				if (skill.getSkillType() == L2SkillType.SUMMON)
+				if (skill.hasEffectType(L2EffectType.SUMMON))
 				{
 					SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SUMMONING_SERVITOR_COSTS_S2_S1);
 					sm.addItemName(skill.getItemConsumeId());
@@ -5520,15 +5519,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
 				stopSkillEffects(true, oldSkill.getId());
 			}
 			
-			if (isPlayer())
-			{
-				// TODO: Unhardcode it!
-				if ((oldSkill instanceof L2SkillSummon) && (oldSkill.getId() == 710) && hasSummon() && (getSummon().getId() == 14870))
-				{
-					getActingPlayer().getSummon().unSummon(getActingPlayer());
-				}
-			}
-			
 			if (oldSkill.isChance() && (_chanceSkills != null))
 			{
 				removeChanceSkill(oldSkill.getId());

+ 15 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java

@@ -29,6 +29,7 @@ import com.l2jserver.gameserver.datatables.ItemTable;
 import com.l2jserver.gameserver.enums.CategoryType;
 import com.l2jserver.gameserver.enums.InstanceType;
 import com.l2jserver.gameserver.enums.NpcRace;
+import com.l2jserver.gameserver.enums.QuestEventType;
 import com.l2jserver.gameserver.enums.ShotType;
 import com.l2jserver.gameserver.enums.Team;
 import com.l2jserver.gameserver.handler.IItemHandler;
@@ -52,6 +53,7 @@ import com.l2jserver.gameserver.model.items.L2Weapon;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.items.type.L2ActionType;
 import com.l2jserver.gameserver.model.olympiad.OlympiadGameManager;
+import com.l2jserver.gameserver.model.quest.Quest;
 import com.l2jserver.gameserver.model.skills.L2Skill;
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
 import com.l2jserver.gameserver.model.zone.ZoneId;
@@ -71,6 +73,7 @@ import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.gameserver.network.serverpackets.TeleportToLocation;
 import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
 import com.l2jserver.gameserver.util.Util;
+import com.l2jserver.util.Rnd;
 
 public abstract class L2Summon extends L2Playable
 {
@@ -119,7 +122,7 @@ public abstract class L2Summon extends L2Playable
 		_owner = owner;
 		_ai = new L2SummonAI(new AIAccessor());
 		
-		setXYZInvisible(owner.getX() + 20, owner.getY() + 20, owner.getZ() + 100);
+		setXYZInvisible(owner.getX() + Rnd.get(-100, 100), owner.getY() + Rnd.get(-100, 100), owner.getZ());
 	}
 	
 	@Override
@@ -147,6 +150,15 @@ public abstract class L2Summon extends L2Playable
 		setShowSummonAnimation(false); // addVisibleObject created the info packets with summon animation
 		// if someone comes into range now, the animation shouldn't show any more
 		_restoreSummon = false;
+		
+		// Notify DP scripts.
+		if (getTemplate().getEventQuests(QuestEventType.ON_SUMMON) != null)
+		{
+			for (Quest quest : getTemplate().getEventQuests(QuestEventType.ON_SUMMON))
+			{
+				quest.onSummon(this);
+			}
+		}
 	}
 	
 	@Override
@@ -206,9 +218,8 @@ public abstract class L2Summon extends L2Playable
 			{
 				if (_ai == null)
 				{
-					_ai = new L2SummonAI(new L2Summon.AIAccessor());
+					return _ai = new L2SummonAI(new L2Summon.AIAccessor());
 				}
-				return _ai;
 			}
 		}
 		return _ai;
@@ -453,6 +464,7 @@ public abstract class L2Summon extends L2Playable
 			storeMe();
 			storeEffect(true);
 			owner.setPet(null);
+			setOwner(null);
 			
 			// Stop AI tasks
 			if (hasAI())

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2ClanHallManagerInstance.java

@@ -32,11 +32,11 @@ import com.l2jserver.gameserver.model.ClanPrivilege;
 import com.l2jserver.gameserver.model.L2TeleportLocation;
 import com.l2jserver.gameserver.model.PcCondOverride;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.effects.L2EffectType;
 import com.l2jserver.gameserver.model.entity.ClanHall;
 import com.l2jserver.gameserver.model.entity.clanhall.AuctionableHall;
 import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
 import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.L2SkillType;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.AgitDecoInfo;
@@ -1379,7 +1379,7 @@ public class L2ClanHallManagerInstance extends L2MerchantInstance
 							skill_lvl = Integer.parseInt(st.nextToken());
 						}
 						skill = SkillTable.getInstance().getInfo(skill_id, skill_lvl);
-						if (skill.getSkillType() == L2SkillType.SUMMON)
+						if (skill.hasEffectType(L2EffectType.SUMMON))
 						{
 							player.doSimultaneousCast(skill);
 						}

+ 2 - 2
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2FortManagerInstance.java

@@ -29,9 +29,9 @@ import com.l2jserver.gameserver.enums.InstanceType;
 import com.l2jserver.gameserver.model.ClanPrivilege;
 import com.l2jserver.gameserver.model.L2TeleportLocation;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.effects.L2EffectType;
 import com.l2jserver.gameserver.model.entity.Fort;
 import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.L2SkillType;
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
 import com.l2jserver.gameserver.network.serverpackets.SortedWareHouseWithdrawalList;
@@ -887,7 +887,7 @@ public class L2FortManagerInstance extends L2MerchantInstance
 							skill_lvl = Integer.parseInt(st.nextToken());
 						}
 						skill = SkillTable.getInstance().getInfo(skill_id, skill_lvl);
-						if (skill.getSkillType() == L2SkillType.SUMMON)
+						if (skill.hasEffectType(L2EffectType.SUMMON))
 						{
 							player.doCast(skill);
 						}

+ 100 - 215
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2ServitorInstance.java

@@ -40,16 +40,21 @@ import com.l2jserver.gameserver.model.L2Object;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Summon;
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.holders.ItemHolder;
 import com.l2jserver.gameserver.model.skills.AbnormalType;
 import com.l2jserver.gameserver.model.skills.BuffInfo;
 import com.l2jserver.gameserver.model.skills.EffectScope;
 import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSummon;
+import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.SetSummonRemainTime;
+import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 
 import gnu.trove.map.hash.TIntObjectHashMap;
 
-public class L2ServitorInstance extends L2Summon
+/**
+ * @author UnAfraid
+ */
+public class L2ServitorInstance extends L2Summon implements Runnable
 {
 	protected static final Logger log = Logger.getLogger(L2ServitorInstance.class.getName());
 	
@@ -57,81 +62,28 @@ public class L2ServitorInstance extends L2Summon
 	private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,remaining_time,buff_index FROM character_summon_skills_save WHERE ownerId=? AND ownerClassIndex=? AND summonSkillId=? ORDER BY buff_index ASC";
 	private static final String DELETE_SKILL_SAVE = "DELETE FROM character_summon_skills_save WHERE ownerId=? AND ownerClassIndex=? AND summonSkillId=?";
 	
-	private float _expPenalty = 0; // exp decrease multiplier (i.e. 0.3 (= 30%) for shadow)
-	private int _itemConsumeId;
-	private int _itemConsumeCount;
-	private int _itemConsumeSteps;
-	private final int _totalLifeTime;
-	private final int _timeLostIdle;
-	private final int _timeLostActive;
-	private int _timeRemaining;
-	private int _nextItemConsumeTime;
-	public int lastShowntimeRemaining; // Following FbiAgent's example to avoid sending useless packets
-	
+	private float _expMultiplier = 0;
+	private ItemHolder _itemConsume;
+	private int _lifeTime;
+	private int _lifeTimeRemaining;
+	private int _consumeItemInterval;
+	private int _consumeItemIntervalRemaining;
 	protected Future<?> _summonLifeTask;
 	
 	private int _referenceSkill;
 	
-	private boolean _shareElementals = false;
-	private double _sharedElementalsPercent = 1;
-	
-	public L2ServitorInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2Skill skill)
+	public L2ServitorInstance(int objectId, L2NpcTemplate template, L2PcInstance owner)
 	{
 		super(objectId, template, owner);
 		setInstanceType(InstanceType.L2ServitorInstance);
 		setShowSummonAnimation(true);
-		
-		if (skill != null)
-		{
-			final L2SkillSummon summonSkill = (L2SkillSummon) skill;
-			_itemConsumeId = summonSkill.getItemConsumeIdOT();
-			_itemConsumeCount = summonSkill.getItemConsumeOT();
-			_itemConsumeSteps = summonSkill.getItemConsumeSteps();
-			_totalLifeTime = summonSkill.getTotalLifeTime();
-			_timeLostIdle = summonSkill.getTimeLostIdle();
-			_timeLostActive = summonSkill.getTimeLostActive();
-			_referenceSkill = summonSkill.getId();
-		}
-		else
-		{
-			// defaults
-			_itemConsumeId = 0;
-			_itemConsumeCount = 0;
-			_itemConsumeSteps = 0;
-			_totalLifeTime = 1200000; // 20 minutes
-			_timeLostIdle = 1000;
-			_timeLostActive = 1000;
-		}
-		_timeRemaining = _totalLifeTime;
-		lastShowntimeRemaining = _totalLifeTime;
-		
-		if (_itemConsumeId == 0)
-		{
-			_nextItemConsumeTime = -1; // do not consume
-		}
-		else if (_itemConsumeSteps == 0)
-		{
-			_nextItemConsumeTime = -1; // do not consume
-		}
-		else
-		{
-			_nextItemConsumeTime = _totalLifeTime - (_totalLifeTime / (_itemConsumeSteps + 1));
-		}
-		
-		// When no item consume is defined task only need to check when summon life time has ended.
-		// Otherwise have to destroy items from owner's inventory in order to let summon live.
-		int delay = 1000;
-		
-		if (Config.DEBUG && (_itemConsumeCount != 0))
-		{
-			_log.warning(getClass().getSimpleName() + ": Item Consume ID: " + _itemConsumeId + ", Count: " + _itemConsumeCount + ", Rate: " + _itemConsumeSteps + " times.");
-		}
-		if (Config.DEBUG)
-		{
-			_log.warning(getClass().getSimpleName() + ": Task Delay " + (delay / 1000) + " seconds.");
-		}
-		
-		_summonLifeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new SummonLifetime(getOwner(), this), delay, delay);
+	}
+	
+	@Override
+	public void onSpawn()
+	{
+		super.onSpawn();
+		_summonLifeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(this, 0, 5000);
 	}
 	
 	@Override
@@ -146,94 +98,76 @@ public class L2ServitorInstance extends L2Summon
 		return 1;
 	}
 	
-	public void setExpPenalty(float expPenalty)
-	{
-		_expPenalty = expPenalty;
-	}
+	// ************************************/
 	
-	public float getExpPenalty()
+	public void setExpMultiplier(float expMultiplier)
 	{
-		return _expPenalty;
+		_expMultiplier = expMultiplier;
 	}
 	
-	public void setSharedElementals(final boolean val)
+	public float getExpMultiplier()
 	{
-		_shareElementals = val;
+		return _expMultiplier;
 	}
 	
-	public boolean isSharingElementals()
-	{
-		return _shareElementals;
-	}
+	// ************************************/
 	
-	public void setSharedElementalsValue(final double val)
+	public void setItemConsume(ItemHolder item)
 	{
-		_sharedElementalsPercent = val;
+		_itemConsume = item;
 	}
 	
-	public double sharedElementalsPercent()
+	public ItemHolder getItemConsume()
 	{
-		return _sharedElementalsPercent;
+		return _itemConsume;
 	}
 	
-	public int getItemConsumeCount()
-	{
-		return _itemConsumeCount;
-	}
+	// ************************************/
 	
-	public int getItemConsumeId()
+	public void setItemConsumeInterval(int interval)
 	{
-		return _itemConsumeId;
+		_consumeItemInterval = _consumeItemIntervalRemaining = interval;
 	}
 	
-	public int getItemConsumeSteps()
+	public int getItemConsumeInterval()
 	{
-		return _itemConsumeSteps;
+		return _consumeItemInterval;
 	}
 	
-	public int getNextItemConsumeTime()
-	{
-		return _nextItemConsumeTime;
-	}
+	// ************************************/
 	
-	public int getTotalLifeTime()
+	public void setLifeTime(int lifeTime)
 	{
-		return _totalLifeTime;
+		_lifeTime = _lifeTimeRemaining = lifeTime;
 	}
 	
-	public int getTimeLostIdle()
+	public int getLifeTime()
 	{
-		return _timeLostIdle;
+		return _lifeTime;
 	}
 	
-	public int getTimeLostActive()
-	{
-		return _timeLostActive;
-	}
+	// ************************************/
 	
-	public int getTimeRemaining()
+	public void setLifeTimeRemaining(int time)
 	{
-		return _timeRemaining;
+		_lifeTimeRemaining = time;
 	}
 	
-	public void setNextItemConsumeTime(int value)
+	public int getLifeTimeRemaining()
 	{
-		_nextItemConsumeTime = value;
+		return _lifeTimeRemaining;
 	}
 	
-	public void decNextItemConsumeTime(int value)
-	{
-		_nextItemConsumeTime -= value;
-	}
+	// ************************************/
 	
-	public void decTimeRemaining(int value)
+	public void setReferenceSkill(int skillId)
 	{
-		_timeRemaining -= value;
+		_referenceSkill = skillId;
 	}
 	
-	public void addExpAndSp(int addToExp, int addToSp)
+	public int getReferenceSkill()
 	{
-		getOwner().addExpAndSp(addToExp, addToSp);
+		return _referenceSkill;
 	}
 	
 	@Override
@@ -244,11 +178,6 @@ public class L2ServitorInstance extends L2Summon
 			return false;
 		}
 		
-		if (Config.DEBUG)
-		{
-			_log.warning(getClass().getSimpleName() + ": " + getTemplate().getName() + " (" + getOwner().getName() + ") has been killed.");
-		}
-		
 		if (_summonLifeTask != null)
 		{
 			_summonLifeTask.cancel(false);
@@ -256,7 +185,6 @@ public class L2ServitorInstance extends L2Summon
 		}
 		
 		CharSummonTable.getInstance().removeServitor(getOwner());
-		
 		return true;
 		
 	}
@@ -415,6 +343,7 @@ public class L2ServitorInstance extends L2Summon
 						ps2.setInt(7, ++buff_index);
 						ps2.execute();
 						
+						// XXX: Rework me!
 						if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId()))
 						{
 							SummonEffectsTable.getInstance().getServitorEffectsOwner().put(getOwner().getObjectId(), new TIntObjectHashMap<TIntObjectHashMap<List<SummonEffect>>>());
@@ -468,6 +397,7 @@ public class L2ServitorInstance extends L2Summon
 								continue;
 							}
 							
+							// XXX: Rework me!
 							if (skill.hasEffects(EffectScope.GENERAL))
 							{
 								if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId()))
@@ -519,81 +449,9 @@ public class L2ServitorInstance extends L2Summon
 		}
 	}
 	
-	static class SummonLifetime implements Runnable
-	{
-		private final L2PcInstance _activeChar;
-		private final L2ServitorInstance _summon;
-		
-		SummonLifetime(L2PcInstance activeChar, L2ServitorInstance newpet)
-		{
-			_activeChar = activeChar;
-			_summon = newpet;
-		}
-		
-		@Override
-		public void run()
-		{
-			if (Config.DEBUG)
-			{
-				log.warning(getClass().getSimpleName() + ": " + _summon.getTemplate().getName() + " (" + _activeChar.getName() + ") run task.");
-			}
-			
-			try
-			{
-				double oldTimeRemaining = _summon.getTimeRemaining();
-				int maxTime = _summon.getTotalLifeTime();
-				double newTimeRemaining;
-				
-				// if pet is attacking
-				if (_summon.isAttackingNow())
-				{
-					_summon.decTimeRemaining(_summon.getTimeLostActive());
-				}
-				else
-				{
-					_summon.decTimeRemaining(_summon.getTimeLostIdle());
-				}
-				newTimeRemaining = _summon.getTimeRemaining();
-				// check if the summon's lifetime has ran out
-				if (newTimeRemaining < 0)
-				{
-					_summon.unSummon(_activeChar);
-				}
-				// check if it is time to consume another item
-				else if ((newTimeRemaining <= _summon.getNextItemConsumeTime()) && (oldTimeRemaining > _summon.getNextItemConsumeTime()))
-				{
-					_summon.decNextItemConsumeTime(maxTime / (_summon.getItemConsumeSteps() + 1));
-					
-					// check if owner has enough itemConsume, if requested
-					if ((_summon.getItemConsumeCount() > 0) && (_summon.getItemConsumeId() != 0) && !_summon.isDead() && !_summon.destroyItemByItemId("Consume", _summon.getItemConsumeId(), _summon.getItemConsumeCount(), _activeChar, true))
-					{
-						_summon.unSummon(_activeChar);
-					}
-				}
-				
-				// prevent useless packet-sending when the difference isn't visible.
-				if ((_summon.lastShowntimeRemaining - newTimeRemaining) > (maxTime / 352))
-				{
-					_summon.sendPacket(new SetSummonRemainTime(maxTime, (int) newTimeRemaining));
-					_summon.lastShowntimeRemaining = (int) newTimeRemaining;
-					_summon.updateEffectIcons();
-				}
-			}
-			catch (Exception e)
-			{
-				log.log(Level.SEVERE, "Error on player [" + _activeChar.getName() + "] summon item consume task.", e);
-			}
-		}
-	}
-	
 	@Override
 	public void unSummon(L2PcInstance owner)
 	{
-		if (Config.DEBUG)
-		{
-			_log.info(getClass().getSimpleName() + ": " + getTemplate().getName() + " (" + owner.getName() + ") unsummoned.");
-		}
-		
 		if (_summonLifeTask != null)
 		{
 			_summonLifeTask.cancel(false);
@@ -617,28 +475,13 @@ public class L2ServitorInstance extends L2Summon
 	@Override
 	public boolean destroyItemByItemId(String process, int itemId, long count, L2Object reference, boolean sendMessage)
 	{
-		if (Config.DEBUG)
-		{
-			_log.warning(getClass().getSimpleName() + ": " + getTemplate().getName() + " (" + getOwner().getName() + ") consume.");
-		}
-		
 		return getOwner().destroyItemByItemId(process, itemId, count, reference, sendMessage);
 	}
 	
-	public void setTimeRemaining(int time)
-	{
-		_timeRemaining = time;
-	}
-	
-	public int getReferenceSkill()
-	{
-		return _referenceSkill;
-	}
-	
 	@Override
 	public byte getAttackElement()
 	{
-		if (isSharingElementals() && (getOwner() != null))
+		if (getOwner() != null)
 		{
 			return getOwner().getAttackElement();
 		}
@@ -648,9 +491,9 @@ public class L2ServitorInstance extends L2Summon
 	@Override
 	public int getAttackElementValue(byte attackAttribute)
 	{
-		if (isSharingElementals() && (getOwner() != null))
+		if (getOwner() != null)
 		{
-			return (int) (getOwner().getAttackElementValue(attackAttribute) * sharedElementalsPercent());
+			return (getOwner().getAttackElementValue(attackAttribute));
 		}
 		return super.getAttackElementValue(attackAttribute);
 	}
@@ -658,9 +501,9 @@ public class L2ServitorInstance extends L2Summon
 	@Override
 	public int getDefenseElementValue(byte defenseAttribute)
 	{
-		if (isSharingElementals() && (getOwner() != null))
+		if (getOwner() != null)
 		{
-			return (int) (getOwner().getDefenseElementValue(defenseAttribute) * sharedElementalsPercent());
+			return (getOwner().getDefenseElementValue(defenseAttribute));
 		}
 		return super.getDefenseElementValue(defenseAttribute);
 	}
@@ -670,4 +513,46 @@ public class L2ServitorInstance extends L2Summon
 	{
 		return true;
 	}
+	
+	@Override
+	public void run()
+	{
+		int usedtime = 5000;
+		int newTimeRemaining = (_lifeTimeRemaining -= usedtime);
+		
+		// check if the summon's lifetime has ran out
+		if (newTimeRemaining < 0)
+		{
+			sendPacket(SystemMessageId.SERVITOR_PASSED_AWAY);
+			unSummon(getOwner());
+			return;
+		}
+		
+		if (_consumeItemInterval > 0)
+		{
+			int newConsumeCountDown = (_consumeItemIntervalRemaining -= usedtime);
+			
+			// check if it is time to consume another item
+			if ((newConsumeCountDown <= 0) && (getItemConsume().getCount() > 0) && (getItemConsume().getId() > 0) && !isDead())
+			{
+				if (destroyItemByItemId("Consume", getItemConsume().getId(), getItemConsume().getCount(), this, false))
+				{
+					final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.SUMMONED_MOB_USES_S1);
+					msg.addSkillName(getItemConsume().getId());
+					sendPacket(msg);
+					
+					// Reset
+					_consumeItemIntervalRemaining = _consumeItemInterval;
+				}
+				else
+				{
+					sendPacket(SystemMessageId.SERVITOR_DISAPPEARED_NOT_ENOUGH_ITEMS);
+					unSummon(getOwner());
+				}
+			}
+		}
+		
+		sendPacket(new SetSummonRemainTime(getLifeTime(), newTimeRemaining));
+		updateEffectIcons();
+	}
 }

+ 1 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/effects/L2EffectType.java

@@ -79,6 +79,7 @@ public enum L2EffectType
 	STATIC_DAMAGE,
 	STEAL_ABNORMAL,
 	STUN,
+	SUMMON,
 	SUMMON_PET,
 	TELEPORT,
 	TELEPORT_TO_TARGET,

+ 27 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/model/quest/Quest.java

@@ -57,6 +57,7 @@ import com.l2jserver.gameserver.model.actor.L2Attackable;
 import com.l2jserver.gameserver.model.actor.L2Character;
 import com.l2jserver.gameserver.model.actor.L2Npc;
 import com.l2jserver.gameserver.model.actor.L2Playable;
+import com.l2jserver.gameserver.model.actor.L2Summon;
 import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -1368,6 +1369,14 @@ public class Quest extends ManagedScript implements IIdentifiable
 		return true;
 	}
 	
+	/**
+	 * @param summon
+	 */
+	public void onSummon(L2Summon summon)
+	{
+		
+	}
+	
 	/**
 	 * Show an error message to the specified player.
 	 * @param player the player to whom to send the error (must be a GM)
@@ -2216,6 +2225,24 @@ public class Quest extends ManagedScript implements IIdentifiable
 		addEventId(QuestEventType.ON_NPC_HATE, npcIds);
 	}
 	
+	/**
+	 * Register onSummon trigger when summon is spawned.
+	 * @param npcIds
+	 */
+	public void addSummonId(int... npcIds)
+	{
+		addEventId(QuestEventType.ON_SUMMON, npcIds);
+	}
+	
+	/**
+	 * Register onSummon trigger when summon is spawned.
+	 * @param npcIds
+	 */
+	public void addSummonId(Collection<Integer> npcIds)
+	{
+		addEventId(QuestEventType.ON_SUMMON, npcIds);
+	}
+	
 	/**
 	 * Use this method to get a random party member from a player's party.<br>
 	 * Useful when distributing rewards after killing an NPC.

+ 0 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/L2SkillType.java

@@ -23,7 +23,6 @@ import java.lang.reflect.Constructor;
 import com.l2jserver.gameserver.model.StatsSet;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillDefault;
 import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSiegeFlag;
-import com.l2jserver.gameserver.model.skills.l2skills.L2SkillSummon;
 
 /**
  * Skill type enumerated.
@@ -44,8 +43,6 @@ public enum L2SkillType
 	SOW,
 	DETECTION,
 	DUMMY,
-	// Summons
-	SUMMON(L2SkillSummon.class),
 	
 	DETECT_TRAP,
 	REMOVE_TRAP,

+ 0 - 167
L2J_Server_BETA/java/com/l2jserver/gameserver/model/skills/l2skills/L2SkillSummon.java

@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2004-2014 L2J Server
- * 
- * This file is part of L2J Server.
- * 
- * L2J Server 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.
- * 
- * L2J Server 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 com.l2jserver.gameserver.model.skills.l2skills;
-
-import com.l2jserver.gameserver.datatables.ExperienceTable;
-import com.l2jserver.gameserver.datatables.NpcData;
-import com.l2jserver.gameserver.idfactory.IdFactory;
-import com.l2jserver.gameserver.model.L2Object;
-import com.l2jserver.gameserver.model.StatsSet;
-import com.l2jserver.gameserver.model.actor.L2Character;
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
-import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
-import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
-import com.l2jserver.gameserver.model.skills.L2Skill;
-
-public class L2SkillSummon extends L2Skill
-{
-	private final float _expPenalty;
-	// What is the total lifetime of summons (in milliseconds)
-	private final int _summonTotalLifeTime;
-	// How much lifetime is lost per second of idleness (non-fighting)
-	private final int _summonTimeLostIdle;
-	// How much time is lost per second of activity (fighting)
-	private final int _summonTimeLostActive;
-	
-	// item consume count over time
-	private final int _itemConsumeOT;
-	// item consume id over time
-	private final int _itemConsumeIdOT;
-	// how many times to consume an item
-	private final int _itemConsumeSteps;
-	// Inherit elementals from master
-	private final boolean _inheritElementals;
-	private final double _elementalSharePercent;
-	
-	public L2SkillSummon(StatsSet set)
-	{
-		super(set);
-		
-		_expPenalty = set.getFloat("expPenalty", 0.f);
-		
-		_summonTotalLifeTime = set.getInt("summonTotalLifeTime", 1200000); // 20 minutes default
-		_summonTimeLostIdle = set.getInt("summonTimeLostIdle", 0);
-		_summonTimeLostActive = set.getInt("summonTimeLostActive", 0);
-		
-		_itemConsumeOT = set.getInt("itemConsumeCountOT", 0);
-		_itemConsumeIdOT = set.getInt("itemConsumeIdOT", 0);
-		_itemConsumeSteps = set.getInt("itemConsumeSteps", 0);
-		
-		_inheritElementals = set.getBoolean("inheritElementals", false);
-		_elementalSharePercent = set.getDouble("inheritPercent", 1);
-	}
-	
-	@Override
-	public void useSkill(L2Character caster, L2Object[] targets)
-	{
-		if ((caster == null) || caster.isAlikeDead() || !caster.isPlayer())
-		{
-			return;
-		}
-		
-		final L2PcInstance activeChar = caster.getActingPlayer();
-		if (getNpcId() <= 0)
-		{
-			activeChar.sendMessage("Summon skill " + getId() + " not implemented yet.");
-			return;
-		}
-		
-		final L2NpcTemplate summonTemplate = NpcData.getInstance().getTemplate(getNpcId());
-		if (summonTemplate == null)
-		{
-			_log.warning("Summon attempt for nonexisting NPC ID:" + getNpcId() + ", skill ID:" + getId());
-			return; // npcID doesn't exist
-		}
-		
-		final L2ServitorInstance summon = new L2ServitorInstance(IdFactory.getInstance().getNextId(), summonTemplate, activeChar, this);
-		summon.setName(summonTemplate.getName());
-		summon.setTitle(activeChar.getName());
-		summon.setExpPenalty(_expPenalty);
-		summon.setSharedElementals(_inheritElementals);
-		summon.setSharedElementalsValue(_elementalSharePercent);
-		
-		if (summon.getLevel() >= ExperienceTable.getInstance().getMaxPetLevel())
-		{
-			summon.getStat().setExp(ExperienceTable.getInstance().getExpForLevel(ExperienceTable.getInstance().getMaxPetLevel() - 1));
-			_log.warning("Summon (" + summon.getName() + ") NpcID: " + summon.getId() + " has a level above " + ExperienceTable.getInstance().getMaxPetLevel() + ". Please rectify.");
-		}
-		else
-		{
-			summon.getStat().setExp(ExperienceTable.getInstance().getExpForLevel(summon.getLevel() % ExperienceTable.getInstance().getMaxPetLevel()));
-		}
-		
-		summon.setCurrentHp(summon.getMaxHp());
-		summon.setCurrentMp(summon.getMaxMp());
-		summon.setHeading(activeChar.getHeading());
-		summon.setRunning();
-		activeChar.setPet(summon);
-		summon.spawnMe(activeChar.getX() + 20, activeChar.getY() + 20, activeChar.getZ());
-	}
-	
-	public final int getTotalLifeTime()
-	{
-		return _summonTotalLifeTime;
-	}
-	
-	public final int getTimeLostIdle()
-	{
-		return _summonTimeLostIdle;
-	}
-	
-	public final int getTimeLostActive()
-	{
-		return _summonTimeLostActive;
-	}
-	
-	/**
-	 * @return Returns the itemConsume count over time.
-	 */
-	public final int getItemConsumeOT()
-	{
-		return _itemConsumeOT;
-	}
-	
-	/**
-	 * @return Returns the itemConsumeId over time.
-	 */
-	public final int getItemConsumeIdOT()
-	{
-		return _itemConsumeIdOT;
-	}
-	
-	public final int getItemConsumeSteps()
-	{
-		return _itemConsumeSteps;
-	}
-	
-	public final float getExpPenalty()
-	{
-		return _expPenalty;
-	}
-	
-	public final boolean getInheritElementals()
-	{
-		return _inheritElementals;
-	}
-	
-	public final double getElementalSharePercent()
-	{
-		return _elementalSharePercent;
-	}
-}

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

@@ -70,8 +70,8 @@ public class PetInfo extends L2GameServerPacket
 		else if (summon.isServitor())
 		{
 			final L2ServitorInstance sum = (L2ServitorInstance) _summon;
-			_curFed = sum.getTimeRemaining();
-			_maxFed = sum.getTotalLifeTime();
+			_curFed = sum.getLifeTimeRemaining();
+			_maxFed = sum.getLifeTime();
 		}
 	}
 	

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

@@ -46,8 +46,8 @@ public class PetStatusUpdate extends L2GameServerPacket
 		else if (_summon instanceof L2ServitorInstance)
 		{
 			L2ServitorInstance sum = (L2ServitorInstance) _summon;
-			_curFed = sum.getTimeRemaining();
-			_maxFed = sum.getTotalLifeTime();
+			_curFed = sum.getLifeTimeRemaining();
+			_maxFed = sum.getLifeTime();
 		}
 	}