|
@@ -14,26 +14,45 @@
|
|
|
*/
|
|
|
package com.l2jserver.gameserver.model.actor.instance;
|
|
|
|
|
|
+import gnu.trove.TIntObjectHashMap;
|
|
|
+
|
|
|
+import java.sql.Connection;
|
|
|
+import java.sql.PreparedStatement;
|
|
|
+import java.sql.ResultSet;
|
|
|
+import java.util.List;
|
|
|
import java.util.concurrent.Future;
|
|
|
import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
+import javolution.util.FastList;
|
|
|
+
|
|
|
import com.l2jserver.Config;
|
|
|
+import com.l2jserver.L2DatabaseFactory;
|
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
|
+import com.l2jserver.gameserver.datatables.CharSummonTable;
|
|
|
import com.l2jserver.gameserver.datatables.SkillTable;
|
|
|
+import com.l2jserver.gameserver.datatables.SummonEffectsTable;
|
|
|
+import com.l2jserver.gameserver.datatables.SummonEffectsTable.SummonEffect;
|
|
|
+import com.l2jserver.gameserver.model.L2Effect;
|
|
|
import com.l2jserver.gameserver.model.L2Object;
|
|
|
import com.l2jserver.gameserver.model.L2Skill;
|
|
|
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
|
import com.l2jserver.gameserver.model.actor.L2Summon;
|
|
|
import com.l2jserver.gameserver.network.serverpackets.SetSummonRemainTime;
|
|
|
+import com.l2jserver.gameserver.skills.Env;
|
|
|
import com.l2jserver.gameserver.skills.l2skills.L2SkillSummon;
|
|
|
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
|
|
|
+import com.l2jserver.gameserver.templates.effects.EffectTemplate;
|
|
|
|
|
|
|
|
|
public class L2SummonInstance extends L2Summon
|
|
|
{
|
|
|
protected static final Logger log = Logger.getLogger(L2SummonInstance.class.getName());
|
|
|
|
|
|
+ private static final String ADD_SKILL_SAVE = "INSERT INTO character_summon_skills_save (ownerId,ownerClassIndex,summonSkillId,skill_id,skill_level,effect_count,effect_cur_time,buff_index) VALUES (?,?,?,?,?,?,?,?)";
|
|
|
+ private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,effect_count,effect_cur_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;
|
|
@@ -47,6 +66,8 @@ public class L2SummonInstance extends L2Summon
|
|
|
|
|
|
private Future<?> _summonLifeTask;
|
|
|
|
|
|
+ private int _referenceSkill;
|
|
|
+
|
|
|
public L2SummonInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2Skill skill)
|
|
|
{
|
|
|
super(objectId, template, owner);
|
|
@@ -62,6 +83,7 @@ public class L2SummonInstance extends L2Summon
|
|
|
_totalLifeTime = summonSkill.getTotalLifeTime();
|
|
|
_timeLostIdle = summonSkill.getTimeLostIdle();
|
|
|
_timeLostActive = summonSkill.getTimeLostActive();
|
|
|
+ _referenceSkill = summonSkill.getId();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -191,6 +213,9 @@ public class L2SummonInstance extends L2Summon
|
|
|
_summonLifeTask.cancel(false);
|
|
|
_summonLifeTask = null;
|
|
|
}
|
|
|
+
|
|
|
+ CharSummonTable.getInstance().removeServitor(getOwner());
|
|
|
+
|
|
|
return true;
|
|
|
|
|
|
}
|
|
@@ -223,6 +248,210 @@ public class L2SummonInstance extends L2Summon
|
|
|
super.doCast(skill);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void setRestoreSummon(boolean val)
|
|
|
+ {
|
|
|
+ _restoreSummon = val;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void store()
|
|
|
+ {
|
|
|
+ if (_referenceSkill == 0 || isDead())
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (Config.RESTORE_SERVITOR_ON_RECONNECT)
|
|
|
+ CharSummonTable.getInstance().saveSummon(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void storeEffect(boolean storeEffects)
|
|
|
+ {
|
|
|
+ if (!Config.SUMMON_STORE_SKILL_COOLTIME)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (getOwner().isInOlympiadMode())
|
|
|
+ return;
|
|
|
+
|
|
|
+ // Clear list for overwrite
|
|
|
+ if (
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId()) &&
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).contains(getOwner().getClassIndex()) &&
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffects(getOwner()).contains(getReferenceSkill())
|
|
|
+ )
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()).clear();
|
|
|
+
|
|
|
+ Connection con = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ con = L2DatabaseFactory.getInstance().getConnection();
|
|
|
+
|
|
|
+ // Delete all current stored effects for summon to avoid dupe
|
|
|
+ PreparedStatement statement = con.prepareStatement(DELETE_SKILL_SAVE);
|
|
|
+
|
|
|
+ statement.setInt(1, getOwner().getObjectId());
|
|
|
+ statement.setInt(2, getOwner().getClassIndex());
|
|
|
+ statement.setInt(3, getReferenceSkill());
|
|
|
+
|
|
|
+ statement.execute();
|
|
|
+ statement.close();
|
|
|
+
|
|
|
+ int buff_index = 0;
|
|
|
+
|
|
|
+ final List<Integer> storedSkills = new FastList<Integer>();
|
|
|
+
|
|
|
+ //Store all effect data along with calculated remaining
|
|
|
+ statement = con.prepareStatement(ADD_SKILL_SAVE);
|
|
|
+
|
|
|
+ if (storeEffects)
|
|
|
+ {
|
|
|
+ for (L2Effect effect : getAllEffects())
|
|
|
+ {
|
|
|
+ if (effect == null)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ switch (effect.getEffectType())
|
|
|
+ {
|
|
|
+ case HEAL_OVER_TIME:
|
|
|
+ case COMBAT_POINT_HEAL_OVER_TIME:
|
|
|
+ // TODO: Fix me.
|
|
|
+ case HIDE:
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ L2Skill skill = effect.getSkill();
|
|
|
+ if (storedSkills.contains(skill.getReuseHashCode()))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ storedSkills.add(skill.getReuseHashCode());
|
|
|
+
|
|
|
+ if (!effect.isHerbEffect() && effect.getInUse() && !skill.isToggle())
|
|
|
+ {
|
|
|
+ statement.setInt(1, getOwner().getObjectId());
|
|
|
+ statement.setInt(2, getOwner().getClassIndex());
|
|
|
+ statement.setInt(3, getReferenceSkill());
|
|
|
+ statement.setInt(4, skill.getId());
|
|
|
+ statement.setInt(5, skill.getLevel());
|
|
|
+ statement.setInt(6, effect.getCount());
|
|
|
+ statement.setInt(7, effect.getTime());
|
|
|
+ statement.setInt(8, ++buff_index);
|
|
|
+ statement.execute();
|
|
|
+
|
|
|
+ if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId())) // Check if charId exists in map
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffectsOwner().put(getOwner().getObjectId(), new TIntObjectHashMap<TIntObjectHashMap<List<SummonEffect>>>());
|
|
|
+ if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).contains(getOwner().getClassIndex())) // Check if classIndex exists in charId map
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).put(getOwner().getClassIndex(), new TIntObjectHashMap<List<SummonEffect>>());
|
|
|
+ if (!SummonEffectsTable.getInstance().getServitorEffects(getOwner()).contains(getReferenceSkill())) // Check is summonSkillId exists in charId+classIndex map
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffects(getOwner()).put(getReferenceSkill(), new FastList<SummonEffect>());
|
|
|
+
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()).add(SummonEffectsTable.getInstance().new SummonEffect(skill, effect.getCount(), effect.getTime()));
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ statement.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ _log.log(Level.WARNING, "Could not store summon effect data: ", e);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ L2DatabaseFactory.close(con);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void restoreEffects()
|
|
|
+ {
|
|
|
+ if (getOwner().isInOlympiadMode())
|
|
|
+ return;
|
|
|
+
|
|
|
+ Connection con = null;
|
|
|
+ PreparedStatement statement = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ con = L2DatabaseFactory.getInstance().getConnection();
|
|
|
+ if (
|
|
|
+ !SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId()) ||
|
|
|
+ !SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).contains(getOwner().getClassIndex()) ||
|
|
|
+ !SummonEffectsTable.getInstance().getServitorEffects(getOwner()).contains(getReferenceSkill())
|
|
|
+ )
|
|
|
+ {
|
|
|
+ statement = con.prepareStatement(RESTORE_SKILL_SAVE);
|
|
|
+ statement.setInt(1, getOwner().getObjectId());
|
|
|
+ statement.setInt(2, getOwner().getClassIndex());
|
|
|
+ statement.setInt(3, getReferenceSkill());
|
|
|
+ ResultSet rset = statement.executeQuery();
|
|
|
+
|
|
|
+ while (rset.next())
|
|
|
+ {
|
|
|
+ int effectCount = rset.getInt("effect_count");
|
|
|
+ int effectCurTime = rset.getInt("effect_cur_time");
|
|
|
+
|
|
|
+ final L2Skill skill = SkillTable.getInstance().getInfo(rset.getInt("skill_id"), rset.getInt("skill_level"));
|
|
|
+ if (skill == null)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (skill.hasEffects())
|
|
|
+ {
|
|
|
+ if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId())) // Check if charId exists in map
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffectsOwner().put(getOwner().getObjectId(), new TIntObjectHashMap<TIntObjectHashMap<List<SummonEffect>>>());
|
|
|
+ if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).contains(getOwner().getClassIndex())) // Check if classIndex exists in charId map
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).put(getOwner().getClassIndex(), new TIntObjectHashMap<List<SummonEffect>>());
|
|
|
+ if (!SummonEffectsTable.getInstance().getServitorEffects(getOwner()).contains(getReferenceSkill())) // Check is summonSkillId exists in charId+classIndex map
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffects(getOwner()).put(getReferenceSkill(), new FastList<SummonEffect>());
|
|
|
+
|
|
|
+ SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()).add(SummonEffectsTable.getInstance().new SummonEffect(skill, effectCount, effectCurTime));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ rset.close();
|
|
|
+ statement.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ statement = con.prepareStatement(DELETE_SKILL_SAVE);
|
|
|
+ statement.setInt(1, getOwner().getObjectId());
|
|
|
+ statement.setInt(2, getOwner().getClassIndex());
|
|
|
+ statement.setInt(3, getReferenceSkill());
|
|
|
+ statement.executeUpdate();
|
|
|
+ statement.close();
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ _log.log(Level.WARNING, "Could not restore " + this + " active effect data: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ L2DatabaseFactory.close(con);
|
|
|
+ if (
|
|
|
+ !SummonEffectsTable.getInstance().getServitorEffectsOwner().contains(getOwner().getObjectId()) ||
|
|
|
+ !SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).contains(getOwner().getClassIndex()) ||
|
|
|
+ !SummonEffectsTable.getInstance().getServitorEffects(getOwner()).contains(getReferenceSkill())
|
|
|
+ )
|
|
|
+ return;
|
|
|
+
|
|
|
+ for (SummonEffect se : SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()))
|
|
|
+ {
|
|
|
+ Env env = new Env();
|
|
|
+ env.player = this;
|
|
|
+ env.target = this;
|
|
|
+ env.skill = se.getSkill();
|
|
|
+ L2Effect ef;
|
|
|
+ for (EffectTemplate et : se.getSkill().getEffectTemplates())
|
|
|
+ {
|
|
|
+ ef = et.getEffect(env);
|
|
|
+ if (ef != null)
|
|
|
+ {
|
|
|
+ ef.setCount(se.getEffectCount());
|
|
|
+ ef.setFirstTime(se.getEffectCurTime());
|
|
|
+ ef.scheduleEffect();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
static class SummonLifetime implements Runnable
|
|
|
{
|
|
|
private L2PcInstance _activeChar;
|
|
@@ -300,6 +529,9 @@ public class L2SummonInstance extends L2Summon
|
|
|
}
|
|
|
|
|
|
super.unSummon(owner);
|
|
|
+
|
|
|
+ if (!_restoreSummon)
|
|
|
+ CharSummonTable.getInstance().removeServitor(owner);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -345,4 +577,14 @@ public class L2SummonInstance extends L2Summon
|
|
|
// bonus from owner
|
|
|
return super.getDefenseElementValue(attribute) + getOwner().getDefenseElementValue(attribute);
|
|
|
}
|
|
|
+
|
|
|
+ public void setTimeRemaining(int time)
|
|
|
+ {
|
|
|
+ _timeRemaining = time;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getReferenceSkill()
|
|
|
+ {
|
|
|
+ return _referenceSkill;
|
|
|
+ }
|
|
|
}
|