Advertisement
Guest User

L2Effect.java

a guest
Jan 20th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.90 KB | None | 0 0
  1. /*
  2.  * This program is free software; you can redistribute it and/or modify
  3.  * it under the terms of the GNU General Public License as published by
  4.  * the Free Software Foundation; either version 2, or (at your option)
  5.  * any later version.
  6.  *
  7.  * This program is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  * GNU General Public License for more details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License
  13.  * along with this program; if not, write to the Free Software
  14.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15.  * 02111-1307, USA.
  16.  *
  17.  * http://www.gnu.org/copyleft/gpl.html
  18.  */
  19. package com.l2jfrozen.gameserver.model;
  20.  
  21. import java.util.List;
  22. import java.util.concurrent.ScheduledFuture;
  23. import java.util.concurrent.TimeUnit;
  24. import java.util.logging.Level;
  25. import java.util.logging.Logger;
  26.  
  27. import javolution.util.FastList;
  28.  
  29. import com.l2jfrozen.gameserver.controllers.GameTimeController;
  30. import com.l2jfrozen.gameserver.model.L2Skill.SkillType;
  31. import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
  32. import com.l2jfrozen.gameserver.network.SystemMessageId;
  33. import com.l2jfrozen.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
  34. import com.l2jfrozen.gameserver.network.serverpackets.MagicEffectIcons;
  35. import com.l2jfrozen.gameserver.network.serverpackets.PartySpelled;
  36. import com.l2jfrozen.gameserver.network.serverpackets.SystemMessage;
  37. import com.l2jfrozen.gameserver.skills.Env;
  38. import com.l2jfrozen.gameserver.skills.effects.EffectTemplate;
  39. import com.l2jfrozen.gameserver.skills.funcs.Func;
  40. import com.l2jfrozen.gameserver.skills.funcs.FuncTemplate;
  41. import com.l2jfrozen.gameserver.skills.funcs.Lambda;
  42. import com.l2jfrozen.gameserver.thread.ThreadPoolManager;
  43.  
  44. /**
  45.  * This class ...
  46.  *
  47.  * @version $Revision: 1.1.2.1.2.12 $ $Date: 2005/04/11 10:06:07 $
  48.  * @author l2jfrozen dev
  49.  */
  50. public abstract class L2Effect
  51. {
  52.     static final Logger _log = Logger.getLogger(L2Effect.class.getName());
  53.  
  54.     public static enum EffectState
  55.     {
  56.         CREATED,
  57.         ACTING,
  58.         FINISHING
  59.     }
  60.  
  61.     public static enum EffectType
  62.     {
  63.         BUFF,
  64.         DEBUFF,
  65.         CHARGE,
  66.         DMG_OVER_TIME,
  67.         HEAL_OVER_TIME,
  68.         COMBAT_POINT_HEAL_OVER_TIME,
  69.         MANA_DMG_OVER_TIME,
  70.         MANA_HEAL_OVER_TIME,
  71.         RELAXING,
  72.         STUN,
  73.         ROOT,
  74.         SLEEP,
  75.         HATE,
  76.         FAKE_DEATH,
  77.         CONFUSION,
  78.         CONFUSE_MOB_ONLY,
  79.         MUTE,
  80.         IMMOBILEUNTILATTACKED,
  81.         FEAR,
  82.         SALVATION,
  83.         SILENT_MOVE,
  84.         SIGNET_EFFECT,
  85.         SIGNET_GROUND,
  86.         SEED,
  87.         PARALYZE,
  88.         STUN_SELF,
  89.         PSYCHICAL_MUTE,
  90.         REMOVE_TARGET,
  91.         TARGET_ME,
  92.         SILENCE_MAGIC_PHYSICAL,
  93.         BETRAY,
  94.         NOBLESSE_BLESSING,
  95.         PHOENIX_BLESSING,
  96.         PETRIFICATION,
  97.         BLUFF,
  98.         BATTLE_FORCE,
  99.         SPELL_FORCE,
  100.         CHARM_OF_LUCK,
  101.         INVINCIBLE,
  102.         PROTECTION_BLESSING,
  103.         INTERRUPT,
  104.         MEDITATION,
  105.         BLOW,
  106.         FUSION,
  107.         CANCEL,
  108.         BLOCK_BUFF,
  109.         BLOCK_DEBUFF,
  110.         PREVENT_BUFF,
  111.         CLAN_GATE,
  112.         NEGATE
  113.     }
  114.  
  115.     private static final Func[] _emptyFunctionSet = new Func[0];
  116.  
  117.     //member _effector is the instance of L2Character that cast/used the spell/skill that is
  118.     //causing this effect.  Do not confuse with the instance of L2Character that
  119.     //is being affected by this effect.
  120.     private final L2Character _effector;
  121.  
  122.     //member _effected is the instance of L2Character that was affected
  123.     //by this effect.  Do not confuse with the instance of L2Character that
  124.     //catsed/used this effect.
  125.     protected final L2Character _effected;
  126.  
  127.     //the skill that was used.
  128.     public L2Skill _skill;
  129.  
  130.     //or the items that was used.
  131.     //private final L2Item _item;
  132.  
  133.     // the value of an update
  134.     private final Lambda _lambda;
  135.  
  136.     // the current state
  137.     private EffectState _state;
  138.  
  139.     // period, seconds
  140.     private final int _period;
  141.     private int _periodStartTicks;
  142.     private int _periodfirsttime;
  143.  
  144.     // function templates
  145.     private final FuncTemplate[] _funcTemplates;
  146.  
  147.     //initial count
  148.     protected int _totalCount;
  149.     // counter
  150.     private int _count;
  151.  
  152.     // abnormal effect mask
  153.     private int _abnormalEffect;
  154.  
  155.     public boolean preventExitUpdate;
  156.  
  157.     private boolean _cancelEffect = false;
  158.    
  159.     public final class EffectTask implements Runnable
  160.     {
  161.         protected final int _delay;
  162.         protected final int _rate;
  163.  
  164.         EffectTask(int pDelay, int pRate)
  165.         {
  166.             _delay = pDelay;
  167.             _rate = pRate;
  168.         }
  169.  
  170.         @Override
  171.         public void run()
  172.         {
  173.             try
  174.             {
  175.                 if(getPeriodfirsttime() == 0)
  176.                 {
  177.                     setPeriodStartTicks(GameTimeController.getGameTicks());
  178.                 }
  179.                 else
  180.                 {
  181.                     setPeriodfirsttime(0);
  182.                 }
  183.                 scheduleEffect();
  184.             }
  185.             catch(Throwable e)
  186.             {
  187.                 _log.log(Level.SEVERE, "", e);
  188.             }
  189.         }
  190.     }
  191.  
  192.     private ScheduledFuture<?> _currentFuture;
  193.     private EffectTask _currentTask;
  194.  
  195.     /** The Identifier of the stack group */
  196.     private final String _stackType;
  197.  
  198.     /** The position of the effect in the stack group */
  199.     private final float _stackOrder;
  200.  
  201.     private final EffectTemplate _template;
  202.  
  203.     private boolean _inUse = false;
  204.  
  205.     protected L2Effect(Env env, EffectTemplate template)
  206.     {
  207.         _template = template;
  208.         _state = EffectState.CREATED;
  209.         _skill = env.skill;
  210.         //_item = env._item == null ? null : env._item.getItem();
  211.         _effected = env.target;
  212.         _effector = env.player;
  213.         _lambda = template.lambda;
  214.         _funcTemplates = template.funcTemplates;
  215.         _count = template.counter;
  216.         _totalCount = _count;
  217.         int temp = template.period;
  218.         if(env.skillMastery)
  219.         {
  220.             temp *= 2;
  221.         }
  222.         _period = temp;
  223.         _abnormalEffect = template.abnormalEffect;
  224.         _stackType = template.stackType;
  225.         _stackOrder = template.stackOrder;
  226.         _periodStartTicks = GameTimeController.getGameTicks();
  227.         _periodfirsttime = 0;
  228.         scheduleEffect();
  229.     }
  230.  
  231.     public int getCount()
  232.     {
  233.         return _count;
  234.     }
  235.  
  236.     public int getTotalCount()
  237.     {
  238.         return _totalCount;
  239.     }
  240.  
  241.     public void setCount(int newcount)
  242.     {
  243.         _count = newcount;
  244.     }
  245.  
  246.     public void setFirstTime(int newfirsttime)
  247.     {
  248.         if(_currentFuture != null)
  249.         {
  250.             _periodStartTicks = GameTimeController.getGameTicks() - newfirsttime * GameTimeController.TICKS_PER_SECOND;
  251.             _currentFuture.cancel(false);
  252.             _currentFuture = null;
  253.             _currentTask = null;
  254.             _periodfirsttime = newfirsttime;
  255.             int duration = _period - _periodfirsttime;
  256.             //_log.warning("Period: "+_period+"-"+_periodfirsttime+"="+duration);
  257.             _currentTask = new EffectTask(duration * 1000, -1);
  258.             _currentFuture = ThreadPoolManager.getInstance().scheduleEffect(_currentTask, duration * 1000);
  259.         }
  260.     }
  261.  
  262.     public int getPeriod()
  263.     {
  264.         return _period;
  265.     }
  266.  
  267.     public int getTime()
  268.     {
  269.         return (GameTimeController.getGameTicks() - _periodStartTicks) / GameTimeController.TICKS_PER_SECOND;
  270.     }
  271.  
  272.     /**
  273.      * Returns the elapsed time of the task.
  274.      *
  275.      * @return Time in seconds.
  276.      */
  277.     public int getTaskTime()
  278.     {
  279.         if(_count == _totalCount)
  280.             return 0;
  281.  
  282.         return Math.abs(_count - _totalCount + 1) * _period + getTime() + 1;
  283.     }
  284.  
  285.     public boolean getInUse()
  286.     {
  287.         return _inUse;
  288.     }
  289.  
  290.     public void setInUse(boolean inUse)
  291.     {
  292.         _inUse = inUse;
  293.     }
  294.  
  295.     public String getStackType()
  296.     {
  297.         return _stackType;
  298.     }
  299.  
  300.     public float getStackOrder()
  301.     {
  302.         return _stackOrder;
  303.     }
  304.  
  305.     public final L2Skill getSkill()
  306.     {
  307.         return _skill;
  308.     }
  309.  
  310.     public final L2Character getEffector()
  311.     {
  312.         return _effector;
  313.     }
  314.  
  315.     public final L2Character getEffected()
  316.     {
  317.         return _effected;
  318.     }
  319.  
  320.     public boolean isSelfEffect()
  321.     {
  322.         return _skill._effectTemplatesSelf != null;
  323.     }
  324.  
  325.     public boolean isHerbEffect()
  326.     {
  327.         if(getSkill().getName().contains("Herb"))
  328.             return true;
  329.  
  330.         return false;
  331.     }
  332.  
  333.     public final double calc()
  334.     {
  335.         Env env = new Env();
  336.         env.player = _effector;
  337.         env.target = _effected;
  338.         env.skill = _skill;
  339.         return _lambda.calc(env);
  340.     }
  341.  
  342.     private synchronized void startEffectTask(int duration)
  343.     {
  344.         stopEffectTask();
  345.         _currentTask = new EffectTask(duration, -1);
  346.         _currentFuture = ThreadPoolManager.getInstance().scheduleEffect(_currentTask, duration);
  347.        
  348.         if (_state == EffectState.ACTING)
  349.         {      
  350.             // To avoid possible NPE caused by player crash
  351.             if (_effected != null)
  352.                 _effected.addEffect(this);
  353.             else
  354.                 _log.warning("Effected is null for skill " + _skill.getId() + " on effect " + getEffectType());
  355.         }
  356.     }
  357.  
  358.     private synchronized void startEffectTaskAtFixedRate(int delay, int rate)
  359.     {
  360.         stopEffectTask();
  361.         _currentTask = new EffectTask(delay, rate);
  362.         _currentFuture = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(_currentTask, delay, rate);
  363.  
  364.         if(_state == EffectState.ACTING)
  365.         {
  366.             _effected.addEffect(this);
  367.         }
  368.     }
  369.  
  370.     /**
  371.      * Stop the L2Effect task and send Server->Client update packet.<BR>
  372.      * <BR>
  373.      * <B><U> Actions</U> :</B><BR>
  374.      * <BR>
  375.      * <li>Cancel the effect in the the abnormal effect map of the L2Character</li> <li>Stop the task of the L2Effect,
  376.      * remove it and update client magic icone</li><BR>
  377.      * <BR>
  378.      */
  379.     public final void exit()
  380.     {
  381.         this.exit(false, false);
  382.     }
  383.    
  384.     public final void exit(boolean cancelEffect)
  385.     {
  386.         this.exit(false, cancelEffect);
  387.     }
  388.  
  389.     public final void exit(boolean preventUpdate, boolean cancelEffect)
  390.     {
  391.         preventExitUpdate = preventUpdate;
  392.         _state = EffectState.FINISHING;
  393.         _cancelEffect = cancelEffect;
  394.         scheduleEffect();
  395.     }
  396.  
  397.     /**
  398.      * Stop the task of the L2Effect, remove it and update client magic icone.<BR>
  399.      * <BR>
  400.      * <B><U> Actions</U> :</B><BR>
  401.      * <BR>
  402.      * <li>Cancel the task</li> <li>Stop and remove L2Effect from L2Character and update client magic icone</li><BR>
  403.      * <BR>
  404.      */
  405.     public synchronized void stopEffectTask()
  406.     {
  407.         // Cancel the task
  408.         if (_currentFuture != null)
  409.         {
  410.             if (!_currentFuture.isCancelled())
  411.                 _currentFuture.cancel(false);
  412.            
  413.             _currentFuture = null;
  414.             _currentTask = null;
  415.            
  416.             // To avoid possible NPE caused by player crash
  417.             if (_effected != null)
  418.                 _effected.removeEffect(this);
  419.             else
  420.                 _log.warning("Effected is null for skill " + _skill.getId() + " on effect " + getEffectType());
  421.         }
  422.     }
  423.  
  424.     /**
  425.      * @return effect type
  426.      */
  427.     public abstract EffectType getEffectType();
  428.  
  429.     /** Notify started */
  430.     public void onStart()
  431.     {
  432.         if(_abnormalEffect != 0)
  433.         {
  434.             getEffected().startAbnormalEffect(_abnormalEffect);
  435.         }
  436.     }
  437.  
  438.     /**
  439.      * Cancel the effect in the the abnormal effect map of the effected L2Character.<BR>
  440.      * <BR>
  441.      */
  442.     public void onExit()
  443.     {
  444.         if(_abnormalEffect != 0)
  445.         {
  446.             getEffected().stopAbnormalEffect(_abnormalEffect);
  447.         }
  448.     }
  449.  
  450.     /**
  451.      * Return true for continuation of this effect
  452.      * @return
  453.      */
  454.     public abstract boolean onActionTime();
  455.  
  456.     public final void rescheduleEffect()
  457.     {
  458.         if(_state != EffectState.ACTING)
  459.         {
  460.             scheduleEffect();
  461.         }
  462.         else
  463.         {
  464.             if(_count > 1)
  465.             {
  466.                 startEffectTaskAtFixedRate(5, _period * 1000);
  467.                 return;
  468.             }
  469.             if(_period > 0)
  470.             {
  471.                 startEffectTask(_period * 1000);
  472.                 return;
  473.             }
  474.         }
  475.     }
  476.  
  477.     public final void scheduleEffect()
  478.     {
  479.         if(_state == EffectState.CREATED)
  480.         {
  481.             _state = EffectState.ACTING;
  482.            
  483.             onStart();
  484.  
  485.             if(_skill.isPvpSkill() && getEffected() != null && getEffected() instanceof L2PcInstance && getShowIcon())
  486.             {
  487.                 SystemMessage smsg = new SystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
  488.                 smsg.addString(_skill.getName());
  489.                 getEffected().sendPacket(smsg);
  490.                 smsg = null;
  491.             }
  492.  
  493.             if(_count > 1)
  494.             {
  495.                 startEffectTaskAtFixedRate(5, _period * 1000);
  496.                 return;
  497.             }
  498.             if(_period > 0)
  499.             {
  500.                 startEffectTask(_period * 1000);
  501.                 return;
  502.             }
  503.         }
  504.  
  505.         if(_state == EffectState.ACTING)
  506.         {
  507.             if(_count-- > 0)
  508.             {
  509.                 if(getInUse())
  510.                 { // effect has to be in use
  511.                     if(onActionTime())
  512.                         return; // false causes effect to finish right away
  513.                 }
  514.                 else if(_count > 0)
  515.                     return;
  516.             }
  517.             _state = EffectState.FINISHING;
  518.         }
  519.  
  520.         if(_state == EffectState.FINISHING)
  521.         {
  522.             // Cancel the effect in the the abnormal effect map of the L2Character
  523.             onExit();
  524.  
  525.             //If the time left is equal to zero, send the message
  526.             if(getEffected() != null
  527.                     && getEffected() instanceof L2PcInstance
  528.                     && getShowIcon()
  529.                     && !getEffected().isDead()){
  530.                
  531.                 // Like L2OFF message S1_HAS_BEEN_ABORTED for toogle skills
  532.                 if (getSkill().isToggle())
  533.                 {
  534.                     SystemMessage smsg3 = new SystemMessage(SystemMessageId.S1_HAS_BEEN_ABORTED);
  535.                     smsg3.addString(getSkill().getName());
  536.                     getEffected().sendPacket(smsg3);
  537.                 }
  538.                 else if(_cancelEffect){
  539.                     SystemMessage smsg3 = new SystemMessage(SystemMessageId.EFFECT_S1_DISAPPEARED);
  540.                     smsg3.addString(getSkill().getName());
  541.                     getEffected().sendPacket(smsg3);
  542.                     smsg3 = null;
  543.                 }else if(_count == 0){
  544.                     SystemMessage smsg3 = new SystemMessage(SystemMessageId.S1_HAS_WORN_OFF);
  545.                     smsg3.addString(_skill.getName());
  546.                     getEffected().sendPacket(smsg3);
  547.                     smsg3 = null;
  548.                 }
  549.                
  550.             }
  551.              
  552.             // Stop the task of the L2Effect, remove it and update client magic icone
  553.             stopEffectTask();
  554.  
  555.         }
  556.     }
  557.  
  558.     public Func[] getStatFuncs()
  559.     {
  560.         if(_funcTemplates == null)
  561.             return _emptyFunctionSet;
  562.         List<Func> funcs = new FastList<Func>();
  563.         for(FuncTemplate t : _funcTemplates)
  564.         {
  565.             Env env = new Env();
  566.             env.player = getEffector();
  567.             env.target = getEffected();
  568.             env.skill = getSkill();
  569.             Func f = t.getFunc(env, this); // effect is owner
  570.             if(f != null)
  571.             {
  572.                 funcs.add(f);
  573.             }
  574.         }
  575.         if(funcs.size() == 0)
  576.             return _emptyFunctionSet;
  577.         return funcs.toArray(new Func[funcs.size()]);
  578.     }
  579.  
  580.     public final void addIcon(MagicEffectIcons mi)
  581.     {
  582.         EffectTask task = _currentTask;
  583.         ScheduledFuture<?> future = _currentFuture;
  584.  
  585.         if(task == null || future == null)
  586.             return;
  587.  
  588.         if(_state == EffectState.FINISHING || _state == EffectState.CREATED)
  589.             return;
  590.  
  591.         if(!getShowIcon())
  592.             return;
  593.  
  594.         L2Skill sk = getSkill();
  595.  
  596.         if(task._rate > 0)
  597.         {
  598.             if(sk.isPotion())
  599.             {
  600.                 mi.addEffect(sk.getId(), getLevel(), sk.getBuffDuration() - getTaskTime() * 1000, false);
  601.             }
  602.             else if(!sk.isToggle())
  603.             {
  604.                 if(sk.is_Debuff())
  605.                     mi.addEffect(sk.getId(), getLevel(), (_count * _period) * 1000,true);
  606.                 else
  607.                     mi.addEffect(sk.getId(), getLevel(), (_count * _period) * 1000,false);
  608.             }
  609.             else
  610.             {
  611.                 mi.addEffect(sk.getId(), getLevel(), -1,true);
  612.             }
  613.         }
  614.         else
  615.         {
  616.             if(sk.getSkillType()==SkillType.DEBUFF)
  617.                 mi.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS)+1000,true);
  618.             else
  619.                 mi.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS)+1000,false);
  620.         }
  621.  
  622.         task = null;
  623.         future = null;
  624.     }
  625.  
  626.     public final void addPartySpelledIcon(PartySpelled ps)
  627.     {
  628.         EffectTask task = _currentTask;
  629.         ScheduledFuture<?> future = _currentFuture;
  630.  
  631.         if(task == null || future == null)
  632.             return;
  633.  
  634.         if(_state == EffectState.FINISHING || _state == EffectState.CREATED)
  635.             return;
  636.  
  637.         L2Skill sk = getSkill();
  638.         ps.addPartySpelledEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
  639.  
  640.         task = null;
  641.         future = null;
  642.         sk = null;
  643.     }
  644.  
  645.     public final void addOlympiadSpelledIcon(ExOlympiadSpelledInfo os)
  646.     {
  647.         EffectTask task = _currentTask;
  648.         ScheduledFuture<?> future = _currentFuture;
  649.  
  650.         if(task == null || future == null)
  651.             return;
  652.  
  653.         if(_state == EffectState.FINISHING || _state == EffectState.CREATED)
  654.             return;
  655.  
  656.         L2Skill sk = getSkill();
  657.         os.addEffect(sk.getId(), getLevel(), (int) future.getDelay(TimeUnit.MILLISECONDS));
  658.  
  659.         sk = null;
  660.         task = null;
  661.         future = null;
  662.     }
  663.  
  664.     public int getLevel()
  665.     {
  666.         return getSkill().getLevel();
  667.     }
  668.  
  669.     public int getPeriodfirsttime()
  670.     {
  671.         return _periodfirsttime;
  672.     }
  673.  
  674.     public void setPeriodfirsttime(int periodfirsttime)
  675.     {
  676.         _periodfirsttime = periodfirsttime;
  677.     }
  678.  
  679.     public int getPeriodStartTicks()
  680.     {
  681.         return _periodStartTicks;
  682.     }
  683.  
  684.     public void setPeriodStartTicks(int periodStartTicks)
  685.     {
  686.         _periodStartTicks = periodStartTicks;
  687.     }
  688.  
  689.     public final boolean getShowIcon()
  690.     {
  691.         return _template.showIcon;
  692.     }
  693.  
  694.     public EffectState get_state()
  695.     {
  696.         return _state;
  697.     }
  698.    
  699.    
  700. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement