Guest User

Untitled

a guest
Feb 9th, 2019
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 92.89 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.skills;
  20.  
  21. import java.util.logging.Logger;
  22.  
  23. import com.l2jfrozen.Config;
  24. import com.l2jfrozen.gameserver.managers.ClanHallManager;
  25. import com.l2jfrozen.gameserver.managers.ClassDamageManager;
  26. import com.l2jfrozen.gameserver.managers.SiegeManager;
  27. import com.l2jfrozen.gameserver.model.Inventory;
  28. import com.l2jfrozen.gameserver.model.L2Character;
  29. import com.l2jfrozen.gameserver.model.L2Effect;
  30. import com.l2jfrozen.gameserver.model.L2SiegeClan;
  31. import com.l2jfrozen.gameserver.model.L2Skill;
  32. import com.l2jfrozen.gameserver.model.L2Skill.SkillType;
  33. import com.l2jfrozen.gameserver.model.L2Summon;
  34. import com.l2jfrozen.gameserver.model.actor.instance.L2CubicInstance;
  35. import com.l2jfrozen.gameserver.model.actor.instance.L2DoorInstance;
  36. import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance;
  37. import com.l2jfrozen.gameserver.model.actor.instance.L2NpcInstance;
  38. import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
  39. import com.l2jfrozen.gameserver.model.actor.instance.L2PetInstance;
  40. import com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance;
  41. import com.l2jfrozen.gameserver.model.entity.ClanHall;
  42. import com.l2jfrozen.gameserver.model.entity.sevensigns.SevenSigns;
  43. import com.l2jfrozen.gameserver.model.entity.sevensigns.SevenSignsFestival;
  44. import com.l2jfrozen.gameserver.model.entity.siege.Siege;
  45. import com.l2jfrozen.gameserver.network.SystemMessageId;
  46. import com.l2jfrozen.gameserver.network.serverpackets.SystemMessage;
  47. import com.l2jfrozen.gameserver.skills.conditions.ConditionPlayerState;
  48. import com.l2jfrozen.gameserver.skills.conditions.ConditionPlayerState.CheckPlayerState;
  49. import com.l2jfrozen.gameserver.skills.conditions.ConditionUsingItemType;
  50. import com.l2jfrozen.gameserver.skills.effects.EffectTemplate;
  51. import com.l2jfrozen.gameserver.skills.funcs.Func;
  52. import com.l2jfrozen.gameserver.templates.L2Armor;
  53. import com.l2jfrozen.gameserver.templates.L2Item;
  54. import com.l2jfrozen.gameserver.templates.L2NpcTemplate;
  55. import com.l2jfrozen.gameserver.templates.L2PcTemplate;
  56. import com.l2jfrozen.gameserver.templates.L2Weapon;
  57. import com.l2jfrozen.gameserver.templates.L2WeaponType;
  58. import com.l2jfrozen.gameserver.util.Util;
  59. import com.l2jfrozen.util.StringUtil;
  60. import com.l2jfrozen.util.random.Rnd;
  61.  
  62. /**
  63.  * Global calculations, can be modified by server admins
  64.  *
  65.  * @author L2JFrozen dev
  66.  */
  67. public final class Formulas
  68. {
  69.     /** Regen Task period */
  70.     protected static final Logger _log = Logger.getLogger(L2Character.class.getName());
  71.     private static final int HP_REGENERATE_PERIOD = 3000; // 3 secs
  72.  
  73.     /*
  74.     public static final int MAX_STAT_VALUE = 100;
  75.  
  76.    
  77.     private static final double[] STRCompute = new double[]
  78.     {
  79.             1.036, 34.845
  80.     }; //{1.016, 28.515}; for C1
  81.     private static final double[] INTCompute = new double[]
  82.     {
  83.             1.020, 31.375
  84.     }; //{1.020, 31.375}; for C1
  85.     private static final double[] DEXCompute = new double[]
  86.     {
  87.             1.009, 19.360
  88.     }; //{1.009, 19.360}; for C1
  89.     private static final double[] WITCompute = new double[]
  90.     {
  91.             1.050, 20.000
  92.     }; //{1.050, 20.000}; for C1
  93.     private static final double[] CONCompute = new double[]
  94.     {
  95.             1.030, 27.632
  96.     }; //{1.015, 12.488}; for C1
  97.     private static final double[] MENCompute = new double[]
  98.     {
  99.             1.010, -0.060
  100.     }; //{1.010, -0.060}; for C1
  101.  
  102.     protected static final double[] WITbonus = new double[MAX_STAT_VALUE];
  103.     protected static final double[] MENbonus = new double[MAX_STAT_VALUE];
  104.     protected static final double[] INTbonus = new double[MAX_STAT_VALUE];
  105.     protected static final double[] STRbonus = new double[MAX_STAT_VALUE];
  106.     protected static final double[] DEXbonus = new double[MAX_STAT_VALUE];
  107.     protected static final double[] CONbonus = new double[MAX_STAT_VALUE];
  108.      
  109.     // These values are 100% matching retail tables, no need to change and no need add
  110.     // calculation into the stat bonus when accessing (not efficient),
  111.     // better to have everything precalculated and use values directly (saves CPU)
  112.     static
  113.     {
  114.         for(int i = 0; i < STRbonus.length; i++)
  115.         {
  116.             STRbonus[i] = Math.floor(Math.pow(STRCompute[0], i - STRCompute[1]) * 100 + .5d) / 100;
  117.         }
  118.         for(int i = 0; i < INTbonus.length; i++)
  119.         {
  120.             INTbonus[i] = Math.floor(Math.pow(INTCompute[0], i - INTCompute[1]) * 100 + .5d) / 100;
  121.         }
  122.         for(int i = 0; i < DEXbonus.length; i++)
  123.         {
  124.             DEXbonus[i] = Math.floor(Math.pow(DEXCompute[0], i - DEXCompute[1]) * 100 + .5d) / 100;
  125.         }
  126.         for(int i = 0; i < WITbonus.length; i++)
  127.         {
  128.             WITbonus[i] = Math.floor(Math.pow(WITCompute[0], i - WITCompute[1]) * 100 + .5d) / 100;
  129.         }
  130.         for(int i = 0; i < CONbonus.length; i++)
  131.         {
  132.             CONbonus[i] = Math.floor(Math.pow(CONCompute[0], i - CONCompute[1]) * 100 + .5d) / 100;
  133.         }
  134.         for(int i = 0; i < MENbonus.length; i++)
  135.         {
  136.             MENbonus[i] = Math.floor(Math.pow(MENCompute[0], i - MENCompute[1]) * 100 + .5d) / 100;
  137.         }
  138.     }
  139.     */
  140.  
  141.     static class FuncAddLevel3 extends Func
  142.     {
  143.         static final FuncAddLevel3[] _instancies = new FuncAddLevel3[Stats.NUM_STATS];
  144.  
  145.         static Func getInstance(final Stats stat)
  146.         {
  147.             final int pos = stat.ordinal();
  148.  
  149.             if(_instancies[pos] == null)
  150.             {
  151.                 _instancies[pos] = new FuncAddLevel3(stat);
  152.             }
  153.             return _instancies[pos];
  154.         }
  155.  
  156.         private FuncAddLevel3(final Stats pStat)
  157.         {
  158.             super(pStat, 0x10, null);
  159.         }
  160.  
  161.         @Override
  162.         public void calc(final Env env)
  163.         {
  164.             env.value += env.player.getLevel() / 3.0;
  165.         }
  166.     }
  167.  
  168.     static class FuncMultLevelMod extends Func
  169.     {
  170.         static final FuncMultLevelMod[] _instancies = new FuncMultLevelMod[Stats.NUM_STATS];
  171.  
  172.         static Func getInstance(final Stats stat)
  173.         {
  174.             final int pos = stat.ordinal();
  175.  
  176.             if(_instancies[pos] == null)
  177.             {
  178.                 _instancies[pos] = new FuncMultLevelMod(stat);
  179.             }
  180.             return _instancies[pos];
  181.         }
  182.  
  183.         private FuncMultLevelMod(final Stats pStat)
  184.         {
  185.             super(pStat, 0x20, null);
  186.         }
  187.  
  188.         @Override
  189.         public void calc(final Env env)
  190.         {
  191.             env.value *= env.player.getLevelMod();
  192.         }
  193.     }
  194.  
  195.     static class FuncMultRegenResting extends Func
  196.     {
  197.         static final FuncMultRegenResting[] _instancies = new FuncMultRegenResting[Stats.NUM_STATS];
  198.  
  199.         /**
  200.          * @param stat
  201.          * @return the Func object corresponding to the state concerned.
  202.          */
  203.         static Func getInstance(Stats stat)
  204.         {
  205.             int pos = stat.ordinal();
  206.  
  207.             if(_instancies[pos] == null)
  208.             {
  209.                 _instancies[pos] = new FuncMultRegenResting(stat);
  210.             }
  211.  
  212.             return _instancies[pos];
  213.         }
  214.  
  215.         /**
  216.          * Constructor of the FuncMultRegenResting.<BR>
  217.          * <BR>
  218.          * @param pStat
  219.          */
  220.         private FuncMultRegenResting(Stats pStat)
  221.         {
  222.             super(pStat, 0x20, null);
  223.             setCondition(new ConditionPlayerState(CheckPlayerState.RESTING, true));
  224.         }
  225.  
  226.         /**
  227.          * Calculate the modifier of the state concerned.<BR>
  228.          * <BR>
  229.          */
  230.         @Override
  231.         public void calc(Env env)
  232.         {
  233.             if(!cond.test(env))
  234.                 return;
  235.  
  236.             env.value *= 1.45;
  237.         }
  238.     }
  239.  
  240.     static class FuncPAtkMod extends Func
  241.     {
  242.         static final FuncPAtkMod _fpa_instance = new FuncPAtkMod();
  243.  
  244.         static Func getInstance()
  245.         {
  246.             return _fpa_instance;
  247.         }
  248.  
  249.         private FuncPAtkMod()
  250.         {
  251.             super(Stats.POWER_ATTACK, 0x30, null);
  252.         }
  253.  
  254.         @Override
  255.         public void calc(Env env)
  256.         {
  257.             if (env.player instanceof L2PetInstance)
  258.             {
  259.                 if (env.player.getActiveWeaponInstance() != null)
  260.                     env.value *= BaseStats.STR.calcBonus(env.player);
  261.             }
  262.             else
  263.                 env.value *= BaseStats.STR.calcBonus(env.player) * env.player.getLevelMod();
  264.         }
  265.     }
  266.  
  267.     static class FuncMAtkMod extends Func
  268.     {
  269.         static final FuncMAtkMod _fma_instance = new FuncMAtkMod();
  270.  
  271.         static Func getInstance()
  272.         {
  273.             return _fma_instance;
  274.         }
  275.  
  276.         private FuncMAtkMod()
  277.         {
  278.             super(Stats.MAGIC_ATTACK, 0x20, null);
  279.         }
  280.  
  281.         @Override
  282.         public void calc(Env env)
  283.         {
  284.             double intb = BaseStats.INT.calcBonus(env.player);
  285.             double lvlb = env.player.getLevelMod();
  286.             env.value *= (lvlb * lvlb) * (intb * intb);
  287.         }
  288.     }
  289.  
  290.     static class FuncMDefMod extends Func
  291.     {
  292.         static final FuncMDefMod _fmm_instance = new FuncMDefMod();
  293.  
  294.         static Func getInstance()
  295.         {
  296.             return _fmm_instance;
  297.         }
  298.  
  299.         private FuncMDefMod()
  300.         {
  301.             super(Stats.MAGIC_DEFENCE, 0x20, null);
  302.         }
  303.  
  304.         @Override
  305.         public void calc(Env env)
  306.         {
  307.             if(env.player instanceof L2PcInstance)
  308.             {
  309.                 L2PcInstance p = (L2PcInstance) env.player;
  310.                 if(p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LFINGER) != null)
  311.                 {
  312.                     env.value -= 5;
  313.                 }
  314.                 if(p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RFINGER) != null)
  315.                 {
  316.                     env.value -= 5;
  317.                 }
  318.                 if(p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEAR) != null)
  319.                 {
  320.                     env.value -= 9;
  321.                 }
  322.                 if(p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_REAR) != null)
  323.                 {
  324.                     env.value -= 9;
  325.                 }
  326.                 if(p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_NECK) != null)
  327.                 {
  328.                     env.value -= 13;
  329.                 }
  330.             }
  331.             env.value *= BaseStats.MEN.calcBonus(env.player) * env.player.getLevelMod();
  332.         }
  333.     }
  334.  
  335.     static class FuncPDefMod extends Func
  336.     {
  337.         static final FuncPDefMod _fmm_instance = new FuncPDefMod();
  338.  
  339.         static Func getInstance()
  340.         {
  341.             return _fmm_instance;
  342.         }
  343.  
  344.         private FuncPDefMod()
  345.         {
  346.             super(Stats.POWER_DEFENCE, 0x20, null);
  347.         }
  348.  
  349.         @Override
  350.         public void calc(Env env)
  351.         {
  352.             if(env.player instanceof L2PcInstance)
  353.             {
  354.                 L2PcInstance p = (L2PcInstance) env.player;
  355.                 boolean hasMagePDef = (p.getClassId().isMage() || p.getClassId().getId() == 0x31); // orc mystics are a special case
  356.                 if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_HEAD) != null)
  357.                     env.value -= 12;
  358.                 L2ItemInstance chest = p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
  359.                 if (chest != null)
  360.                     env.value -= hasMagePDef ? 15 : 31;
  361.                 if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS) != null || (chest != null && chest.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR))
  362.                     env.value -= hasMagePDef ? 8 : 18;
  363.                 if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_GLOVES) != null)
  364.                     env.value -= 8;
  365.                 if (p.getInventory().getPaperdollItem(Inventory.PAPERDOLL_FEET) != null)
  366.                     env.value -= 7;
  367.             }
  368.             env.value *= env.player.getLevelMod();
  369.         }
  370.     }
  371.  
  372.     static class FuncBowAtkRange extends Func
  373.     {
  374.         private static final FuncBowAtkRange _fbar_instance = new FuncBowAtkRange();
  375.  
  376.         static Func getInstance()
  377.         {
  378.             return _fbar_instance;
  379.         }
  380.  
  381.         private FuncBowAtkRange()
  382.         {
  383.             super(Stats.POWER_ATTACK_RANGE, 0x10, null);
  384.             setCondition(new ConditionUsingItemType(L2WeaponType.BOW.mask()));
  385.         }
  386.  
  387.         @Override
  388.         public void calc(Env env)
  389.         {
  390.             if(!cond.test(env))
  391.                 return;
  392.             env.value += 460;
  393.         }
  394.     }
  395.    
  396.     static class FuncAtkAccuracy extends Func
  397.     {
  398.         static final FuncAtkAccuracy _faa_instance = new FuncAtkAccuracy();
  399.        
  400.         static Func getInstance()
  401.         {
  402.             return _faa_instance;
  403.         }
  404.        
  405.         private FuncAtkAccuracy()
  406.         {
  407.             super(Stats.ACCURACY_COMBAT, 0x10, null);
  408.         }
  409.        
  410.         @Override
  411.         public void calc(Env env)
  412.         {
  413.             final int level = env.player.getLevel();
  414.             // [Square(DEX)]*6 + lvl + weapon hitbonus;
  415.            
  416.             L2Character p = env.player;
  417.             if (p instanceof L2PetInstance)
  418.                 env.value += Math.sqrt(env.player.getDEX());
  419.             else
  420.             {
  421.                 env.value += Math.sqrt(env.player.getDEX()) * 6;
  422.                 env.value += level;
  423.                 if (level > 77)
  424.                     env.value += (level - 77);
  425.                 if (level > 69)
  426.                     env.value += (level - 69);
  427.                 if (env.player instanceof L2Summon)
  428.                     env.value += (level < 60) ? 4 : 5;
  429.             }
  430.         }
  431.     }
  432.  
  433.     static class FuncAtkEvasion extends Func
  434.     {
  435.         static final FuncAtkEvasion _fae_instance = new FuncAtkEvasion();
  436.        
  437.         static Func getInstance()
  438.         {
  439.             return _fae_instance;
  440.         }
  441.        
  442.         private FuncAtkEvasion()
  443.         {
  444.             super(Stats.EVASION_RATE, 0x10, null);
  445.         }
  446.        
  447.         @Override
  448.         public void calc(Env env)
  449.         {
  450.             final int level = env.player.getLevel();
  451.             // [Square(DEX)]*6 + lvl;
  452.            
  453.             L2Character p = env.player;
  454.             if (p instanceof L2PetInstance)
  455.                 env.value += Math.sqrt(env.player.getDEX());
  456.             else
  457.             {
  458.                 env.value += Math.sqrt(env.player.getDEX()) * 6;
  459.                 env.value += level;
  460.                 if (level > 77)
  461.                     env.value += (level - 77);
  462.                 if (level > 69)
  463.                     env.value += (level - 69);
  464.             }
  465.         }
  466.     }
  467.  
  468.     static class FuncAtkCritical extends Func
  469.     {
  470.         static final FuncAtkCritical _fac_instance = new FuncAtkCritical();
  471.        
  472.         static Func getInstance()
  473.         {
  474.             return _fac_instance;
  475.         }
  476.        
  477.         private FuncAtkCritical()
  478.         {
  479.             super(Stats.CRITICAL_RATE, 0x09, null);
  480.         }
  481.        
  482.         @Override
  483.         public void calc(Env env)
  484.         {
  485.             env.value *= BaseStats.DEX.calcBonus(env.player);
  486.            
  487.             L2Character p = env.player;    
  488.             if (!(p instanceof L2PetInstance))
  489.                 env.value *= 10;
  490.            
  491.             env.baseValue = env.value;
  492.         }
  493.     }
  494.  
  495.     static class FuncMAtkCritical extends Func
  496.     {
  497.         static final FuncMAtkCritical _fac_instance = new FuncMAtkCritical();
  498.  
  499.         static Func getInstance()
  500.         {
  501.             return _fac_instance;
  502.         }
  503.  
  504.         private FuncMAtkCritical()
  505.         {
  506.             super(Stats.MCRITICAL_RATE, 0x30, null);
  507.         }
  508.  
  509.         @Override
  510.         public void calc(Env env)
  511.         {
  512.             L2Character p = env.player;
  513.             if(p instanceof L2Summon)
  514.                 env.value = 8; // TODO: needs retail value
  515.             else if (p instanceof L2PcInstance && p.getActiveWeaponInstance() != null)
  516.                 env.value *= BaseStats.WIT.calcBonus(p);
  517.         }
  518.     }
  519.  
  520.     static class FuncMoveSpeed extends Func
  521.     {
  522.         static final FuncMoveSpeed _fms_instance = new FuncMoveSpeed();
  523.  
  524.         static Func getInstance()
  525.         {
  526.             return _fms_instance;
  527.         }
  528.  
  529.         private FuncMoveSpeed()
  530.         {
  531.             super(Stats.RUN_SPEED, 0x30, null);
  532.         }
  533.  
  534.         @Override
  535.         public void calc(Env env)
  536.         {
  537.             env.value *= BaseStats.DEX.calcBonus(env.player);
  538.         }
  539.     }
  540.  
  541.     static class FuncPAtkSpeed extends Func
  542.     {
  543.         static final FuncPAtkSpeed _fas_instance = new FuncPAtkSpeed();
  544.  
  545.         static Func getInstance()
  546.         {
  547.             return _fas_instance;
  548.         }
  549.  
  550.         private FuncPAtkSpeed()
  551.         {
  552.             super(Stats.POWER_ATTACK_SPEED, 0x20, null);
  553.         }
  554.  
  555.         @Override
  556.         public void calc(Env env)
  557.         {
  558.             env.value *= BaseStats.DEX.calcBonus(env.player);
  559.         }
  560.     }
  561.  
  562.     static class FuncMAtkSpeed extends Func
  563.     {
  564.         static final FuncMAtkSpeed _fas_instance = new FuncMAtkSpeed();
  565.  
  566.         static Func getInstance()
  567.         {
  568.             return _fas_instance;
  569.         }
  570.  
  571.         private FuncMAtkSpeed()
  572.         {
  573.             super(Stats.MAGIC_ATTACK_SPEED, 0x20, null);
  574.         }
  575.  
  576.         @Override
  577.         public void calc(Env env)
  578.         {
  579.             env.value *= BaseStats.WIT.calcBonus(env.player);
  580.         }
  581.     }
  582.  
  583.     static class FuncHennaSTR extends Func
  584.     {
  585.         static final FuncHennaSTR _fh_instance = new FuncHennaSTR();
  586.  
  587.         static Func getInstance()
  588.         {
  589.             return _fh_instance;
  590.         }
  591.  
  592.         private FuncHennaSTR()
  593.         {
  594.             super(Stats.STAT_STR, 0x10, null);
  595.         }
  596.  
  597.         @Override
  598.         public void calc(Env env)
  599.         {
  600.             //          L2PcTemplate t = (L2PcTemplate)env._player.getTemplate();
  601.             L2PcInstance pc = (L2PcInstance) env.player;
  602.             if (pc != null) env.value += pc.getHennaStatSTR();
  603.         }
  604.     }
  605.  
  606.     static class FuncHennaDEX extends Func
  607.     {
  608.         static final FuncHennaDEX _fh_instance = new FuncHennaDEX();
  609.  
  610.         static Func getInstance()
  611.         {
  612.             return _fh_instance;
  613.         }
  614.  
  615.         private FuncHennaDEX()
  616.         {
  617.             super(Stats.STAT_DEX, 0x10, null);
  618.         }
  619.  
  620.         @Override
  621.         public void calc(Env env)
  622.         {
  623.             //          L2PcTemplate t = (L2PcTemplate)env._player.getTemplate();
  624.             L2PcInstance pc = (L2PcInstance) env.player;
  625.             if (pc != null) env.value += pc.getHennaStatDEX();
  626.         }
  627.     }
  628.  
  629.     static class FuncHennaINT extends Func
  630.     {
  631.         static final FuncHennaINT _fh_instance = new FuncHennaINT();
  632.  
  633.         static Func getInstance()
  634.         {
  635.             return _fh_instance;
  636.         }
  637.  
  638.         private FuncHennaINT()
  639.         {
  640.             super(Stats.STAT_INT, 0x10, null);
  641.         }
  642.  
  643.         @Override
  644.         public void calc(Env env)
  645.         {
  646.             //          L2PcTemplate t = (L2PcTemplate)env._player.getTemplate();
  647.             L2PcInstance pc = (L2PcInstance) env.player;
  648.             if (pc != null) env.value += pc.getHennaStatINT();
  649.         }
  650.     }
  651.  
  652.     static class FuncHennaMEN extends Func
  653.     {
  654.         static final FuncHennaMEN _fh_instance = new FuncHennaMEN();
  655.  
  656.         static Func getInstance()
  657.         {
  658.             return _fh_instance;
  659.         }
  660.  
  661.         private FuncHennaMEN()
  662.         {
  663.             super(Stats.STAT_MEN, 0x10, null);
  664.         }
  665.  
  666.         @Override
  667.         public void calc(Env env)
  668.         {
  669.             //          L2PcTemplate t = (L2PcTemplate)env._player.getTemplate();
  670.             L2PcInstance pc = (L2PcInstance) env.player;
  671.             if (pc != null) env.value += pc.getHennaStatMEN();
  672.         }
  673.     }
  674.  
  675.     static class FuncHennaCON extends Func
  676.     {
  677.         static final FuncHennaCON _fh_instance = new FuncHennaCON();
  678.  
  679.         static Func getInstance()
  680.         {
  681.             return _fh_instance;
  682.         }
  683.  
  684.         private FuncHennaCON()
  685.         {
  686.             super(Stats.STAT_CON, 0x10, null);
  687.         }
  688.  
  689.         @Override
  690.         public void calc(Env env)
  691.         {
  692.             //          L2PcTemplate t = (L2PcTemplate)env._player.getTemplate();
  693.             L2PcInstance pc = (L2PcInstance) env.player;
  694.             if (pc != null) env.value += pc.getHennaStatCON();
  695.         }
  696.     }
  697.  
  698.     static class FuncHennaWIT extends Func
  699.     {
  700.         static final FuncHennaWIT _fh_instance = new FuncHennaWIT();
  701.  
  702.         static Func getInstance()
  703.         {
  704.             return _fh_instance;
  705.         }
  706.  
  707.         private FuncHennaWIT()
  708.         {
  709.             super(Stats.STAT_WIT, 0x10, null);
  710.         }
  711.  
  712.         @Override
  713.         public void calc(Env env)
  714.         {
  715.             //          L2PcTemplate t = (L2PcTemplate)env._player.getTemplate();
  716.             L2PcInstance pc = (L2PcInstance) env.player;
  717.             if (pc != null) env.value += pc.getHennaStatWIT();
  718.         }
  719.     }
  720.  
  721.     static class FuncMaxHpAdd extends Func
  722.     {
  723.         static final FuncMaxHpAdd _fmha_instance = new FuncMaxHpAdd();
  724.  
  725.         static Func getInstance()
  726.         {
  727.             return _fmha_instance;
  728.         }
  729.  
  730.         private FuncMaxHpAdd()
  731.         {
  732.             super(Stats.MAX_HP, 0x10, null);
  733.         }
  734.  
  735.         @Override
  736.         public void calc(Env env)
  737.         {
  738.             L2PcTemplate t = (L2PcTemplate) env.player.getTemplate();
  739.             int lvl = env.player.getLevel() - t.classBaseLevel;
  740.             double hpmod = t.lvlHpMod * lvl;
  741.             double hpmax = (t.lvlHpAdd + hpmod) * lvl;
  742.             double hpmin = (t.lvlHpAdd * lvl) + hpmod;
  743.             env.value += (hpmax + hpmin) / 2;
  744.         }
  745.     }
  746.  
  747.     static class FuncMaxHpMul extends Func
  748.     {
  749.         static final FuncMaxHpMul _fmhm_instance = new FuncMaxHpMul();
  750.  
  751.         static Func getInstance()
  752.         {
  753.             return _fmhm_instance;
  754.         }
  755.  
  756.         private FuncMaxHpMul()
  757.         {
  758.             super(Stats.MAX_HP, 0x20, null);
  759.         }
  760.  
  761.         @Override
  762.         public void calc(Env env)
  763.         {
  764.             env.value *= BaseStats.CON.calcBonus(env.player);
  765.         }
  766.     }
  767.  
  768.     static class FuncMaxCpAdd extends Func
  769.     {
  770.         static final FuncMaxCpAdd _fmca_instance = new FuncMaxCpAdd();
  771.  
  772.         static Func getInstance()
  773.         {
  774.             return _fmca_instance;
  775.         }
  776.  
  777.         private FuncMaxCpAdd()
  778.         {
  779.             super(Stats.MAX_CP, 0x10, null);
  780.         }
  781.  
  782.         @Override
  783.         public void calc(Env env)
  784.         {
  785.             L2PcTemplate t = (L2PcTemplate) env.player.getTemplate();
  786.             int lvl = env.player.getLevel() - t.classBaseLevel;
  787.             double cpmod = t.lvlCpMod * lvl;
  788.             double cpmax = (t.lvlCpAdd + cpmod) * lvl;
  789.             double cpmin = (t.lvlCpAdd * lvl) + cpmod;
  790.             env.value += (cpmax + cpmin) / 2;
  791.         }
  792.     }
  793.  
  794.     static class FuncMaxCpMul extends Func
  795.     {
  796.         static final FuncMaxCpMul _fmcm_instance = new FuncMaxCpMul();
  797.  
  798.         static Func getInstance()
  799.         {
  800.             return _fmcm_instance;
  801.         }
  802.  
  803.         private FuncMaxCpMul()
  804.         {
  805.             super(Stats.MAX_CP, 0x20, null);
  806.         }
  807.  
  808.         @Override
  809.         public void calc(Env env)
  810.         {
  811.             env.value *= BaseStats.CON.calcBonus(env.player);
  812.         }
  813.     }
  814.  
  815.     static class FuncMaxMpAdd extends Func
  816.     {
  817.         static final FuncMaxMpAdd _fmma_instance = new FuncMaxMpAdd();
  818.  
  819.         static Func getInstance()
  820.         {
  821.             return _fmma_instance;
  822.         }
  823.  
  824.         private FuncMaxMpAdd()
  825.         {
  826.             super(Stats.MAX_MP, 0x10, null);
  827.         }
  828.  
  829.         @Override
  830.         public void calc(Env env)
  831.         {
  832.             L2PcTemplate t = (L2PcTemplate) env.player.getTemplate();
  833.             int lvl = env.player.getLevel() - t.classBaseLevel;
  834.             double mpmod = t.lvlMpMod * lvl;
  835.             double mpmax = (t.lvlMpAdd + mpmod) * lvl;
  836.             double mpmin = (t.lvlMpAdd * lvl) + mpmod;
  837.             env.value += (mpmax + mpmin) / 2;
  838.         }
  839.     }
  840.  
  841.     static class FuncMaxMpMul extends Func
  842.     {
  843.         static final FuncMaxMpMul _fmmm_instance = new FuncMaxMpMul();
  844.  
  845.         static Func getInstance()
  846.         {
  847.             return _fmmm_instance;
  848.         }
  849.  
  850.         private FuncMaxMpMul()
  851.         {
  852.             super(Stats.MAX_MP, 0x20, null);
  853.         }
  854.  
  855.         @Override
  856.         public void calc(Env env)
  857.         {
  858.             env.value *= BaseStats.MEN.calcBonus(env.player);
  859.         }
  860.     }
  861.  
  862.     private static final Formulas _instance = new Formulas();
  863.  
  864.     public static Formulas getInstance()
  865.     {
  866.         return _instance;
  867.     }
  868.  
  869.     private Formulas()
  870.     {}
  871.  
  872.     /**
  873.      * @param cha
  874.      * @return the period between 2 regeneration task (3s for L2Character, 5 min for L2DoorInstance).
  875.      */
  876.     public static int getRegeneratePeriod(L2Character cha)
  877.     {
  878.         if(cha instanceof L2DoorInstance)
  879.             return HP_REGENERATE_PERIOD * 100; // 5 mins
  880.  
  881.         return HP_REGENERATE_PERIOD; // 3s
  882.     }
  883.  
  884.     /**
  885.      * <B><U> Concept</U> :</B><BR>
  886.      * <BR>
  887.      * A calculator is created to manage and dynamically calculate the effect of a character property (ex : MAX_HP,
  888.      * REGENERATE_HP_RATE...). In fact, each calculator is a table of Func object in which each Func represents a
  889.      * Mathematics function : <BR>
  890.      * <BR>
  891.      * FuncAtkAccuracy -> Math.sqrt(_player.getDEX())*6+_player.getLevel()<BR>
  892.      * <BR>
  893.      * To reduce cache memory use, L2NPCInstances who don't have skills share the same Calculator set called
  894.      * <B>NPC_STD_CALCULATOR</B>.<BR>
  895.      * <BR>
  896.      * @return the standard NPC Calculator set containing ACCURACY_COMBAT and EVASION_RATE.
  897.      */
  898.     public Calculator[] getStdNPCCalculators()
  899.     {
  900.         Calculator[] std = new Calculator[Stats.NUM_STATS];
  901.        
  902.         std[Stats.MAX_HP.ordinal()] = new Calculator();
  903.         std[Stats.MAX_HP.ordinal()].addFunc(FuncMaxHpMul.getInstance());
  904.        
  905.         std[Stats.MAX_MP.ordinal()] = new Calculator();
  906.         std[Stats.MAX_MP.ordinal()].addFunc(FuncMaxMpMul.getInstance());
  907.        
  908.         std[Stats.POWER_ATTACK.ordinal()] = new Calculator();
  909.         std[Stats.POWER_ATTACK.ordinal()].addFunc(FuncPAtkMod.getInstance());
  910.        
  911.         std[Stats.MAGIC_ATTACK.ordinal()] = new Calculator();
  912.         std[Stats.MAGIC_ATTACK.ordinal()].addFunc(FuncMAtkMod.getInstance());
  913.        
  914.         std[Stats.POWER_DEFENCE.ordinal()] = new Calculator();
  915.         std[Stats.POWER_DEFENCE.ordinal()].addFunc(FuncPDefMod.getInstance());
  916.        
  917.         std[Stats.MAGIC_DEFENCE.ordinal()] = new Calculator();
  918.         std[Stats.MAGIC_DEFENCE.ordinal()].addFunc(FuncMDefMod.getInstance());
  919.        
  920.         std[Stats.CRITICAL_RATE.ordinal()] = new Calculator();
  921.         std[Stats.CRITICAL_RATE.ordinal()].addFunc(FuncAtkCritical.getInstance());
  922.        
  923.         std[Stats.MCRITICAL_RATE.ordinal()] = new Calculator();
  924.         std[Stats.MCRITICAL_RATE.ordinal()].addFunc(FuncMAtkCritical.getInstance());
  925.        
  926.         std[Stats.ACCURACY_COMBAT.ordinal()] = new Calculator();
  927.         std[Stats.ACCURACY_COMBAT.ordinal()].addFunc(FuncAtkAccuracy.getInstance());
  928.        
  929.         std[Stats.EVASION_RATE.ordinal()] = new Calculator();
  930.         std[Stats.EVASION_RATE.ordinal()].addFunc(FuncAtkEvasion.getInstance());
  931.        
  932.         std[Stats.POWER_ATTACK_SPEED.ordinal()] = new Calculator();
  933.         std[Stats.POWER_ATTACK_SPEED.ordinal()].addFunc(FuncPAtkSpeed.getInstance());
  934.        
  935.         std[Stats.MAGIC_ATTACK_SPEED.ordinal()] = new Calculator();
  936.         std[Stats.MAGIC_ATTACK_SPEED.ordinal()].addFunc(FuncMAtkSpeed.getInstance());
  937.        
  938.         std[Stats.RUN_SPEED.ordinal()] = new Calculator();
  939.         std[Stats.RUN_SPEED.ordinal()].addFunc(FuncMoveSpeed.getInstance());
  940.        
  941.         return std;
  942.     }
  943.    
  944.     /* 
  945.         // Add the FuncAtkAccuracy to the Standard Calculator of ACCURACY_COMBAT
  946.         std[Stats.ACCURACY_COMBAT.ordinal()] = new Calculator();
  947.         std[Stats.ACCURACY_COMBAT.ordinal()].addFunc(FuncAtkAccuracy.getInstance());
  948.  
  949.         // Add the FuncAtkEvasion to the Standard Calculator of EVASION_RATE
  950.         std[Stats.EVASION_RATE.ordinal()] = new Calculator();
  951.         std[Stats.EVASION_RATE.ordinal()].addFunc(FuncAtkEvasion.getInstance());
  952.        
  953.         return std;
  954.     }
  955.     */
  956.  
  957.     /**
  958.      * Add basics Func objects to L2PcInstance and L2Summon.<BR>
  959.      * <BR>
  960.      * <B><U> Concept</U> :</B><BR>
  961.      * <BR>
  962.      * A calculator is created to manage and dynamically calculate the effect of a character property (ex : MAX_HP,
  963.      * REGENERATE_HP_RATE...). In fact, each calculator is a table of Func object in which each Func represents a
  964.      * mathematic function : <BR>
  965.      * <BR>
  966.      * FuncAtkAccuracy -> Math.sqrt(_player.getDEX())*6+_player.getLevel()<BR>
  967.      * <BR>
  968.      *
  969.      * @param cha L2PcInstance or L2Summon that must obtain basic Func objects
  970.      */
  971.     public void addFuncsToNewCharacter(L2Character cha)
  972.     {
  973.         if(cha instanceof L2PcInstance)
  974.         {
  975.             cha.addStatFunc(FuncMaxHpAdd.getInstance());
  976.             cha.addStatFunc(FuncMaxHpMul.getInstance());
  977.             cha.addStatFunc(FuncMaxCpAdd.getInstance());
  978.             cha.addStatFunc(FuncMaxCpMul.getInstance());
  979.             cha.addStatFunc(FuncMaxMpAdd.getInstance());
  980.             cha.addStatFunc(FuncMaxMpMul.getInstance());
  981.             //cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_HP_RATE));
  982.             //cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_CP_RATE));
  983.             //cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_MP_RATE));
  984.             cha.addStatFunc(FuncBowAtkRange.getInstance());
  985.             //cha.addStatFunc(FuncMultLevelMod.getInstance(Stats.POWER_ATTACK));
  986.             //cha.addStatFunc(FuncMultLevelMod.getInstance(Stats.POWER_DEFENCE));
  987.             //cha.addStatFunc(FuncMultLevelMod.getInstance(Stats.MAGIC_DEFENCE));
  988.             cha.addStatFunc(FuncPAtkMod.getInstance());
  989.             cha.addStatFunc(FuncMAtkMod.getInstance());
  990.             cha.addStatFunc(FuncPDefMod.getInstance());
  991.             cha.addStatFunc(FuncMDefMod.getInstance());
  992.             cha.addStatFunc(FuncAtkCritical.getInstance());
  993.             cha.addStatFunc(FuncMAtkCritical.getInstance());
  994.             cha.addStatFunc(FuncAtkAccuracy.getInstance());
  995.             cha.addStatFunc(FuncAtkEvasion.getInstance());
  996.             cha.addStatFunc(FuncPAtkSpeed.getInstance());
  997.             cha.addStatFunc(FuncMAtkSpeed.getInstance());
  998.             cha.addStatFunc(FuncMoveSpeed.getInstance());
  999.  
  1000.             cha.addStatFunc(FuncHennaSTR.getInstance());
  1001.             cha.addStatFunc(FuncHennaDEX.getInstance());
  1002.             cha.addStatFunc(FuncHennaINT.getInstance());
  1003.             cha.addStatFunc(FuncHennaMEN.getInstance());
  1004.             cha.addStatFunc(FuncHennaCON.getInstance());
  1005.             cha.addStatFunc(FuncHennaWIT.getInstance());
  1006.         }
  1007.         else if(cha instanceof L2PetInstance)
  1008.         {
  1009.             cha.addStatFunc(FuncPAtkMod.getInstance());
  1010.             //cha.addStatFunc(FuncMAtkMod.getInstance());
  1011.             //cha.addStatFunc(FuncPDefMod.getInstance());
  1012.             cha.addStatFunc(FuncMDefMod.getInstance());
  1013.             cha.addStatFunc(FuncAtkCritical.getInstance());
  1014.             cha.addStatFunc(FuncMAtkCritical.getInstance());
  1015.             cha.addStatFunc(FuncAtkAccuracy.getInstance());
  1016.             cha.addStatFunc(FuncAtkEvasion.getInstance());
  1017.             cha.addStatFunc(FuncMoveSpeed.getInstance());
  1018.             cha.addStatFunc(FuncPAtkSpeed.getInstance());
  1019.             cha.addStatFunc(FuncMAtkSpeed.getInstance());
  1020.         }
  1021.         else if(cha instanceof L2Summon)
  1022.         {
  1023.             //cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_HP_RATE));
  1024.             //cha.addStatFunc(FuncMultRegenResting.getInstance(Stats.REGENERATE_MP_RATE));
  1025.             cha.addStatFunc(FuncAtkCritical.getInstance());
  1026.             cha.addStatFunc(FuncMAtkCritical.getInstance());
  1027.             cha.addStatFunc(FuncAtkAccuracy.getInstance());
  1028.             cha.addStatFunc(FuncAtkEvasion.getInstance());
  1029.             cha.addStatFunc(FuncMoveSpeed.getInstance());
  1030.         }
  1031.     }
  1032.  
  1033.     /**
  1034.      * Calculate the HP regen rate (base + modifiers).<BR>
  1035.      * <BR>
  1036.      * @param cha
  1037.      * @return
  1038.      */
  1039.     public final static double calcHpRegen(L2Character cha)
  1040.     {
  1041.         double init = cha.getTemplate().baseHpReg;
  1042.         double hpRegenMultiplier = cha.isRaid() ? Config.RAID_HP_REGEN_MULTIPLIER : Config.HP_REGEN_MULTIPLIER;
  1043.         double hpRegenBonus = 0;
  1044.  
  1045.         if(Config.L2JMOD_CHAMPION_ENABLE && cha.isChampion())
  1046.         {
  1047.             hpRegenMultiplier *= Config.L2JMOD_CHAMPION_HP_REGEN;
  1048.         }
  1049.  
  1050.         if(cha instanceof L2PcInstance)
  1051.         {
  1052.             L2PcInstance player = (L2PcInstance) cha;
  1053.  
  1054.             // Calculate correct baseHpReg value for certain level of PC
  1055.             init += (player.getLevel() > 10) ? ((player.getLevel() - 1) / 10.0) : 0.5;
  1056.            
  1057.             // SevenSigns Festival modifier
  1058.             if(SevenSignsFestival.getInstance().isFestivalInProgress() && player.isFestivalParticipant())
  1059.             {
  1060.                 hpRegenMultiplier *= Formulas.calcFestivalRegenModifier(player);
  1061.             }
  1062.             else
  1063.             {
  1064.                 double siegeModifier = Formulas.calcSiegeRegenModifer(player);
  1065.                 if(siegeModifier > 0)
  1066.                 {
  1067.                     hpRegenMultiplier *= siegeModifier;
  1068.                 }
  1069.             }
  1070.  
  1071.             if(player.isInsideZone(L2Character.ZONE_CLANHALL) && player.getClan() != null)
  1072.             {
  1073.                 int clanHallIndex = player.getClan().getHasHideout();
  1074.                 if(clanHallIndex > 0)
  1075.                 {
  1076.                     ClanHall clansHall = ClanHallManager.getInstance().getClanHallById(clanHallIndex);
  1077.                     if(clansHall != null)
  1078.                         if(clansHall.getFunction(ClanHall.FUNC_RESTORE_HP) != null)
  1079.                         {
  1080.                             hpRegenMultiplier *= 1 + clansHall.getFunction(ClanHall.FUNC_RESTORE_HP).getLvl() / 100;
  1081.                         }
  1082.                 }
  1083.             }
  1084.  
  1085.             // Mother Tree effect is calculated at last
  1086.             if(player.isInsideZone(L2Character.ZONE_MOTHERTREE))
  1087.             {
  1088.                 hpRegenBonus += 2;
  1089.             }
  1090.  
  1091.             // Calculate Movement bonus
  1092.             if(player.isSitting())
  1093.             {
  1094.                 hpRegenMultiplier *= 1.5; // Sitting
  1095.             }
  1096.             else if(!player.isMoving())
  1097.             {
  1098.                 hpRegenMultiplier *= 1.1; // Staying
  1099.             }
  1100.             else if(player.isRunning())
  1101.             {
  1102.                 hpRegenMultiplier *= 0.7; // Running
  1103.             }
  1104.  
  1105.             // Add CON bonus
  1106.             //init *= cha.getLevelMod() * CONbonus[cha.getCON()];
  1107.             init *= cha.getLevelMod() * BaseStats.CON.calcBonus(cha);
  1108.         }
  1109.  
  1110.         if(init < 1)
  1111.         {
  1112.             init = 1;
  1113.         }
  1114.  
  1115.         return cha.calcStat(Stats.REGENERATE_HP_RATE, init, null, null) * hpRegenMultiplier + hpRegenBonus;
  1116.     }
  1117.  
  1118.     /**
  1119.      * Calculate the MP regen rate (base + modifiers).<BR>
  1120.      * <BR>
  1121.      * @param cha
  1122.      * @return
  1123.      */
  1124.     public final static double calcMpRegen(L2Character cha)
  1125.     {
  1126.         double init = cha.getTemplate().baseMpReg;
  1127.         double mpRegenMultiplier = cha.isRaid() ? Config.RAID_MP_REGEN_MULTIPLIER : Config.MP_REGEN_MULTIPLIER;
  1128.         double mpRegenBonus = 0;
  1129.  
  1130.         if(cha instanceof L2PcInstance)
  1131.         {
  1132.             L2PcInstance player = (L2PcInstance) cha;
  1133.  
  1134.             // Calculate correct baseMpReg value for certain level of PC
  1135.             init += 0.3 * ((player.getLevel() - 1) / 10.0);
  1136.            
  1137.             // SevenSigns Festival modifier
  1138.             if(SevenSignsFestival.getInstance().isFestivalInProgress() && player.isFestivalParticipant())
  1139.             {
  1140.                 mpRegenMultiplier *= calcFestivalRegenModifier(player);
  1141.             }
  1142.  
  1143.             // Mother Tree effect is calculated at last
  1144.             if(player.isInsideZone(L2Character.ZONE_MOTHERTREE))
  1145.             {
  1146.                 mpRegenBonus += 1;
  1147.             }
  1148.  
  1149.             if(player.isInsideZone(L2Character.ZONE_CLANHALL) && player.getClan() != null)
  1150.             {
  1151.                 int clanHallIndex = player.getClan().getHasHideout();
  1152.                 if(clanHallIndex > 0)
  1153.                 {
  1154.                     ClanHall clansHall = ClanHallManager.getInstance().getClanHallById(clanHallIndex);
  1155.                     if(clansHall != null)
  1156.                         if(clansHall.getFunction(ClanHall.FUNC_RESTORE_MP) != null)
  1157.                         {
  1158.                             mpRegenMultiplier *= 1 + clansHall.getFunction(ClanHall.FUNC_RESTORE_MP).getLvl() / 100;
  1159.                         }
  1160.                 }
  1161.             }
  1162.  
  1163.             // Calculate Movement bonus
  1164.             if(player.isSitting())
  1165.             {
  1166.                 mpRegenMultiplier *= 1.5; // Sitting
  1167.             }
  1168.             else if(!player.isMoving())
  1169.             {
  1170.                 mpRegenMultiplier *= 1.1; // Staying
  1171.             }
  1172.             else if(player.isRunning())
  1173.             {
  1174.                 mpRegenMultiplier *= 0.7; // Running
  1175.             }
  1176.  
  1177.             // Add MEN bonus
  1178.             init *= cha.getLevelMod() * BaseStats.MEN.calcBonus(cha);
  1179.         }
  1180.  
  1181.         if(init < 1)
  1182.         {
  1183.             init = 1;
  1184.         }
  1185.  
  1186.         return cha.calcStat(Stats.REGENERATE_MP_RATE, init, null, null) * mpRegenMultiplier + mpRegenBonus;
  1187.     }
  1188.  
  1189.     /**
  1190.      * Calculate the CP regen rate (base + modifiers).<BR>
  1191.      * <BR>
  1192.      * @param cha
  1193.      * @return
  1194.      */
  1195.     public final static double calcCpRegen(L2Character cha)
  1196.     {
  1197.         double init = cha.getTemplate().baseHpReg;
  1198.         double cpRegenMultiplier = Config.CP_REGEN_MULTIPLIER;
  1199.         double cpRegenBonus = 0;
  1200.  
  1201.         if(cha instanceof L2PcInstance)
  1202.         {
  1203.             L2PcInstance player = (L2PcInstance) cha;
  1204.  
  1205.             // Calculate correct baseHpReg value for certain level of PC
  1206.             init += player.getLevel() > 10 ? (player.getLevel() - 1) / 10.0 : 0.5;
  1207.  
  1208.             // Calculate Movement bonus
  1209.             if(player.isSitting())
  1210.             {
  1211.                 cpRegenMultiplier *= 1.5; // Sitting
  1212.             }
  1213.             else if(!player.isMoving())
  1214.             {
  1215.                 cpRegenMultiplier *= 1.1; // Staying
  1216.             }
  1217.             else if(player.isRunning())
  1218.             {
  1219.                 cpRegenMultiplier *= 0.7; // Running
  1220.             }
  1221.         }
  1222.         else
  1223.         {
  1224.             // Calculate Movement bonus
  1225.             if(!cha.isMoving())
  1226.             {
  1227.                 cpRegenMultiplier *= 1.1; // Staying
  1228.             }
  1229.             else if(cha.isRunning())
  1230.             {
  1231.                 cpRegenMultiplier *= 0.7; // Running
  1232.             }
  1233.         }
  1234.  
  1235.         // Apply CON bonus
  1236.         init *= cha.getLevelMod() * BaseStats.CON.calcBonus(cha);
  1237.         if (init < 1)
  1238.             init = 1;
  1239.        
  1240.         return cha.calcStat(Stats.REGENERATE_CP_RATE, init, null, null) * cpRegenMultiplier + cpRegenBonus;
  1241.     }
  1242.  
  1243.     @SuppressWarnings("deprecation")
  1244.     public final static double calcFestivalRegenModifier(L2PcInstance activeChar)
  1245.     {
  1246.         final int[] festivalInfo = SevenSignsFestival.getInstance().getFestivalForPlayer(activeChar);
  1247.         final int oracle = festivalInfo[0];
  1248.         final int festivalId = festivalInfo[1];
  1249.         int[] festivalCenter;
  1250.  
  1251.         // If the player isn't found in the festival, leave the regen rate as it is.
  1252.         if(festivalId < 0)
  1253.             return 0;
  1254.  
  1255.         // Retrieve the X and Y coords for the center of the festival arena the player is in.
  1256.         if(oracle == SevenSigns.CABAL_DAWN)
  1257.         {
  1258.             festivalCenter = SevenSignsFestival.FESTIVAL_DAWN_PLAYER_SPAWNS[festivalId];
  1259.         }
  1260.         else
  1261.         {
  1262.             festivalCenter = SevenSignsFestival.FESTIVAL_DUSK_PLAYER_SPAWNS[festivalId];
  1263.         }
  1264.  
  1265.         // Check the distance between the player and the player spawn point, in the center of the arena.
  1266.         double distToCenter = activeChar.getDistance(festivalCenter[0], festivalCenter[1]);
  1267.  
  1268.         if(Config.DEBUG)
  1269.         {
  1270.             _log.info("Distance: " + distToCenter + ", RegenMulti: " + distToCenter * 2.5 / 50);
  1271.         }
  1272.  
  1273.         return 1.0 - distToCenter * 0.0005; // Maximum Decreased Regen of ~ -65%;
  1274.     }
  1275.  
  1276.     public final static double calcSiegeRegenModifer(L2PcInstance activeChar)
  1277.     {
  1278.         if(activeChar == null || activeChar.getClan() == null)
  1279.             return 0;
  1280.  
  1281.         Siege siege = SiegeManager.getInstance().getSiege(activeChar.getPosition().getX(), activeChar.getPosition().getY(), activeChar.getPosition().getZ());
  1282.         if(siege == null || !siege.getIsInProgress())
  1283.             return 0;
  1284.  
  1285.         L2SiegeClan siegeClan = siege.getAttackerClan(activeChar.getClan().getClanId());
  1286.         if(siegeClan == null || siegeClan.getFlag().size() == 0 || !Util.checkIfInRange(200, activeChar, siegeClan.getFlag().get(0), true))
  1287.             return 0;
  1288.  
  1289.         return 1.5; // If all is true, then modifer will be 50% more
  1290.     }
  1291.  
  1292.     /**
  1293.      * Calculate blow damage based on cAtk
  1294.      * @param attacker
  1295.      * @param target
  1296.      * @param skill
  1297.      * @param shld
  1298.      * @param crit
  1299.      * @param ss
  1300.      * @return
  1301.      */
  1302.     public static double calcBlowDamage(L2Character attacker, L2Character target, L2Skill skill, boolean shld, boolean crit, boolean ss)
  1303.     {
  1304.         /*
  1305.          * wtf is this shit -Nefer
  1306.          *
  1307.         if((skill.getCondition() & L2Skill.COND_BEHIND) != 0 && !attacker.isBehind(target))
  1308.             return 0;
  1309.         */
  1310.        
  1311.         double damage = attacker.getPAtk(target);
  1312.         double defence = target.getPDef(attacker);
  1313.        
  1314.         if(ss)
  1315.         {
  1316.             damage *= 2.;
  1317.         }
  1318.        
  1319.         if(shld)
  1320.         {
  1321.             defence += target.getShldDef();
  1322.         }
  1323.        
  1324.         if(crit){
  1325.            
  1326.             //double cAtkMultiplied = (damage) + attacker.calcStat(Stats.CRITICAL_DAMAGE, damage, target, skill);
  1327.             double improvedDamageByCriticalVuln = target.calcStat(Stats.CRIT_VULN, damage, target, skill);
  1328.             double improvedDamageByCriticalVulnAndAdd =  (attacker.calcStat(Stats.CRITICAL_DAMAGE_ADD, improvedDamageByCriticalVuln, target, skill));
  1329.            
  1330.             if(Config.DEBUG){
  1331.                 System.out.println("Attacker '"+attacker.getName()+"' Dagger Critical Damage Debug:");
  1332.                 System.out.println("    -   Initial Damage:  "+damage);
  1333.                 System.out.println("    -   improvedDamageByCriticalVuln: "+improvedDamageByCriticalVuln);
  1334.                 System.out.println("    -   improvedDamageByCriticalVulnAndAdd: "+improvedDamageByCriticalVulnAndAdd);
  1335.             }
  1336.            
  1337.             damage = improvedDamageByCriticalVulnAndAdd;
  1338.            
  1339.             /*
  1340.             damage = attacker.calcStat(Stats.CRITICAL_DAMAGE, (damage+power), target, skill);
  1341.             damage += attacker.calcStat(Stats.CRITICAL_DAMAGE_ADD, 0, target, skill) * 6.5;
  1342.             damage *= target.calcStat(Stats.CRIT_VULN, target.getTemplate().baseCritVuln, target, skill);
  1343.             */
  1344.            
  1345.             L2Effect vicious = attacker.getFirstEffect(312);
  1346.             if (vicious != null && damage > 1)
  1347.             {
  1348.                 for (Func func : vicious.getStatFuncs())
  1349.                 {
  1350.                     Env env = new Env();
  1351.                     env.player = attacker;
  1352.                     env.target = target;
  1353.                     env.skill = skill;
  1354.                     env.value = damage;
  1355.                     func.calc(env);
  1356.                     damage = (int) env.value;
  1357.                 }
  1358.             }
  1359.            
  1360.         }
  1361.        
  1362.         //skill add is not influenced by criticals improvements,  so it's applied later
  1363.         double skillpower = skill.getPower(attacker);
  1364.         float ssboost = skill.getSSBoost();
  1365.         if(ssboost <= 0)
  1366.             damage += skillpower;
  1367.         else if(ssboost > 0)
  1368.         {
  1369.             if(ss)
  1370.             {
  1371.                 skillpower *= ssboost;
  1372.                 damage += skillpower;
  1373.             }
  1374.             else
  1375.                 damage += skillpower;
  1376.         }
  1377.  
  1378.         //possible skill power critical hit, based on Official Description:
  1379.         /* skill critical effects
  1380.          * (skill damage x2) have been added
  1381.          * */
  1382.         if(Formulas.calcCrit(skill.getBaseCritRate() * 10 * BaseStats.DEX.calcBonus(attacker)))
  1383.             damage*=2;
  1384.        
  1385.         damage *= 70. / defence;
  1386.        
  1387.         //finally, apply the critical multiplier if present (it's not subjected to defense)
  1388.         if(crit){
  1389.             damage = attacker.calcStat(Stats.CRITICAL_DAMAGE, damage, target, skill);
  1390.         }
  1391.        
  1392.         //Multiplier should be removed, it's false ??
  1393.         //damage += 1.5 * attacker.calcStat(Stats.CRITICAL_DAMAGE, damage + power, target, skill);
  1394.         //damage *= (double)attacker.getLevel()/target.getLevel();
  1395.  
  1396.         // get the vulnerability for the instance due to skills (buffs, passives, toggles, etc)
  1397.         damage = target.calcStat(Stats.DAGGER_WPN_VULN, damage, target, null);
  1398.         // get the natural vulnerability for the template
  1399.         if(target instanceof L2NpcInstance)
  1400.         {
  1401.             damage *= ((L2NpcInstance) target).getTemplate().getVulnerability(Stats.DAGGER_WPN_VULN);
  1402.         }
  1403.        
  1404.         // Weapon random damage
  1405.         damage *= attacker.getRandomDamageMultiplier();
  1406.        
  1407.         // After C4 nobles make 4% more dmg in PvP.
  1408.         if(attacker instanceof L2PcInstance && ((L2PcInstance) attacker).isNoble() && (target instanceof L2PcInstance || target instanceof L2Summon))
  1409.         {
  1410.             damage *= 1.04;
  1411.         }
  1412.  
  1413.         // Sami: Must be removed, after armor resistances are checked.
  1414.         // These values are a quick fix to balance dagger gameplay and give
  1415.         // armor resistances vs dagger. daggerWpnRes could also be used if a skill
  1416.         // was given to all classes. The values here try to be a compromise.
  1417.         // They were originally added in a late C4 rev (2289).
  1418.         if(target instanceof L2PcInstance)
  1419.         {
  1420.             L2Armor armor = ((L2PcInstance) target).getActiveChestArmorItem();
  1421.             if(armor != null)
  1422.             {
  1423.                 if(((L2PcInstance) target).isWearingHeavyArmor())
  1424.                 {
  1425.                     damage /= Config.ALT_DAGGER_DMG_VS_HEAVY;
  1426.                 }
  1427.                 if(((L2PcInstance) target).isWearingLightArmor())
  1428.                 {
  1429.                     damage /= Config.ALT_DAGGER_DMG_VS_LIGHT;
  1430.                 }
  1431.                 if(((L2PcInstance) target).isWearingMagicArmor())
  1432.                 {
  1433.                     damage /= Config.ALT_DAGGER_DMG_VS_ROBE;
  1434.                 }
  1435.             }
  1436.         }
  1437.        
  1438.         if(Config.ENABLE_CLASS_DAMAGES && attacker instanceof L2PcInstance && target instanceof L2PcInstance){
  1439.            
  1440.             if(((L2PcInstance) attacker).isInOlympiadMode() && ((L2PcInstance) target).isInOlympiadMode()){
  1441.                
  1442.                 if(Config.ENABLE_CLASS_DAMAGES_IN_OLY){
  1443.                     damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  1444.                 }
  1445.                
  1446.             }else{
  1447.                
  1448.                 damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  1449.            
  1450.             }
  1451.         }
  1452.        
  1453.         return damage < 1 ? 1. : damage;
  1454.     }
  1455.  
  1456.     /**
  1457.      * Calculated damage caused by ATTACK of attacker on target, called separatly for each weapon, if dual-weapon is
  1458.      * used.
  1459.      *
  1460.      * @param attacker player or NPC that makes ATTACK
  1461.      * @param target player or NPC, target of ATTACK
  1462.      * @param skill
  1463.      * @param shld
  1464.      * @param crit if the ATTACK have critical success
  1465.      * @param dual if dual weapon is used
  1466.      * @param ss if weapon item was charged by soulshot
  1467.      * @return damage points
  1468.      */
  1469.     public final static double calcPhysDam(L2Character attacker, L2Character target, L2Skill skill, boolean shld, boolean crit, boolean dual, boolean ss)
  1470.     {
  1471.         if(attacker instanceof L2PcInstance)
  1472.         {
  1473.             L2PcInstance pcInst = (L2PcInstance) attacker;
  1474.             if(pcInst.isGM() && !pcInst.getAccessLevel().canGiveDamage())
  1475.                 return 0;
  1476.         }
  1477.  
  1478.         double damage = attacker.getPAtk(target);
  1479.         double defence = target.getPDef(attacker);
  1480.         if(ss)
  1481.         {
  1482.             damage *= 2;
  1483.         }
  1484.  
  1485.         if(skill != null)
  1486.         {
  1487.             double skillpower = skill.getPower(attacker);
  1488.             float ssboost = skill.getSSBoost();
  1489.             if(ssboost <= 0)
  1490.             {
  1491.                 damage += skillpower;
  1492.             }
  1493.             else if(ssboost > 0)
  1494.             {
  1495.                 if(ss)
  1496.                 {
  1497.                     skillpower *= ssboost;
  1498.                     damage += skillpower;
  1499.                 }
  1500.                 else
  1501.                 {
  1502.                     damage += skillpower;
  1503.                 }
  1504.             }
  1505.         }
  1506.  
  1507.         // In C5 summons make 10 % less dmg in PvP.
  1508.         if(attacker instanceof L2Summon && target instanceof L2PcInstance)
  1509.         {
  1510.             damage *= 0.9;
  1511.         }
  1512.  
  1513.         // After C4 nobles make 4% more dmg in PvP.
  1514.         if(attacker instanceof L2PcInstance && ((L2PcInstance) attacker).isNoble() && (target instanceof L2PcInstance || target instanceof L2Summon))
  1515.         {
  1516.             damage *= 1.04;
  1517.         }
  1518.  
  1519.         // defence modifier depending of the attacker weapon
  1520.         L2Weapon weapon = attacker.getActiveWeaponItem();
  1521.         Stats stat = null;
  1522.         if(weapon != null)
  1523.         {
  1524.             switch(weapon.getItemType())
  1525.             {
  1526.                 case BOW:
  1527.                     stat = Stats.BOW_WPN_VULN;
  1528.                     break;
  1529.                 case BLUNT:
  1530.                     stat = Stats.BLUNT_WPN_VULN;
  1531.                     break;
  1532.                 case DAGGER:
  1533.                     stat = Stats.DAGGER_WPN_VULN;
  1534.                     break;
  1535.                 case DUAL:
  1536.                     stat = Stats.DUAL_WPN_VULN;
  1537.                     break;
  1538.                 case DUALFIST:
  1539.                     stat = Stats.DUALFIST_WPN_VULN;
  1540.                     break;
  1541.                 case ETC:
  1542.                     stat = Stats.ETC_WPN_VULN;
  1543.                     break;
  1544.                 case FIST:
  1545.                     stat = Stats.FIST_WPN_VULN;
  1546.                     break;
  1547.                 case POLE:
  1548.                     stat = Stats.POLE_WPN_VULN;
  1549.                     break;
  1550.                 case SWORD:
  1551.                     stat = Stats.SWORD_WPN_VULN;
  1552.                     break;
  1553.                 case BIGSWORD:
  1554.                     stat = Stats.BIGSWORD_WPN_VULN;
  1555.                     break;
  1556.                 case BIGBLUNT:
  1557.                     stat = Stats.BIGBLUNT_WPN_VULN;
  1558.                     break;
  1559.             }
  1560.         }
  1561.  
  1562.         if (crit)
  1563.         {
  1564.             //Finally retail like formula
  1565.             double cAtkMultiplied = damage + attacker.calcStat(Stats.CRITICAL_DAMAGE, damage, target, skill);
  1566.             double cAtkVuln = target.calcStat(Stats.CRIT_VULN, 1, target, null);
  1567.             double improvedDamageByCriticalMulAndVuln = cAtkMultiplied * cAtkVuln;
  1568.             double improvedDamageByCriticalMulAndAdd = improvedDamageByCriticalMulAndVuln + attacker.calcStat(Stats.CRITICAL_DAMAGE_ADD, 0, target, skill);
  1569.            
  1570.             if(Config.DEBUG){
  1571.                 System.out.println("Attacker '"+attacker.getName()+"' Critical Damage Debug:");
  1572.                 System.out.println("    -   Initial Damage:  "+damage);
  1573.                 System.out.println("    -   Damage increased of mult:  "+cAtkMultiplied);
  1574.                 System.out.println("    -   cAtkVuln Mult:  "+cAtkVuln);
  1575.                 System.out.println("    -   improvedDamageByCriticalMulAndVuln: "+improvedDamageByCriticalMulAndVuln);
  1576.                 System.out.println("    -   improvedDamageByCriticalMulAndAdd: "+improvedDamageByCriticalMulAndAdd);
  1577.             }
  1578.            
  1579.             damage = improvedDamageByCriticalMulAndAdd;
  1580.            
  1581.         }
  1582.        
  1583.         damage = 70 * damage / defence;
  1584.        
  1585.  
  1586.         if(shld && !Config.ALT_GAME_SHIELD_BLOCKS)
  1587.         {
  1588.             defence += target.getShldDef();
  1589.         }
  1590.  
  1591.        
  1592.         //damage = 70 * damage / defence;
  1593.  
  1594.         if(stat != null)
  1595.         {
  1596.             // get the vulnerability due to skills (buffs, passives, toggles, etc)
  1597.             damage = target.calcStat(stat, damage, target, null);
  1598.             if(target instanceof L2NpcInstance)
  1599.             {
  1600.                 // get the natural vulnerability for the template
  1601.                 damage *= ((L2NpcInstance) target).getTemplate().getVulnerability(stat);
  1602.             }
  1603.         }
  1604.        
  1605.  
  1606.         damage += Rnd.nextDouble() * damage / 10;
  1607.         //      damage += _rnd.nextDouble()* attacker.getRandomDamage(target);
  1608.         //      }
  1609.         if(shld && Config.ALT_GAME_SHIELD_BLOCKS)
  1610.         {
  1611.             damage -= target.getShldDef();
  1612.             if(damage < 0)
  1613.             {
  1614.                 damage = 0;
  1615.             }
  1616.         }
  1617.  
  1618.         if(target instanceof L2PcInstance && weapon != null && weapon.getItemType() == L2WeaponType.DAGGER && skill != null)
  1619.         {
  1620.             L2Armor armor = ((L2PcInstance) target).getActiveChestArmorItem();
  1621.             if(armor != null)
  1622.             {
  1623.                 if(((L2PcInstance) target).isWearingHeavyArmor())
  1624.                 {
  1625.                     damage /= Config.ALT_DAGGER_DMG_VS_HEAVY;
  1626.                 }
  1627.                 if(((L2PcInstance) target).isWearingLightArmor())
  1628.                 {
  1629.                     damage /= Config.ALT_DAGGER_DMG_VS_LIGHT;
  1630.                 }
  1631.                 if(((L2PcInstance) target).isWearingMagicArmor())
  1632.                 {
  1633.                     damage /= Config.ALT_DAGGER_DMG_VS_ROBE;
  1634.                 }
  1635.             }
  1636.         }
  1637.  
  1638.         if(attacker instanceof L2NpcInstance)
  1639.         {
  1640.             //Skill Race : Undead
  1641.             if(((L2NpcInstance) attacker).getTemplate().getRace() == L2NpcTemplate.Race.UNDEAD)
  1642.             {
  1643.                 damage /= attacker.getPDefUndead(target);
  1644.             }
  1645.  
  1646.             if(((L2NpcInstance) attacker).getTemplate().getRace() == L2NpcTemplate.Race.PLANT)
  1647.             {
  1648.                 damage /= attacker.getPDefPlants(target);
  1649.             }
  1650.  
  1651.             if(((L2NpcInstance) attacker).getTemplate().getRace() == L2NpcTemplate.Race.BUG)
  1652.             {
  1653.                 damage /= attacker.getPDefInsects(target);
  1654.             }
  1655.  
  1656.             if(((L2NpcInstance) attacker).getTemplate().getRace() == L2NpcTemplate.Race.ANIMAL)
  1657.             {
  1658.                 damage /= attacker.getPDefAnimals(target);
  1659.             }
  1660.  
  1661.             if(((L2NpcInstance) attacker).getTemplate().getRace() == L2NpcTemplate.Race.BEAST)
  1662.             {
  1663.                 damage /= attacker.getPDefMonsters(target);
  1664.             }
  1665.  
  1666.             if(((L2NpcInstance) attacker).getTemplate().getRace() == L2NpcTemplate.Race.DRAGON)
  1667.             {
  1668.                 damage /= attacker.getPDefDragons(target);
  1669.             }
  1670.         }
  1671.  
  1672.         if(target instanceof L2NpcInstance)
  1673.         {
  1674.             switch(((L2NpcInstance) target).getTemplate().getRace())
  1675.             {
  1676.                 case UNDEAD:
  1677.                     damage *= attacker.getPAtkUndead(target);
  1678.                     break;
  1679.                 case BEAST:
  1680.                     damage *= attacker.getPAtkMonsters(target);
  1681.                     break;
  1682.                 case ANIMAL:
  1683.                     damage *= attacker.getPAtkAnimals(target);
  1684.                     break;
  1685.                 case PLANT:
  1686.                     damage *= attacker.getPAtkPlants(target);
  1687.                     break;
  1688.                 case DRAGON:
  1689.                     damage *= attacker.getPAtkDragons(target);
  1690.                     break;
  1691.                 case ANGEL:
  1692.                     damage *= attacker.getPAtkAngels(target);
  1693.                     break;
  1694.                 case BUG:
  1695.                     damage *= attacker.getPAtkInsects(target);
  1696.                     break;
  1697.                 default:
  1698.                     // nothing
  1699.                     break;
  1700.             }
  1701.         }
  1702.  
  1703.         if(shld)
  1704.         {
  1705.             if(100 - Config.ALT_PERFECT_SHLD_BLOCK < Rnd.get(100))
  1706.             {
  1707.                 damage = 1;
  1708.                 target.sendPacket(new SystemMessage(SystemMessageId.YOUR_EXCELLENT_SHIELD_DEFENSE_WAS_A_SUCCESS));
  1709.             }
  1710.         }
  1711.  
  1712.         if(damage > 0 && damage < 1)
  1713.         {
  1714.             damage = 1;
  1715.         }
  1716.         else if(damage < 0)
  1717.         {
  1718.             damage = 0;
  1719.         }
  1720.  
  1721.         // Dmg bonusses in PvP fight
  1722.         if((attacker instanceof L2PcInstance || attacker instanceof L2Summon) && (target instanceof L2PcInstance || target instanceof L2Summon))
  1723.         {
  1724.             if(skill == null)
  1725.             {
  1726.                 damage *= attacker.calcStat(Stats.PVP_PHYSICAL_DMG, 1, null, null);
  1727.             }
  1728.             else
  1729.             {
  1730.                 damage *= attacker.calcStat(Stats.PVP_PHYS_SKILL_DMG, 1, null, null);
  1731.             }
  1732.         }
  1733.  
  1734.         if(attacker instanceof L2PcInstance)
  1735.         {
  1736.             if(((L2PcInstance) attacker).getClassId().isMage())
  1737.             {
  1738.                 damage = damage * Config.ALT_MAGES_PHYSICAL_DAMAGE_MULTI;
  1739.             }
  1740.             else
  1741.             {
  1742.                 damage = damage * Config.ALT_FIGHTERS_PHYSICAL_DAMAGE_MULTI;
  1743.             }
  1744.         }
  1745.         else if(attacker instanceof L2Summon)
  1746.         {
  1747.             damage = damage * Config.ALT_PETS_PHYSICAL_DAMAGE_MULTI;
  1748.         }
  1749.         else if(attacker instanceof L2NpcInstance)
  1750.         {
  1751.             damage = damage * Config.ALT_NPC_PHYSICAL_DAMAGE_MULTI;
  1752.         }
  1753.  
  1754.         if(Config.ENABLE_CLASS_DAMAGES && attacker instanceof L2PcInstance && target instanceof L2PcInstance){
  1755.            
  1756.             if(((L2PcInstance) attacker).isInOlympiadMode() && ((L2PcInstance) target).isInOlympiadMode()){
  1757.                
  1758.                 if(Config.ENABLE_CLASS_DAMAGES_IN_OLY){
  1759.                     damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  1760.                 }
  1761.                
  1762.             }else{
  1763.                
  1764.                 damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  1765.            
  1766.             }
  1767.         }
  1768.  
  1769.         return damage;
  1770.     }
  1771.  
  1772.     public final static double calcMagicDam(L2Character attacker, L2Character target, L2Skill skill, boolean ss, boolean bss, boolean mcrit)
  1773.     {
  1774.         // Add Matk/Mdef Bonus
  1775.         int ssModifier = 1;
  1776.         // Add Bonus for Sps/SS
  1777.         if(attacker instanceof L2Summon && !(attacker instanceof L2PetInstance)){
  1778.            
  1779.             if (bss){
  1780.                 //((L2Summon)attacker).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  1781.                 ssModifier = 4;
  1782.             }else if(ss){
  1783.                 //((L2Summon)attacker).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  1784.                 ssModifier = 2;
  1785.             }
  1786.            
  1787.         }else{
  1788.             L2ItemInstance weapon = attacker.getActiveWeaponInstance();
  1789.             if(weapon!=null){
  1790.                 if (bss){
  1791.                     //weapon.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  1792.                     ssModifier = 4;
  1793.                 }else if (ss){
  1794.                     //weapon.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  1795.                     ssModifier = 2;
  1796.                 }
  1797.             }
  1798.         }
  1799.        
  1800.         if(attacker instanceof L2PcInstance)
  1801.         {
  1802.             L2PcInstance pcInst = (L2PcInstance) attacker;
  1803.             if(pcInst.isGM() && !pcInst.getAccessLevel().canGiveDamage())
  1804.                 return 0;
  1805.         }
  1806.  
  1807.         double mAtk = attacker.getMAtk(target, skill);
  1808.         double mDef = target.getMDef(attacker, skill);
  1809.        
  1810.         //apply ss bonus
  1811.         mAtk *= ssModifier;
  1812.        
  1813.         double damage = mAtk / mDef * skill.getPower(attacker) * calcSkillVulnerability(target, skill);
  1814.  
  1815.         // In C5 summons make 10 % less dmg in PvP.
  1816.         if(attacker instanceof L2Summon && target instanceof L2PcInstance)
  1817.         {
  1818.             damage *= 0.9;
  1819.         }
  1820.  
  1821.         // After C4 nobles make 4% more dmg in PvP.
  1822.         if(attacker instanceof L2PcInstance && ((L2PcInstance) attacker).isNoble() && (target instanceof L2PcInstance || target instanceof L2Summon))
  1823.         {
  1824.             damage *= 1.04;
  1825.         }
  1826.  
  1827.         // Failure calculation
  1828.         if(Config.ALT_GAME_MAGICFAILURES && !calcMagicSuccess(attacker, target, skill))
  1829.         {
  1830.             if(attacker instanceof L2PcInstance)
  1831.             {
  1832.                 if(calcMagicSuccess(attacker, target, skill) && target.getLevel() - attacker.getLevel() <= 9)
  1833.                 {
  1834.                     if(skill.getSkillType() == SkillType.DRAIN)
  1835.                     {
  1836.                         attacker.sendPacket(new SystemMessage(SystemMessageId.DRAIN_HALF_SUCCESFUL));
  1837.                     }
  1838.                     else
  1839.                     {
  1840.                         attacker.sendPacket(new SystemMessage(SystemMessageId.ATTACK_FAILED));
  1841.                     }
  1842.  
  1843.                     damage /= 2;
  1844.                 }
  1845.                 else
  1846.                 {
  1847.                     SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  1848.                     sm.addString(target.getName());
  1849.                     sm.addSkillName(skill.getId());
  1850.                     attacker.sendPacket(sm);
  1851.  
  1852.                     damage = 1;
  1853.                 }
  1854.             }
  1855.  
  1856.             if(target instanceof L2PcInstance)
  1857.             {
  1858.                 if(skill.getSkillType() == SkillType.DRAIN)
  1859.                 {
  1860.                     SystemMessage sm = new SystemMessage(SystemMessageId.RESISTED_S1_DRAIN);
  1861.                     sm.addString(attacker.getName());
  1862.                     target.sendPacket(sm);
  1863.                 }
  1864.                 else
  1865.                 {
  1866.                     SystemMessage sm = new SystemMessage(SystemMessageId.RESISTED_S1_MAGIC);
  1867.                     sm.addString(attacker.getName());
  1868.                     target.sendPacket(sm);
  1869.                 }
  1870.             }
  1871.         }
  1872.         else if(mcrit)
  1873.         {
  1874.             //damage *= 4;
  1875.             damage *= Config.MAGIC_CRITICAL_POWER;
  1876.         }
  1877.  
  1878.         // Pvp bonusses for dmg
  1879.         if((attacker instanceof L2PcInstance || attacker instanceof L2Summon) && (target instanceof L2PcInstance || target instanceof L2Summon))
  1880.         {
  1881.             if(skill.isMagic())
  1882.             {
  1883.                 damage *= attacker.calcStat(Stats.PVP_MAGICAL_DMG, 1, null, null);
  1884.             }
  1885.             else
  1886.             {
  1887.                 damage *= attacker.calcStat(Stats.PVP_PHYS_SKILL_DMG, 1, null, null);
  1888.             }
  1889.         }
  1890.  
  1891.         if(attacker instanceof L2PcInstance)
  1892.         {
  1893.             if(((L2PcInstance) attacker).getClassId().isMage())
  1894.             {
  1895.                 damage = damage * Config.ALT_MAGES_MAGICAL_DAMAGE_MULTI;
  1896.             }
  1897.             else
  1898.             {
  1899.                 damage = damage * Config.ALT_FIGHTERS_MAGICAL_DAMAGE_MULTI;
  1900.             }
  1901.         }
  1902.         else if(attacker instanceof L2Summon)
  1903.         {
  1904.             damage = damage * Config.ALT_PETS_MAGICAL_DAMAGE_MULTI;
  1905.         }
  1906.         else if(attacker instanceof L2NpcInstance)
  1907.         {
  1908.             damage = damage * Config.ALT_NPC_MAGICAL_DAMAGE_MULTI;
  1909.         }
  1910.  
  1911.         if(target instanceof L2PlayableInstance)
  1912.         {
  1913.             damage *= skill.getPvpMulti();
  1914.         }
  1915.  
  1916.         if(skill.getSkillType() == SkillType.DEATHLINK)
  1917.         {
  1918.             damage = damage * (1.0 - attacker.getStatus().getCurrentHp() / attacker.getMaxHp()) * 2.0;
  1919.         }
  1920.  
  1921.         if(Config.ENABLE_CLASS_DAMAGES && attacker instanceof L2PcInstance && target instanceof L2PcInstance){
  1922.            
  1923.             if(((L2PcInstance) attacker).isInOlympiadMode() && ((L2PcInstance) target).isInOlympiadMode()){
  1924.                
  1925.                 if(Config.ENABLE_CLASS_DAMAGES_IN_OLY){
  1926.                     damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  1927.                 }
  1928.                
  1929.             }else{
  1930.                
  1931.                 damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  1932.            
  1933.             }
  1934.         }
  1935.        
  1936.         return damage;
  1937.     }
  1938.    
  1939.  
  1940.     public static final double calcMagicDam(L2CubicInstance attacker, L2Character target, L2Skill skill, boolean mcrit)
  1941.     {
  1942.         double damage = calcMagicDam(attacker.getOwner(), target, skill, false, false , mcrit);
  1943.         return damage;
  1944.     }
  1945.  
  1946.     /**
  1947.      * @param rate
  1948.      * @return true in case of critical hit
  1949.      */
  1950.     public final static boolean calcCrit(double rate)
  1951.     {
  1952.         return rate > Rnd.get(1000);
  1953.     }
  1954.  
  1955.     /**
  1956.      * Calcul value of blow success
  1957.      * @param activeChar
  1958.      * @param target
  1959.      * @param chance
  1960.      * @return
  1961.      */
  1962.     public final boolean calcBlow(L2Character activeChar, L2Character target, int chance)
  1963.     {
  1964.         return activeChar.calcStat(Stats.BLOW_RATE, chance * (1.0 + (activeChar.getDEX() - 20) / 100), target, null) > Rnd.get(100);
  1965.     }
  1966.  
  1967.     /**
  1968.      * Calcul value of lethal chance
  1969.      * @param activeChar
  1970.      * @param target
  1971.      * @param baseLethal
  1972.      * @return
  1973.      */
  1974.     public final static double calcLethal(L2Character activeChar, L2Character target, int baseLethal)
  1975.     {
  1976.         return activeChar.calcStat(Stats.LETHAL_RATE, (baseLethal * (double) activeChar.getLevel() / target.getLevel()), target, null);
  1977.     }
  1978.    
  1979.     public static final boolean calcLethalHit(L2Character activeChar, L2Character target, L2Skill skill)
  1980.     {
  1981.         if((target.isRaid() && Config.ALLOW_RAID_LETHAL) || (!target.isRaid() && !(target instanceof L2DoorInstance) && !(Config.ALLOW_LETHAL_PROTECTION_MOBS && target instanceof L2NpcInstance && (Config.LIST_LETHAL_PROTECTED_MOBS.contains(((L2NpcInstance) target).getNpcId())))))
  1982.            
  1983.         if ((!target.isRaid() || Config.ALLOW_RAID_LETHAL)
  1984.                 && !(target instanceof L2DoorInstance)
  1985.                 && !(target instanceof L2NpcInstance && ((L2NpcInstance) target).getNpcId() == 35062)
  1986.                 && !(Config.ALLOW_LETHAL_PROTECTION_MOBS && target instanceof L2NpcInstance && (Config.LIST_LETHAL_PROTECTED_MOBS.contains(((L2NpcInstance) target).getNpcId()))))
  1987.         {
  1988.             //activeChar.sendMessage(Double.toString(chance));
  1989.             //activeChar.sendMessage(Double.toString(calcLethal(activeChar, target, skill.getLethalChance2(),skill.getMagicLevel())));
  1990.             //activeChar.sendMessage(Double.toString(calcLethal(activeChar, target, skill.getLethalChance1(),skill.getMagicLevel())));
  1991.            
  1992.             // 2nd lethal effect activate (cp,hp to 1 or if target is npc then hp to 1)
  1993.             if (skill.getLethalChance2() > 0 && Rnd.get(1000) < calcLethal(activeChar, target, skill.getLethalChance2()))
  1994.             {
  1995.                 if (target instanceof L2NpcInstance)
  1996.                     target.reduceCurrentHp(target.getCurrentHp() - 1, activeChar);
  1997.                 else if (target instanceof L2PcInstance) // If is a active player set his HP and CP to 1
  1998.                 {
  1999.                     L2PcInstance player = (L2PcInstance) target;
  2000.                     if (!player.isInvul())
  2001.                     {
  2002.                         if (!(activeChar instanceof L2PcInstance &&
  2003.                                 (((L2PcInstance)activeChar).isGM() && !((L2PcInstance)activeChar).getAccessLevel().canGiveDamage())))
  2004.                         {
  2005.                             player.setCurrentHp(1);
  2006.                             player.setCurrentCp(1);
  2007.                             player.sendPacket(new SystemMessage(SystemMessageId.LETHAL_STRIKE_SUCCESSFUL));
  2008.                         }
  2009.                     }
  2010.                 }
  2011.                 activeChar.sendPacket(new SystemMessage(SystemMessageId.LETHAL_STRIKE));
  2012.             }
  2013.             else if (skill.getLethalChance1() > 0 && Rnd.get(1000) < calcLethal(activeChar, target, skill.getLethalChance1()))
  2014.             {
  2015.                 if (target instanceof L2PcInstance)
  2016.                 {
  2017.                     L2PcInstance player = (L2PcInstance) target;
  2018.                     if (!player.isInvul())
  2019.                     {
  2020.                         if (!(activeChar instanceof L2PcInstance &&
  2021.                                 (((L2PcInstance)activeChar).isGM() && !((L2PcInstance)activeChar).getAccessLevel().canGiveDamage())))
  2022.                         {
  2023.                             player.setCurrentCp(1); // Set CP to 1
  2024.                             player.sendPacket(SystemMessage.sendString("Combat points disappear when hit with a half kill skill"));
  2025.                         }
  2026.                     }
  2027.                 }
  2028.                 //TODO: remove half kill since SYSMsg got changed.
  2029.                 /*else if (target instanceof L2Npc) // If is a monster remove first damage and after 50% of current hp
  2030.                     target.reduceCurrentHp(target.getCurrentHp() / 2, activeChar, skill);*/
  2031.                
  2032.             }
  2033.             else
  2034.                 return false;
  2035.         }
  2036.         else
  2037.             return false;
  2038.        
  2039.         return true;
  2040.     }
  2041.  
  2042.     public final static boolean calcMCrit(double mRate)
  2043.     {
  2044.         return mRate > Rnd.get(1000);
  2045.     }
  2046.  
  2047.     /**
  2048.      * @param target
  2049.      * @param dmg
  2050.      * @return true in case when ATTACK is canceled due to hit
  2051.      */
  2052.     public final static boolean calcAtkBreak(L2Character target, double dmg)
  2053.     {
  2054.         if(target instanceof L2PcInstance)
  2055.         {
  2056.             if(((L2PcInstance) target).getForceBuff() != null)
  2057.                 return true;
  2058.  
  2059.             //          if (target.isCastingNow()&& target.getLastSkillCast() != null)
  2060.             //              if (target.getLastSkillCast().isCancelIfHit())
  2061.             //                  return true;
  2062.         }
  2063.         double init = 0;
  2064.  
  2065.         if(Config.ALT_GAME_CANCEL_CAST && target.isCastingNow())
  2066.         {
  2067.             init = 15;
  2068.         }
  2069.  
  2070.         if(Config.ALT_GAME_CANCEL_BOW && target.isAttackingNow())
  2071.         {
  2072.             L2Weapon wpn = target.getActiveWeaponItem();
  2073.             if(wpn != null && wpn.getItemType() == L2WeaponType.BOW)
  2074.             {
  2075.                 init = 15;
  2076.             }
  2077.         }
  2078.  
  2079.         if(target.isRaid() || target.isInvul() || init <= 0)
  2080.             return false; // No attack break
  2081.  
  2082.         // Chance of break is higher with higher dmg
  2083.         init += Math.sqrt(13 * dmg);
  2084.  
  2085.         // Chance is affected by target MEN
  2086.         init -= (BaseStats.MEN.calcBonus(target) * 100 - 100);
  2087.        
  2088.         // Calculate all modifiers for ATTACK_CANCEL
  2089.         double rate = target.calcStat(Stats.ATTACK_CANCEL, init, null, null);
  2090.  
  2091.         // Adjust the rate to be between 1 and 99
  2092.         if(rate > 99)
  2093.         {
  2094.             rate = 99;
  2095.         }
  2096.         else if(rate < 1)
  2097.         {
  2098.             rate = 1;
  2099.         }
  2100.  
  2101.         return Rnd.get(100) < rate;
  2102.     }
  2103.  
  2104.     /**
  2105.      * Calculate delay (in milliseconds) before next ATTACK
  2106.      * @param attacker
  2107.      * @param target
  2108.      * @param rate
  2109.      * @return
  2110.      */
  2111.     public final int calcPAtkSpd(L2Character attacker, L2Character target, double rate)
  2112.     {
  2113.         // measured Oct 2006 by Tank6585, formula by Sami
  2114.         // attack speed 312 equals 1500 ms delay... (or 300 + 40 ms delay?)
  2115.         if(rate < 2)
  2116.             return 2700;
  2117.         return (int) (470000 / rate);
  2118.     }
  2119.  
  2120.     /**
  2121.      * Calculate delay (in milliseconds) for skills cast
  2122.      * @param attacker
  2123.      * @param target
  2124.      * @param skill
  2125.      * @param skillTime
  2126.      * @return
  2127.      */
  2128.     public final int calcMAtkSpd(L2Character attacker, L2Character target, L2Skill skill, double skillTime)
  2129.     {
  2130.         if(skill.isMagic())
  2131.             return (int) (skillTime * 333 / attacker.getMAtkSpd());
  2132.         return (int) (skillTime * 333 / attacker.getPAtkSpd());
  2133.     }
  2134.  
  2135.     /**
  2136.      * Calculate delay (in milliseconds) for skills cast
  2137.      * @param attacker
  2138.      * @param skill
  2139.      * @param skillTime
  2140.      * @return
  2141.      */
  2142.     public final int calcMAtkSpd(L2Character attacker, L2Skill skill, double skillTime)
  2143.     {
  2144.         if(skill.isMagic())
  2145.             return (int) (skillTime * 333 / attacker.getMAtkSpd());
  2146.         return (int) (skillTime * 333 / attacker.getPAtkSpd());
  2147.     }
  2148.  
  2149.     /**
  2150.      * @param attacker
  2151.      * @param target
  2152.      * @return true if hit missed (taget evaded)
  2153.      */
  2154.     public static boolean calcHitMiss(L2Character attacker, L2Character target)
  2155.     {
  2156.         /*
  2157.         // OLD FORMULA
  2158.         // accuracy+dexterity => probability to hit in percents
  2159.         int acc_attacker;
  2160.         int evas_target;
  2161.         acc_attacker = attacker.getAccuracy();
  2162.         evas_target = target.getEvasionRate(attacker);
  2163.         int d = 85 + acc_attacker - evas_target;
  2164.         return d < Rnd.get(100);
  2165.         */
  2166.        
  2167.         int chance = (80 + (2 * (attacker.getAccuracy() - target.getEvasionRate(attacker))))*10;       
  2168.         // Get additional bonus from the conditions when you are attacking
  2169.         chance *= hitConditionBonus.getConditionBonus(attacker, target);
  2170.        
  2171.         chance = Math.max(chance, 200);
  2172.         chance = Math.min(chance, 980);
  2173.        
  2174.         return chance < Rnd.get(1000);
  2175.     }
  2176.  
  2177.     /**
  2178.      * @param attacker
  2179.      * @param target
  2180.      * @return true if shield defence successfull
  2181.      */
  2182.     public static boolean calcShldUse(L2Character attacker, L2Character target)
  2183.     {
  2184.         L2Weapon at_weapon = attacker.getActiveWeaponItem();
  2185.         // double shldRate = target.calcStat(Stats.SHIELD_RATE, 0, attacker, null) * DEXbonus[target.getDEX()];
  2186.         double shldRate = target.calcStat(Stats.SHIELD_RATE, 0, attacker, null) * BaseStats.DEX.calcBonus(target);
  2187.         if (shldRate == 0.0)
  2188.             return false;
  2189.         // Check for passive skill Aegis (316) or Aegis Stance (318)
  2190.         // Like L2OFF you can't parry if your target is behind you
  2191.         if (target.getKnownSkill(316) == null && target.getFirstEffect(318) == null)
  2192.             if (target.isBehind(attacker) || !target.isFront(attacker) || !attacker.isFront(target))
  2193.                 return false;
  2194.         // if attacker use bow and target wear shield, shield block rate is multiplied by 1.3 (30%)
  2195.         if (at_weapon != null && at_weapon.getItemType() == L2WeaponType.BOW)
  2196.         {
  2197.             shldRate *= 1.3;
  2198.         }
  2199.         return shldRate > Rnd.get(100);
  2200.     }
  2201.  
  2202.     public boolean calcMagicAffected(L2Character actor, L2Character target, L2Skill skill)
  2203.     {
  2204.         // TODO: CHECK/FIX THIS FORMULA UP!!
  2205.         SkillType type = skill.getSkillType();
  2206.         double defence = 0;
  2207.         if(skill.isActive() && skill.isOffensive())
  2208.         {
  2209.             defence = target.getMDef(actor, skill);
  2210.         }
  2211.  
  2212.         double attack = 2 * actor.getMAtk(target, skill) * calcSkillVulnerability(target, skill);
  2213.         double d = (attack - defence) / (attack + defence);
  2214.         if(target.isRaid() && (type == SkillType.CONFUSION || type == SkillType.MUTE || type == SkillType.PARALYZE || type == SkillType.ROOT || type == SkillType.FEAR || type == SkillType.SLEEP || type == SkillType.STUN || type == SkillType.DEBUFF || type == SkillType.AGGDEBUFF))
  2215.         {
  2216.             if(d > 0 && Rnd.get(1000) == 1)
  2217.                 return true;
  2218.             return false;
  2219.         }
  2220.  
  2221.         if (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, null, skill) > 0 && skill.is_Debuff())
  2222.             return false;
  2223.        
  2224.         d += 0.5 * Rnd.nextGaussian();
  2225.         return d > 0;
  2226.     }
  2227.    
  2228.     public static double calcSkillVulnerability(L2Character target, L2Skill skill)
  2229.     {
  2230.         double multiplier = 1; // initialize...
  2231.  
  2232.         // Get the skill type to calculate its effect in function of base stats
  2233.         // of the L2Character target
  2234.         if(skill != null)
  2235.         {
  2236.             // first, get the natural template vulnerability values for the target
  2237.             Stats stat = skill.getStat();
  2238.             if(stat != null)
  2239.             {
  2240.                 switch(stat)
  2241.                 {
  2242.                     case AGGRESSION:
  2243.                         multiplier = target.getTemplate().baseAggressionVuln;
  2244.                         break;
  2245.                     case BLEED:
  2246.                         multiplier = target.getTemplate().baseBleedVuln;
  2247.                         break;
  2248.                     case POISON:
  2249.                         multiplier = target.getTemplate().basePoisonVuln;
  2250.                         break;
  2251.                     case STUN:
  2252.                         multiplier = target.getTemplate().baseStunVuln;
  2253.                         break;
  2254.                     case ROOT:
  2255.                         multiplier = target.getTemplate().baseRootVuln;
  2256.                         break;
  2257.                     case MOVEMENT:
  2258.                         multiplier = target.getTemplate().baseMovementVuln;
  2259.                         break;
  2260.                     case CONFUSION:
  2261.                         multiplier = target.getTemplate().baseConfusionVuln;
  2262.                         break;
  2263.                     case SLEEP:
  2264.                         multiplier = target.getTemplate().baseSleepVuln;
  2265.                         break;
  2266.                     case FIRE:
  2267.                         multiplier = target.getTemplate().baseFireVuln;
  2268.                         break;
  2269.                     case WIND:
  2270.                         multiplier = target.getTemplate().baseWindVuln;
  2271.                         break;
  2272.                     case WATER:
  2273.                         multiplier = target.getTemplate().baseWaterVuln;
  2274.                         break;
  2275.                     case EARTH:
  2276.                         multiplier = target.getTemplate().baseEarthVuln;
  2277.                         break;
  2278.                     case HOLY:
  2279.                         multiplier = target.getTemplate().baseHolyVuln;
  2280.                         break;
  2281.                     case DARK:
  2282.                         multiplier = target.getTemplate().baseDarkVuln;
  2283.                         break;
  2284.                     default:
  2285.                         multiplier = 1;
  2286.                 }
  2287.             }
  2288.  
  2289.             // Next, calculate the elemental vulnerabilities
  2290.             switch(skill.getElement())
  2291.             {
  2292.                 case L2Skill.ELEMENT_EARTH:
  2293.                     multiplier = target.calcStat(Stats.EARTH_VULN, multiplier, target, skill);
  2294.                     break;
  2295.                 case L2Skill.ELEMENT_FIRE:
  2296.                     multiplier = target.calcStat(Stats.FIRE_VULN, multiplier, target, skill);
  2297.                     break;
  2298.                 case L2Skill.ELEMENT_WATER:
  2299.                     multiplier = target.calcStat(Stats.WATER_VULN, multiplier, target, skill);
  2300.                     break;
  2301.                 case L2Skill.ELEMENT_WIND:
  2302.                     multiplier = target.calcStat(Stats.WIND_VULN, multiplier, target, skill);
  2303.                     break;
  2304.                 case L2Skill.ELEMENT_HOLY:
  2305.                     multiplier = target.calcStat(Stats.HOLY_VULN, multiplier, target, skill);
  2306.                     break;
  2307.                 case L2Skill.ELEMENT_DARK:
  2308.                     multiplier = target.calcStat(Stats.DARK_VULN, multiplier, target, skill);
  2309.                     break;
  2310.             }
  2311.  
  2312.             // Finally, calculate skilltype vulnerabilities
  2313.             SkillType type = skill.getSkillType();
  2314.  
  2315.             // For additional effects on PDAM and MDAM skills (like STUN, SHOCK, PARALYZE...)
  2316.             if(type != null && (type == SkillType.PDAM || type == SkillType.MDAM))
  2317.             {
  2318.                 type = skill.getEffectType();
  2319.             }
  2320.  
  2321.             if(type != null)
  2322.             {
  2323.                 switch(type)
  2324.                 {
  2325.                     case BLEED:
  2326.                         multiplier = target.calcStat(Stats.BLEED_VULN, multiplier, target, null);
  2327.                         break;
  2328.                     case POISON:
  2329.                         multiplier = target.calcStat(Stats.POISON_VULN, multiplier, target, null);
  2330.                         break;
  2331.                     case STUN:
  2332.                         multiplier = target.calcStat(Stats.STUN_VULN, multiplier, target, null);
  2333.                         break;
  2334.                     case PARALYZE:
  2335.                         multiplier = target.calcStat(Stats.PARALYZE_VULN, multiplier, target, null);
  2336.                         break;
  2337.                     case ROOT:
  2338.                         multiplier = target.calcStat(Stats.ROOT_VULN, multiplier, target, null);
  2339.                         break;
  2340.                     case SLEEP:
  2341.                         multiplier = target.calcStat(Stats.SLEEP_VULN, multiplier, target, null);
  2342.                         break;
  2343.                     case MUTE:
  2344.                     case FEAR:
  2345.                     case BETRAY:
  2346.                     case AGGREDUCE_CHAR:
  2347.                         multiplier = target.calcStat(Stats.DERANGEMENT_VULN, multiplier, target, null);
  2348.                         break;
  2349.                     case CONFUSION:
  2350.                         multiplier = target.calcStat(Stats.CONFUSION_VULN, multiplier, target, null);
  2351.                         break;
  2352.                     case DEBUFF:
  2353.                     case WEAKNESS:
  2354.                         multiplier = target.calcStat(Stats.DEBUFF_VULN, multiplier, target, null);
  2355.                         break;
  2356.                     case BUFF:
  2357.                         multiplier = target.calcStat(Stats.BUFF_VULN, multiplier, target, null);
  2358.                         break;
  2359.                 }
  2360.             }
  2361.  
  2362.         }
  2363.         return multiplier;
  2364.     }
  2365.  
  2366.     /*
  2367.     public double calcSkillStatModifier(SkillType type, L2Character target)
  2368.     {
  2369.         double multiplier = 1;
  2370.         if(type == null)
  2371.             return multiplier;
  2372.         switch(type)
  2373.         {
  2374.             case STUN:
  2375.             case BLEED:
  2376.                 multiplier = 2 - Math.sqrt(CONbonus[target.getCON()]);
  2377.                 break;
  2378.             case POISON:
  2379.             case SLEEP:
  2380.             case DEBUFF:
  2381.             case WEAKNESS:
  2382.             case ERASE:
  2383.             case ROOT:
  2384.             case MUTE:
  2385.             case FEAR:
  2386.             case BETRAY:
  2387.             case CONFUSION:
  2388.             case AGGREDUCE_CHAR:
  2389.             case PARALYZE:
  2390.                 multiplier = 2 - Math.sqrt(MENbonus[target.getMEN()]);
  2391.                 break;
  2392.             default:
  2393.                 return multiplier;
  2394.         }
  2395.         if(multiplier < 0)
  2396.         {
  2397.             multiplier = 0;
  2398.         }
  2399.         return multiplier;
  2400.     }
  2401.     */
  2402.    
  2403.    
  2404.     public static double calcSkillStatModifier(L2Skill skill, L2Character target)
  2405.     {
  2406.         final BaseStats saveVs = skill.getSavevs();
  2407.         if (saveVs == null)
  2408.             return 1;
  2409.        
  2410.         return 1 / saveVs.calcBonus(target);
  2411.     }
  2412.    
  2413.     public static boolean calcCubicSkillSuccess(final L2CubicInstance attacker, final L2Character target, L2Skill skill)
  2414.     {
  2415.         if(attacker == null){
  2416.             return false;
  2417.         }
  2418.        
  2419.         if (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, null, skill) > 0 && skill.is_Debuff())
  2420.             return false;
  2421.        
  2422.         SkillType type = skill.getSkillType();
  2423.        
  2424.         // these skills should not work on RaidBoss
  2425.         if (target.isRaid())
  2426.         {
  2427.             switch (type)
  2428.             {
  2429.                 case CONFUSION:
  2430.                 case ROOT:
  2431.                 case STUN:
  2432.                 case MUTE:
  2433.                 case FEAR:
  2434.                 case DEBUFF:
  2435.                 case PARALYZE:
  2436.                 case SLEEP:
  2437.                 case AGGDEBUFF:
  2438.                     return false;
  2439.             }
  2440.         }
  2441.        
  2442.         int value = (int) skill.getPower();
  2443.         double statModifier = calcSkillStatModifier(skill, target);
  2444.         int rate = (int) (value * statModifier);
  2445.        
  2446.         // Add Matk/Mdef Bonus
  2447.         double mAtkModifier = 0;
  2448.         if (skill.isMagic())
  2449.         {
  2450.             mAtkModifier = target.getMDef(attacker.getOwner(), skill);
  2451.            
  2452.             mAtkModifier = Math.pow(attacker.getMAtk() / mAtkModifier, 0.2);
  2453.            
  2454.             rate += (int) (mAtkModifier * 100) - 100;
  2455.         }
  2456.        
  2457.         // Resists
  2458.         double vulnModifier = calcSkillVulnerability(target, skill);
  2459.         double res = vulnModifier;
  2460.         double resMod = 1;
  2461.         if (res != 0)
  2462.         {
  2463.             if (res < 0)
  2464.             {
  2465.                 resMod = 1 - 0.075 * res;
  2466.                 resMod = 1 / resMod;
  2467.             }
  2468.             else{
  2469.                 double x_factor = 1.3;
  2470.                
  2471.                 if((resMod = res*x_factor)>1){
  2472.                     resMod = res;
  2473.                 }
  2474.                
  2475.             }
  2476.            
  2477.             if(resMod>0.9){
  2478.                 resMod = 0.9;
  2479.             }else if(resMod<0.5){
  2480.                 resMod = 0.5;
  2481.             }
  2482.            
  2483.             rate *= resMod;
  2484.         }
  2485.        
  2486.         //lvl modifier.
  2487.         int deltamod = calcLvlDependModifier(attacker.getOwner(), target, skill);
  2488.         rate += deltamod;
  2489.        
  2490.         if (rate > skill.getMaxChance())
  2491.             rate = skill.getMaxChance();
  2492.         else if (rate < skill.getMinChance())
  2493.             rate = skill.getMinChance();
  2494.        
  2495.         if (Config.SKILLSDEBUG)
  2496.         {
  2497.             final StringBuilder stat = new StringBuilder(100);
  2498.             StringUtil.append(stat,
  2499.                     skill.getName(),
  2500.                     " calcCubicSkillSuccess: ",
  2501.                     " type:", skill.getSkillType().toString(),
  2502.                     " power:", String.valueOf(value),
  2503.                     " stat:", String.format("%1.2f", statModifier),
  2504.                     " res:", String.format("%1.2f", resMod), "(",
  2505.                     String.format("%1.2f", vulnModifier),")",
  2506.                     " mAtk:", String.format("%1.2f", mAtkModifier),
  2507.                     " lvl:", String.valueOf(deltamod),
  2508.                     " total:", String.valueOf(rate)
  2509.             );
  2510.             final String result = stat.toString();
  2511.             _log.info(result);
  2512.         }
  2513.         return (Rnd.get(100) < rate);
  2514.     }
  2515.    
  2516.     public boolean calcSkillSuccess(final L2Character attacker, final L2Character target, L2Skill skill, boolean ss, boolean sps, boolean bss)
  2517.     {
  2518.         if(attacker == null){
  2519.             return false;
  2520.         }
  2521.        
  2522.         if (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, null, skill) > 0 && skill.is_Debuff())
  2523.             return false;
  2524.        
  2525.         // Add Matk/Mdef Bonus
  2526.         double mAtkModifier = 1;
  2527.         int ssModifier = 1;
  2528.         if (skill.isMagic())
  2529.         {
  2530.             mAtkModifier = target.getMDef(target, skill);
  2531.            
  2532.             if (bss){
  2533.                 ssModifier = 4;
  2534.             }else if(sps){
  2535.                 ssModifier = 2;
  2536.             }
  2537.             /*
  2538.             // Add Bonus for Sps/SS
  2539.             if(attacker instanceof L2Summon && !(attacker instanceof L2PetInstance)){
  2540.                
  2541.                 if (bss){
  2542.                     ((L2Summon)attacker).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  2543.                     ssModifier = 4;
  2544.                 }else if(sps){
  2545.                     ((L2Summon)attacker).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  2546.                     ssModifier = 2;
  2547.                 }
  2548.                
  2549.             }else{
  2550.                 L2ItemInstance weapon = attacker.getActiveWeaponInstance();
  2551.                 if(weapon!=null){
  2552.                     if (bss){
  2553.                         weapon.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  2554.                         ssModifier = 4;
  2555.                     }else if (sps){
  2556.                         weapon.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  2557.                         ssModifier = 2;
  2558.                     }
  2559.                 }
  2560.             }
  2561.             */
  2562.            
  2563.             mAtkModifier = 14 * Math.sqrt(ssModifier * attacker.getMAtk(target, skill)) / mAtkModifier;
  2564.            
  2565.            
  2566.         }/*else{
  2567.            
  2568.             L2ItemInstance weapon = attacker.getActiveWeaponInstance();
  2569.             if(weapon!=null){
  2570.                 if(ss){
  2571.                     weapon.setChargedSoulshot(L2ItemInstance.CHARGED_NONE);
  2572.                 }
  2573.             }
  2574.            
  2575.             //no soulshots influence over not magic attacks
  2576.         }*/
  2577.        
  2578.         SkillType type = skill.getSkillType();
  2579.  
  2580.         if(target.isRaid() && (type == SkillType.CONFUSION || type == SkillType.MUTE || type == SkillType.PARALYZE || type == SkillType.ROOT || type == SkillType.FEAR || type == SkillType.SLEEP || type == SkillType.STUN || type == SkillType.DEBUFF || type == SkillType.AGGDEBUFF))
  2581.             return false; // these skills should not work on RaidBoss
  2582.  
  2583.         if(target.isInvul() && (type == SkillType.CONFUSION || type == SkillType.MUTE || type == SkillType.PARALYZE || type == SkillType.ROOT || type == SkillType.FEAR || type == SkillType.SLEEP || type == SkillType.STUN || type == SkillType.DEBUFF || type == SkillType.CANCEL || type == SkillType.NEGATE || type == SkillType.WARRIOR_BANE || type == SkillType.MAGE_BANE))
  2584.             return false; // these skills should not work on Invulable persons
  2585.  
  2586.         int value = (int) skill.getPower();
  2587.         double statModifier = calcSkillStatModifier(skill, target);
  2588.        
  2589.         // Calculate BaseRate.
  2590.         int rate = (int) (value * statModifier);
  2591.        
  2592.         //matk modifier
  2593.         rate = (int) (rate * mAtkModifier);
  2594.        
  2595.         // Resists
  2596.         double vulnModifier = calcSkillVulnerability(target, skill);
  2597.        
  2598.         //double profModifier = calcSkillProficiency(skill, attacker, target);
  2599.         double res = vulnModifier/* + profModifier*/;
  2600.         double resMod = 1;
  2601.         if (res != 0)
  2602.         {
  2603.             if (res < 0)
  2604.             {
  2605.                 resMod = 1 - 0.075 * res;
  2606.                 resMod = 1 / resMod;
  2607.             }
  2608.             else{
  2609.                 double x_factor = 1.3;
  2610.                
  2611.                 if((resMod = res*x_factor)>1){
  2612.                     resMod = res;
  2613.                 }
  2614.                
  2615.             }
  2616.            
  2617.             if(resMod>0.9){
  2618.                 resMod = 0.9;
  2619.             }else if(resMod<0.5){
  2620.                 resMod = 0.5;
  2621.             }
  2622.            
  2623.             rate *= resMod;
  2624.         }
  2625.        
  2626.         //lvl modifier.
  2627.         int deltamod = calcLvlDependModifier(attacker, target, skill);
  2628.         rate += deltamod;
  2629.        
  2630.         if (rate > skill.getMaxChance())
  2631.             rate = skill.getMaxChance();
  2632.         else if (rate < skill.getMinChance())
  2633.             rate = skill.getMinChance();
  2634.        
  2635.         //physics configuration addons
  2636.         float physics_mult = getChanceMultiplier(skill);
  2637.         rate *= physics_mult;
  2638.        
  2639.         if(Config.SKILLSDEBUG)
  2640.         {
  2641.             final StringBuilder stat = new StringBuilder(100);
  2642.             StringUtil.append(stat,
  2643.                     " calcSkillSuccess: ",
  2644.                     skill.getName(),
  2645.                     " ID:", ""+skill.getId(),
  2646.                     " type:", skill.getSkillType().toString(),
  2647.                     " power:", String.valueOf(value),
  2648.                     " stat:", String.format("%1.2f", statModifier),
  2649.                     " res:", String.format("%1.2f", resMod), "(",
  2650.                     String.format("%1.2f", vulnModifier),
  2651.                     " mAtk:", String.format("%1.2f", mAtkModifier),
  2652.                     " ss:", String.valueOf(ssModifier),
  2653.                     " lvl:", String.valueOf(deltamod),
  2654.                     " physics configuration multiplier:", String.valueOf(physics_mult),
  2655.                     " total:", String.valueOf(rate)
  2656.             );
  2657.             final String result = stat.toString();
  2658.             if (Config.DEVELOPER)
  2659.                 _log.info(result);
  2660.            
  2661.         }
  2662.        
  2663.         if(attacker instanceof L2PcInstance && Config.SEND_SKILLS_CHANCE_TO_PLAYERS)
  2664.             ((L2PcInstance) attacker).sendMessage("Skill: "+skill.getName()+" Chance: " + rate + "%");
  2665.        
  2666.         return Rnd.get(100) < rate;
  2667.     }
  2668.    
  2669.     public static boolean calcEffectSuccess(final L2Character attacker, final L2Character target, EffectTemplate effect, L2Skill skill, boolean ss, boolean sps, boolean bss)
  2670.     {
  2671.         if(attacker == null){
  2672.             return false;
  2673.         }
  2674.        
  2675.         if (target.calcStat(Stats.DEBUFF_IMMUNITY, 0, null, skill) > 0 && skill.is_Debuff())
  2676.             return false;
  2677.        
  2678.         final SkillType type = effect.effectType;
  2679.         final int value = (int)effect.effectPower;
  2680.         if (type == null)
  2681.         {
  2682.             return Rnd.get(100) < value;
  2683.         }
  2684.         else if (type.equals(SkillType.CANCEL)) // CANCEL-type effects land always
  2685.             return true;
  2686.        
  2687.         double statModifier = calcSkillStatModifier(skill, target);
  2688.        
  2689.         // Calculate BaseRate.
  2690.         int rate = (int) (value * statModifier);
  2691.        
  2692.         // Add Matk/Mdef Bonus
  2693.         double mAtkModifier = 0;
  2694.         int ssModifier = 0;
  2695.         if (skill.isMagic())
  2696.         {
  2697.             mAtkModifier = target.getMDef(target, skill);
  2698.             //if (shld == SHIELD_DEFENSE_SUCCEED)
  2699.             //  mAtkModifier += target.getShldDef();
  2700.            
  2701.             // Add Bonus for Sps/SS
  2702.             if (bss)
  2703.                 ssModifier = 4;
  2704.             else if (sps)
  2705.                 ssModifier = 2;
  2706.             else
  2707.                 ssModifier = 1;
  2708.            
  2709.             mAtkModifier = 14 * Math.sqrt(ssModifier * attacker.getMAtk(target, skill)) / mAtkModifier;
  2710.            
  2711.             rate = (int) (rate * mAtkModifier);
  2712.         }
  2713.        
  2714.         // Resists
  2715.         double vulnModifier = calcSkillTypeVulnerability(1, target, type);
  2716.         //double profModifier = calcSkillTypeProficiency(0, attacker, target, type);
  2717.        
  2718.         double res = vulnModifier;
  2719.         double resMod = 1;
  2720.         if (res != 0)
  2721.         {
  2722.             if (res < 0)
  2723.             {
  2724.                 resMod = 1 - 0.075 * res;
  2725.                 resMod = 1 / resMod;
  2726.             }
  2727.             else{
  2728.                 double x_factor = 1.3;
  2729.                
  2730.                 if((resMod = res*x_factor)>1){
  2731.                     resMod = res;
  2732.                 }
  2733.                
  2734.             }
  2735.            
  2736.             if(resMod>0.9){
  2737.                 resMod = 0.9;
  2738.             }else if(resMod<0.5){
  2739.                 resMod = 0.5;
  2740.             }
  2741.            
  2742.             rate *= resMod;
  2743.         }
  2744.         /*
  2745.         double res = vulnModifier;
  2746.         double resMod = 1;
  2747.         if (res != 0)
  2748.         {
  2749.             if (res < 0)
  2750.             {
  2751.                 resMod = 1 - 0.075 * res;
  2752.                 resMod = 1 / resMod;
  2753.             }
  2754.             else
  2755.                 resMod = 1 + 0.02 * res;
  2756.            
  2757.             rate *= resMod;
  2758.         }
  2759.         */
  2760.        
  2761.         //int elementModifier = calcElementModifier(attacker, target, skill);
  2762.         //rate += elementModifier;
  2763.        
  2764.         //lvl modifier.
  2765.         int deltamod = calcLvlDependModifier(attacker, target, skill);
  2766.         rate += deltamod;
  2767.        
  2768.         if (rate > skill.getMaxChance())
  2769.             rate = skill.getMaxChance();
  2770.         else if (rate < skill.getMinChance())
  2771.             rate = skill.getMinChance();
  2772.        
  2773.         //physics configuration addons
  2774.         float physics_mult = getChanceMultiplier(skill);
  2775.         rate *= physics_mult;
  2776.        
  2777.         if(Config.SKILLSDEBUG)
  2778.         {
  2779.             final StringBuilder stat = new StringBuilder(100);
  2780.             StringUtil.append(stat,
  2781.                     " calcEffectSuccess: ",skill.getName(),
  2782.                     " type:", skill.getSkillType().toString(),
  2783.                     " power:", String.valueOf(value),
  2784.                     " stat:", String.format("%1.2f", statModifier),
  2785.                     " res:", String.format("%1.2f", resMod), "(",
  2786.                     String.format("%1.2f", vulnModifier),
  2787.                     " mAtk:", String.format("%1.2f", mAtkModifier),
  2788.                     " ss:", String.valueOf(ssModifier),
  2789.                     " lvl:", String.valueOf(deltamod),
  2790.                     " physics configuration multiplier:", String.valueOf(physics_mult),
  2791.                     " total:", String.valueOf(rate)
  2792.             );
  2793.             final String result = stat.toString();
  2794.             if (Config.DEVELOPER)
  2795.                 _log.info(result);
  2796.            
  2797.         }
  2798.        
  2799.         if(attacker instanceof L2PcInstance && Config.SEND_SKILLS_CHANCE_TO_PLAYERS)
  2800.             ((L2PcInstance) attacker).sendMessage("EffectType "+effect.effectType+" Chance: " + rate + "%");
  2801.        
  2802.         return (Rnd.get(100) < rate);
  2803.     }
  2804.    
  2805.     public static double calcSkillTypeVulnerability(double multiplier, L2Character target, SkillType type)
  2806.     {
  2807.         if (type != null)
  2808.         {
  2809.             switch (type)
  2810.             {
  2811.                 case BLEED:
  2812.                     multiplier = target.calcStat(Stats.BLEED_VULN, multiplier, target, null);
  2813.                     break;
  2814.                 case POISON:
  2815.                     multiplier = target.calcStat(Stats.POISON_VULN, multiplier, target, null);
  2816.                     break;
  2817.                 case STUN:
  2818.                     multiplier = target.calcStat(Stats.STUN_VULN, multiplier, target, null);
  2819.                     break;
  2820.                 case PARALYZE:
  2821.                     multiplier = target.calcStat(Stats.PARALYZE_VULN, multiplier, target, null);
  2822.                     break;
  2823.                 case ROOT:
  2824.                     multiplier = target.calcStat(Stats.ROOT_VULN, multiplier, target, null);
  2825.                     break;
  2826.                 case SLEEP:
  2827.                     multiplier = target.calcStat(Stats.SLEEP_VULN, multiplier, target, null);
  2828.                     break;
  2829.                 case MUTE:
  2830.                 case FEAR:
  2831.                 case BETRAY:
  2832.                 case AGGDEBUFF:
  2833.                 case ERASE:
  2834.                     multiplier = target.calcStat(Stats.DERANGEMENT_VULN, multiplier, target, null);
  2835.                     break;
  2836.                 case CONFUSION:
  2837.                 case CONFUSE_MOB_ONLY:
  2838.                     multiplier = target.calcStat(Stats.CONFUSION_VULN, multiplier, target, null);
  2839.                     break;
  2840.                 case DEBUFF:
  2841.                     multiplier = target.calcStat(Stats.DEBUFF_VULN, multiplier, target, null);
  2842.                     break;
  2843.                 case BUFF:
  2844.                     multiplier = target.calcStat(Stats.BUFF_VULN, multiplier, target, null);
  2845.                     break;
  2846.                 case CANCEL:
  2847.                     multiplier = target.calcStat(Stats.CANCEL_VULN, multiplier, target, null);
  2848.                     break;
  2849.                 default:
  2850.             }
  2851.         }
  2852.        
  2853.         return multiplier;
  2854.     }
  2855.    
  2856.     public static int calcLvlDependModifier(final L2Character attacker, final L2Character target, L2Skill skill)
  2857.     {
  2858.         if(attacker == null){
  2859.             return 0;
  2860.         }
  2861.        
  2862.         if (skill.getLevelDepend() == 0)
  2863.             return 0;
  2864.        
  2865.         final int attackerMod;
  2866.         if (skill.getMagicLevel() > 0)
  2867.             attackerMod = skill.getMagicLevel();
  2868.         else
  2869.             attackerMod = attacker.getLevel();
  2870.        
  2871.         final int delta = attackerMod - target.getLevel();
  2872.         int deltamod = delta / 5;
  2873.         deltamod = deltamod * 5;
  2874.         if (deltamod != delta)
  2875.         {
  2876.             if (delta < 0)
  2877.                 deltamod -= 5;
  2878.             else
  2879.                 deltamod += 5;
  2880.         }
  2881.        
  2882.         return deltamod;
  2883.     }
  2884.  
  2885.     public static float getChanceMultiplier(L2Skill skill){
  2886.        
  2887.         float multiplier = 1;
  2888.        
  2889.         if(skill != null && skill.getSkillType()!=null)
  2890.         {
  2891.             switch(skill.getSkillType())
  2892.             {
  2893.                 case BLEED:
  2894.                     multiplier = Config.BLEED_CHANCE_MODIFIER;
  2895.                     break;
  2896.                 case POISON:
  2897.                     multiplier = Config.POISON_CHANCE_MODIFIER;
  2898.                     break;
  2899.                 case STUN:
  2900.                     multiplier = Config.STUN_CHANCE_MODIFIER;
  2901.                     break;
  2902.                 case PARALYZE:
  2903.                     multiplier = Config.PARALYZE_CHANCE_MODIFIER;
  2904.                     break;
  2905.                 case ROOT:
  2906.                     multiplier = Config.ROOT_CHANCE_MODIFIER;
  2907.                     break;
  2908.                 case SLEEP:
  2909.                     multiplier = Config.SLEEP_CHANCE_MODIFIER;
  2910.                     break;
  2911.                 case MUTE:
  2912.                 case FEAR:
  2913.                 case BETRAY:
  2914.                 case AGGREDUCE_CHAR:
  2915.                     multiplier = Config.FEAR_CHANCE_MODIFIER;
  2916.                     break;
  2917.                 case CONFUSION:
  2918.                     multiplier = Config.CONFUSION_CHANCE_MODIFIER;
  2919.                     break;
  2920.                 case DEBUFF:
  2921.                 case WEAKNESS:
  2922.                 case WARRIOR_BANE:
  2923.                 case MAGE_BANE:
  2924.                     multiplier = Config.DEBUFF_CHANCE_MODIFIER;
  2925.                     break;
  2926.                 case BUFF:
  2927.                     multiplier = Config.BUFF_CHANCE_MODIFIER;
  2928.                     break;
  2929.             }
  2930.         }
  2931.        
  2932.         return multiplier;
  2933.        
  2934.     }
  2935.    
  2936.     public boolean calcBuffSuccess(L2Character target, L2Skill skill)
  2937.     {
  2938.         int rate = 100 * (int)calcSkillVulnerability(target, skill);
  2939.         return Rnd.get(100) < rate;
  2940.     }
  2941.  
  2942.     public static boolean calcMagicSuccess(L2Character attacker, L2Character target, L2Skill skill)
  2943.     {
  2944.         double lvlDifference = target.getLevel() - (skill.getMagicLevel() > 0 ? skill.getMagicLevel() : attacker.getLevel());
  2945.         int rate = Math.round((float) (Math.pow(1.3, lvlDifference) * 100));
  2946.  
  2947.         return Rnd.get(10000) > rate;
  2948.     }
  2949.  
  2950.     public boolean calculateUnlockChance(L2Skill skill)
  2951.     {
  2952.         int level = skill.getLevel();
  2953.         int chance = 0;
  2954.         switch(level)
  2955.         {
  2956.             case 1:
  2957.                 chance = 30;
  2958.                 break;
  2959.  
  2960.             case 2:
  2961.                 chance = 50;
  2962.                 break;
  2963.  
  2964.             case 3:
  2965.                 chance = 75;
  2966.                 break;
  2967.  
  2968.             case 4:
  2969.             case 5:
  2970.             case 6:
  2971.             case 7:
  2972.             case 8:
  2973.             case 9:
  2974.             case 10:
  2975.             case 11:
  2976.             case 12:
  2977.             case 13:
  2978.             case 14:
  2979.                 chance = 100;
  2980.                 break;
  2981.         }
  2982.         if(Rnd.get(120) > chance)
  2983.             return false;
  2984.         return true;
  2985.     }
  2986.  
  2987.     public double calcManaDam(final L2Character attacker, final L2Character target, L2Skill skill, boolean ss, boolean bss)
  2988.     {
  2989.         if(attacker == null || target == null){
  2990.             return 0;
  2991.         }
  2992.        
  2993.         //Mana Burnt = (SQR(M.Atk)*Power*(Target Max MP/97))/M.Def
  2994.         double mAtk = attacker.getMAtk(target, skill);
  2995.         double mDef = target.getMDef(attacker, skill);
  2996.         double mp = target.getMaxMp();
  2997.        
  2998.         int ssModifier = 1;
  2999.         // Add Bonus for Sps/SS
  3000.         if(attacker instanceof L2Summon && !(attacker instanceof L2PetInstance)){
  3001.            
  3002.             if (bss){
  3003.                 //((L2Summon)attacker).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  3004.                 ssModifier = 4;
  3005.             }else if(ss){
  3006.                 //((L2Summon)attacker).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  3007.                 ssModifier = 2;
  3008.             }
  3009.            
  3010.         }else{
  3011.             L2ItemInstance weapon = attacker.getActiveWeaponInstance();
  3012.             if(weapon!=null){
  3013.                 if (bss){
  3014.                     //weapon.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  3015.                     ssModifier = 4;
  3016.                 }else if (ss){
  3017.                     //weapon.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  3018.                     ssModifier = 2;
  3019.                 }
  3020.             }
  3021.         }
  3022.        
  3023.         mAtk *= ssModifier;
  3024.  
  3025.         double damage = Math.sqrt(mAtk) * skill.getPower(attacker) * mp / 97 / mDef;
  3026.         damage *= calcSkillVulnerability(target, skill);
  3027.         return damage;
  3028.     }
  3029.  
  3030.     public double calculateSkillResurrectRestorePercent(double baseRestorePercent, L2Character caster )
  3031.     {
  3032.         double restorePercent = baseRestorePercent;
  3033.        
  3034.         //double modifier = WITbonus[casterWIT];
  3035.         double modifier = BaseStats.WIT.calcBonus(caster);
  3036.        
  3037.         if(restorePercent != 100 && restorePercent != 0)
  3038.         {
  3039.  
  3040.             restorePercent = baseRestorePercent * modifier;
  3041.  
  3042.             if(restorePercent - baseRestorePercent > 20.0)
  3043.             {
  3044.                 restorePercent = baseRestorePercent + 20.0;
  3045.             }
  3046.         }
  3047.  
  3048.         if(restorePercent > 100)
  3049.         {
  3050.             restorePercent = 100;
  3051.         }
  3052.         if(restorePercent < baseRestorePercent)
  3053.         {
  3054.             restorePercent = baseRestorePercent;
  3055.         }
  3056.  
  3057.         return restorePercent;
  3058.     }
  3059.  
  3060.     /*
  3061.     public static double getSTRBonus(L2Character activeChar)
  3062.     {
  3063.         return STRbonus[activeChar.getSTR()];
  3064.     }
  3065.     */
  3066.  
  3067.     public static boolean calcPhysicalSkillEvasion(L2Character target, L2Skill skill)
  3068.     {
  3069.         if(skill.isMagic() || skill.getCastRange() > 40)
  3070.             return false;
  3071.  
  3072.         return Rnd.get(100) < target.calcStat(Stats.P_SKILL_EVASION, 0, null, skill);
  3073.     }
  3074.  
  3075.     public boolean calcSkillMastery(final L2Character actor)
  3076.     {
  3077.         if(actor == null)
  3078.             return false;
  3079.  
  3080.         double val = actor.getStat().calcStat(Stats.SKILL_MASTERY, 0, null, null);
  3081.  
  3082.         if(actor instanceof L2PcInstance)
  3083.         {
  3084.             if(((L2PcInstance) actor).isMageClass())
  3085.             {
  3086.                
  3087.                 //val *= INTbonus[actor.getINT()];
  3088.                 val *= BaseStats.INT.calcBonus(actor);
  3089.             }
  3090.             else
  3091.             {
  3092.                 //val *= STRbonus[actor.getSTR()];
  3093.                 val *= BaseStats.STR.calcBonus(actor);
  3094.             }
  3095.         }
  3096.  
  3097.         return Rnd.get(100) < val;
  3098.     }
  3099.    
  3100.     /**
  3101.      * Calculate damage caused by falling
  3102.      * @param cha
  3103.      * @param fallHeight
  3104.      * @return damage
  3105.      */
  3106.     public static double calcFallDam(L2Character cha, int fallHeight)
  3107.     {
  3108.         if (!Config.FALL_DAMAGE || fallHeight < 0)
  3109.             return 0;
  3110.         final double damage = cha.calcStat(Stats.FALL, fallHeight * cha.getMaxHp() / 1000, null, null);
  3111.         return damage;
  3112.     }
  3113.    
  3114.     /** Calculated damage caused by charges skills types. - THX aCis
  3115.      * The special thing is about the multiplier (56 and not 70), and about the fixed amount of damages
  3116.      *
  3117.      * @param attacker player or NPC that makes ATTACK
  3118.      * @param target player or NPC, target of ATTACK
  3119.      * @param skill
  3120.      * @param shld
  3121.      * @param crit if the ATTACK have critical success
  3122.      * @param ss if weapon item was charged by soulshot
  3123.      * @param _numCharges
  3124.      * @return damage points
  3125.      */
  3126.     public static final double calcChargeSkillsDam(L2Character attacker, L2Character target, L2Skill skill, boolean shld, boolean crit, boolean ss, int _numCharges)
  3127.     {
  3128.         if (attacker instanceof L2PcInstance)
  3129.         {
  3130.             L2PcInstance pcInst = (L2PcInstance)attacker;
  3131.             if (pcInst.isGM() && !pcInst.getAccessLevel().canGiveDamage())
  3132.                     return 0;
  3133.         }
  3134.        
  3135.         final boolean isPvP = (attacker instanceof L2PlayableInstance) && (target instanceof L2PlayableInstance);
  3136.         double damage = attacker.getPAtk(target);
  3137.         double defence = target.getPDef(attacker);
  3138.        
  3139.         if (ss){
  3140.             damage *= 2;
  3141.         }
  3142.        
  3143.         if (crit)
  3144.         {
  3145.             //double cAtkMultiplied = (damage) + attacker.calcStat(Stats.CRITICAL_DAMAGE, damage, target, skill);
  3146.             double improvedDamageByCriticalVuln = target.calcStat(Stats.CRIT_VULN, damage, target, skill);
  3147.             double improvedDamageByCriticalVulnAndAdd =  (attacker.calcStat(Stats.CRITICAL_DAMAGE_ADD, improvedDamageByCriticalVuln, target, skill));
  3148.            
  3149.             if(Config.DEBUG){
  3150.                 System.out.println("Attacker '"+attacker.getName()+"' Charge Skills Critical Damage Debug:");
  3151.                 System.out.println("    -   Initial Damage:  "+damage);
  3152.                 System.out.println("    -   improvedDamageByCriticalVuln: "+improvedDamageByCriticalVuln);
  3153.                 System.out.println("    -   improvedDamageByCriticalVulnAndAdd: "+improvedDamageByCriticalVulnAndAdd);
  3154.             }
  3155.            
  3156.             damage = improvedDamageByCriticalVulnAndAdd;
  3157.            
  3158.             /*
  3159.             //Finally retail like formula
  3160.             double cAtkMultiplied = damage+attacker.calcStat(Stats.CRITICAL_DAMAGE, damage, target, skill);
  3161.             double cAtkVuln = target.calcStat(Stats.CRIT_VULN, 1, target, null);
  3162.             double improvedDamageByCriticalMulAndVuln = cAtkMultiplied * cAtkVuln;
  3163.             double improvedDamageByCriticalMulAndAdd = improvedDamageByCriticalMulAndVuln + attacker.calcStat(Stats.CRITICAL_DAMAGE_ADD, 0, target, skill);
  3164.            
  3165.             if(Config.DEBUG){
  3166.                 System.out.println("Attacker '"+attacker.getName()+"' Critical Skill Damage Debug:");
  3167.                 System.out.println("    -   Initial Damage:  "+damage);
  3168.                 System.out.println("    -   Damage increased of mult:  "+cAtkMultiplied);
  3169.                 System.out.println("    -   cAtkVuln Mult:  "+cAtkVuln);
  3170.                 System.out.println("    -   improvedDamageByCriticalMulAndVuln: "+improvedDamageByCriticalMulAndVuln);
  3171.                 System.out.println("    -   improvedDamageByCriticalMulAndAdd: "+improvedDamageByCriticalMulAndAdd);
  3172.             }
  3173.            
  3174.             damage = improvedDamageByCriticalMulAndAdd;
  3175.             */
  3176.            
  3177.             /*
  3178.             //Finally retail like formula
  3179.             damage = 2 * attacker.calcStat(Stats.CRITICAL_DAMAGE, 1, target, skill) * target.calcStat(Stats.CRIT_VULN, 1, target, null) * (56 * damage / defence);
  3180.             //Crit dmg add is almost useless in normal hits...
  3181.             damage += (attacker.calcStat(Stats.CRITICAL_DAMAGE_ADD, 0, target, skill) * 56 / defence);
  3182.             */
  3183.         }
  3184.  
  3185.         if (skill != null) //skill add is not influenced by criticals improvements,
  3186.                            //so it's applied later
  3187.         {
  3188.             double skillpower = skill.getPower(attacker);
  3189.             float ssboost = skill.getSSBoost();
  3190.             if(ssboost <= 0)
  3191.                 damage += skillpower;
  3192.             else if(ssboost > 0)
  3193.             {
  3194.                 if(ss)
  3195.                 {
  3196.                     skillpower *= ssboost;
  3197.                     damage += skillpower;
  3198.                 }
  3199.                 else
  3200.                     damage += skillpower;
  3201.             }
  3202.  
  3203.             // Charges multiplier, just when skill is used
  3204.             if(_numCharges >= 1)
  3205.             {
  3206.                 double chargesModifier = 0.7 + (0.3 * _numCharges);
  3207.                 damage *= chargesModifier;
  3208.             }
  3209.  
  3210.         }
  3211.        
  3212.         damage = 56 * damage / defence;
  3213.  
  3214.         //finally, apply the critical multiplier if present (it's not subjected to defense)
  3215.         if(crit){
  3216.             damage = attacker.calcStat(Stats.CRITICAL_DAMAGE, damage, target, skill);
  3217.         }
  3218.        
  3219.         // defence modifier depending of the attacker weapon
  3220.         L2Weapon weapon = attacker.getActiveWeaponItem();
  3221.         Stats stat = null;
  3222.         if (weapon != null)
  3223.         {
  3224.             switch (weapon.getItemType())
  3225.             {
  3226.                 case BOW:
  3227.                     stat = Stats.BOW_WPN_VULN;
  3228.                     break;
  3229.                 case BLUNT:
  3230.                     stat = Stats.BLUNT_WPN_VULN;
  3231.                     break;
  3232.                 case BIGSWORD:
  3233.                     stat = Stats.BIGSWORD_WPN_VULN;
  3234.                     break;
  3235.                 case BIGBLUNT:
  3236.                     stat = Stats.BIGBLUNT_WPN_VULN;
  3237.                     break;
  3238.                 case DAGGER:
  3239.                     stat = Stats.DAGGER_WPN_VULN;
  3240.                     break;
  3241.                 case DUAL:
  3242.                     stat = Stats.DUAL_WPN_VULN;
  3243.                     break;
  3244.                 case DUALFIST:
  3245.                     stat = Stats.DUALFIST_WPN_VULN;
  3246.                     break;
  3247.                 case ETC:
  3248.                     stat = Stats.ETC_WPN_VULN;
  3249.                     break;
  3250.                 case FIST:
  3251.                     stat = Stats.FIST_WPN_VULN;
  3252.                     break;
  3253.                 case POLE:
  3254.                     stat = Stats.POLE_WPN_VULN;
  3255.                     break;
  3256.                 case SWORD:
  3257.                     stat = Stats.SWORD_WPN_VULN;
  3258.                     break;
  3259.             }
  3260.         }
  3261.        
  3262.         if (stat != null)
  3263.             damage = target.calcStat(stat, damage, target, null);
  3264.        
  3265.         // Weapon random damage
  3266.         damage *= attacker.getRandomDamageMultiplier();
  3267.        
  3268.         // After C4 nobles make 4% more dmg in PvP.
  3269.         if(attacker instanceof L2PcInstance && ((L2PcInstance) attacker).isNoble() && (target instanceof L2PcInstance || target instanceof L2Summon))
  3270.         {
  3271.             damage *= 1.04;
  3272.         }
  3273.  
  3274.         //System.out.println("  -   Final damage: "+damage);
  3275.        
  3276.         if(shld && Config.ALT_GAME_SHIELD_BLOCKS)
  3277.         {
  3278.             damage -= target.getShldDef();
  3279.             if(damage < 0)
  3280.             {
  3281.                 damage = 0;
  3282.             }
  3283.         }
  3284.        
  3285.         if (target instanceof L2NpcInstance)
  3286.         {
  3287.             double multiplier;
  3288.             switch (((L2NpcInstance) target).getTemplate().getRace())
  3289.             {
  3290.                 case BEAST:
  3291.                     multiplier = 1 + ((attacker.getPAtkMonsters(target) - target.getPDefMonsters(target))/100);
  3292.                     damage *= multiplier;
  3293.                     break;
  3294.                 case ANIMAL:
  3295.                     multiplier = 1 + ((attacker.getPAtkAnimals(target) - target.getPDefAnimals(target))/100);
  3296.                     damage *= multiplier;
  3297.                     break;
  3298.                 case PLANT:
  3299.                     multiplier = 1 + ((attacker.getPAtkPlants(target) - target.getPDefPlants(target))/100);
  3300.                     damage *= multiplier;
  3301.                     break;
  3302.                 case DRAGON:
  3303.                     multiplier = 1 + ((attacker.getPAtkDragons(target) - target.getPDefDragons(target))/100);
  3304.                     damage *= multiplier;
  3305.                     break;
  3306.                 case ANGEL:
  3307.                     multiplier = 1 + ((attacker.getPAtkAngels(target) - target.getPDefAngels(target))/100);
  3308.                     damage *= multiplier;
  3309.                     break;
  3310.                 case BUG:
  3311.                     multiplier = 1 + ((attacker.getPAtkInsects(target) - target.getPDefInsects(target))/100);
  3312.                     damage *= multiplier;
  3313.                     break;
  3314.                 case GIANT:
  3315.                     multiplier = 1 + ((attacker.getPAtkGiants(target) - target.getPDefGiants(target))/100);
  3316.                     damage *= multiplier;
  3317.                     break;
  3318.                 case MAGICCREATURE:
  3319.                     multiplier = 1 + ((attacker.getPAtkMagicCreatures(target) - target.getPDefMagicCreatures(target))/100);
  3320.                     damage *= multiplier;
  3321.                     break;
  3322.                 default:
  3323.                     // nothing
  3324.                     break;
  3325.             }
  3326.         }
  3327.        
  3328.         if(shld)
  3329.         {
  3330.             if(100 - Config.ALT_PERFECT_SHLD_BLOCK < Rnd.get(100))
  3331.             {
  3332.                 damage = 1;
  3333.                 target.sendPacket(new SystemMessage(SystemMessageId.YOUR_EXCELLENT_SHIELD_DEFENSE_WAS_A_SUCCESS));
  3334.             }
  3335.         }
  3336.  
  3337.         if (damage > 0 && damage < 1)
  3338.             damage = 1;
  3339.         else if (damage < 0)
  3340.             damage = 0;
  3341.        
  3342.         // Dmg bonusses in PvP fight
  3343.         if(isPvP)
  3344.         {
  3345.             if(skill == null)
  3346.                 damage *= attacker.calcStat(Stats.PVP_PHYSICAL_DMG, 1, null, null);
  3347.             else
  3348.                 damage *= attacker.calcStat(Stats.PVP_PHYS_SKILL_DMG, 1, null, null);
  3349.         }
  3350.        
  3351.         if(Config.ENABLE_CLASS_DAMAGES && attacker instanceof L2PcInstance && target instanceof L2PcInstance){
  3352.            
  3353.             if(((L2PcInstance) attacker).isInOlympiadMode() && ((L2PcInstance) target).isInOlympiadMode()){
  3354.                
  3355.                 if(Config.ENABLE_CLASS_DAMAGES_IN_OLY){
  3356.                     damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  3357.                 }
  3358.                
  3359.             }else{
  3360.                
  3361.                 damage = damage*ClassDamageManager.getDamageMultiplier((L2PcInstance) attacker, (L2PcInstance) target);
  3362.            
  3363.             }
  3364.         }
  3365.        
  3366.         return damage;
  3367.     }
  3368.  
  3369. }
Advertisement
Add Comment
Please, Sign In to add comment