|
@@ -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();
|
|
|
+ }
|
|
|
}
|