|
@@ -18,20 +18,15 @@ import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
import com.l2jserver.gameserver.handler.IItemHandler;
|
|
import com.l2jserver.gameserver.handler.IItemHandler;
|
|
import com.l2jserver.gameserver.model.actor.L2Playable;
|
|
import com.l2jserver.gameserver.model.actor.L2Playable;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
-import com.l2jserver.gameserver.model.actor.instance.L2PcInstance.TimeStamp;
|
|
|
|
-import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
|
|
|
|
import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2ServitorInstance;
|
|
import com.l2jserver.gameserver.model.entity.TvTEvent;
|
|
import com.l2jserver.gameserver.model.entity.TvTEvent;
|
|
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
|
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
|
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
|
import com.l2jserver.gameserver.model.items.type.L2EtcItemType;
|
|
import com.l2jserver.gameserver.model.items.type.L2EtcItemType;
|
|
import com.l2jserver.gameserver.model.skills.L2Skill;
|
|
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.SystemMessageId;
|
|
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
|
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
|
-import com.l2jserver.gameserver.network.serverpackets.ExUseSharedGroupItem;
|
|
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
-import com.l2jserver.gameserver.util.L2TIntObjectHashMap;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* Template for item skills handler.<br>
|
|
* Template for item skills handler.<br>
|
|
@@ -40,192 +35,179 @@ import com.l2jserver.gameserver.util.L2TIntObjectHashMap;
|
|
public class ItemSkillsTemplate implements IItemHandler
|
|
public class ItemSkillsTemplate implements IItemHandler
|
|
{
|
|
{
|
|
@Override
|
|
@Override
|
|
- public void useItem(L2Playable playable, L2ItemInstance item, boolean forceUse)
|
|
|
|
|
|
+ public boolean useItem(L2Playable playable, L2ItemInstance item, boolean forceUse)
|
|
{
|
|
{
|
|
- L2PcInstance activeChar;
|
|
|
|
- boolean isPet = playable instanceof L2PetInstance;
|
|
|
|
- if (isPet)
|
|
|
|
|
|
+ final L2PcInstance activeChar = playable.getActingPlayer();
|
|
|
|
+ if (!playable.isPet() && !playable.isPlayer())
|
|
{
|
|
{
|
|
- activeChar = ((L2PetInstance) playable).getOwner();
|
|
|
|
- }
|
|
|
|
- else if (playable instanceof L2PcInstance)
|
|
|
|
- {
|
|
|
|
- activeChar = (L2PcInstance) playable;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
if (!TvTEvent.onScrollUse(playable.getObjectId()))
|
|
if (!TvTEvent.onScrollUse(playable.getObjectId()))
|
|
{
|
|
{
|
|
playable.sendPacket(ActionFailed.STATIC_PACKET);
|
|
playable.sendPacket(ActionFailed.STATIC_PACKET);
|
|
- return;
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
- // pets can use items only when they are tradeable
|
|
|
|
- if (isPet && !item.isTradeable())
|
|
|
|
|
|
+ // Pets can use items only when they are tradable.
|
|
|
|
+ if (playable.isPet() && !item.isTradeable())
|
|
{
|
|
{
|
|
activeChar.sendPacket(SystemMessageId.ITEM_NOT_FOR_PETS);
|
|
activeChar.sendPacket(SystemMessageId.ITEM_NOT_FOR_PETS);
|
|
- return;
|
|
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ System.out.println("Trying to use item Id: " + item.getItemId() + "!!!!!!");
|
|
|
|
+ if (!checkReuse(activeChar, null, item))
|
|
|
|
+ {
|
|
|
|
+ System.out.println("Avoiding item usage due reuse time!");
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
int skillId;
|
|
int skillId;
|
|
int skillLvl;
|
|
int skillLvl;
|
|
|
|
|
|
final SkillHolder[] skills = item.getEtcItem().getSkills();
|
|
final SkillHolder[] skills = item.getEtcItem().getSkills();
|
|
- if (skills != null)
|
|
|
|
|
|
+ if (skills == null)
|
|
|
|
+ {
|
|
|
|
+ _log.info("Item " + item + " does not have registered any skill for handler.");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (SkillHolder skillInfo : skills)
|
|
{
|
|
{
|
|
- for (SkillHolder skillInfo : skills)
|
|
|
|
|
|
+ if (skillInfo == null)
|
|
{
|
|
{
|
|
- if (skillInfo == null)
|
|
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ skillId = skillInfo.getSkillId();
|
|
|
|
+ skillLvl = skillInfo.getSkillLvl();
|
|
|
|
+ L2Skill itemSkill = skillInfo.getSkill();
|
|
|
|
+
|
|
|
|
+ if (itemSkill != null)
|
|
|
|
+ {
|
|
|
|
+ if (!itemSkill.checkCondition(playable, playable.getTarget(), false))
|
|
{
|
|
{
|
|
- continue;
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
- skillId = skillInfo.getSkillId();
|
|
|
|
- skillLvl = skillInfo.getSkillLvl();
|
|
|
|
- L2Skill itemSkill = skillInfo.getSkill();
|
|
|
|
|
|
+ if (playable.isSkillDisabled(itemSkill))
|
|
|
|
+ {
|
|
|
|
+ checkReuse(activeChar, itemSkill, item);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- if (itemSkill != null)
|
|
|
|
|
|
+ if (!itemSkill.isPotion() && playable.isCastingNow())
|
|
{
|
|
{
|
|
- if (!itemSkill.checkCondition(playable, playable.getTarget(), false))
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (playable.isSkillDisabled(itemSkill))
|
|
|
|
- {
|
|
|
|
- reuse(activeChar, itemSkill, item);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!itemSkill.isPotion() && playable.isCastingNow())
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ((itemSkill.getItemConsumeId() == 0) && (itemSkill.getItemConsume() > 0) && (itemSkill.isPotion() || itemSkill.isSimultaneousCast()))
|
|
|
|
- {
|
|
|
|
- if (!playable.destroyItem("Consume", item.getObjectId(), itemSkill.getItemConsume(), null, false))
|
|
|
|
- {
|
|
|
|
- activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // send message to owner
|
|
|
|
- if (isPet)
|
|
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((itemSkill.getItemConsumeId() == 0) && (itemSkill.getItemConsume() > 0) && (itemSkill.isPotion() || itemSkill.isSimultaneousCast()))
|
|
|
|
+ {
|
|
|
|
+ if (!playable.destroyItem("Consume", item.getObjectId(), itemSkill.getItemConsume(), null, false))
|
|
{
|
|
{
|
|
- SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PET_USES_S1);
|
|
|
|
- sm.addString(itemSkill.getName());
|
|
|
|
- activeChar.sendPacket(sm);
|
|
|
|
|
|
+ activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // send message to owner
|
|
|
|
+ if (playable.isPet())
|
|
|
|
+ {
|
|
|
|
+ SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PET_USES_S1);
|
|
|
|
+ sm.addString(itemSkill.getName());
|
|
|
|
+ activeChar.sendPacket(sm);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ switch (skillId)
|
|
{
|
|
{
|
|
- switch (skillId)
|
|
|
|
- {
|
|
|
|
- // short buff icon for healing potions
|
|
|
|
- case 2031:
|
|
|
|
- case 2032:
|
|
|
|
- case 2037:
|
|
|
|
- case 26025:
|
|
|
|
- case 26026:
|
|
|
|
- int buffId = activeChar._shortBuffTaskSkillId;
|
|
|
|
- // greater healing potions
|
|
|
|
- if ((skillId == 2037) || (skillId == 26025))
|
|
|
|
- {
|
|
|
|
- activeChar.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
|
|
|
|
- }
|
|
|
|
- else if (((skillId == 2032) || (skillId == 26026)) && (buffId != 2037) && (buffId != 26025))
|
|
|
|
|
|
+ // short buff icon for healing potions
|
|
|
|
+ case 2031:
|
|
|
|
+ case 2032:
|
|
|
|
+ case 2037:
|
|
|
|
+ case 26025:
|
|
|
|
+ case 26026:
|
|
|
|
+ int buffId = activeChar._shortBuffTaskSkillId;
|
|
|
|
+ // greater healing potions
|
|
|
|
+ if ((skillId == 2037) || (skillId == 26025))
|
|
|
|
+ {
|
|
|
|
+ activeChar.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
|
|
|
|
+ }
|
|
|
|
+ else if (((skillId == 2032) || (skillId == 26026)) && (buffId != 2037) && (buffId != 26025))
|
|
|
|
+ {
|
|
|
|
+ activeChar.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
|
|
|
|
+ // lesser healing potions
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if ((buffId != 2037) && (buffId != 26025) && (buffId != 2032) && (buffId != 26026))
|
|
{
|
|
{
|
|
activeChar.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
|
|
activeChar.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
|
|
- // lesser healing potions
|
|
|
|
}
|
|
}
|
|
- else
|
|
|
|
- {
|
|
|
|
- if ((buffId != 2037) && (buffId != 26025) && (buffId != 2032) && (buffId != 26026))
|
|
|
|
- {
|
|
|
|
- activeChar.shortBuffStatusUpdate(skillId, skillLvl, itemSkill.getBuffDuration() / 1000);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (itemSkill.isPotion() || itemSkill.isSimultaneousCast())
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (itemSkill.isPotion() || itemSkill.isSimultaneousCast())
|
|
|
|
+ {
|
|
|
|
+ playable.doSimultaneousCast(itemSkill);
|
|
|
|
+ // Summons should be affected by herbs too, self time effect is handled at L2Effect constructor
|
|
|
|
+ if (!playable.isPet() && (item.getItemType() == L2EtcItemType.HERB) && (activeChar.getPet() != null) && (activeChar.getPet() instanceof L2ServitorInstance))
|
|
{
|
|
{
|
|
- playable.doSimultaneousCast(itemSkill);
|
|
|
|
- // Summons should be affected by herbs too, self time effect is handled at L2Effect constructor
|
|
|
|
- if (!isPet && (item.getItemType() == L2EtcItemType.HERB) && (activeChar.getPet() != null) && (activeChar.getPet() instanceof L2ServitorInstance))
|
|
|
|
- {
|
|
|
|
- activeChar.getPet().doSimultaneousCast(itemSkill);
|
|
|
|
- }
|
|
|
|
|
|
+ activeChar.getPet().doSimultaneousCast(itemSkill);
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ playable.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
|
|
|
+
|
|
|
|
+ if (!playable.useMagic(itemSkill, forceUse, false))
|
|
{
|
|
{
|
|
- playable.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
|
|
|
-
|
|
|
|
- // TODO: Remove when reuse time for sub-class is implemented.
|
|
|
|
- if (activeChar.isSubClassActive() && (itemSkill.getSkillType() == L2SkillType.EXTRACTABLE) && (itemSkill.getReuseDelay() > 5000))
|
|
|
|
- {
|
|
|
|
- activeChar.sendPacket(SystemMessageId.MAIN_CLASS_SKILL_ONLY);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!playable.useMagic(itemSkill, forceUse, false))
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Consume.
|
|
|
|
- if ((itemSkill.getItemConsumeId() == 0) && (itemSkill.getItemConsume() > 0))
|
|
|
|
- {
|
|
|
|
- if (!activeChar.destroyItem("Consume", item.getObjectId(), itemSkill.getItemConsume(), null, false))
|
|
|
|
- {
|
|
|
|
- activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
- if (itemSkill.getReuseDelay() > 0)
|
|
|
|
|
|
+ // Consume.
|
|
|
|
+ if ((itemSkill.getItemConsumeId() == 0) && (itemSkill.getItemConsume() > 0))
|
|
{
|
|
{
|
|
- activeChar.addTimeStamp(itemSkill, itemSkill.getReuseDelay());
|
|
|
|
- // activeChar.disableSkill(itemSkill, itemSkill.getReuseDelay());
|
|
|
|
- if (item.isEtcItem())
|
|
|
|
|
|
+ if (!activeChar.destroyItem("Consume", item.getObjectId(), itemSkill.getItemConsume(), null, false))
|
|
{
|
|
{
|
|
- final int group = item.getEtcItem().getSharedReuseGroup();
|
|
|
|
- if (group >= 0)
|
|
|
|
- {
|
|
|
|
- activeChar.sendPacket(new ExUseSharedGroupItem(item.getItemId(), group, itemSkill.getReuseDelay(), itemSkill.getReuseDelay()));
|
|
|
|
- }
|
|
|
|
|
|
+ activeChar.sendPacket(SystemMessageId.NOT_ENOUGH_ITEMS);
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (itemSkill.getReuseDelay() > 0)
|
|
|
|
+ {
|
|
|
|
+ activeChar.addTimeStamp(itemSkill, itemSkill.getReuseDelay());
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else
|
|
|
|
- {
|
|
|
|
- _log.info("Item " + item + " does not have registered any skill for handler.");
|
|
|
|
- }
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
- private void reuse(L2PcInstance player, L2Skill skill, L2ItemInstance item)
|
|
|
|
|
|
+ /**
|
|
|
|
+ * @param player
|
|
|
|
+ * @param skill
|
|
|
|
+ * @param item
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private boolean checkReuse(L2PcInstance player, L2Skill skill, L2ItemInstance item)
|
|
{
|
|
{
|
|
- SystemMessage sm = null;
|
|
|
|
- final L2TIntObjectHashMap<TimeStamp> timeStamp = player.getReuseTimeStamp();
|
|
|
|
-
|
|
|
|
- if ((timeStamp != null) && timeStamp.containsKey(skill.getReuseHashCode()))
|
|
|
|
|
|
+ final SystemMessage sm;
|
|
|
|
+ final long remainingTime = (skill != null) ? player.getSkillRemainingReuseTime(skill.getReuseHashCode()) : player.getItemRemainingReuseTime(item.getObjectId());
|
|
|
|
+ final boolean isAvailable = remainingTime <= 0;
|
|
|
|
+ if (!isAvailable)
|
|
{
|
|
{
|
|
- final long remainingTime = player.getReuseTimeStamp().get(skill.getReuseHashCode()).getRemaining();
|
|
|
|
final int hours = (int) (remainingTime / 3600000L);
|
|
final int hours = (int) (remainingTime / 3600000L);
|
|
final int minutes = (int) (remainingTime % 3600000L) / 60000;
|
|
final int minutes = (int) (remainingTime % 3600000L) / 60000;
|
|
final int seconds = (int) ((remainingTime / 1000) % 60);
|
|
final int seconds = (int) ((remainingTime / 1000) % 60);
|
|
if (hours > 0)
|
|
if (hours > 0)
|
|
{
|
|
{
|
|
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HOURS_S3_MINUTES_S4_SECONDS_REMAINING_FOR_REUSE_S1);
|
|
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HOURS_S3_MINUTES_S4_SECONDS_REMAINING_FOR_REUSE_S1);
|
|
- if (skill.isPotion())
|
|
|
|
|
|
+ if ((skill == null) || skill.isPotion())
|
|
{
|
|
{
|
|
sm.addItemName(item);
|
|
sm.addItemName(item);
|
|
}
|
|
}
|
|
@@ -239,7 +221,7 @@ public class ItemSkillsTemplate implements IItemHandler
|
|
else if (minutes > 0)
|
|
else if (minutes > 0)
|
|
{
|
|
{
|
|
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_MINUTES_S3_SECONDS_REMAINING_FOR_REUSE_S1);
|
|
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_MINUTES_S3_SECONDS_REMAINING_FOR_REUSE_S1);
|
|
- if (skill.isPotion())
|
|
|
|
|
|
+ if ((skill == null) || skill.isPotion())
|
|
{
|
|
{
|
|
sm.addItemName(item);
|
|
sm.addItemName(item);
|
|
}
|
|
}
|
|
@@ -252,7 +234,7 @@ public class ItemSkillsTemplate implements IItemHandler
|
|
else
|
|
else
|
|
{
|
|
{
|
|
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_SECONDS_REMAINING_FOR_REUSE_S1);
|
|
sm = SystemMessage.getSystemMessage(SystemMessageId.S2_SECONDS_REMAINING_FOR_REUSE_S1);
|
|
- if (skill.isPotion())
|
|
|
|
|
|
+ if ((skill == null) || skill.isPotion())
|
|
{
|
|
{
|
|
sm.addItemName(item);
|
|
sm.addItemName(item);
|
|
}
|
|
}
|
|
@@ -262,15 +244,6 @@ public class ItemSkillsTemplate implements IItemHandler
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sm.addNumber(seconds);
|
|
sm.addNumber(seconds);
|
|
-
|
|
|
|
- if (item.isEtcItem())
|
|
|
|
- {
|
|
|
|
- final int group = item.getEtcItem().getSharedReuseGroup();
|
|
|
|
- if (group >= 0)
|
|
|
|
- {
|
|
|
|
- player.sendPacket(new ExUseSharedGroupItem(item.getItemId(), group, (int) remainingTime, skill.getReuseDelay()));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
@@ -278,5 +251,6 @@ public class ItemSkillsTemplate implements IItemHandler
|
|
sm.addItemName(item);
|
|
sm.addItemName(item);
|
|
}
|
|
}
|
|
player.sendPacket(sm);
|
|
player.sendPacket(sm);
|
|
|
|
+ return isAvailable;
|
|
}
|
|
}
|
|
}
|
|
}
|