Advertisement
Guest User

Untitled

a guest
Jul 1st, 2015
419
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 439.62 KB | None | 0 0
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3.  
  4. #include "../common/cbasetypes.h"
  5. #include "../common/timer.h"
  6. #include "../common/nullpo.h"
  7. #include "../common/random.h"
  8. #include "../common/showmsg.h"
  9. #include "../common/malloc.h"
  10. #include "../common/utils.h"
  11. #include "../common/ers.h"
  12. #include "../common/strlib.h"
  13.  
  14. #include "map.h"
  15. #include "path.h"
  16. #include "pc.h"
  17. #include "pet.h"
  18. #include "battleground.h"
  19. #include "homunculus.h"
  20. #include "mercenary.h"
  21. #include "elemental.h"
  22.  
  23. #include <stdlib.h>
  24. #include <math.h>
  25.  
  26. // Regen related flags.
  27. enum e_regen {
  28.     RGN_NONE = 0x00,
  29.     RGN_HP   = 0x01,
  30.     RGN_SP   = 0x02,
  31.     RGN_SHP  = 0x04,
  32.     RGN_SSP  = 0x08,
  33. };
  34.  
  35. // Bonus values and upgrade chances for refining equipment
  36. static struct {
  37.     int chance[MAX_REFINE]; /// Success chance
  38.     int bonus[MAX_REFINE]; /// Cumulative fixed bonus damage
  39.     int randombonus_max[MAX_REFINE]; /// Cumulative maximum random bonus damage
  40. } refine_info[REFINE_TYPE_MAX];
  41.  
  42. static int atkmods[3][MAX_WEAPON_TYPE]; /// ATK weapon modification for size (size_fix.txt)
  43.  
  44. static struct eri *sc_data_ers; /// For sc_data entries
  45. static struct status_data dummy_status;
  46.  
  47. short current_equip_item_index; /// Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
  48. unsigned int current_equip_combo_pos; /// For combo items we need to save the position of all involved items here
  49. int current_equip_card_id; /// To prevent card-stacking (from jA) [Skotlex]
  50. // We need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only to avoid cards exploits
  51.  
  52. static unsigned short status_calc_str(struct block_list *,struct status_change *,int);
  53. static unsigned short status_calc_agi(struct block_list *,struct status_change *,int);
  54. static unsigned short status_calc_vit(struct block_list *,struct status_change *,int);
  55. static unsigned short status_calc_int(struct block_list *,struct status_change *,int);
  56. static unsigned short status_calc_dex(struct block_list *,struct status_change *,int);
  57. static unsigned short status_calc_luk(struct block_list *,struct status_change *,int);
  58. static unsigned short status_calc_batk(struct block_list *,struct status_change *,int);
  59. static unsigned short status_calc_watk(struct block_list *,struct status_change *,int);
  60. static unsigned short status_calc_matk(struct block_list *,struct status_change *,int);
  61. static signed short status_calc_hit(struct block_list *,struct status_change *,int);
  62. static signed short status_calc_critical(struct block_list *,struct status_change *,int);
  63. static signed short status_calc_flee(struct block_list *,struct status_change *,int);
  64. static signed short status_calc_flee2(struct block_list *,struct status_change *,int);
  65. static defType status_calc_def(struct block_list *bl, struct status_change *sc, int);
  66. static signed short status_calc_def2(struct block_list *,struct status_change *,int);
  67. static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int);
  68. static signed short status_calc_mdef2(struct block_list *,struct status_change *,int);
  69. static unsigned short status_calc_speed(struct block_list *,struct status_change *,int);
  70. static short status_calc_aspd_rate(struct block_list *,struct status_change *,int);
  71. static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion);
  72. #ifdef RENEWAL_ASPD
  73. static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag);
  74. #endif
  75. static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int);
  76. static unsigned int status_calc_maxhp(struct block_list *bl, uint64 maxhp);
  77. static unsigned int status_calc_maxsp(struct block_list *bl, uint64 maxsp);
  78. static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element);
  79. static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv);
  80. static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode);
  81. #ifdef RENEWAL
  82. static unsigned short status_calc_ematk(struct block_list *,struct status_change *,int);
  83. #endif
  84. static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type);
  85. static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type);
  86. static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned int stat, bool isHP);
  87.  
  88. /**
  89.  * Returns the status change associated with a skill.
  90.  * @param skill The skill to look up
  91.  * @return The status registered for this skill
  92.  */
  93. sc_type status_skill2sc(int skill)
  94. {
  95.     int idx = skill_get_index(skill);
  96.     if( idx == 0 ) {
  97.         ShowError("status_skill2sc: Unsupported skill id %d\n", skill);
  98.         return SC_NONE;
  99.     }
  100.     return SkillStatusChangeTable[idx];
  101. }
  102.  
  103. /**
  104.  * Returns the FIRST skill (in order of definition in initChangeTables) to use a given status change.
  105.  * Utilized for various duration lookups. Use with caution!
  106.  * @param sc The status to look up
  107.  * @return A skill associated with the status
  108.  */
  109. int status_sc2skill(sc_type sc)
  110. {
  111.     if( sc < 0 || sc >= SC_MAX ) {
  112.         ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
  113.         return 0;
  114.     }
  115.  
  116.     return StatusSkillChangeTable[sc];
  117. }
  118.  
  119. /**
  120.  * Returns the status calculation flag associated with a given status change.
  121.  * @param sc The status to look up
  122.  * @return The scb_flag registered for this status (see enum scb_flag)
  123.  */
  124. unsigned int status_sc2scb_flag(sc_type sc)
  125. {
  126.     if( sc < 0 || sc >= SC_MAX ) {
  127.         ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc);
  128.         return SCB_NONE;
  129.     }
  130.  
  131.     return StatusChangeFlagTable[sc];
  132. }
  133.  
  134. /**
  135.  * Returns the bl types which require a status change packet to be sent for a given client status identifier.
  136.  * @param type The client-side status identifier to look up (see enum si_type)
  137.  * @return The bl types relevant to the type (see enum bl_type)
  138.  */
  139. int status_type2relevant_bl_types(int type)
  140. {
  141.     if( type < 0 || type >= SI_MAX ) {
  142.         ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type);
  143.         return SI_BLANK;
  144.     }
  145.  
  146.     return StatusRelevantBLTypes[type];
  147. }
  148.  
  149. #define add_sc(skill,sc) set_sc(skill,sc,SI_BLANK,SCB_NONE)
  150. // Indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units
  151. #define set_sc_with_vfx(skill, sc, icon, flag) set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) StatusRelevantBLTypes[(icon)] |= BL_SCEFFECT
  152.  
  153. static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
  154. {
  155.     uint16 idx = skill_get_index(skill_id);
  156.     if( idx == 0 ) {
  157.         ShowError("set_sc: Unsupported skill id %d (SC: %d. Icon: %d)\n", skill_id, sc, icon);
  158.         return;
  159.     }
  160.     if( sc < 0 || sc >= SC_MAX ) {
  161.         ShowError("set_sc: Unsupported status change id %d (Skill: %d. Icon: %d)\n", sc, skill_id, icon);
  162.         return;
  163.     }
  164.  
  165.     if( StatusSkillChangeTable[sc] == 0 )
  166.         StatusSkillChangeTable[sc] = skill_id;
  167.     if( StatusIconChangeTable[sc] == SI_BLANK )
  168.         StatusIconChangeTable[sc] = icon;
  169.     StatusChangeFlagTable[sc] |= flag;
  170.  
  171.     if( SkillStatusChangeTable[idx] == SC_NONE )
  172.         SkillStatusChangeTable[idx] = sc;
  173. }
  174.  
  175. static void set_sc_with_vfx_noskill(sc_type sc, int icon, unsigned flag) {
  176.     if (sc > SC_NONE && sc < SC_MAX) {
  177.         if (StatusIconChangeTable[sc] == SI_BLANK)
  178.             StatusIconChangeTable[sc] = icon;
  179.         StatusChangeFlagTable[sc] |= flag;
  180.     }
  181.     if (icon > SI_BLANK && icon < SI_MAX)
  182.         StatusRelevantBLTypes[icon] |= BL_SCEFFECT;
  183. }
  184.  
  185. void initChangeTables(void)
  186. {
  187.     int i;
  188.  
  189.     for (i = 0; i < SC_MAX; i++)
  190.         StatusIconChangeTable[i] = SI_BLANK;
  191.  
  192.     for (i = 0; i < MAX_SKILL; i++)
  193.         SkillStatusChangeTable[i] = SC_NONE;
  194.  
  195.     for (i = 0; i < SI_MAX; i++)
  196.         StatusRelevantBLTypes[i] = BL_PC;
  197.  
  198.     memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
  199.     memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
  200.     memset(StatusChangeStateTable, 0, sizeof(StatusChangeStateTable));
  201.     memset(StatusDisplayType, 0, sizeof(StatusDisplayType));
  202.  
  203.  
  204.     /* First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex] */
  205.     set_sc( NPC_PETRIFYATTACK   , SC_STONE      , SI_BLANK      , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
  206.     set_sc( NPC_WIDEFREEZE      , SC_FREEZE     , SI_BLANK      , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
  207.     add_sc( NPC_STUNATTACK      , SC_STUN       );
  208.     add_sc( NPC_SLEEPATTACK     , SC_SLEEP      );
  209.     set_sc( NPC_POISON      , SC_POISON     , SI_BLANK      , SCB_DEF2|SCB_REGEN );
  210.     set_sc( NPC_CURSEATTACK     , SC_CURSE      , SI_BLANK      , SCB_LUK|SCB_BATK|SCB_WATK|SCB_SPEED );
  211.     add_sc( NPC_SILENCEATTACK   , SC_SILENCE        );
  212.     add_sc( NPC_WIDECONFUSE     , SC_CONFUSION      );
  213.     set_sc( NPC_BLINDATTACK     , SC_BLIND      , SI_BLANK      , SCB_HIT|SCB_FLEE );
  214.     set_sc( NPC_BLEEDING        , SC_BLEEDING       , SI_BLEEDING       , SCB_REGEN );
  215.     set_sc( NPC_POISON      , SC_DPOISON        , SI_BLANK      , SCB_DEF2|SCB_REGEN );
  216.     add_sc( ALL_REVERSEORCISH,  SC_ORCISH );
  217.  
  218.     /* The main status definitions */
  219.     add_sc( SM_BASH         , SC_STUN       );
  220.     set_sc( SM_PROVOKE      , SC_PROVOKE        , SI_PROVOKE        , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
  221.     add_sc( SM_MAGNUM       , SC_WATK_ELEMENT   );
  222.     set_sc( SM_ENDURE       , SC_ENDURE     , SI_ENDURE     , SCB_MDEF|SCB_DSPD );
  223.     add_sc( MG_SIGHT        , SC_SIGHT      );
  224.     add_sc( MG_SAFETYWALL       , SC_SAFETYWALL     );
  225.     add_sc( MG_FROSTDIVER       , SC_FREEZE     );
  226.     add_sc( MG_STONECURSE       , SC_STONE      );
  227.     add_sc( AL_RUWACH       , SC_RUWACH     );
  228.     add_sc( AL_PNEUMA       , SC_PNEUMA     );
  229.     set_sc( AL_INCAGI       , SC_INCREASEAGI    , SI_INCREASEAGI    , SCB_AGI|SCB_SPEED );
  230.     set_sc( AL_DECAGI       , SC_DECREASEAGI    , SI_DECREASEAGI    , SCB_AGI|SCB_SPEED );
  231.     set_sc( AL_CRUCIS       , SC_SIGNUMCRUCIS   , SI_SIGNUMCRUCIS   , SCB_DEF );
  232.     set_sc( AL_ANGELUS      , SC_ANGELUS        , SI_ANGELUS        , SCB_DEF2 );
  233.     set_sc( AL_BLESSING     , SC_BLESSING       , SI_BLESSING       , SCB_STR|SCB_INT|SCB_DEX );
  234.     set_sc( AC_CONCENTRATION    , SC_CONCENTRATE    , SI_CONCENTRATE    , SCB_AGI|SCB_DEX );
  235.     set_sc( TF_HIDING       , SC_HIDING     , SI_HIDING     , SCB_SPEED );
  236.     add_sc( TF_POISON       , SC_POISON     );
  237.     set_sc( KN_TWOHANDQUICKEN   , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD );
  238.     set_sc( KN_AUTOCOUNTER      , SC_AUTOCOUNTER    , SI_AUTOCOUNTER    , SCB_NONE );
  239.     set_sc( PR_IMPOSITIO        , SC_IMPOSITIO      , SI_IMPOSITIO      ,
  240. #ifndef RENEWAL
  241.         SCB_WATK );
  242. #else
  243.         SCB_NONE );
  244. #endif
  245.     set_sc( PR_SUFFRAGIUM       , SC_SUFFRAGIUM     , SI_SUFFRAGIUM     , SCB_NONE );
  246.     set_sc( PR_ASPERSIO     , SC_ASPERSIO       , SI_ASPERSIO       , SCB_ATK_ELE );
  247.     set_sc( PR_BENEDICTIO       , SC_BENEDICTIO     , SI_BENEDICTIO     , SCB_DEF_ELE );
  248.     set_sc( PR_SLOWPOISON       , SC_SLOWPOISON     , SI_SLOWPOISON     , SCB_REGEN );
  249.     set_sc( PR_KYRIE        , SC_KYRIE      , SI_KYRIE      , SCB_NONE );
  250.     set_sc( PR_MAGNIFICAT       , SC_MAGNIFICAT     , SI_MAGNIFICAT     , SCB_REGEN );
  251.     set_sc( PR_GLORIA       , SC_GLORIA     , SI_GLORIA     , SCB_LUK );
  252.     add_sc( PR_LEXDIVINA        , SC_SILENCE        );
  253.     set_sc( PR_LEXAETERNA       , SC_AETERNA        , SI_AETERNA        , SCB_NONE );
  254.     add_sc( WZ_METEOR       , SC_STUN       );
  255.     add_sc( WZ_VERMILION        , SC_BLIND      );
  256.     add_sc( WZ_FROSTNOVA        , SC_FREEZE     );
  257.     add_sc( WZ_STORMGUST        , SC_FREEZE     );
  258.     set_sc( WZ_QUAGMIRE     , SC_QUAGMIRE       , SI_QUAGMIRE       , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
  259.     set_sc( BS_ADRENALINE       , SC_ADRENALINE     , SI_ADRENALINE     , SCB_ASPD );
  260.     set_sc( BS_WEAPONPERFECT    , SC_WEAPONPERFECTION   , SI_WEAPONPERFECTION   , SCB_NONE );
  261.     set_sc( BS_OVERTHRUST       , SC_OVERTHRUST     , SI_OVERTHRUST     , SCB_NONE );
  262.     set_sc( BS_MAXIMIZE     , SC_MAXIMIZEPOWER  , SI_MAXIMIZEPOWER  , SCB_REGEN );
  263.     add_sc( HT_LANDMINE     , SC_STUN       );
  264.     set_sc( HT_ANKLESNARE   , SC_ANKLE  , SI_ANKLESNARE , SCB_NONE );
  265.     add_sc( HT_SANDMAN      , SC_SLEEP      );
  266.     add_sc( HT_FLASHER      , SC_BLIND      );
  267.     add_sc( HT_FREEZINGTRAP     , SC_FREEZE     );
  268.     set_sc( AS_CLOAKING     , SC_CLOAKING       , SI_CLOAKING       , SCB_CRI|SCB_SPEED );
  269.     add_sc( AS_SONICBLOW        , SC_STUN       );
  270.     set_sc( AS_ENCHANTPOISON    , SC_ENCPOISON      , SI_ENCPOISON      , SCB_ATK_ELE );
  271.     set_sc( AS_POISONREACT      , SC_POISONREACT    , SI_POISONREACT    , SCB_NONE );
  272.     add_sc( AS_VENOMDUST        , SC_POISON     );
  273.     set_sc( AS_SPLASHER     , SC_SPLASHER   , SI_SPLASHER   , SCB_NONE );
  274.     set_sc( NV_TRICKDEAD        , SC_TRICKDEAD      , SI_TRICKDEAD      , SCB_REGEN );
  275.     set_sc( SM_AUTOBERSERK      , SC_AUTOBERSERK    , SI_AUTOBERSERK    , SCB_NONE );
  276.     add_sc( TF_SPRINKLESAND     , SC_BLIND      );
  277.     add_sc( TF_THROWSTONE       , SC_STUN       );
  278.     set_sc( MC_LOUD         , SC_LOUD       , SI_LOUD       , SCB_STR );
  279.     set_sc( MG_ENERGYCOAT       , SC_ENERGYCOAT     , SI_ENERGYCOAT     , SCB_NONE );
  280.     set_sc( NPC_EMOTION     , SC_MODECHANGE     , SI_BLANK      , SCB_MODE );
  281.     add_sc( NPC_EMOTION_ON      , SC_MODECHANGE     );
  282.     set_sc( NPC_ATTRICHANGE     , SC_ELEMENTALCHANGE    , SI_ARMOR_PROPERTY , SCB_DEF_ELE );
  283.     add_sc( NPC_CHANGEWATER     , SC_ELEMENTALCHANGE    );
  284.     add_sc( NPC_CHANGEGROUND    , SC_ELEMENTALCHANGE    );
  285.     add_sc( NPC_CHANGEFIRE      , SC_ELEMENTALCHANGE    );
  286.     add_sc( NPC_CHANGEWIND      , SC_ELEMENTALCHANGE    );
  287.     add_sc( NPC_CHANGEPOISON    , SC_ELEMENTALCHANGE    );
  288.     add_sc( NPC_CHANGEHOLY      , SC_ELEMENTALCHANGE    );
  289.     add_sc( NPC_CHANGEDARKNESS  , SC_ELEMENTALCHANGE    );
  290.     add_sc( NPC_CHANGETELEKINESIS   , SC_ELEMENTALCHANGE    );
  291.     add_sc( NPC_POISON      , SC_POISON     );
  292.     add_sc( NPC_BLINDATTACK     , SC_BLIND      );
  293.     add_sc( NPC_SILENCEATTACK   , SC_SILENCE        );
  294.     add_sc( NPC_STUNATTACK      , SC_STUN       );
  295.     add_sc( NPC_PETRIFYATTACK   , SC_STONE      );
  296.     add_sc( NPC_CURSEATTACK     , SC_CURSE      );
  297.     add_sc( NPC_SLEEPATTACK     , SC_SLEEP      );
  298.     add_sc( NPC_MAGICALATTACK   , SC_MAGICALATTACK  );
  299.     set_sc( NPC_KEEPING     , SC_KEEPING        , SI_BLANK      , SCB_DEF );
  300.     add_sc( NPC_DARKBLESSING    , SC_COMA       );
  301.     set_sc( NPC_BARRIER     , SC_BARRIER        , SI_BARRIER    , SCB_MDEF|SCB_DEF );
  302.     add_sc( NPC_DEFENDER        , SC_ARMOR      );
  303.     add_sc( NPC_LICK        , SC_STUN       );
  304.     set_sc( NPC_HALLUCINATION   , SC_HALLUCINATION  , SI_HALLUCINATION  , SCB_NONE );
  305.     add_sc( NPC_REBIRTH     , SC_REBIRTH        );
  306.     add_sc( RG_RAID         , SC_STUN       );
  307. #ifdef RENEWAL
  308.     add_sc( RG_RAID         , SC_RAID       );
  309.     add_sc( RG_BACKSTAP     , SC_STUN       );
  310. #endif
  311.     set_sc( RG_STRIPWEAPON      , SC_STRIPWEAPON    , SI_STRIPWEAPON    , SCB_WATK );
  312.     set_sc( RG_STRIPSHIELD      , SC_STRIPSHIELD    , SI_STRIPSHIELD    , SCB_DEF );
  313.     set_sc( RG_STRIPARMOR       , SC_STRIPARMOR     , SI_STRIPARMOR     , SCB_VIT );
  314.     set_sc( RG_STRIPHELM        , SC_STRIPHELM      , SI_STRIPHELM      , SCB_INT );
  315.     add_sc( AM_ACIDTERROR       , SC_BLEEDING       );
  316.     set_sc( AM_CP_WEAPON        , SC_CP_WEAPON      , SI_CP_WEAPON      , SCB_NONE );
  317.     set_sc( AM_CP_SHIELD        , SC_CP_SHIELD      , SI_CP_SHIELD      , SCB_NONE );
  318.     set_sc( AM_CP_ARMOR     , SC_CP_ARMOR       , SI_CP_ARMOR       , SCB_NONE );
  319.     set_sc( AM_CP_HELM      , SC_CP_HELM        , SI_CP_HELM        , SCB_NONE );
  320.     set_sc( CR_AUTOGUARD        , SC_AUTOGUARD      , SI_AUTOGUARD      , SCB_NONE );
  321.     add_sc( CR_SHIELDCHARGE     , SC_STUN       );
  322.     set_sc( CR_REFLECTSHIELD    , SC_REFLECTSHIELD  , SI_REFLECTSHIELD  , SCB_NONE );
  323.     add_sc( CR_HOLYCROSS        , SC_BLIND      );
  324.     add_sc( CR_GRANDCROSS       , SC_BLIND      );
  325.     set_sc( CR_DEVOTION     , SC_DEVOTION   , SI_DEVOTION   , SCB_NONE);
  326.     set_sc( CR_PROVIDENCE       , SC_PROVIDENCE     , SI_PROVIDENCE     , SCB_ALL );
  327.     set_sc( CR_DEFENDER     , SC_DEFENDER       , SI_DEFENDER       , SCB_SPEED|SCB_ASPD );
  328.     set_sc( CR_SPEARQUICKEN     , SC_SPEARQUICKEN   , SI_SPEARQUICKEN   , SCB_ASPD|SCB_CRI|SCB_FLEE );
  329.     set_sc( MO_STEELBODY        , SC_STEELBODY      , SI_STEELBODY      , SCB_DEF|SCB_MDEF|SCB_ASPD|SCB_SPEED );
  330.     add_sc( MO_BLADESTOP        , SC_BLADESTOP_WAIT );
  331.     set_sc( MO_BLADESTOP        , SC_BLADESTOP  , SI_BLADESTOP  , SCB_NONE );
  332.     set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS   , SI_EXPLOSIONSPIRITS   , SCB_CRI|SCB_REGEN );
  333.     set_sc( MO_EXTREMITYFIST    , SC_EXTREMITYFIST  , SI_BLANK          , SCB_REGEN );
  334. #ifdef RENEWAL
  335.     set_sc( MO_EXTREMITYFIST    , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST  , SCB_NONE );
  336. #endif
  337.     set_sc( SA_MAGICROD     , SC_MAGICROD   , SI_MAGICROD   , SCB_NONE );
  338.     set_sc( SA_AUTOSPELL        , SC_AUTOSPELL      , SI_AUTOSPELL      , SCB_NONE );
  339.     set_sc( SA_FLAMELAUNCHER    , SC_FIREWEAPON     , SI_FIREWEAPON     , SCB_ATK_ELE );
  340.     set_sc( SA_FROSTWEAPON      , SC_WATERWEAPON    , SI_WATERWEAPON    , SCB_ATK_ELE );
  341.     set_sc( SA_LIGHTNINGLOADER  , SC_WINDWEAPON     , SI_WINDWEAPON     , SCB_ATK_ELE );
  342.     set_sc( SA_SEISMICWEAPON    , SC_EARTHWEAPON    , SI_EARTHWEAPON    , SCB_ATK_ELE );
  343.     set_sc( SA_VOLCANO      , SC_VOLCANO        , SI_LANDENDOW      , SCB_WATK );
  344.     set_sc( SA_DELUGE       , SC_DELUGE     , SI_LANDENDOW      , SCB_MAXHP );
  345.     set_sc( SA_VIOLENTGALE      , SC_VIOLENTGALE    , SI_LANDENDOW      , SCB_FLEE );
  346.     add_sc( SA_REVERSEORCISH    , SC_ORCISH     );
  347.     add_sc( SA_COMA         , SC_COMA       );
  348.     set_sc( BD_ENCORE       , SC_DANCING        , SI_BDPLAYING      , SCB_SPEED|SCB_REGEN );
  349.     set_sc( BD_RICHMANKIM       , SC_RICHMANKIM     , SI_RICHMANKIM , SCB_NONE  );
  350.     set_sc( BD_ETERNALCHAOS     , SC_ETERNALCHAOS   , SI_ETERNALCHAOS   , SCB_DEF2 );
  351.     set_sc( BD_DRUMBATTLEFIELD  , SC_DRUMBATTLE     , SI_DRUMBATTLEFIELD    ,
  352. #ifndef RENEWAL
  353.         SCB_WATK|SCB_DEF );
  354. #else
  355.         SCB_DEF );
  356. #endif
  357.     set_sc( BD_RINGNIBELUNGEN   , SC_NIBELUNGEN     , SI_RINGNIBELUNGEN     ,
  358. #ifndef RENEWAL
  359.         SCB_WATK );
  360. #else
  361.         SCB_NONE );
  362. #endif
  363.     set_sc( BD_ROKISWEIL        , SC_ROKISWEIL  , SI_ROKISWEIL  , SCB_NONE );
  364.     set_sc( BD_INTOABYSS        , SC_INTOABYSS  , SI_INTOABYSS  , SCB_NONE );
  365.     set_sc( BD_SIEGFRIED        , SC_SIEGFRIED      , SI_SIEGFRIED  , SCB_ALL );
  366.     add_sc( BA_FROSTJOKER       , SC_FREEZE     );
  367.     set_sc( BA_WHISTLE      , SC_WHISTLE        , SI_WHISTLE        , SCB_FLEE|SCB_FLEE2 );
  368.     set_sc( BA_ASSASSINCROSS    , SC_ASSNCROS       , SI_ASSASSINCROSS      , SCB_ASPD );
  369.     set_sc( BA_POEMBRAGI        , SC_POEMBRAGI  , SI_POEMBRAGI  , SCB_NONE  );
  370.     set_sc( BA_APPLEIDUN        , SC_APPLEIDUN      , SI_APPLEIDUN      , SCB_MAXHP );
  371.     add_sc( DC_SCREAM       , SC_STUN );
  372.     set_sc( DC_HUMMING      , SC_HUMMING        , SI_HUMMING        , SCB_HIT );
  373.     set_sc( DC_DONTFORGETME     , SC_DONTFORGETME   , SI_DONTFORGETME   , SCB_SPEED|SCB_ASPD );
  374.     set_sc( DC_FORTUNEKISS      , SC_FORTUNE        , SI_FORTUNEKISS    , SCB_CRI );
  375.     set_sc( DC_SERVICEFORYOU    , SC_SERVICE4U      , SI_SERVICEFORYOU  , SCB_ALL );
  376.     add_sc( NPC_DARKCROSS       , SC_BLIND      );
  377.     add_sc( NPC_GRANDDARKNESS   , SC_BLIND      );
  378.     set_sc( NPC_STOP        , SC_STOP       , SI_STOP       , SCB_NONE );
  379.     set_sc( NPC_WEAPONBRAKER    , SC_BROKENWEAPON   , SI_BROKENWEAPON   , SCB_NONE );
  380.     set_sc( NPC_ARMORBRAKE      , SC_BROKENARMOR    , SI_BROKENARMOR    , SCB_NONE );
  381.     set_sc( NPC_CHANGEUNDEAD    , SC_CHANGEUNDEAD   , SI_UNDEAD     , SCB_DEF_ELE );
  382.     set_sc( NPC_POWERUP     , SC_INCHITRATE     , SI_BLANK      , SCB_HIT );
  383.     set_sc( NPC_AGIUP       , SC_INCFLEERATE    , SI_BLANK      , SCB_FLEE );
  384.     add_sc( NPC_INVISIBLE       , SC_CLOAKING       );
  385.     set_sc( LK_AURABLADE        , SC_AURABLADE      , SI_AURABLADE      , SCB_NONE );
  386.     set_sc( LK_PARRYING     , SC_PARRYING       , SI_PARRYING       , SCB_NONE );
  387.     set_sc( LK_CONCENTRATION    , SC_CONCENTRATION  , SI_CONCENTRATION  ,
  388. #ifndef RENEWAL
  389.         SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2 );
  390. #else
  391.         SCB_HIT|SCB_DEF );
  392. #endif
  393.     set_sc( LK_TENSIONRELAX     , SC_TENSIONRELAX   , SI_TENSIONRELAX   , SCB_REGEN );
  394.     set_sc( LK_BERSERK      , SC_BERSERK        , SI_BERSERK        , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
  395.     set_sc( HP_ASSUMPTIO        , SC_ASSUMPTIO      ,
  396. #ifndef RENEWAL
  397.             SI_ASSUMPTIO        , SCB_NONE );
  398. #else
  399.             SI_ASSUMPTIO2       , SCB_NONE );
  400. #endif
  401.     add_sc( HP_BASILICA     , SC_BASILICA       );
  402.     set_sc( HW_MAGICPOWER       , SC_MAGICPOWER     , SI_MAGICPOWER     , SCB_MATK );
  403.     add_sc( PA_SACRIFICE        , SC_SACRIFICE      );
  404.     set_sc( PA_GOSPEL       , SC_GOSPEL     , SI_GOSPEL     , SCB_SPEED|SCB_ASPD );
  405.     add_sc( PA_GOSPEL       , SC_SCRESIST       );
  406.     add_sc( CH_TIGERFIST        , SC_STOP       );
  407.     set_sc( ASC_EDP         , SC_EDP        , SI_EDP        , SCB_NONE );
  408.     set_sc( SN_SIGHT        , SC_TRUESIGHT      , SI_TRUESIGHT      , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_CRI|SCB_HIT );
  409.     set_sc( SN_WINDWALK     , SC_WINDWALK       , SI_WINDWALK       , SCB_FLEE|SCB_SPEED );
  410.     set_sc( WS_MELTDOWN     , SC_MELTDOWN       , SI_MELTDOWN       , SCB_NONE );
  411.     set_sc( WS_CARTBOOST        , SC_CARTBOOST      , SI_CARTBOOST      , SCB_SPEED );
  412.     set_sc( ST_CHASEWALK        , SC_CHASEWALK      , SI_CHASEWALK      , SCB_SPEED );
  413.     set_sc( ST_REJECTSWORD      , SC_REJECTSWORD    , SI_REJECTSWORD    , SCB_NONE );
  414.     add_sc( ST_REJECTSWORD      , SC_AUTOCOUNTER    );
  415.     set_sc( CG_MARIONETTE       , SC_MARIONETTE     , SI_MARIONETTE     , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  416.     set_sc( CG_MARIONETTE       , SC_MARIONETTE2    , SI_MARIONETTE2    , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  417.     add_sc( LK_SPIRALPIERCE     , SC_STOP       );
  418.     add_sc( LK_HEADCRUSH        , SC_BLEEDING       );
  419.     set_sc( LK_JOINTBEAT        , SC_JOINTBEAT      , SI_JOINTBEAT      , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD );
  420.     add_sc( HW_NAPALMVULCAN     , SC_CURSE      );
  421.     set_sc( PF_MINDBREAKER      , SC_MINDBREAKER    , SI_MINDBREAKER    , SCB_MATK|SCB_MDEF2 );
  422.     set_sc( PF_MEMORIZE     , SC_MEMORIZE   , SI_MEMORIZE   , SCB_NONE );
  423.     set_sc( PF_FOGWALL      , SC_FOGWALL    , SI_FOGWALL    , SCB_NONE );
  424.     set_sc( PF_SPIDERWEB        , SC_SPIDERWEB      , SI_SPIDERWEB      , SCB_FLEE );
  425.     set_sc( WE_BABY         , SC_BABY       , SI_BABY       , SCB_NONE );
  426.     set_sc( TK_RUN          , SC_RUN        , SI_RUN        , SCB_SPEED|SCB_DSPD );
  427.     set_sc( TK_RUN          , SC_SPURT      , SI_SPURT      , SCB_STR );
  428.     set_sc( TK_READYSTORM       , SC_READYSTORM     , SI_READYSTORM     , SCB_NONE );
  429.     set_sc( TK_READYDOWN        , SC_READYDOWN      , SI_READYDOWN      , SCB_NONE );
  430.     add_sc( TK_DOWNKICK     , SC_STUN       );
  431.     set_sc( TK_READYTURN        , SC_READYTURN      , SI_READYTURN      , SCB_NONE );
  432.     set_sc( TK_READYCOUNTER     , SC_READYCOUNTER   , SI_READYCOUNTER   , SCB_NONE );
  433.     set_sc( TK_DODGE        , SC_DODGE      , SI_DODGE      , SCB_NONE );
  434.     set_sc( TK_SPTIME       , SC_EARTHSCROLL    , SI_EARTHSCROLL    , SCB_NONE );
  435.     add_sc( TK_SEVENWIND        , SC_SEVENWIND      );
  436.     set_sc( TK_SEVENWIND        , SC_GHOSTWEAPON    , SI_GHOSTWEAPON    , SCB_ATK_ELE );
  437.     set_sc( TK_SEVENWIND        , SC_SHADOWWEAPON   , SI_SHADOWWEAPON   , SCB_ATK_ELE );
  438.     set_sc( SG_SUN_WARM     , SC_WARM       , SI_WARM       , SCB_NONE );
  439.     add_sc( SG_MOON_WARM        , SC_WARM       );
  440.     add_sc( SG_STAR_WARM        , SC_WARM       );
  441.     set_sc( SG_SUN_COMFORT      , SC_SUN_COMFORT    , SI_SUN_COMFORT    , SCB_DEF2 );
  442.     set_sc( SG_MOON_COMFORT     , SC_MOON_COMFORT   , SI_MOON_COMFORT   , SCB_FLEE );
  443.     set_sc( SG_STAR_COMFORT     , SC_STAR_COMFORT   , SI_STAR_COMFORT   , SCB_ASPD );
  444.     add_sc( SG_FRIEND       , SC_SKILLRATE_UP   );
  445.     set_sc( SG_KNOWLEDGE        , SC_KNOWLEDGE      , SI_BLANK      , SCB_ALL );
  446.     set_sc( SG_FUSION       , SC_FUSION     , SI_BLANK      , SCB_SPEED );
  447.     set_sc( BS_ADRENALINE2      , SC_ADRENALINE2    , SI_ADRENALINE2    , SCB_ASPD );
  448.     set_sc( SL_KAIZEL       , SC_KAIZEL     , SI_KAIZEL     , SCB_NONE );
  449.     set_sc( SL_KAAHI        , SC_KAAHI      , SI_KAAHI      , SCB_NONE );
  450.     set_sc( SL_KAUPE        , SC_KAUPE      , SI_KAUPE      , SCB_NONE );
  451.     set_sc( SL_KAITE        , SC_KAITE      , SI_KAITE      , SCB_NONE );
  452.     add_sc( SL_STUN         , SC_STUN       );
  453.     set_sc( SL_SWOO         , SC_SWOO       , SI_SWOO       , SCB_SPEED );
  454.     set_sc( SL_SKE          , SC_SKE        , SI_BLANK      , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2 );
  455.     set_sc( SL_SKA          , SC_SKA        , SI_BLANK      , SCB_DEF|SCB_MDEF|SCB_SPEED|SCB_ASPD );
  456.     set_sc( SL_SMA          , SC_SMA        , SI_SMA        , SCB_NONE );
  457.     set_sc( SM_SELFPROVOKE      , SC_PROVOKE        , SI_PROVOKE        , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
  458.     set_sc( ST_PRESERVE     , SC_PRESERVE       , SI_PRESERVE       , SCB_NONE );
  459.     set_sc( PF_DOUBLECASTING    , SC_DOUBLECAST     , SI_DOUBLECAST     , SCB_NONE );
  460.     set_sc( HW_GRAVITATION      , SC_GRAVITATION    , SI_GRAVITATION    , SCB_ASPD );
  461.     add_sc( WS_CARTTERMINATION  , SC_STUN       );
  462.     set_sc( WS_OVERTHRUSTMAX    , SC_MAXOVERTHRUST  , SI_MAXOVERTHRUST  , SCB_NONE );
  463.     set_sc( CG_LONGINGFREEDOM   , SC_LONGING        , SI_LONGING        , SCB_SPEED|SCB_ASPD );
  464.     set_sc( CG_HERMODE      , SC_HERMODE    , SI_HERMODE    , SCB_NONE      );
  465.     set_sc( ITEM_ENCHANTARMS    , SC_ENCHANTARMS    , SI_BLANK      , SCB_ATK_ELE );
  466.     set_sc( SL_HIGH         , SC_SPIRIT     , SI_SPIRIT     , SCB_ALL );
  467.     set_sc( KN_ONEHAND      , SC_ONEHAND        , SI_ONEHAND        , SCB_ASPD );
  468.     set_sc( GS_FLING        , SC_FLING      , SI_BLANK      , SCB_DEF|SCB_DEF2 );
  469.     add_sc( GS_CRACKER      , SC_STUN       );
  470.     add_sc( GS_DISARM       , SC_STRIPWEAPON    );
  471.     add_sc( GS_PIERCINGSHOT     , SC_BLEEDING       );
  472.     set_sc( GS_MADNESSCANCEL    , SC_MADNESSCANCEL  , SI_MADNESSCANCEL  ,
  473. #ifndef RENEWAL
  474.         SCB_BATK|SCB_ASPD );
  475. #else
  476.         SCB_ASPD );
  477. #endif
  478.     set_sc( GS_ADJUSTMENT       , SC_ADJUSTMENT     , SI_ADJUSTMENT     , SCB_HIT|SCB_FLEE );
  479.     set_sc( GS_INCREASING       , SC_INCREASING     , SI_ACCURACY       , SCB_AGI|SCB_DEX|SCB_HIT );
  480.     set_sc( GS_GATLINGFEVER     , SC_GATLINGFEVER   , SI_GATLINGFEVER   ,
  481. #ifndef RENEWAL
  482.         SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
  483. #else
  484.         SCB_FLEE|SCB_SPEED|SCB_ASPD );
  485. #endif
  486.     add_sc( NJ_TATAMIGAESHI     , SC_TATAMIGAESHI   );
  487.     set_sc( NJ_SUITON       , SC_SUITON     , SI_BLANK      , SCB_AGI|SCB_SPEED );
  488.     add_sc( NJ_HYOUSYOURAKU     , SC_FREEZE     );
  489.     set_sc( NJ_NEN          , SC_NEN        , SI_NEN        , SCB_STR|SCB_INT );
  490.     set_sc( NJ_UTSUSEMI     , SC_UTSUSEMI       , SI_UTSUSEMI       , SCB_NONE );
  491.     set_sc( NJ_BUNSINJYUTSU     , SC_BUNSINJYUTSU   , SI_BUNSINJYUTSU   , SCB_DYE );
  492.  
  493.     add_sc( NPC_ICEBREATH       , SC_FREEZE     );
  494.     add_sc( NPC_ACIDBREATH      , SC_POISON     );
  495.     add_sc( NPC_HELLJUDGEMENT   , SC_CURSE      );
  496.     add_sc( NPC_WIDESILENCE     , SC_SILENCE        );
  497.     add_sc( NPC_WIDEFREEZE      , SC_FREEZE     );
  498.     add_sc( NPC_WIDEBLEEDING    , SC_BLEEDING       );
  499.     add_sc( NPC_WIDESTONE       , SC_STONE      );
  500.     add_sc( NPC_WIDECONFUSE     , SC_CONFUSION      );
  501.     add_sc( NPC_WIDESLEEP       , SC_SLEEP      );
  502.     add_sc( NPC_WIDESIGHT       , SC_SIGHT      );
  503.     add_sc( NPC_EVILLAND        , SC_BLIND      );
  504.     add_sc( NPC_MAGICMIRROR     , SC_MAGICMIRROR    );
  505.     set_sc( NPC_SLOWCAST        , SC_SLOWCAST       , SI_SLOWCAST       , SCB_NONE );
  506.     set_sc( NPC_CRITICALWOUND   , SC_CRITICALWOUND  , SI_CRITICALWOUND  , SCB_NONE );
  507.     set_sc( NPC_STONESKIN       , SC_ARMORCHANGE    , SI_BLANK      , SCB_NONE );
  508.     add_sc( NPC_ANTIMAGIC       , SC_ARMORCHANGE    );
  509.     add_sc( NPC_WIDECURSE       , SC_CURSE      );
  510.     add_sc( NPC_WIDESTUN        , SC_STUN       );
  511.  
  512.     set_sc( NPC_HELLPOWER       , SC_HELLPOWER      , SI_HELLPOWER      , SCB_NONE );
  513.     set_sc( NPC_WIDEHELLDIGNITY , SC_HELLPOWER      , SI_HELLPOWER      , SCB_NONE );
  514.     set_sc( NPC_INVINCIBLE      , SC_INVINCIBLE     , SI_INVINCIBLE     , SCB_SPEED );
  515.     set_sc( NPC_INVINCIBLEOFF   , SC_INVINCIBLEOFF  , SI_BLANK      , SCB_SPEED );
  516.  
  517.     set_sc( CASH_BLESSING       , SC_BLESSING       , SI_BLESSING       , SCB_STR|SCB_INT|SCB_DEX );
  518.     set_sc( CASH_INCAGI     , SC_INCREASEAGI    , SI_INCREASEAGI    , SCB_AGI|SCB_SPEED );
  519.     set_sc( CASH_ASSUMPTIO      , SC_ASSUMPTIO      , SI_ASSUMPTIO      , SCB_NONE );
  520.  
  521.     set_sc( ALL_PARTYFLEE       , SC_PARTYFLEE      , SI_PARTYFLEE      , SCB_NONE );
  522.     set_sc( ALL_ODINS_POWER     , SC_ODINS_POWER    , SI_ODINS_POWER    , SCB_WATK|SCB_MATK|SCB_MDEF|SCB_DEF );
  523.  
  524.     set_sc( CR_SHRINK       , SC_SHRINK     , SI_SHRINK     , SCB_NONE );
  525.     set_sc( RG_CLOSECONFINE     , SC_CLOSECONFINE2  , SI_CLOSECONFINE2  , SCB_NONE );
  526.     set_sc( RG_CLOSECONFINE     , SC_CLOSECONFINE   , SI_CLOSECONFINE   , SCB_FLEE );
  527.     set_sc( WZ_SIGHTBLASTER     , SC_SIGHTBLASTER   , SI_SIGHTBLASTER   , SCB_NONE );
  528.     set_sc( DC_WINKCHARM        , SC_WINKCHARM      , SI_WINKCHARM      , SCB_NONE );
  529.     add_sc( MO_BALKYOUNG        , SC_STUN       );
  530.     add_sc( SA_ELEMENTWATER     , SC_ELEMENTALCHANGE    );
  531.     add_sc( SA_ELEMENTFIRE      , SC_ELEMENTALCHANGE    );
  532.     add_sc( SA_ELEMENTGROUND    , SC_ELEMENTALCHANGE    );
  533.     add_sc( SA_ELEMENTWIND      , SC_ELEMENTALCHANGE    );
  534.  
  535.     set_sc( HLIF_AVOID      , SC_AVOID      , SI_BLANK      , SCB_SPEED );
  536.     set_sc( HLIF_CHANGE     , SC_CHANGE     , SI_BLANK      , SCB_VIT|SCB_INT );
  537.     set_sc( HFLI_FLEET      , SC_FLEET      , SI_BLANK      , SCB_ASPD|SCB_BATK|SCB_WATK );
  538.     set_sc( HFLI_SPEED      , SC_SPEED      , SI_BLANK      , SCB_FLEE );
  539.     set_sc( HAMI_DEFENCE        , SC_DEFENCE        , SI_BLANK      , SCB_DEF );
  540.     set_sc( HAMI_BLOODLUST      , SC_BLOODLUST      , SI_BLANK      , SCB_BATK|SCB_WATK );
  541.  
  542.     /* Homunculus S */
  543.     add_sc(MH_STAHL_HORN        , SC_STUN       );
  544.     set_sc(MH_ANGRIFFS_MODUS    , SC_ANGRIFFS_MODUS , SI_ANGRIFFS_MODUS , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_MAXHP );
  545.     set_sc(MH_GOLDENE_FERSE     , SC_GOLDENE_FERSE  , SI_GOLDENE_FERSE  , SCB_ASPD|SCB_FLEE );
  546.     add_sc(MH_STEINWAND     , SC_SAFETYWALL     );
  547.     set_sc(MH_OVERED_BOOST      , SC_OVERED_BOOST   , SI_OVERED_BOOST ,     SCB_FLEE|SCB_ASPD|SCB_DEF );
  548.     set_sc(MH_LIGHT_OF_REGENE   , SC_LIGHT_OF_REGENE, SI_LIGHT_OF_REGENE,   SCB_NONE);
  549.     set_sc(MH_VOLCANIC_ASH      , SC_ASH        , SI_VOLCANIC_ASH   , SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE );
  550.     set_sc(MH_GRANITIC_ARMOR    , SC_GRANITIC_ARMOR , SI_GRANITIC_ARMOR , SCB_NONE );
  551.     set_sc(MH_MAGMA_FLOW        , SC_MAGMA_FLOW     , SI_MAGMA_FLOW     , SCB_NONE );
  552.     set_sc(MH_PYROCLASTIC       , SC_PYROCLASTIC    , SI_PYROCLASTIC    , SCB_BATK|SCB_ATK_ELE );
  553.     set_sc(MH_LAVA_SLIDE        , SC_BURNING        , SI_BURNT          , SCB_MDEF );
  554.     set_sc(MH_NEEDLE_OF_PARALYZE    , SC_PARALYSIS      , SI_NEEDLE_OF_PARALYZE , SCB_DEF2 );
  555.     add_sc(MH_POISON_MIST       , SC_BLIND      );
  556.     set_sc(MH_PAIN_KILLER       , SC_PAIN_KILLER    , SI_PAIN_KILLER    , SCB_ASPD );
  557.  
  558.     add_sc(MH_STYLE_CHANGE      , SC_STYLE_CHANGE   );
  559.     set_sc(MH_TINDER_BREAKER    , SC_TINDER_BREAKER2    , SI_TINDER_BREAKER     , SCB_FLEE );
  560.     set_sc(MH_TINDER_BREAKER    , SC_TINDER_BREAKER , SI_TINDER_BREAKER_POSTDELAY   , SCB_FLEE );
  561.     set_sc(MH_CBC           , SC_CBC        , SI_CBC            , SCB_FLEE );
  562.     set_sc(MH_EQC           , SC_EQC        , SI_EQC            , SCB_DEF2|SCB_BATK|SCB_MAXHP );
  563.  
  564.     add_sc( MER_CRASH       , SC_STUN       );
  565.     set_sc( MER_PROVOKE     , SC_PROVOKE        , SI_PROVOKE        , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
  566.     add_sc( MS_MAGNUM       , SC_WATK_ELEMENT   );
  567.     add_sc( MER_SIGHT       , SC_SIGHT      );
  568.     set_sc( MER_DECAGI      , SC_DECREASEAGI    , SI_DECREASEAGI    , SCB_AGI|SCB_SPEED );
  569.     set_sc( MER_MAGNIFICAT      , SC_MAGNIFICAT     , SI_MAGNIFICAT     , SCB_REGEN );
  570.     add_sc( MER_LEXDIVINA       , SC_SILENCE        );
  571.     add_sc( MA_LANDMINE     , SC_STUN       );
  572.     add_sc( MA_SANDMAN      , SC_SLEEP      );
  573.     add_sc( MA_FREEZINGTRAP     , SC_FREEZE     );
  574.     set_sc( MER_AUTOBERSERK     , SC_AUTOBERSERK    , SI_AUTOBERSERK    , SCB_NONE );
  575.     set_sc( ML_AUTOGUARD        , SC_AUTOGUARD      , SI_AUTOGUARD      , SCB_NONE );
  576.     set_sc( MS_REFLECTSHIELD    , SC_REFLECTSHIELD  , SI_REFLECTSHIELD  , SCB_NONE );
  577.     set_sc( ML_DEFENDER     , SC_DEFENDER       , SI_DEFENDER       , SCB_SPEED|SCB_ASPD );
  578.     set_sc( MS_PARRYING     , SC_PARRYING       , SI_PARRYING       , SCB_NONE );
  579.     set_sc( MS_BERSERK      , SC_BERSERK        , SI_BERSERK        , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
  580.     add_sc( ML_SPIRALPIERCE     , SC_STOP       );
  581.     set_sc( MER_QUICKEN     , SC_MERC_QUICKEN   , SI_BLANK      , SCB_ASPD );
  582.     add_sc( ML_DEVOTION     , SC_DEVOTION       );
  583.     set_sc( MER_KYRIE       , SC_KYRIE      , SI_KYRIE      , SCB_NONE );
  584.     set_sc( MER_BLESSING        , SC_BLESSING       , SI_BLESSING       , SCB_STR|SCB_INT|SCB_DEX );
  585.     set_sc( MER_INCAGI      , SC_INCREASEAGI    , SI_INCREASEAGI    , SCB_AGI|SCB_SPEED );
  586.  
  587.     set_sc( GD_LEADERSHIP       , SC_LEADERSHIP     , SI_BLANK      , SCB_STR );
  588.     set_sc( GD_GLORYWOUNDS      , SC_GLORYWOUNDS    , SI_BLANK      , SCB_VIT );
  589.     set_sc( GD_SOULCOLD     , SC_SOULCOLD       , SI_BLANK      , SCB_AGI );
  590.     set_sc( GD_HAWKEYES     , SC_HAWKEYES       , SI_BLANK      , SCB_DEX );
  591.  
  592.     set_sc( GD_BATTLEORDER      , SC_BATTLEORDERS   , SI_GDSKILL_BATTLEORDER    , SCB_STR|SCB_INT|SCB_DEX );
  593.     set_sc( GD_REGENERATION     , SC_REGENERATION   , SI_GDSKILL_REGENERATION   , SCB_REGEN );
  594.  
  595.     /* Rune Knight */
  596.     set_sc( RK_ENCHANTBLADE     , SC_ENCHANTBLADE   , SI_ENCHANTBLADE       , SCB_NONE );
  597.     set_sc( RK_DRAGONHOWLING    , SC_FEAR       , SI_BLANK          , SCB_FLEE|SCB_HIT );
  598.     set_sc( RK_DEATHBOUND       , SC_DEATHBOUND     , SI_DEATHBOUND         , SCB_NONE );
  599.     set_sc( RK_WINDCUTTER       , SC_FEAR       , SI_BLANK          , SCB_FLEE|SCB_HIT );
  600.     set_sc( RK_DRAGONBREATH     , SC_BURNING     , SI_BURNT         , SCB_MDEF );
  601.     set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD   , SI_REUSE_MILLENNIUMSHIELD , SCB_NONE );
  602.     set_sc( RK_REFRESH      , SC_REFRESH        , SI_REFRESH            , SCB_NONE );
  603.     set_sc( RK_GIANTGROWTH      , SC_GIANTGROWTH    , SI_GIANTGROWTH        , SCB_STR );
  604.     set_sc( RK_STONEHARDSKIN    , SC_STONEHARDSKIN  , SI_STONEHARDSKIN      , SCB_DEF|SCB_MDEF );
  605.     set_sc( RK_VITALITYACTIVATION   , SC_VITALITYACTIVATION , SI_VITALITYACTIVATION     , SCB_REGEN );
  606.     set_sc( RK_FIGHTINGSPIRIT   , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT     , SCB_WATK|SCB_ASPD );
  607.     set_sc( RK_ABUNDANCE        , SC_ABUNDANCE      , SI_ABUNDANCE          , SCB_NONE );
  608.     set_sc( RK_CRUSHSTRIKE      , SC_CRUSHSTRIKE    , SI_CRUSHSTRIKE        , SCB_NONE );
  609.     set_sc_with_vfx( RK_DRAGONBREATH_WATER  , SC_FREEZING   , SI_FROSTMISTY         , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 );
  610.    
  611.     /* GC Guillotine Cross */
  612.     set_sc_with_vfx( GC_VENOMIMPRESS, SC_VENOMIMPRESS   , SI_VENOMIMPRESS   , SCB_NONE );
  613.     set_sc( GC_POISONINGWEAPON  , SC_POISONINGWEAPON    , SI_POISONINGWEAPON    , SCB_NONE );
  614.     set_sc( GC_WEAPONBLOCKING   , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE );
  615.     set_sc( GC_CLOAKINGEXCEED   , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED );
  616.     set_sc( GC_HALLUCINATIONWALK    , SC_HALLUCINATIONWALK  , SI_HALLUCINATIONWALK  , SCB_FLEE );
  617.     set_sc( GC_ROLLINGCUTTER    , SC_ROLLINGCUTTER  , SI_ROLLINGCUTTER  , SCB_NONE );
  618.     set_sc_with_vfx( GC_DARKCROW    , SC_DARKCROW       , SI_DARKCROW       , SCB_NONE );
  619.  
  620.     /* Arch Bishop */
  621.     set_sc( AB_ADORAMUS     , SC_ADORAMUS       , SI_ADORAMUS       , SCB_AGI|SCB_SPEED );
  622.     add_sc( AB_CLEMENTIA        , SC_BLESSING       );
  623.     add_sc( AB_CANTO        , SC_INCREASEAGI    );
  624.     set_sc( AB_EPICLESIS        , SC_EPICLESIS      , SI_EPICLESIS      , SCB_MAXHP );
  625.     add_sc( AB_PRAEFATIO        , SC_KYRIE      );
  626.     set_sc_with_vfx( AB_ORATIO  , SC_ORATIO     , SI_ORATIO     , SCB_NONE );
  627.     set_sc( AB_LAUDAAGNUS       , SC_LAUDAAGNUS     , SI_LAUDAAGNUS     , SCB_VIT );
  628.     set_sc( AB_LAUDARAMUS       , SC_LAUDARAMUS     , SI_LAUDARAMUS     , SCB_LUK );
  629.     set_sc( AB_RENOVATIO        , SC_RENOVATIO      , SI_RENOVATIO      , SCB_REGEN );
  630.     set_sc( AB_EXPIATIO     , SC_EXPIATIO       , SI_EXPIATIO       , SCB_NONE );
  631.     set_sc( AB_DUPLELIGHT       , SC_DUPLELIGHT     , SI_DUPLELIGHT     , SCB_NONE );
  632.     set_sc( AB_SECRAMENT        , SC_SECRAMENT      , SI_SECRAMENT      , SCB_NONE );
  633.     set_sc( AB_OFFERTORIUM      , SC_OFFERTORIUM    , SI_OFFERTORIUM    , SCB_NONE );
  634.  
  635.     /* Warlock */
  636.     add_sc( WL_WHITEIMPRISON    , SC_WHITEIMPRISON  );
  637.     set_sc_with_vfx( WL_FROSTMISTY  , SC_FREEZING       , SI_FROSTMISTY     , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 );
  638.     add_sc( WL_JACKFROST        , SC_FREEZE       );
  639.     set_sc( WL_MARSHOFABYSS     , SC_MARSHOFABYSS   , SI_MARSHOFABYSS   , SCB_AGI|SCB_DEX|SCB_SPEED );
  640.     set_sc( WL_RECOGNIZEDSPELL  , SC_RECOGNIZEDSPELL    , SI_RECOGNIZEDSPELL    , SCB_MATK);
  641.     add_sc( WL_SIENNAEXECRATE   , SC_STONE        );
  642.     set_sc( WL_STASIS           , SC_STASIS     , SI_STASIS     , SCB_NONE );
  643.     add_sc( WL_CRIMSONROCK      , SC_STUN         );
  644.     set_sc( WL_HELLINFERNO      , SC_BURNING         , SI_BURNT           , SCB_MDEF );
  645.     set_sc( WL_COMET            , SC_BURNING         , SI_BURNT           , SCB_MDEF );
  646.     set_sc( WL_TELEKINESIS_INTENSE  , SC_TELEKINESIS_INTENSE, SI_TELEKINESIS_INTENSE, SCB_MATK );
  647.  
  648.     /* Ranger */
  649.     set_sc( RA_FEARBREEZE       , SC_FEARBREEZE     , SI_FEARBREEZE     , SCB_NONE );
  650.     set_sc( RA_ELECTRICSHOCKER  , SC_ELECTRICSHOCKER    , SI_ELECTRICSHOCKER    , SCB_NONE );
  651.     set_sc( RA_WUGDASH          , SC_WUGDASH        , SI_WUGDASH        , SCB_SPEED|SCB_DSPD );
  652.     set_sc( RA_WUGBITE          , SC_BITE           , SI_WUGBITE        , SCB_NONE );
  653.     set_sc( RA_CAMOUFLAGE       , SC_CAMOUFLAGE     , SI_CAMOUFLAGE     , SCB_SPEED|SCB_DEF|SCB_DEF2 );
  654.     add_sc( RA_MAGENTATRAP      , SC_ELEMENTALCHANGE    );
  655.     add_sc( RA_COBALTTRAP       , SC_ELEMENTALCHANGE    );
  656.     add_sc( RA_MAIZETRAP        , SC_ELEMENTALCHANGE    );
  657.     add_sc( RA_VERDURETRAP      , SC_ELEMENTALCHANGE    );
  658.     set_sc( RA_FIRINGTRAP       , SC_BURNING        , SI_BURNT          , SCB_MDEF );
  659.     set_sc_with_vfx( RA_ICEBOUNDTRAP, SC_FREEZING       , SI_FROSTMISTY     , SCB_SPEED|SCB_ASPD|SCB_DEF|SCB_DEF2 );
  660.     set_sc( RA_UNLIMIT      , SC_UNLIMIT        , SI_UNLIMIT        , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
  661.  
  662.     /* Mechanic */
  663.     set_sc( NC_ACCELERATION     , SC_ACCELERATION   , SI_ACCELERATION   , SCB_SPEED );
  664.     set_sc( NC_HOVERING     , SC_HOVERING       , SI_HOVERING       , SCB_SPEED );
  665.     set_sc( NC_SHAPESHIFT       , SC_SHAPESHIFT     , SI_SHAPESHIFT     , SCB_DEF_ELE );
  666.     set_sc( NC_INFRAREDSCAN     , SC_INFRAREDSCAN   , SI_INFRAREDSCAN   , SCB_FLEE );
  667.     set_sc( NC_ANALYZE      , SC_ANALYZE        , SI_ANALYZE        , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
  668.     set_sc( NC_MAGNETICFIELD    , SC_MAGNETICFIELD  , SI_MAGNETICFIELD  , SCB_NONE );
  669.     set_sc( NC_NEUTRALBARRIER   , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_DEF|SCB_MDEF );
  670.     set_sc( NC_STEALTHFIELD     , SC_STEALTHFIELD   , SI_STEALTHFIELD   , SCB_NONE );
  671.  
  672.     /* Royal Guard */
  673.     set_sc( LG_REFLECTDAMAGE    , SC_REFLECTDAMAGE  , SI_LG_REFLECTDAMAGE   , SCB_NONE );
  674.     set_sc( LG_FORCEOFVANGUARD  , SC_FORCEOFVANGUARD    , SI_FORCEOFVANGUARD    , SCB_MAXHP );
  675.     set_sc( LG_EXEEDBREAK       , SC_EXEEDBREAK     , SI_EXEEDBREAK     , SCB_NONE );
  676.     set_sc( LG_PRESTIGE     , SC_PRESTIGE       , SI_PRESTIGE       , SCB_DEF );
  677.     set_sc( LG_BANDING      , SC_BANDING        , SI_BANDING        , SCB_DEF2|SCB_WATK );
  678.     set_sc( LG_PIETY        , SC_BENEDICTIO     , SI_BENEDICTIO     , SCB_DEF_ELE );
  679.     set_sc( LG_EARTHDRIVE       , SC_EARTHDRIVE     , SI_EARTHDRIVE     , SCB_DEF|SCB_ASPD );
  680.     set_sc( LG_INSPIRATION      , SC_INSPIRATION    , SI_INSPIRATION    , SCB_WATK|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK|SCB_HIT|SCB_MAXHP);
  681.     set_sc( LG_KINGS_GRACE      , SC_KINGS_GRACE    , SI_KINGS_GRACE    , SCB_NONE );
  682.  
  683.     /* Shadow Chaser */
  684.     set_sc( SC_REPRODUCE        , SC__REPRODUCE     , SI_REPRODUCE      , SCB_NONE );
  685.     set_sc( SC_AUTOSHADOWSPELL  , SC__AUTOSHADOWSPELL   , SI_AUTOSHADOWSPELL    , SCB_NONE );
  686.     set_sc( SC_SHADOWFORM       , SC__SHADOWFORM    , SI_SHADOWFORM     , SCB_NONE );
  687.     set_sc( SC_BODYPAINT        , SC__BODYPAINT     , SI_BODYPAINT      , SCB_ASPD );
  688.     set_sc( SC_INVISIBILITY     , SC__INVISIBILITY  , SI_INVISIBILITY   , SCB_ASPD|SCB_CRI|SCB_ATK_ELE );
  689.     set_sc( SC_DEADLYINFECT     , SC__DEADLYINFECT  , SI_DEADLYINFECT   , SCB_NONE );
  690.     set_sc( SC_ENERVATION       , SC__ENERVATION    , SI_ENERVATION     , SCB_BATK|SCB_WATK );
  691.     set_sc( SC_GROOMY       , SC__GROOMY        , SI_GROOMY     , SCB_ASPD|SCB_HIT );
  692.     set_sc( SC_IGNORANCE        , SC__IGNORANCE     , SI_IGNORANCE      , SCB_NONE );
  693.     set_sc( SC_LAZINESS     , SC__LAZINESS      , SI_LAZINESS       , SCB_FLEE|SCB_SPEED );
  694.     set_sc( SC_UNLUCKY      , SC__UNLUCKY       , SI_UNLUCKY        , SCB_CRI|SCB_FLEE2 );
  695.     set_sc( SC_WEAKNESS     , SC__WEAKNESS      , SI_WEAKNESS       , SCB_MAXHP );
  696.     set_sc( SC_STRIPACCESSARY   , SC__STRIPACCESSORY    , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
  697.     set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE       , SI_MANHOLE        , SCB_NONE );
  698.     add_sc( SC_CHAOSPANIC       , SC_CONFUSION      );
  699.     add_sc( SC_BLOODYLUST       , SC_BERSERK        );
  700.     add_sc( SC_FEINTBOMB        , SC__FEINTBOMB     );
  701.  
  702.     /* Sura */
  703.     add_sc( SR_DRAGONCOMBO          , SC_STUN       );
  704.     add_sc( SR_EARTHSHAKER          , SC_STUN       );
  705.     set_sc( SR_CRESCENTELBOW        , SC_CRESCENTELBOW  , SI_CRESCENTELBOW      , SCB_NONE );
  706.     set_sc_with_vfx( SR_CURSEDCIRCLE    , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET    , SCB_NONE );
  707.     set_sc( SR_LIGHTNINGWALK        , SC_LIGHTNINGWALK  , SI_LIGHTNINGWALK      , SCB_NONE );
  708.     set_sc( SR_RAISINGDRAGON        , SC_RAISINGDRAGON  , SI_RAISINGDRAGON      , SCB_REGEN|SCB_MAXHP|SCB_MAXSP );
  709.     set_sc( SR_GENTLETOUCH_ENERGYGAIN   , SC_GT_ENERGYGAIN  , SI_GENTLETOUCH_ENERGYGAIN , SCB_NONE );
  710.     set_sc( SR_GENTLETOUCH_CHANGE       , SC_GT_CHANGE      , SI_GENTLETOUCH_CHANGE     , SCB_WATK|SCB_MDEF|SCB_ASPD );
  711.     set_sc( SR_GENTLETOUCH_REVITALIZE   , SC_GT_REVITALIZE  , SI_GENTLETOUCH_REVITALIZE , SCB_MAXHP|SCB_REGEN );
  712.     set_sc( SR_FLASHCOMBO           , SC_FLASHCOMBO     , SI_FLASHCOMBO         , SCB_NONE );
  713.     add_sc( SR_FLASHCOMBO_ATK_STEP1 , SC_STUN       );
  714.  
  715.     /* Wanderer / Minstrel */
  716.     set_sc( WA_SWING_DANCE          , SC_SWINGDANCE         , SI_SWINGDANCE         , SCB_SPEED|SCB_ASPD );
  717.     set_sc( WA_SYMPHONY_OF_LOVER        , SC_SYMPHONYOFLOVER        , SI_SYMPHONYOFLOVERS       , SCB_MDEF );
  718.     set_sc( WA_MOONLIT_SERENADE     , SC_MOONLITSERENADE        , SI_MOONLITSERENADE        , SCB_MATK );
  719.     set_sc( MI_RUSH_WINDMILL        , SC_RUSHWINDMILL       , SI_RUSHWINDMILL       , SCB_WATK  );
  720.     set_sc( MI_ECHOSONG         , SC_ECHOSONG           , SI_ECHOSONG           , SCB_DEF  );
  721.     set_sc( MI_HARMONIZE            , SC_HARMONIZE          , SI_HARMONIZE          , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  722.     set_sc_with_vfx( WM_POEMOFNETHERWORLD   , SC_NETHERWORLD        , SI_NETHERWORLD        , SCB_NONE );
  723.     set_sc_with_vfx( WM_VOICEOFSIREN    , SC_VOICEOFSIREN       , SI_VOICEOFSIREN       , SCB_NONE );
  724.     set_sc_with_vfx( WM_LULLABY_DEEPSLEEP   , SC_DEEPSLEEP          , SI_DEEPSLEEP          , SCB_NONE );
  725.     set_sc( WM_SIRCLEOFNATURE       , SC_SIRCLEOFNATURE     , SI_SIRCLEOFNATURE     , SCB_NONE );
  726.     set_sc( WM_GLOOMYDAY            , SC_GLOOMYDAY          , SI_GLOOMYDAY          , SCB_FLEE|SCB_SPEED|SCB_ASPD );
  727.     set_sc( WM_SONG_OF_MANA         , SC_SONGOFMANA         , SI_SONGOFMANA         , SCB_NONE );
  728.     set_sc( WM_DANCE_WITH_WUG       , SC_DANCEWITHWUG       , SI_DANCEWITHWUG       , SCB_ASPD );
  729.     set_sc( WM_SATURDAY_NIGHT_FEVER     , SC_SATURDAYNIGHTFEVER     , SI_SATURDAYNIGHTFEVER     , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
  730.     set_sc( WM_LERADS_DEW           , SC_LERADSDEW          , SI_LERADSDEW          , SCB_MAXHP );
  731.     set_sc( WM_MELODYOFSINK         , SC_MELODYOFSINK       , SI_MELODYOFSINK       , SCB_INT );
  732.     set_sc( WM_BEYOND_OF_WARCRY     , SC_BEYONDOFWARCRY     , SI_WARCRYOFBEYOND     , SCB_STR|SCB_CRI|SCB_MAXHP );
  733.     set_sc( WM_UNLIMITED_HUMMING_VOICE  , SC_UNLIMITEDHUMMINGVOICE  , SI_UNLIMITEDHUMMINGVOICE  , SCB_NONE );
  734.     set_sc( WM_FRIGG_SONG           , SC_FRIGG_SONG         , SI_FRIGG_SONG         , SCB_MAXHP );
  735.  
  736.     /* Sorcerer */
  737.     set_sc( SO_FIREWALK     , SC_PROPERTYWALK   , SI_PROPERTYWALK   , SCB_NONE );
  738.     set_sc( SO_ELECTRICWALK     , SC_PROPERTYWALK   , SI_PROPERTYWALK   , SCB_NONE );
  739.     set_sc( SO_SPELLFIST        , SC_SPELLFIST      , SI_SPELLFIST      , SCB_NONE );
  740.     set_sc_with_vfx( SO_DIAMONDDUST , SC_CRYSTALIZE     , SI_COLD       , SCB_NONE );
  741.     set_sc( SO_CLOUD_KILL   , SC_POISON         , SI_CLOUDKILL      , SCB_NONE );
  742.     set_sc( SO_STRIKING     , SC_STRIKING       , SI_STRIKING       , SCB_WATK|SCB_CRI );
  743.     set_sc( SO_WARMER       , SC_WARMER     , SI_WARMER     , SCB_NONE );
  744.     set_sc( SO_VACUUM_EXTREME   , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
  745.     set_sc( SO_ARRULLO      , SC_DEEPSLEEP      , SI_DEEPSLEEP      , SCB_NONE );
  746.     set_sc( SO_FIRE_INSIGNIA    , SC_FIRE_INSIGNIA  , SI_FIRE_INSIGNIA  , SCB_MATK|SCB_BATK|SCB_WATK|SCB_ATK_ELE|SCB_REGEN );
  747.     set_sc( SO_WATER_INSIGNIA   , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK|SCB_ATK_ELE|SCB_REGEN );
  748.     set_sc( SO_WIND_INSIGNIA    , SC_WIND_INSIGNIA  , SI_WIND_INSIGNIA  , SCB_WATK|SCB_ATK_ELE|SCB_REGEN );
  749.     set_sc( SO_EARTH_INSIGNIA   , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK|SCB_ATK_ELE|SCB_REGEN );
  750.  
  751.     /* Genetic */
  752.     set_sc( GN_CARTBOOST            , SC_GN_CARTBOOST   , SI_GN_CARTBOOST           , SCB_SPEED );
  753.     set_sc( GN_THORNS_TRAP          , SC_THORNSTRAP     , SI_THORNTRAP          , SCB_NONE );
  754.     set_sc_with_vfx( GN_BLOOD_SUCKER    , SC_BLOODSUCKER    , SI_BLOODSUCKER        , SCB_NONE );
  755.     set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER  , SC_SMOKEPOWDER    , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_FLEE );
  756.     set_sc( GN_FIRE_EXPANSION_TEAR_GAS  , SC_TEARGAS        , SI_FIRE_EXPANSION_TEAR_GAS    , SCB_HIT|SCB_FLEE );
  757.     set_sc( GN_MANDRAGORA           , SC_MANDRAGORA     , SI_MANDRAGORA         , SCB_INT );
  758.     set_sc_with_vfx( GN_ILLUSIONDOPING  , SC_ILLUSIONDOPING , SI_ILLUSIONDOPING     , SCB_HIT );
  759.  
  760.     /* Elemental spirits' status changes */
  761.     set_sc( EL_CIRCLE_OF_FIRE   , SC_CIRCLE_OF_FIRE_OPTION  , SI_CIRCLE_OF_FIRE_OPTION  , SCB_NONE );
  762.     set_sc( EL_FIRE_CLOAK       , SC_FIRE_CLOAK_OPTION      , SI_FIRE_CLOAK_OPTION      , SCB_ALL );
  763.     set_sc( EL_WATER_SCREEN     , SC_WATER_SCREEN_OPTION    , SI_WATER_SCREEN_OPTION    , SCB_NONE );
  764.     set_sc( EL_WATER_DROP       , SC_WATER_DROP_OPTION      , SI_WATER_DROP_OPTION      , SCB_ALL );
  765.     set_sc( EL_WATER_BARRIER    , SC_WATER_BARRIER      , SI_WATER_BARRIER      , SCB_WATK|SCB_FLEE );
  766.     set_sc( EL_WIND_STEP        , SC_WIND_STEP_OPTION       , SI_WIND_STEP_OPTION       , SCB_SPEED|SCB_FLEE );
  767.     set_sc( EL_WIND_CURTAIN     , SC_WIND_CURTAIN_OPTION    , SI_WIND_CURTAIN_OPTION    , SCB_ALL );
  768.     set_sc( EL_ZEPHYR       , SC_ZEPHYR         , SI_ZEPHYR         , SCB_FLEE );
  769.     set_sc( EL_SOLID_SKIN       , SC_SOLID_SKIN_OPTION      , SI_SOLID_SKIN_OPTION      , SCB_DEF|SCB_MAXHP );
  770.     set_sc( EL_STONE_SHIELD     , SC_STONE_SHIELD_OPTION    , SI_STONE_SHIELD_OPTION    , SCB_ALL );
  771.     set_sc( EL_POWER_OF_GAIA    , SC_POWER_OF_GAIA      , SI_POWER_OF_GAIA      , SCB_MAXHP|SCB_DEF|SCB_SPEED );
  772.     set_sc( EL_PYROTECHNIC      , SC_PYROTECHNIC_OPTION     , SI_PYROTECHNIC_OPTION     , SCB_WATK );
  773.     set_sc( EL_HEATER       , SC_HEATER_OPTION      , SI_HEATER_OPTION      , SCB_WATK );
  774.     set_sc( EL_TROPIC       , SC_TROPIC_OPTION      , SI_TROPIC_OPTION      , SCB_WATK );
  775.     set_sc( EL_AQUAPLAY     , SC_AQUAPLAY_OPTION        , SI_AQUAPLAY_OPTION        , SCB_MATK );
  776.     set_sc( EL_COOLER       , SC_COOLER_OPTION      , SI_COOLER_OPTION      , SCB_MATK );
  777.     set_sc( EL_CHILLY_AIR       , SC_CHILLY_AIR_OPTION      , SI_CHILLY_AIR_OPTION      , SCB_MATK );
  778.     set_sc( EL_GUST         , SC_GUST_OPTION        , SI_GUST_OPTION        , SCB_ASPD );
  779.     set_sc( EL_BLAST        , SC_BLAST_OPTION       , SI_BLAST_OPTION       , SCB_ASPD );
  780.     set_sc( EL_WILD_STORM       , SC_WILD_STORM_OPTION      , SI_WILD_STORM_OPTION      , SCB_ASPD );
  781.     set_sc( EL_PETROLOGY        , SC_PETROLOGY_OPTION       , SI_PETROLOGY_OPTION       , SCB_MAXHP );
  782.     set_sc( EL_CURSED_SOIL      , SC_CURSED_SOIL_OPTION     , SI_CURSED_SOIL_OPTION     , SCB_MAXHP );
  783.     set_sc( EL_UPHEAVAL     , SC_UPHEAVAL_OPTION        , SI_UPHEAVAL_OPTION        , SCB_MAXHP );
  784.     set_sc( EL_TIDAL_WEAPON     , SC_TIDAL_WEAPON_OPTION    , SI_TIDAL_WEAPON_OPTION    , SCB_ALL );
  785.     set_sc( EL_ROCK_CRUSHER     , SC_ROCK_CRUSHER       , SI_ROCK_CRUSHER       , SCB_DEF );
  786.     set_sc( EL_ROCK_CRUSHER_ATK , SC_ROCK_CRUSHER_ATK       , SI_ROCK_CRUSHER_ATK       , SCB_SPEED );
  787.  
  788.     add_sc( KO_YAMIKUMO         , SC_HIDING     );
  789.     set_sc_with_vfx( KO_JYUMONJIKIRI    , SC_JYUMONJIKIRI   , SI_KO_JYUMONJIKIRI    , SCB_NONE );
  790.     add_sc( KO_MAKIBISHI            , SC_STUN       );
  791.     set_sc( KO_MEIKYOUSISUI         , SC_MEIKYOUSISUI   , SI_MEIKYOUSISUI   , SCB_NONE );
  792.     set_sc( KO_KYOUGAKU         , SC_KYOUGAKU       , SI_KYOUGAKU       , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  793.     add_sc( KO_JYUSATSU         , SC_CURSE      );
  794.     set_sc( KO_ZENKAI           , SC_ZENKAI     , SI_ZENKAI     , SCB_NONE );
  795.     set_sc( KO_IZAYOI           , SC_IZAYOI     , SI_IZAYOI     , SCB_MATK );
  796.     set_sc( KG_KYOMU            , SC_KYOMU      , SI_KYOMU      , SCB_NONE );
  797.     set_sc( KG_KAGEMUSYA            , SC_KAGEMUSYA      , SI_KAGEMUSYA      , SCB_NONE );
  798.     set_sc( KG_KAGEHUMI         , SC_KAGEHUMI       , SI_KG_KAGEHUMI    , SCB_NONE );
  799.     set_sc( OB_ZANGETSU         , SC_ZANGETSU       , SI_ZANGETSU       , SCB_MATK|SCB_BATK );
  800.     set_sc_with_vfx( OB_AKAITSUKI       , SC_AKAITSUKI      , SI_AKAITSUKI      , SCB_NONE );
  801.     set_sc( OB_OBOROGENSOU          , SC_GENSOU     , SI_GENSOU     , SCB_NONE );
  802.  
  803.     set_sc( ALL_FULL_THROTTLE       , SC_FULL_THROTTLE  , SI_FULL_THROTTLE  , SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
  804.  
  805.     /* Rebellion */
  806.     add_sc( RL_MASS_SPIRAL      , SC_BLEEDING );
  807.     add_sc( RL_HAMMER_OF_GOD    , SC_STUN );
  808.     set_sc( RL_H_MINE       , SC_H_MINE     , SI_H_MINE     , SCB_NONE);
  809.     set_sc( RL_B_TRAP       , SC_B_TRAP     , SI_B_TRAP     , SCB_SPEED );
  810.     set_sc( RL_E_CHAIN      , SC_E_CHAIN    , SI_E_CHAIN    , SCB_NONE );
  811.     set_sc( RL_P_ALTER      , SC_P_ALTER    , SI_P_ALTER    , SCB_NONE );
  812.     set_sc( RL_SLUGSHOT     , SC_STUN       , SI_SLUGSHOT   , SCB_NONE );
  813.     set_sc( RL_HEAT_BARREL  , SC_HEAT_BARREL    , SI_HEAT_BARREL    , SCB_FLEE|SCB_ASPD );
  814.     set_sc_with_vfx( RL_C_MARKER    , SC_C_MARKER       , SI_C_MARKER       , SCB_FLEE );
  815.     set_sc_with_vfx( RL_AM_BLAST    , SC_ANTI_M_BLAST   , SI_ANTI_M_BLAST   , SCB_NONE );
  816.  
  817.     set_sc_with_vfx_noskill( SC_MOONSTAR    , SI_MOONSTAR   , SCB_NONE );
  818.     set_sc_with_vfx_noskill( SC_SUPER_STAR  , SI_SUPER_STAR , SCB_NONE );
  819.     set_sc_with_vfx_noskill( SC_ALL_RIDING  , SI_ALL_RIDING , SCB_SPEED );
  820.  
  821.     /* Storing the target job rather than simply SC_SPIRIT simplifies code later on */
  822.     SkillStatusChangeTable[skill_get_index(SL_ALCHEMIST)]   = (sc_type)MAPID_ALCHEMIST,
  823.     SkillStatusChangeTable[skill_get_index(SL_MONK)]        = (sc_type)MAPID_MONK,
  824.     SkillStatusChangeTable[skill_get_index(SL_STAR)]        = (sc_type)MAPID_STAR_GLADIATOR,
  825.     SkillStatusChangeTable[skill_get_index(SL_SAGE)]        = (sc_type)MAPID_SAGE,
  826.     SkillStatusChangeTable[skill_get_index(SL_CRUSADER)]    = (sc_type)MAPID_CRUSADER,
  827.     SkillStatusChangeTable[skill_get_index(SL_SUPERNOVICE)] = (sc_type)MAPID_SUPER_NOVICE,
  828.     SkillStatusChangeTable[skill_get_index(SL_KNIGHT)]  = (sc_type)MAPID_KNIGHT,
  829.     SkillStatusChangeTable[skill_get_index(SL_WIZARD)]  = (sc_type)MAPID_WIZARD,
  830.     SkillStatusChangeTable[skill_get_index(SL_PRIEST)]  = (sc_type)MAPID_PRIEST,
  831.     SkillStatusChangeTable[skill_get_index(SL_BARDDANCER)]  = (sc_type)MAPID_BARDDANCER,
  832.     SkillStatusChangeTable[skill_get_index(SL_ROGUE)]   = (sc_type)MAPID_ROGUE,
  833.     SkillStatusChangeTable[skill_get_index(SL_ASSASIN)] = (sc_type)MAPID_ASSASSIN,
  834.     SkillStatusChangeTable[skill_get_index(SL_BLACKSMITH)]  = (sc_type)MAPID_BLACKSMITH,
  835.     SkillStatusChangeTable[skill_get_index(SL_HUNTER)]  = (sc_type)MAPID_HUNTER,
  836.     SkillStatusChangeTable[skill_get_index(SL_SOULLINKER)]  = (sc_type)MAPID_SOUL_LINKER,
  837.  
  838.     /* Status that don't have a skill associated */
  839.     StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
  840.     StatusIconChangeTable[SC_WEIGHT90] = SI_WEIGHT90;
  841.     StatusIconChangeTable[SC_ASPDPOTION0] = SI_ASPDPOTION0;
  842.     StatusIconChangeTable[SC_ASPDPOTION1] = SI_ASPDPOTION1;
  843.     StatusIconChangeTable[SC_ASPDPOTION2] = SI_ASPDPOTION2;
  844.     StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
  845.     StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
  846.     StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
  847.     StatusIconChangeTable[SC_CHASEWALK2] = SI_CHASEWALK2;
  848.     StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
  849.     StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
  850.     StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
  851.     StatusIconChangeTable[SC_AGIFOOD] = SI_FOODAGI;
  852.     StatusIconChangeTable[SC_VITFOOD] = SI_FOODVIT;
  853.     StatusIconChangeTable[SC_INTFOOD] = SI_FOODINT;
  854.     StatusIconChangeTable[SC_DEXFOOD] = SI_FOODDEX;
  855.     StatusIconChangeTable[SC_LUKFOOD] = SI_FOODLUK;
  856.     StatusIconChangeTable[SC_FLEEFOOD] = SI_FOODFLEE;
  857.     StatusIconChangeTable[SC_HITFOOD] = SI_FOODHIT;
  858.     StatusIconChangeTable[SC_CRIFOOD] = SI_FOODCRI;
  859.     StatusIconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
  860.     StatusIconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
  861.     StatusIconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
  862.     StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
  863.     StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
  864.     StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
  865.     StatusIconChangeTable[SC_ATKPOTION] = SI_PLUSATTACKPOWER;
  866.     StatusIconChangeTable[SC_MATKPOTION] = SI_PLUSMAGICPOWER;
  867.  
  868.     /* Cash Items */
  869.     StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
  870.     StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
  871.     StatusIconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH;
  872.     StatusIconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
  873.     StatusIconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
  874.     StatusIconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
  875.     StatusIconChangeTable[SC_EXPBOOST] = SI_EXPBOOST;
  876.     StatusIconChangeTable[SC_ITEMBOOST] = SI_ITEMBOOST;
  877.     StatusIconChangeTable[SC_JEXPBOOST] = SI_CASH_PLUSONLYJOBEXP;
  878.     StatusIconChangeTable[SC_LIFEINSURANCE] = SI_LIFEINSURANCE;
  879.     StatusIconChangeTable[SC_BOSSMAPINFO] = SI_BOSSMAPINFO;
  880.     StatusIconChangeTable[SC_DEF_RATE] = SI_DEF_RATE;
  881.     StatusIconChangeTable[SC_MDEF_RATE] = SI_MDEF_RATE;
  882.     StatusIconChangeTable[SC_INCCRI] = SI_INCCRI;
  883.     StatusIconChangeTable[SC_INCFLEE2] = SI_PLUSAVOIDVALUE;
  884.     StatusIconChangeTable[SC_INCHEALRATE] = SI_INCHEALRATE;
  885.     StatusIconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
  886.     StatusIconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
  887.     StatusIconChangeTable[SC_SPCOST_RATE] = SI_ATKER_BLOOD;
  888.     StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_TARGET_BLOOD;
  889.  
  890.     /* Mercenary Bonus Effects */
  891.     StatusIconChangeTable[SC_MERC_FLEEUP] = SI_MERC_FLEEUP;
  892.     StatusIconChangeTable[SC_MERC_ATKUP] = SI_MERC_ATKUP;
  893.     StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
  894.     StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
  895.     StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
  896.  
  897.     /* Warlock Spheres */
  898.     StatusIconChangeTable[SC_SPHERE_1] = SI_SPHERE_1;
  899.     StatusIconChangeTable[SC_SPHERE_2] = SI_SPHERE_2;
  900.     StatusIconChangeTable[SC_SPHERE_3] = SI_SPHERE_3;
  901.     StatusIconChangeTable[SC_SPHERE_4] = SI_SPHERE_4;
  902.     StatusIconChangeTable[SC_SPHERE_5] = SI_SPHERE_5;
  903.  
  904.     /* Warlock Preserved spells */
  905.     StatusIconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
  906.     StatusIconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
  907.     StatusIconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3;
  908.     StatusIconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
  909.     StatusIconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
  910.     StatusIconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
  911.     StatusIconChangeTable[SC_MAXSPELLBOOK] = SI_SPELLBOOK7;
  912.     StatusIconChangeTable[SC_FREEZE_SP] = SI_FREEZE_SP;
  913.  
  914.     StatusIconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
  915.     StatusIconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
  916.     StatusIconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
  917.     StatusIconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
  918.  
  919.     StatusIconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
  920.     StatusIconChangeTable[SC_TOXIN] = SI_TOXIN;
  921.     StatusIconChangeTable[SC_PARALYSE] = SI_PARALYSE;
  922.     StatusIconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
  923.     StatusIconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
  924.     StatusIconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
  925.     StatusIconChangeTable[SC_PYREXIA] = SI_PYREXIA;
  926.     StatusIconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
  927.     StatusIconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
  928.     StatusIconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
  929.     StatusIconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
  930.     StatusIconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
  931.     StatusIconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
  932.     StatusIconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY;
  933.  
  934.     StatusIconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
  935.     StatusIconChangeTable[SC__BLOODYLUST] = SI_BLOODYLUST;
  936.     StatusIconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
  937.     StatusIconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
  938.     StatusIconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
  939.     StatusIconChangeTable[SC_BANANA_BOMB_SITDOWN] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
  940.  
  941.     /* Genetics New Food Items Status Icons */
  942.     StatusIconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
  943.     StatusIconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
  944.     StatusIconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
  945.     StatusIconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
  946.     StatusIconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
  947.     StatusIconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
  948.     StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
  949.     StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] = SI_EXTRACT_WHITE_POTION_Z;
  950.     StatusIconChangeTable[SC_VITATA_500] = SI_VITATA_500;
  951.     StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] = SI_EXTRACT_SALAMINE_JUICE;
  952.     StatusIconChangeTable[SC_BOOST500] = SI_BOOST500;
  953.     StatusIconChangeTable[SC_FULL_SWING_K] = SI_FULL_SWING_K;
  954.     StatusIconChangeTable[SC_MANA_PLUS] = SI_MANA_PLUS;
  955.     StatusIconChangeTable[SC_MUSTLE_M] = SI_MUSTLE_M;
  956.     StatusIconChangeTable[SC_LIFE_FORCE_F] = SI_LIFE_FORCE_F;
  957.  
  958.     /* Elemental Spirit's 'side' status change icons */
  959.     StatusIconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
  960.     StatusIconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
  961.     StatusIconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
  962.     StatusIconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
  963.     StatusIconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
  964.     StatusIconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
  965.     StatusIconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
  966.     StatusIconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
  967.     StatusIconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
  968.     StatusIconChangeTable[SC_HEATER] = SI_HEATER;
  969.     StatusIconChangeTable[SC_TROPIC] = SI_TROPIC;
  970.     StatusIconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
  971.     StatusIconChangeTable[SC_COOLER] = SI_COOLER;
  972.     StatusIconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
  973.     StatusIconChangeTable[SC_GUST] = SI_GUST;
  974.     StatusIconChangeTable[SC_BLAST] = SI_BLAST;
  975.     StatusIconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
  976.     StatusIconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
  977.     StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
  978.     StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
  979.  
  980.     StatusIconChangeTable[SC_REBOUND] = SI_REBOUND;
  981.     StatusIconChangeTable[SC_DEFSET] = SI_SET_NUM_DEF;
  982.     StatusIconChangeTable[SC_MDEFSET] = SI_SET_NUM_MDEF;
  983.     StatusIconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
  984.     StatusIconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
  985.     StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
  986.     StatusIconChangeTable[SC_MTF_ASPD] = SI_MTF_ASPD;
  987.     StatusIconChangeTable[SC_MTF_RANGEATK] = SI_MTF_RANGEATK;
  988.     StatusIconChangeTable[SC_MTF_MATK] = SI_MTF_MATK;
  989.     StatusIconChangeTable[SC_MTF_MLEATKED] = SI_MTF_MLEATKED;
  990.     StatusIconChangeTable[SC_MTF_CRIDAMAGE] = SI_MTF_CRIDAMAGE;
  991.     StatusIconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
  992.     StatusIconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
  993.     StatusIconChangeTable[SC_QD_SHOT_READY] = SI_E_QD_SHOT_READY;
  994.     StatusIconChangeTable[SC_HEAT_BARREL_AFTER] = SI_HEAT_BARREL_AFTER;
  995.     StatusIconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS;
  996.     StatusIconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC;
  997.     StatusIconChangeTable[SC_QUEST_BUFF1] = SI_QUEST_BUFF1;
  998.     StatusIconChangeTable[SC_QUEST_BUFF2] = SI_QUEST_BUFF2;
  999.     StatusIconChangeTable[SC_QUEST_BUFF3] = SI_QUEST_BUFF3;
  1000.     StatusIconChangeTable[SC_MTF_ASPD2] = SI_MTF_ASPD2;
  1001.     StatusIconChangeTable[SC_MTF_RANGEATK2] = SI_MTF_RANGEATK2;
  1002.     StatusIconChangeTable[SC_MTF_MATK2] = SI_MTF_MATK2;
  1003.     StatusIconChangeTable[SC_2011RWC_SCROLL] = SI_2011RWC_SCROLL;
  1004.     StatusIconChangeTable[SC_JP_EVENT04] = SI_JP_EVENT04;
  1005.     StatusIconChangeTable[SC_MTF_HITFLEE] = SI_MTF_HITFLEE;
  1006.     StatusIconChangeTable[SC_MTF_MHP] = SI_MTF_MHP;
  1007.     StatusIconChangeTable[SC_MTF_MSP] = SI_MTF_MSP;
  1008.     StatusIconChangeTable[SC_MTF_PUMPKIN] = SI_MTF_PUMPKIN;
  1009.  
  1010.     /* Other SC which are not necessarily associated to skills */
  1011.     StatusChangeFlagTable[SC_ASPDPOTION0] |= SCB_ASPD;
  1012.     StatusChangeFlagTable[SC_ASPDPOTION1] |= SCB_ASPD;
  1013.     StatusChangeFlagTable[SC_ASPDPOTION2] |= SCB_ASPD;
  1014.     StatusChangeFlagTable[SC_ASPDPOTION3] |= SCB_ASPD;
  1015.     StatusChangeFlagTable[SC_SPEEDUP0] |= SCB_SPEED;
  1016.     StatusChangeFlagTable[SC_SPEEDUP1] |= SCB_SPEED;
  1017.     StatusChangeFlagTable[SC_ATKPOTION] |= SCB_BATK;
  1018.     StatusChangeFlagTable[SC_MATKPOTION] |= SCB_MATK;
  1019.     StatusChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
  1020.     StatusChangeFlagTable[SC_INCSTR] |= SCB_STR;
  1021.     StatusChangeFlagTable[SC_INCAGI] |= SCB_AGI;
  1022.     StatusChangeFlagTable[SC_INCVIT] |= SCB_VIT;
  1023.     StatusChangeFlagTable[SC_INCINT] |= SCB_INT;
  1024.     StatusChangeFlagTable[SC_INCDEX] |= SCB_DEX;
  1025.     StatusChangeFlagTable[SC_INCLUK] |= SCB_LUK;
  1026.     StatusChangeFlagTable[SC_INCHIT] |= SCB_HIT;
  1027.     StatusChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
  1028.     StatusChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
  1029.     StatusChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
  1030.     StatusChangeFlagTable[SC_INCCRI] |= SCB_CRI;
  1031.     StatusChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
  1032.     StatusChangeFlagTable[SC_INCFLEE2] |= SCB_FLEE2;
  1033.     StatusChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
  1034.     StatusChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
  1035.     StatusChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
  1036.     StatusChangeFlagTable[SC_INCMSP] |= SCB_MAXSP;
  1037.     StatusChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
  1038.     StatusChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
  1039.     StatusChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
  1040.     StatusChangeFlagTable[SC_STRFOOD] |= SCB_STR;
  1041.     StatusChangeFlagTable[SC_AGIFOOD] |= SCB_AGI;
  1042.     StatusChangeFlagTable[SC_VITFOOD] |= SCB_VIT;
  1043.     StatusChangeFlagTable[SC_INTFOOD] |= SCB_INT;
  1044.     StatusChangeFlagTable[SC_DEXFOOD] |= SCB_DEX;
  1045.     StatusChangeFlagTable[SC_LUKFOOD] |= SCB_LUK;
  1046.     StatusChangeFlagTable[SC_FLEEFOOD] |= SCB_FLEE;
  1047.     StatusChangeFlagTable[SC_HITFOOD] |= SCB_HIT;
  1048.     StatusChangeFlagTable[SC_CRIFOOD] |= SCB_CRI;
  1049.     StatusChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
  1050.     StatusChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
  1051.     StatusChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
  1052.     StatusChangeFlagTable[SC_ARMOR_ELEMENT] |= SCB_DEF_ELE;
  1053.     StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_DEF_ELE;
  1054.     StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
  1055.     StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
  1056.     StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
  1057.     StatusChangeFlagTable[SC_SLOWDOWN] |= SCB_SPEED;
  1058.     StatusChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
  1059.  
  1060.     /* Cash Items */
  1061.     StatusChangeFlagTable[SC_FOOD_STR_CASH] |= SCB_STR;
  1062.     StatusChangeFlagTable[SC_FOOD_AGI_CASH] |= SCB_AGI;
  1063.     StatusChangeFlagTable[SC_FOOD_VIT_CASH] |= SCB_VIT;
  1064.     StatusChangeFlagTable[SC_FOOD_DEX_CASH] |= SCB_DEX;
  1065.     StatusChangeFlagTable[SC_FOOD_INT_CASH] |= SCB_INT;
  1066.     StatusChangeFlagTable[SC_FOOD_LUK_CASH] |= SCB_LUK;
  1067.  
  1068.     /* Mercenary Bonus Effects */
  1069.     StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE;
  1070.     StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK;
  1071.     StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
  1072.     StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
  1073.     StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
  1074.  
  1075.     StatusChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED;
  1076.     StatusChangeFlagTable[SC_HALLUCINATIONWALK_POSTDELAY] |= SCB_SPEED|SCB_ASPD;
  1077.     StatusChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD;
  1078.     StatusChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
  1079.     StatusChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
  1080.     StatusChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN;
  1081.     StatusChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE;
  1082.     StatusChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
  1083.     StatusChangeFlagTable[SC_BANDING_DEFENCE] |= SCB_SPEED;
  1084.     StatusChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK;
  1085.     StatusChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF;
  1086.     StatusChangeFlagTable[SC_STOMACHACHE] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_DEX|SCB_INT|SCB_LUK;
  1087.     StatusChangeFlagTable[SC_MYSTERIOUS_POWDER] |= SCB_MAXHP;
  1088.     StatusChangeFlagTable[SC_MELON_BOMB] |= SCB_SPEED|SCB_ASPD;
  1089.     StatusChangeFlagTable[SC_BANANA_BOMB] |= SCB_LUK;
  1090.     StatusChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
  1091.     StatusChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
  1092.     StatusChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT;
  1093.     StatusChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
  1094.     StatusChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
  1095.     StatusChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
  1096.     StatusChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
  1097.     StatusChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
  1098.     StatusChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
  1099.     StatusChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
  1100.     StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
  1101.     StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
  1102.     StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN|SCB_MAXSP;
  1103.     StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
  1104.     StatusChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN;
  1105.     StatusChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2;
  1106.     StatusChangeFlagTable[SC_MDEFSET] |= SCB_MDEF|SCB_MDEF2;
  1107.     StatusChangeFlagTable[SC_WEDDING] |= SCB_SPEED;
  1108.     StatusChangeFlagTable[SC_ALL_RIDING] |= SCB_SPEED;
  1109.     StatusChangeFlagTable[SC_PUSH_CART] |= SCB_SPEED;
  1110.     StatusChangeFlagTable[SC_MTF_ASPD] |= SCB_ASPD|SCB_HIT;
  1111.     StatusChangeFlagTable[SC_MTF_MATK] |= SCB_MATK;
  1112.     StatusChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL;
  1113.     StatusChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
  1114.     StatusChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
  1115.     StatusChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE;
  1116.     StatusChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE;
  1117.     StatusChangeFlagTable[SC_QUEST_BUFF1] |= SCB_BATK|SCB_MATK;
  1118.     StatusChangeFlagTable[SC_QUEST_BUFF2] |= SCB_BATK|SCB_MATK;
  1119.     StatusChangeFlagTable[SC_QUEST_BUFF3] |= SCB_BATK|SCB_MATK;
  1120.     StatusChangeFlagTable[SC_MTF_ASPD2] |= SCB_ASPD|SCB_HIT;
  1121.     StatusChangeFlagTable[SC_MTF_MATK2] |= SCB_MATK;
  1122.     StatusChangeFlagTable[SC_2011RWC_SCROLL] |= SCB_BATK|SCB_MATK|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
  1123.     StatusChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT|SCB_FLEE;
  1124.     StatusChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP;
  1125.     StatusChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP;
  1126.  
  1127. #ifdef RENEWAL
  1128.     // renewal EDP increases your weapon atk
  1129.     StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
  1130. #endif
  1131.  
  1132.     if( !battle_config.display_hallucination ) // Disable Hallucination.
  1133.         StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
  1134.  
  1135.     /* StatusDisplayType Table [Ind] */
  1136.     StatusDisplayType[SC_ALL_RIDING]      = true;
  1137.     StatusDisplayType[SC_PUSH_CART]       = true;
  1138.     StatusDisplayType[SC_SPHERE_1]        = true;
  1139.     StatusDisplayType[SC_SPHERE_2]        = true;
  1140.     StatusDisplayType[SC_SPHERE_3]        = true;
  1141.     StatusDisplayType[SC_SPHERE_4]        = true;
  1142.     StatusDisplayType[SC_SPHERE_5]        = true;
  1143.     StatusDisplayType[SC_CAMOUFLAGE]      = true;
  1144.     StatusDisplayType[SC_DUPLELIGHT]      = true;
  1145.     StatusDisplayType[SC_ORATIO]          = true;
  1146.     StatusDisplayType[SC_FREEZING]        = true;
  1147.     StatusDisplayType[SC_VENOMIMPRESS]    = true;
  1148.     StatusDisplayType[SC_HALLUCINATIONWALK]   = true;
  1149.     StatusDisplayType[SC_ROLLINGCUTTER]   = true;
  1150.     StatusDisplayType[SC_BANDING]         = true;
  1151.     StatusDisplayType[SC_CRYSTALIZE]      = true;
  1152.     StatusDisplayType[SC_DEEPSLEEP]       = true;
  1153.     StatusDisplayType[SC_CURSEDCIRCLE_ATKER]  = true;
  1154.     StatusDisplayType[SC_CURSEDCIRCLE_TARGET] = true;
  1155.     StatusDisplayType[SC_NETHERWORLD]     = true;
  1156.     StatusDisplayType[SC_VOICEOFSIREN]    = true;
  1157.     StatusDisplayType[SC_BLOODSUCKER]     = true;
  1158.     StatusDisplayType[SC__SHADOWFORM]     = true;
  1159.     StatusDisplayType[SC__MANHOLE]        = true;
  1160.     StatusDisplayType[SC_JYUMONJIKIRI]    = true;
  1161.     StatusDisplayType[SC_AKAITSUKI]       = true;
  1162.     StatusDisplayType[SC_MONSTER_TRANSFORM]   = true;
  1163.     StatusDisplayType[SC_DARKCROW]        = true;
  1164.     StatusDisplayType[SC_OFFERTORIUM]     = true;
  1165.     StatusDisplayType[SC_TELEKINESIS_INTENSE] = true;
  1166.     StatusDisplayType[SC_UNLIMIT]         = true;
  1167.     StatusDisplayType[SC_ILLUSIONDOPING]      = true;
  1168.     StatusDisplayType[SC_C_MARKER]        = true;
  1169.     StatusDisplayType[SC_ANTI_M_BLAST]    = true;
  1170.     StatusDisplayType[SC_MOONSTAR]        = true;
  1171.     StatusDisplayType[SC_SUPER_STAR]      = true;
  1172.     StatusDisplayType[SC_STRANGELIGHTS]   = true;
  1173.     StatusDisplayType[SC_DECORATION_OF_MUSIC] = true;
  1174.  
  1175.     /* StatusChangeState (SCS_) NOMOVE */
  1176.     StatusChangeStateTable[SC_ANKLE]                |= SCS_NOMOVE;
  1177.     StatusChangeStateTable[SC_AUTOCOUNTER]          |= SCS_NOMOVE;
  1178.     StatusChangeStateTable[SC_TRICKDEAD]            |= SCS_NOMOVE;
  1179.     StatusChangeStateTable[SC_BLADESTOP]            |= SCS_NOMOVE;
  1180.     StatusChangeStateTable[SC_BLADESTOP_WAIT]       |= SCS_NOMOVE;
  1181.     StatusChangeStateTable[SC_GOSPEL]               |= SCS_NOMOVE|SCS_NOMOVECOND;
  1182.     StatusChangeStateTable[SC_BASILICA]             |= SCS_NOMOVE|SCS_NOMOVECOND;
  1183.     StatusChangeStateTable[SC_STOP]                 |= SCS_NOMOVE;
  1184.     StatusChangeStateTable[SC_CLOSECONFINE]         |= SCS_NOMOVE;
  1185.     StatusChangeStateTable[SC_CLOSECONFINE2]        |= SCS_NOMOVE;
  1186.     StatusChangeStateTable[SC_TINDER_BREAKER]       |= SCS_NOMOVE;
  1187.     StatusChangeStateTable[SC_TINDER_BREAKER2]      |= SCS_NOMOVE;
  1188.     StatusChangeStateTable[SC_MADNESSCANCEL]        |= SCS_NOMOVE;
  1189.     StatusChangeStateTable[SC_GRAVITATION]          |= SCS_NOMOVE|SCS_NOMOVECOND;
  1190.     StatusChangeStateTable[SC_WHITEIMPRISON]        |= SCS_NOMOVE;
  1191.     StatusChangeStateTable[SC_ELECTRICSHOCKER]      |= SCS_NOMOVE;
  1192.     StatusChangeStateTable[SC_BITE]                 |= SCS_NOMOVE;
  1193.     StatusChangeStateTable[SC_THORNSTRAP]           |= SCS_NOMOVE;
  1194.     StatusChangeStateTable[SC_MAGNETICFIELD]        |= SCS_NOMOVE|SCS_NOMOVECOND;
  1195.     StatusChangeStateTable[SC__MANHOLE]             |= SCS_NOMOVE;
  1196.     StatusChangeStateTable[SC_CURSEDCIRCLE_ATKER]   |= SCS_NOMOVE;
  1197.     StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET]  |= SCS_NOMOVE;
  1198.     StatusChangeStateTable[SC_CRYSTALIZE]           |= SCS_NOMOVE|SCS_NOMOVECOND;
  1199.     StatusChangeStateTable[SC_NETHERWORLD]          |= SCS_NOMOVE;
  1200.     StatusChangeStateTable[SC_CAMOUFLAGE]           |= SCS_NOMOVE|SCS_NOMOVECOND;
  1201.     StatusChangeStateTable[SC_MEIKYOUSISUI]         |= SCS_NOMOVE;
  1202.     StatusChangeStateTable[SC_KAGEHUMI]             |= SCS_NOMOVE;
  1203.     StatusChangeStateTable[SC_PARALYSIS]            |= SCS_NOMOVE;
  1204.     StatusChangeStateTable[SC_KINGS_GRACE]          |= SCS_NOMOVE;
  1205.     StatusChangeStateTable[SC_VACUUM_EXTREME]       |= SCS_NOMOVE;
  1206.  
  1207.     /* StatusChangeState (SCS_) NOPICKUPITEMS */
  1208.     StatusChangeStateTable[SC_HIDING]               |= SCS_NOPICKITEM;
  1209.     StatusChangeStateTable[SC_CLOAKING]             |= SCS_NOPICKITEM;
  1210.     StatusChangeStateTable[SC_TRICKDEAD]            |= SCS_NOPICKITEM;
  1211.     StatusChangeStateTable[SC_BLADESTOP]            |= SCS_NOPICKITEM;
  1212.     StatusChangeStateTable[SC_CLOAKINGEXCEED]       |= SCS_NOPICKITEM;
  1213.     StatusChangeStateTable[SC__FEINTBOMB]           |= SCS_NOPICKITEM;
  1214.     StatusChangeStateTable[SC_NOCHAT]               |= SCS_NOPICKITEM|SCS_NOPICKITEMCOND;
  1215.  
  1216.     /* StatusChangeState (SCS_) NODROPITEMS */
  1217.     StatusChangeStateTable[SC_AUTOCOUNTER]          |= SCS_NODROPITEM;
  1218.     StatusChangeStateTable[SC_BLADESTOP]            |= SCS_NODROPITEM;
  1219.     StatusChangeStateTable[SC_NOCHAT]               |= SCS_NODROPITEM|SCS_NODROPITEMCOND;
  1220.  
  1221.     /* StatusChangeState (SCS_) NOCAST (skills) */
  1222.     StatusChangeStateTable[SC_SILENCE]              |= SCS_NOCAST;
  1223.     StatusChangeStateTable[SC_STEELBODY]            |= SCS_NOCAST;
  1224.     StatusChangeStateTable[SC_BERSERK]              |= SCS_NOCAST;
  1225.     StatusChangeStateTable[SC__BLOODYLUST]          |= SCS_NOCAST;
  1226.     StatusChangeStateTable[SC_DEATHBOUND]           |= SCS_NOCAST;
  1227.     StatusChangeStateTable[SC_OBLIVIONCURSE]        |= SCS_NOCAST;
  1228.     StatusChangeStateTable[SC_WHITEIMPRISON]        |= SCS_NOCAST;
  1229.     StatusChangeStateTable[SC__SHADOWFORM]          |= SCS_NOCAST;
  1230.     StatusChangeStateTable[SC__INVISIBILITY]        |= SCS_NOCAST;
  1231.     StatusChangeStateTable[SC_CRYSTALIZE]           |= SCS_NOCAST|SCS_NOCASTCOND;
  1232.     StatusChangeStateTable[SC__IGNORANCE]           |= SCS_NOCAST;
  1233.     StatusChangeStateTable[SC__MANHOLE]             |= SCS_NOCAST;
  1234.     StatusChangeStateTable[SC_DEEPSLEEP]            |= SCS_NOCAST;
  1235.     StatusChangeStateTable[SC_SATURDAYNIGHTFEVER]   |= SCS_NOCAST;
  1236.     StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET]  |= SCS_NOCAST;
  1237.     StatusChangeStateTable[SC_KINGS_GRACE]          |= SCS_NOCAST;
  1238.     StatusChangeStateTable[SC_HEAT_BARREL_AFTER]    |= SCS_NOCAST;
  1239.  
  1240.     /* StatusChangeState (SCS_) NOCHAT (skills) */
  1241.     StatusChangeStateTable[SC_BERSERK]              |= SCS_NOCHAT;
  1242.     StatusChangeStateTable[SC_SATURDAYNIGHTFEVER]   |= SCS_NOCHAT;
  1243.     StatusChangeStateTable[SC_DEEPSLEEP]            |= SCS_NOCHAT;
  1244.     StatusChangeStateTable[SC_NOCHAT]               |= SCS_NOCHAT|SCS_NOCHATCOND;
  1245. }
  1246.  
  1247. static void initDummyData(void)
  1248. {
  1249.     memset(&dummy_status, 0, sizeof(dummy_status));
  1250.     dummy_status.hp =
  1251.     dummy_status.max_hp =
  1252.     dummy_status.max_sp =
  1253.     dummy_status.str =
  1254.     dummy_status.agi =
  1255.     dummy_status.vit =
  1256.     dummy_status.int_ =
  1257.     dummy_status.dex =
  1258.     dummy_status.luk =
  1259.     dummy_status.hit = 1;
  1260.     dummy_status.speed = 2000;
  1261.     dummy_status.adelay = 4000;
  1262.     dummy_status.amotion = 2000;
  1263.     dummy_status.dmotion = 2000;
  1264.     dummy_status.ele_lv = 1; // Min elemental level.
  1265.     dummy_status.mode = MD_CANMOVE;
  1266. }
  1267.  
  1268. /**
  1269.  * For copying a status_data structure from b to a, without overwriting current Hp and Sp
  1270.  * @param a: Status data structure to copy from
  1271.  * @param b: Status data structure to copy to
  1272.  */
  1273. static inline void status_cpy(struct status_data* a, const struct status_data* b)
  1274. {
  1275.     memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
  1276. }
  1277.  
  1278. /**
  1279.  * Sets HP to a given value
  1280.  * Will always succeed (overrides heal impediment statuses) but can't kill an object
  1281.  * @param bl: Object whose HP will be set [PC|MOB|HOM|MER|ELEM|NPC]
  1282.  * @param hp: What the HP is to be set as
  1283.  * @param flag: Used in case final value is higher than current
  1284.  *      Use 2 to display healing effect
  1285.  * @return heal or zapped HP if valid
  1286.  */
  1287. int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
  1288. {
  1289.     struct status_data *status;
  1290.     if (hp < 1)
  1291.         return 0;
  1292.     status = status_get_status_data(bl);
  1293.     if (status == &dummy_status)
  1294.         return 0;
  1295.  
  1296.     if (hp > status->max_hp)
  1297.         hp = status->max_hp;
  1298.     if (hp == status->hp)
  1299.         return 0;
  1300.     if (hp > status->hp)
  1301.         return status_heal(bl, hp - status->hp, 0, 1|flag);
  1302.     return status_zap(bl, status->hp - hp, 0);
  1303. }
  1304.  
  1305. /**
  1306.  * Sets Max HP to a given value
  1307.  * @param bl: Object whose Max HP will be set [PC|MOB|HOM|MER|ELEM|NPC]
  1308.  * @param maxhp: What the Max HP is to be set as
  1309.  * @param flag: Used in case final value is higher than current
  1310.  *      Use 2 to display healing effect
  1311.  * @return heal or zapped HP if valid
  1312.  */
  1313. int status_set_maxhp(struct block_list *bl, unsigned int maxhp, int flag)
  1314. {
  1315.     struct status_data *status;
  1316.     if (maxhp < 1)
  1317.         return 0;
  1318.     status = status_get_status_data(bl);
  1319.     if (status == &dummy_status)
  1320.         return 0;
  1321.  
  1322.     if (maxhp == status->max_hp)
  1323.         return 0;
  1324.     if (maxhp > status->max_hp)
  1325.         status_heal(bl, maxhp - status->max_hp, 0, 1|flag);
  1326.     else
  1327.         status_zap(bl, status->max_hp - maxhp, 0);
  1328.  
  1329.     status->max_hp = maxhp;
  1330.     return maxhp;
  1331. }
  1332.  
  1333. /**
  1334.  * Sets SP to a given value
  1335.  * @param bl: Object whose SP will be set [PC|HOM|MER|ELEM]
  1336.  * @param sp: What the SP is to be set as
  1337.  * @param flag: Used in case final value is higher than current
  1338.  *      Use 2 to display healing effect    
  1339.  * @return heal or zapped SP if valid
  1340.  */
  1341. int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
  1342. {
  1343.     struct status_data *status;
  1344.  
  1345.     status = status_get_status_data(bl);
  1346.     if (status == &dummy_status)
  1347.         return 0;
  1348.  
  1349.     if (sp > status->max_sp)
  1350.         sp = status->max_sp;
  1351.     if (sp == status->sp)
  1352.         return 0;
  1353.     if (sp > status->sp)
  1354.         return status_heal(bl, 0, sp - status->sp, 1|flag);
  1355.     return status_zap(bl, 0, status->sp - sp);
  1356. }
  1357.  
  1358. /**
  1359.  * Sets Max SP to a given value
  1360.  * @param bl: Object whose Max SP will be set [PC|HOM|MER|ELEM]
  1361.  * @param maxsp: What the Max SP is to be set as
  1362.  * @param flag: Used in case final value is higher than current
  1363.  *      Use 2 to display healing effect
  1364.  * @return heal or zapped HP if valid
  1365.  */
  1366. int status_set_maxsp(struct block_list *bl, unsigned int maxsp, int flag)
  1367. {
  1368.     struct status_data *status;
  1369.     if (maxsp < 1)
  1370.         return 0;
  1371.     status = status_get_status_data(bl);
  1372.     if (status == &dummy_status)
  1373.         return 0;
  1374.  
  1375.     if (maxsp == status->max_sp)
  1376.         return 0;
  1377.     if (maxsp > status->max_sp)
  1378.         status_heal(bl, maxsp - status->max_sp, 0, 1|flag);
  1379.     else
  1380.         status_zap(bl, status->max_sp - maxsp, 0);
  1381.  
  1382.     status->max_sp = maxsp;
  1383.     return maxsp;
  1384. }
  1385.  
  1386. /**
  1387.  * Takes HP/SP from an Object
  1388.  * @param bl: Object who will have HP/SP taken [PC|MOB|HOM|MER|ELEM]
  1389.  * @param hp: How much HP to charge
  1390.  * @param sp: How much SP to charge
  1391.  * @return hp+sp through status_damage()
  1392.  * Note: HP/SP are integer values, not percentages. Values should be
  1393.  *   calculated either within function call or before
  1394.  */
  1395. int64 status_charge(struct block_list* bl, int64 hp, int64 sp)
  1396. {
  1397.     if(!(bl->type&BL_CONSUME))
  1398.         return (int)hp+sp; // Assume all was charged so there are no 'not enough' fails.
  1399.     return status_damage(NULL, bl, hp, sp, 0, 3);
  1400. }
  1401.  
  1402. /**
  1403.  * Inflicts damage on the target with the according walkdelay.
  1404.  * @param src: Source object giving damage [PC|MOB|PET|HOM|MER|ELEM]
  1405.  * @param target: Target of the damage
  1406.  * @param dhp: How much damage to HP
  1407.  * @param dsp: How much damage to SP
  1408.  * @param walkdelay: Amount of time before object can walk again
  1409.  * @param flag: Damage flag decides various options
  1410.  *      flag&1: Passive damage - Does not trigger cancelling status changes
  1411.  *      flag&2: Fail if there is not enough to subtract
  1412.  *      flag&4: Mob does not give EXP/Loot if killed
  1413.  *      flag&8: Used to damage SP of a dead character
  1414.  * @return hp+sp
  1415.  * Note: HP/SP are integer values, not percentages. Values should be
  1416.  *   calculated either within function call or before
  1417.  */
  1418. int status_damage(struct block_list *src,struct block_list *target,int64 dhp, int64 dsp, int walkdelay, int flag)
  1419. {
  1420.     struct status_data *status;
  1421.     struct status_change *sc;
  1422.     int hp = (int)cap_value(dhp,INT_MIN,INT_MAX);
  1423.     int sp = (int)cap_value(dsp,INT_MIN,INT_MAX);
  1424.  
  1425.     nullpo_ret(target);
  1426.  
  1427.     if(sp && !(target->type&BL_CONSUME))
  1428.         sp = 0; // Not a valid SP target.
  1429.  
  1430.     if (hp < 0) { // Assume absorbed damage.
  1431.         status_heal(target, -hp, 0, 1);
  1432.         hp = 0;
  1433.     }
  1434.  
  1435.     if (sp < 0) {
  1436.         status_heal(target, 0, -sp, 1);
  1437.         sp = 0;
  1438.     }
  1439.  
  1440.     if (target->type == BL_SKILL)
  1441.         return (int)skill_unit_ondamaged((struct skill_unit *)target, hp);
  1442.  
  1443.     status = status_get_status_data(target);
  1444.     if(!status || status == &dummy_status )
  1445.         return 0;
  1446.  
  1447.     if ((unsigned int)hp >= status->hp) {
  1448.         if (flag&2) return 0;
  1449.         hp = status->hp;
  1450.     }
  1451.  
  1452.     if ((unsigned int)sp > status->sp) {
  1453.         if (flag&2) return 0;
  1454.         sp = status->sp;
  1455.     }
  1456.  
  1457.     if (!hp && !sp)
  1458.         return 0;
  1459.  
  1460.     if( !status->hp )
  1461.         flag |= 8;
  1462.  
  1463.     sc = status_get_sc(target);
  1464.     if( hp && battle_config.invincible_nodamage && src && sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
  1465.         hp = 1;
  1466.  
  1467.     if( hp && !(flag&1) ) {
  1468.         if( sc ) {
  1469.             struct status_change_entry *sce;
  1470.             if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  1471.                 status_change_end(target, SC_STONE, INVALID_TIMER);
  1472.             status_change_end(target, SC_FREEZE, INVALID_TIMER);
  1473.             status_change_end(target, SC_SLEEP, INVALID_TIMER);
  1474.             status_change_end(target, SC_WINKCHARM, INVALID_TIMER);
  1475.             status_change_end(target, SC_CONFUSION, INVALID_TIMER);
  1476.             status_change_end(target, SC_TRICKDEAD, INVALID_TIMER);
  1477.             status_change_end(target, SC_HIDING, INVALID_TIMER);
  1478.             status_change_end(target, SC_CLOAKING, INVALID_TIMER);
  1479.             status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
  1480.             status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
  1481.             status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER);
  1482.             if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
  1483.                 /** [Skotlex]
  1484.                 * Endure count is only reduced by non-players on non-gvg maps.
  1485.                 * val4 signals infinite endure.
  1486.                 **/
  1487.                 if (src && src->type != BL_PC && !map_flag_gvg(target->m) && !map[target->m].flag.battleground && --(sce->val2) < 0)
  1488.                     status_change_end(target, SC_ENDURE, INVALID_TIMER);
  1489.             }
  1490.             if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF) {
  1491.                 struct skill_unit_group* sg = skill_id2group(sce->val4);
  1492.                 if (sg) {
  1493.                     skill_delunitgroup(sg);
  1494.                     sce->val4 = 0;
  1495.                     status_change_end(target, SC_GRAVITATION, INVALID_TIMER);
  1496.                 }
  1497.             }
  1498.             if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
  1499.                 status_change_end(target, SC_DANCING, INVALID_TIMER);
  1500.             if(sc->data[SC_CLOAKINGEXCEED] && --(sc->data[SC_CLOAKINGEXCEED]->val2) <= 0)
  1501.                 status_change_end(target, SC_CLOAKINGEXCEED, INVALID_TIMER);
  1502.             if(sc->data[SC_KAGEMUSYA] && --(sc->data[SC_KAGEMUSYA]->val3) <= 0)
  1503.                 status_change_end(target, SC_KAGEMUSYA, INVALID_TIMER);
  1504.         }
  1505.  
  1506.         if (target->type == BL_PC)
  1507.             pc_bonus_script_clear(BL_CAST(BL_PC,target),BSF_REM_ON_DAMAGED);
  1508.         unit_skillcastcancel(target, 2);
  1509.     }
  1510.  
  1511.     status->hp-= hp;
  1512.     status->sp-= sp;
  1513.  
  1514.     if (sc && hp && status->hp) {
  1515.         if (sc->data[SC_AUTOBERSERK] &&
  1516.             (!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) &&
  1517.             status->hp < status->max_hp>>2)
  1518.             sc_start4(src,target,SC_PROVOKE,100,10,1,0,0,0);
  1519.         if (sc->data[SC_BERSERK] && status->hp <= 100)
  1520.             status_change_end(target, SC_BERSERK, INVALID_TIMER);
  1521.         if( sc->data[SC_RAISINGDRAGON] && status->hp <= 1000 )
  1522.             status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
  1523.         if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
  1524.             status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
  1525.     }
  1526.  
  1527.     switch (target->type) {
  1528.         case BL_PC:  pc_damage((TBL_PC*)target,src,hp,sp); break;
  1529.         case BL_MOB: mob_damage((TBL_MOB*)target, src, hp); break;
  1530.         case BL_HOM: hom_damage((TBL_HOM*)target); break;
  1531.         case BL_MER: mercenary_heal((TBL_MER*)target,hp,sp); break;
  1532.         case BL_ELEM: elemental_heal((TBL_ELEM*)target,hp,sp); break;
  1533.     }
  1534.  
  1535.     if( src && target->type == BL_PC && ((TBL_PC*)target)->disguise ) { // Stop walking when attacked in disguise to prevent walk-delay bug
  1536.         unit_stop_walking( target, 1 );
  1537.     }
  1538.  
  1539.     if( status->hp || (flag&8) ) { // Still lives or has been dead before this damage.
  1540.         if (walkdelay)
  1541.             unit_set_walkdelay(target, gettick(), walkdelay, 0);
  1542.         return (int)(hp+sp);
  1543.     }
  1544.  
  1545.     status->hp = 0;
  1546.     /** [Skotlex]
  1547.     * NOTE: These dead functions should return:
  1548.     * 0: Death cancelled, auto-revived.
  1549.     * Non-zero: Standard death. Clear status, cancel move/attack, etc
  1550.     * &2: Remove object from map.
  1551.     * &4: Delete object from memory. (One time spawn mobs)
  1552.     **/
  1553.     switch (target->type) {
  1554.         case BL_PC:  flag = pc_dead((TBL_PC*)target,src); break;
  1555.         case BL_MOB: flag = mob_dead((TBL_MOB*)target, src, flag&4?3:0); break;
  1556.         case BL_HOM: flag = hom_dead((TBL_HOM*)target); break;
  1557.         case BL_MER: flag = mercenary_dead((TBL_MER*)target); break;
  1558.         case BL_ELEM: flag = elemental_dead((TBL_ELEM*)target); break;
  1559.         default:    // Unhandled case, do nothing to object.
  1560.             flag = 0;
  1561.             break;
  1562.     }
  1563.  
  1564.     if(!flag) // Death cancelled.
  1565.         return (int)(hp+sp);
  1566.  
  1567.     // Normal death
  1568.     if (battle_config.clear_unit_ondeath &&
  1569.         battle_config.clear_unit_ondeath&target->type)
  1570.         skill_clear_unitgroup(target);
  1571.  
  1572.     if(target->type&BL_REGEN) { // Reset regen ticks.
  1573.         struct regen_data *regen = status_get_regen_data(target);
  1574.         if (regen) {
  1575.             memset(&regen->tick, 0, sizeof(regen->tick));
  1576.             if (regen->sregen)
  1577.                 memset(&regen->sregen->tick, 0, sizeof(regen->sregen->tick));
  1578.             if (regen->ssregen)
  1579.                 memset(&regen->ssregen->tick, 0, sizeof(regen->ssregen->tick));
  1580.         }
  1581.     }
  1582.  
  1583.     if( sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m) ) { // flag&8 = disable Kaizel
  1584.         int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
  1585.         // Look for Osiris Card's bonus effect on the character and revive 100% or revive normally
  1586.         if ( target->type == BL_PC && BL_CAST(BL_PC,target)->special_state.restart_full_recover )
  1587.             status_revive(target, 100, 100);
  1588.         else
  1589.             status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
  1590.         status_change_clear(target,0);
  1591.         clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1);
  1592.         sc_start(src,target,status_skill2sc(PR_KYRIE),100,10,time);
  1593.  
  1594.         if( target->type == BL_MOB )
  1595.             ((TBL_MOB*)target)->state.rebirth = 1;
  1596.  
  1597.         return (int)(hp+sp);
  1598.     }
  1599.     if (target->type == BL_MOB && sc && sc->data[SC_REBIRTH] && !((TBL_MOB*) target)->state.rebirth) { // Ensure the monster has not already rebirthed before doing so.
  1600.         status_revive(target, sc->data[SC_REBIRTH]->val2, 0);
  1601.         status_change_clear(target,0);
  1602.         ((TBL_MOB*)target)->state.rebirth = 1;
  1603.  
  1604.         return (int)(hp+sp);
  1605.     }
  1606.  
  1607.     status_change_clear(target,0);
  1608.  
  1609.     if(flag&4) // Delete from memory. (also invokes map removal code)
  1610.         unit_free(target,CLR_DEAD);
  1611.     else if(flag&2) // remove from map
  1612.         unit_remove_map(target,CLR_DEAD);
  1613.     else { // Some death states that would normally be handled by unit_remove_map
  1614.         unit_stop_attack(target);
  1615.         unit_stop_walking(target,1);
  1616.         unit_skillcastcancel(target,0);
  1617.         clif_clearunit_area(target,CLR_DEAD);
  1618.         skill_unit_move(target,gettick(),4);
  1619.         skill_cleartimerskill(target);
  1620.     }
  1621.  
  1622.     // Always run NPC scripts for players last
  1623.     //FIXME those ain't always run if a player die if he was resurect meanwhile
  1624.     //cf SC_REBIRTH, SC_KAIZEL, pc_dead...
  1625.     if(target->type == BL_PC) {
  1626.         TBL_PC *sd = BL_CAST(BL_PC,target);
  1627.         if( sd->bg_id ) {
  1628.             struct battleground_data *bg;
  1629.             if( (bg = bg_team_search(sd->bg_id)) != NULL && bg->die_event[0] )
  1630.                 npc_event(sd, bg->die_event, 0);
  1631.         }
  1632.  
  1633.         npc_script_event(sd,NPCE_DIE);
  1634.     }
  1635.  
  1636.     return (int)(hp+sp);
  1637. }
  1638.  
  1639. /**
  1640.  * Heals an object
  1641.  * @param bl: Object to heal [PC|MOB|HOM|MER|ELEM]
  1642.  * @param hhp: How much HP to heal
  1643.  * @param hsp: How much SP to heal
  1644.  * @param flag: Whether it's Forced(&1) or gives HP/SP(&2) heal effect \n
  1645.  *      Forced healing overrides heal impedement statuses (Berserk)
  1646.  * @return hp+sp
  1647.  */
  1648. int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
  1649. {
  1650.     struct status_data *status;
  1651.     struct status_change *sc;
  1652.     int hp = (int)cap_value(hhp,INT_MIN,INT_MAX);
  1653.     int sp = (int)cap_value(hsp,INT_MIN,INT_MAX);
  1654.  
  1655.     status = status_get_status_data(bl);
  1656.  
  1657.     if (status == &dummy_status || !status->hp)
  1658.         return 0;
  1659.  
  1660.     sc = status_get_sc(bl);
  1661.     if (sc && !sc->count)
  1662.         sc = NULL;
  1663.  
  1664.     if (hp < 0) {
  1665.         if (hp == INT_MIN) // -INT_MIN == INT_MIN in some architectures!
  1666.             hp++;
  1667.         status_damage(NULL, bl, -hp, 0, 0, 1);
  1668.         hp = 0;
  1669.     }
  1670.  
  1671.     if(hp) {
  1672.         if( sc && (sc->data[SC_BERSERK]) ) {
  1673.             if( flag&1 )
  1674.                 flag &= ~2;
  1675.             else
  1676.                 hp = 0;
  1677.         }
  1678.  
  1679.         if((unsigned int)hp > status->max_hp - status->hp)
  1680.             hp = status->max_hp - status->hp;
  1681.     }
  1682.  
  1683.     if(sp < 0) {
  1684.         if (sp == INT_MIN)
  1685.             sp++;
  1686.         status_damage(NULL, bl, 0, -sp, 0, 1);
  1687.         sp = 0;
  1688.     }
  1689.  
  1690.     if(sp) {
  1691.         if((unsigned int)sp > status->max_sp - status->sp)
  1692.             sp = status->max_sp - status->sp;
  1693.     }
  1694.  
  1695.     if(!sp && !hp)
  1696.         return 0;
  1697.  
  1698.     status->hp += hp;
  1699.     status->sp += sp;
  1700.  
  1701.     if(hp && sc &&
  1702.         sc->data[SC_AUTOBERSERK] &&
  1703.         sc->data[SC_PROVOKE] &&
  1704.         sc->data[SC_PROVOKE]->val2==1 &&
  1705.         status->hp>=status->max_hp>>2
  1706.     )   // End auto berserk.
  1707.         status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
  1708.  
  1709.     // Send HP update to client
  1710.     switch(bl->type) {
  1711.         case BL_PC:  pc_heal((TBL_PC*)bl,hp,sp,flag&2?1:0); break;
  1712.         case BL_MOB: mob_heal((TBL_MOB*)bl,hp); break;
  1713.         case BL_HOM: hom_heal((TBL_HOM*)bl); break;
  1714.         case BL_MER: mercenary_heal((TBL_MER*)bl,hp,sp); break;
  1715.         case BL_ELEM: elemental_heal((TBL_ELEM*)bl,hp,sp); break;
  1716.     }
  1717.  
  1718.     return (int)hp+sp;
  1719. }
  1720.  
  1721. /**
  1722.  * Applies percentage based damage to a unit.
  1723.  * If a mob is killed this way and there is no src, no EXP/Drops will be awarded.
  1724.  * @param src: Object initiating HP/SP modification [PC|MOB|PET|HOM|MER|ELEM]
  1725.  * @param target: Object to modify HP/SP
  1726.  * @param hp_rate: Percentage of HP to modify. If > 0:percent is of current HP, if < 0:percent is of max HP
  1727.  * @param sp_rate: Percentage of SP to modify. If > 0:percent is of current SP, if < 0:percent is of max SP
  1728.  * @param flag: \n
  1729.  *      0: Heal target \n
  1730.  *      1: Use status_damage \n
  1731.  *      2: Use status_damage and make sure target must not die from subtraction
  1732.  * @return hp+sp through status_heal()
  1733.  */
  1734. int status_percent_change(struct block_list *src, struct block_list *target, int8 hp_rate, int8 sp_rate, uint8 flag)
  1735. {
  1736.     struct status_data *status;
  1737.     unsigned int hp = 0, sp = 0;
  1738.  
  1739.     status = status_get_status_data(target);
  1740.  
  1741.  
  1742.     // It's safe now [MarkZD]
  1743.     if (hp_rate > 99)
  1744.         hp = status->hp;
  1745.     else if (hp_rate > 0)
  1746.         hp = apply_rate(status->hp, hp_rate);
  1747.     else if (hp_rate < -99)
  1748.         hp = status->max_hp;
  1749.     else if (hp_rate < 0)
  1750.         hp = (apply_rate(status->max_hp, -hp_rate));
  1751.     if (hp_rate && !hp)
  1752.         hp = 1;
  1753.  
  1754.     if (flag == 2 && hp >= status->hp)
  1755.         hp = status->hp-1; // Must not kill target.
  1756.  
  1757.     if (sp_rate > 99)
  1758.         sp = status->sp;
  1759.     else if (sp_rate > 0)
  1760.         sp = apply_rate(status->sp, sp_rate);
  1761.     else if (sp_rate < -99)
  1762.         sp = status->max_sp;
  1763.     else if (sp_rate < 0)
  1764.         sp = (apply_rate(status->max_sp, -sp_rate));
  1765.     if (sp_rate && !sp)
  1766.         sp = 1;
  1767.  
  1768.     // Ugly check in case damage dealt is too much for the received args of
  1769.     // status_heal / status_damage. [Skotlex]
  1770.     if (hp > INT_MAX) {
  1771.         hp -= INT_MAX;
  1772.         if (flag)
  1773.             status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
  1774.         else
  1775.             status_heal(target, INT_MAX, 0, 0);
  1776.     }
  1777.     if (sp > INT_MAX) {
  1778.         sp -= INT_MAX;
  1779.         if (flag)
  1780.             status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
  1781.         else
  1782.             status_heal(target, 0, INT_MAX, 0);
  1783.     }
  1784.     if (flag)
  1785.         return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1));
  1786.     return status_heal(target, hp, sp, 0);
  1787. }
  1788.  
  1789. /**
  1790.  * Revives a unit
  1791.  * @param bl: Object to revive [PC|MOB|HOM]
  1792.  * @param per_hp: Percentage of HP to revive with
  1793.  * @param per_sp: Percentage of SP to revive with
  1794.  * @return Successful (1) or Invalid target (0)
  1795.  */
  1796. int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
  1797. {
  1798.     struct status_data *status;
  1799.     unsigned int hp, sp;
  1800.     if (!status_isdead(bl)) return 0;
  1801.  
  1802.     status = status_get_status_data(bl);
  1803.     if (status == &dummy_status)
  1804.         return 0; // Invalid target.
  1805.  
  1806.     hp = (int64)status->max_hp * per_hp/100;
  1807.     sp = (int64)status->max_sp * per_sp/100;
  1808.  
  1809.     if(hp > status->max_hp - status->hp)
  1810.         hp = status->max_hp - status->hp;
  1811.     else if (per_hp && !hp)
  1812.         hp = 1;
  1813.  
  1814.     if(sp > status->max_sp - status->sp)
  1815.         sp = status->max_sp - status->sp;
  1816.     else if (per_sp && !sp)
  1817.         sp = 1;
  1818.  
  1819.     status->hp += hp;
  1820.     status->sp += sp;
  1821.  
  1822.     if (bl->prev) // Animation only if character is already on a map.
  1823.         clif_resurrection(bl, 1);
  1824.     switch (bl->type) {
  1825.         case BL_PC:  pc_revive((TBL_PC*)bl, hp, sp); break;
  1826.         case BL_MOB: mob_revive((TBL_MOB*)bl, hp); break;
  1827.         case BL_HOM: hom_revive((TBL_HOM*)bl, hp, sp); break;
  1828.     }
  1829.     return 1;
  1830. }
  1831.  
  1832. /**
  1833.  * Checks whether the src can use the skill on the target,
  1834.  * taking into account status/option of both source/target
  1835.  * @param src:  Object using skill on target [PC|MOB|PET|HOM|MER|ELEM]
  1836.         src MAY be NULL to indicate we shouldn't check it, this is a ground-based skill attack
  1837.  * @param target: Object being targeted by src [PC|MOB|HOM|MER|ELEM]
  1838.          target MAY be NULL, which checks if src can cast skill_id on the ground
  1839.  * @param skill_id: Skill ID being used on target
  1840.  * @param flag: 0 - Trying to use skill on target
  1841.  *      1 - Cast bar is done
  1842.  *      2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones
  1843.  * @return src can use skill (1) or cannot use skill (0)
  1844.  * @author [Skotlex]
  1845.  */
  1846. bool status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag) {
  1847.     struct status_data *status;
  1848.     struct status_change *sc = NULL, *tsc;
  1849.     int hide_flag;
  1850.  
  1851.     status = src ? status_get_status_data(src) : &dummy_status;
  1852.  
  1853.     if (src && src->type != BL_PC && status_isdead(src))
  1854.         return false;
  1855.  
  1856.     if (!skill_id) { // Normal attack checks.
  1857.         // This mode is only needed for melee attacking.
  1858.         if (!(status->mode&MD_CANATTACK))
  1859.             return false;
  1860.         // Dead state is not checked for skills as some skills can be used
  1861.         // on dead characters, said checks are left to skill.c [Skotlex]
  1862.         if (target && status_isdead(target))
  1863.             return false;
  1864.         if( src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] && src->type != BL_MOB)
  1865.             return false;
  1866.     }
  1867.  
  1868.     switch( skill_id ) {
  1869.         case PA_PRESSURE:
  1870.             if( flag && target ) {
  1871.                 // Gloria Avoids pretty much everything....
  1872.                 tsc = status_get_sc(target);
  1873.                 if(tsc && tsc->option&OPTION_HIDE)
  1874.                     return false;
  1875.             }
  1876.             break;
  1877.         case GN_WALLOFTHORN:
  1878.             if( target && status_isdead(target) )
  1879.                 return false;
  1880.             break;
  1881.         case AL_TELEPORT:
  1882.         case ALL_ODINS_POWER:
  1883.             // Should fail when used on top of Land Protector [Skotlex]
  1884.             if (src && map_getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR)
  1885.                 && !(status->mode&MD_BOSS)
  1886.                 && (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id))
  1887.                 return false;
  1888.             break;
  1889.         default:
  1890.             break;
  1891.     }
  1892.  
  1893.     if ( src )
  1894.         sc = status_get_sc(src);
  1895.  
  1896.     if( sc && sc->count ) {
  1897.         if (sc->data[SC_ALL_RIDING])
  1898.             return false; //You can't use skills while in the new mounts (The client doesn't let you, this is to make cheat-safe)
  1899.  
  1900.         if ((sc->data[SC_ASH] && rnd()%2)) {
  1901.             if (src->type == BL_PC)
  1902.                 clif_skill_fail((TBL_PC*)src,skill_id,USESKILL_FAIL_LEVEL,0);
  1903.             return false;
  1904.         }
  1905.  
  1906.         if (skill_id != RK_REFRESH && sc->opt1 && !(sc->opt1 == OPT1_CRYSTALIZE && src->type == BL_MOB) && sc->opt1 != OPT1_BURNING && skill_id != SR_GENTLETOUCH_CURE) { // Stuned/Frozen/etc
  1907.             if (flag != 1) // Can't cast, casted stuff can't damage.
  1908.                 return false;
  1909.             if (!(skill_get_inf(skill_id)&INF_GROUND_SKILL))
  1910.                 return false; // Targetted spells can't come off.
  1911.         }
  1912.  
  1913.         if (
  1914.             (sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD)
  1915.             || (sc->data[SC_AUTOCOUNTER] && !flag && skill_id)
  1916.             || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL)
  1917.         )
  1918.             return false;
  1919.  
  1920.         if (sc->data[SC_WINKCHARM] && target && !flag) { // Prevents skill usage
  1921.             if (unit_bl2ud(src) && (unit_bl2ud(src))->walktimer == INVALID_TIMER)
  1922.                 unit_walktobl(src, map_id2bl(sc->data[SC_WINKCHARM]->val2), 3, 1);
  1923.             clif_emotion(src, E_LV);
  1924.             return false;
  1925.         }
  1926.  
  1927.         if (sc->data[SC_BLADESTOP]) {
  1928.             switch (sc->data[SC_BLADESTOP]->val1) {
  1929.                 case 5: if (skill_id == MO_EXTREMITYFIST) break;
  1930.                 case 4: if (skill_id == MO_CHAINCOMBO) break;
  1931.                 case 3: if (skill_id == MO_INVESTIGATE) break;
  1932.                 case 2: if (skill_id == MO_FINGEROFFENSIVE) break;
  1933.                 default: return false;
  1934.             }
  1935.         }
  1936.  
  1937.         if (sc->data[SC_DANCING] && flag!=2) {
  1938.             if (src->type == BL_PC && ((skill_id >= WA_SWING_DANCE && skill_id <= WM_UNLIMITED_HUMMING_VOICE ) ||
  1939.                 skill_id == WM_FRIGG_SONG))
  1940.             { // Lvl 5 Lesson or higher allow you use 3rd job skills while dancing.
  1941.                 if( pc_checkskill((TBL_PC*)src,WM_LESSON) < 5 )
  1942.                     return false;
  1943.             } else if(sc->data[SC_LONGING]) { // Allow everything except dancing/re-dancing. [Skotlex]
  1944.                 if (skill_id == BD_ENCORE ||
  1945.                     skill_get_inf2(skill_id)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL)
  1946.                     )
  1947.                     return false;
  1948.             } else if(!(skill_get_inf3(skill_id)&INF3_USABLE_DANCE)) // Skills that can be used in dancing state
  1949.                 return false;
  1950.             if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_id == BD_ADAPTATION)
  1951.                 return false; // Can't amp out of Wand of Hermode :/ [Skotlex]
  1952.         }
  1953.  
  1954.         if (skill_id && // Do not block item-casted skills.
  1955.             (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id)
  1956.         ) { // Skills blocked through status changes...
  1957.             if (!flag && ( // Blocked only from using the skill (stuff like autospell may still go through
  1958.                 sc->cant.cast ||
  1959.                 (sc->data[SC_BASILICA] && (sc->data[SC_BASILICA]->val4 != src->id || skill_id != HP_BASILICA)) || // Only Basilica caster that can cast, and only Basilica to cancel it
  1960.                 (sc->data[SC_MARIONETTE] && skill_id != CG_MARIONETTE) || // Only skill you can use is marionette again to cancel it
  1961.                 (sc->data[SC_MARIONETTE2] && skill_id == CG_MARIONETTE) || // Cannot use marionette if you are being buffed by another
  1962.                 (sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_id)) ||
  1963.                 (sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_id))
  1964.             ))
  1965.                 return false;
  1966.  
  1967.             // Skill blocking.
  1968.             if (
  1969.                 (sc->data[SC_VOLCANO] && skill_id == WZ_ICEWALL) ||
  1970.                 (sc->data[SC_ROKISWEIL] && skill_id != BD_ADAPTATION) ||
  1971.                 (sc->data[SC_HERMODE] && skill_get_inf(skill_id) & INF_SUPPORT_SKILL) ||
  1972.                 (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOSKILL)
  1973.             )
  1974.                 return false;
  1975.         }
  1976.  
  1977.         if (sc->option) {
  1978.             if ((sc->option&OPTION_HIDE) && src->type == BL_PC && (!skill_id || !(skill_get_inf3(skill_id)&INF3_USABLE_HIDING))) {
  1979.                 // Non players can use all skills while hidden.
  1980.                 return false;
  1981.             }
  1982.             if (sc->option&OPTION_CHASEWALK && skill_id != ST_CHASEWALK)
  1983.                 return false;
  1984.         }
  1985.     }
  1986.  
  1987.     if (target == NULL || target == src) // No further checking needed.
  1988.         return true;
  1989.  
  1990.     tsc = status_get_sc(target);
  1991.  
  1992.     if (tsc && tsc->count) {
  1993.         /**
  1994.         * Attacks in invincible are capped to 1 damage and handled in batte.c.
  1995.         * Allow spell break and eske for sealed shrine GDB when in INVINCIBLE state.
  1996.         **/
  1997.         if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] && skill_id && !(skill_id&(SA_SPELLBREAKER|SL_SKE)) )
  1998.             return false;
  1999.         if(!skill_id && tsc->data[SC_TRICKDEAD])
  2000.             return false;
  2001.         if((skill_id == WZ_STORMGUST || skill_id == WZ_FROSTNOVA || skill_id == NJ_HYOUSYOURAKU)
  2002.             && tsc->data[SC_FREEZE])
  2003.             return false;
  2004.         if(skill_id == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
  2005.             return false;
  2006.         if (tsc->data[SC__MANHOLE] && !(skill_get_inf3(skill_id)&INF3_USABLE_MANHOLE))
  2007.             return false;
  2008.     }
  2009.  
  2010.     // If targetting, cloak+hide protect you, otherwise only hiding does.
  2011.     hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
  2012.  
  2013.     // Skill that can hit hidden target
  2014.     if( skill_get_inf3(skill_id)&INF3_HIT_HIDING )
  2015.         hide_flag &= ~OPTION_HIDE;
  2016.  
  2017.     switch( target->type ) {
  2018.         case BL_PC: {
  2019.                 struct map_session_data *tsd = (TBL_PC*)target;
  2020.                 bool is_boss = (status->mode&MD_BOSS);
  2021.                 bool is_detect = ((status->mode&MD_DETECTOR)?true:false);// god-knows-why gcc doesn't shut up until this happens
  2022.  
  2023.                 if (pc_isinvisible(tsd))
  2024.                     return false;
  2025.                 if (tsc) {
  2026.                     if ((tsc->option&hide_flag) && !(status->mode&MD_BOSS) && (tsd->special_state.perfect_hiding || !is_detect))
  2027.                         return false;
  2028.                     if (tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) && (tsd->special_state.perfect_hiding || is_detect))
  2029.                         return false;
  2030.                     if (tsc->data[SC__FEINTBOMB] && (is_boss || is_detect))
  2031.                         return false;
  2032.                     if (tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && (!skill_id || (!flag && src)))
  2033.                         return false;
  2034.                     if (tsc->data[SC_STEALTHFIELD] && !(is_boss || is_detect))
  2035.                         return false;
  2036.                 }
  2037.             }
  2038.             break;
  2039.         case BL_ITEM: // Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
  2040.             // !TODO: Would be nice if this could be used to judge whether the player can or not pick up the item it targets. [Skotlex]
  2041.             if (status->mode&MD_LOOTER)
  2042.                 return true;
  2043.             return false;
  2044.         case BL_HOM:
  2045.         case BL_MER:
  2046.         case BL_ELEM:
  2047.             if( target->type == BL_HOM && skill_id && battle_config.hom_setting&HOMSET_NO_SUPPORT_SKILL && skill_get_inf(skill_id)&INF_SUPPORT_SKILL && battle_get_master(target) != src )
  2048.                 return false; // Can't use support skills on Homunculus (only Master/Self)
  2049.             if( target->type == BL_MER && (skill_id == PR_ASPERSIO || (skill_id >= SA_FLAMELAUNCHER && skill_id <= SA_SEISMICWEAPON)) && battle_get_master(target) != src )
  2050.                 return false; // Can't use Weapon endow skills on Mercenary (only Master)
  2051.             if( skill_id == AM_POTIONPITCHER && ( target->type == BL_MER || target->type == BL_ELEM) )
  2052.                 return false; // Can't use Potion Pitcher on Mercenaries
  2053.         default:
  2054.             // Check for chase-walk/hiding/cloaking opponents.
  2055.             if( tsc ) {
  2056.                 if( tsc->option&hide_flag && !(status->mode&(MD_BOSS|MD_DETECTOR)))
  2057.                     return false;
  2058.             }
  2059.     }
  2060.     return true;
  2061. }
  2062.  
  2063. /**
  2064.  * Checks whether the src can see the target
  2065.  * @param src:  Object using skill on target [PC|MOB|PET|HOM|MER|ELEM]
  2066.  * @param target: Object being targeted by src [PC|MOB|HOM|MER|ELEM]
  2067.  * @return src can see (1) or target is invisible (0)
  2068.  * @author [Skotlex]
  2069.  */
  2070. int status_check_visibility(struct block_list *src, struct block_list *target)
  2071. {
  2072.     int view_range;
  2073.     struct status_data* status = status_get_status_data(src);
  2074.     struct status_change* tsc = status_get_sc(target);
  2075.     switch (src->type) {
  2076.         case BL_MOB:
  2077.             view_range = ((TBL_MOB*)src)->min_chase;
  2078.             break;
  2079.         case BL_PET:
  2080.             view_range = ((TBL_PET*)src)->db->range2;
  2081.             break;
  2082.         default:
  2083.             view_range = AREA_SIZE;
  2084.     }
  2085.  
  2086.     if (src->m != target->m || !check_distance_bl(src, target, view_range))
  2087.         return 0;
  2088.  
  2089.     if ( src->type == BL_NPC) // NPCs don't care for the rest
  2090.         return 1;
  2091.  
  2092.     if (tsc) {
  2093.         switch (target->type) { // Check for chase-walk/hiding/cloaking opponents.
  2094.             case BL_PC: {
  2095.                     struct map_session_data *tsd = (TBL_PC*)target;
  2096.  
  2097.                     if (((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD]) && !(status->mode&MD_BOSS) && (tsd->special_state.perfect_hiding || !(status->mode&MD_DETECTOR)))
  2098.                         return 0;
  2099.                     if (tsc->data[SC_CLOAKINGEXCEED] && !(status->mode&MD_BOSS) && ((tsd && tsd->special_state.perfect_hiding) || (status->mode&MD_DETECTOR)))
  2100.                         return 0;
  2101.                     if (tsc->data[SC__FEINTBOMB] && !(status->mode&(MD_BOSS|MD_DETECTOR)))
  2102.                         return 0;
  2103.                 }
  2104.                 break;
  2105.             default:
  2106.                 if (((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD]) && !(status->mode&(MD_BOSS|MD_DETECTOR)))
  2107.                     return 0;
  2108.         }
  2109.     }
  2110.  
  2111.     return 1;
  2112. }
  2113.  
  2114. /**
  2115.  * Base ASPD value taken from the job tables
  2116.  * @param sd: Player object
  2117.  * @param status: Player status
  2118.  * @return base amotion after single/dual weapon and shield adjustments [RENEWAL]
  2119.  *    base amotion after single/dual weapon and stats adjustments [PRE-RENEWAL]
  2120.  */
  2121. int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status)
  2122. {
  2123.     int amotion;
  2124.     int classidx = pc_class2idx(sd->status.class_);
  2125. #ifdef RENEWAL_ASPD
  2126.     short mod = -1;
  2127.  
  2128.     switch( sd->weapontype2 ) { // Adjustment for dual weilding
  2129.         case W_DAGGER:  mod = 0;    break; // 0, 1, 1
  2130.         case W_1HSWORD:
  2131.         case W_1HAXE:   mod = 1;
  2132.             if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
  2133.                 mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
  2134.     }
  2135.  
  2136.     amotion = ( sd->status.weapon < MAX_WEAPON_TYPE && mod < 0 )
  2137.             ? (job_info[classidx].aspd_base[sd->status.weapon]) // Single weapon
  2138.             : ((job_info[classidx].aspd_base[sd->weapontype2] // Dual-wield
  2139.             + job_info[classidx].aspd_base[sd->weapontype2]) * 6 / 10 + 10 * mod
  2140.             - job_info[classidx].aspd_base[sd->weapontype2]
  2141.             + job_info[classidx].aspd_base[sd->weapontype1]);
  2142.  
  2143.     if ( sd->status.shield )
  2144.             amotion += ( 2000 - job_info[classidx].aspd_base[W_FIST] ) +
  2145.                     ( job_info[classidx].aspd_base[MAX_WEAPON_TYPE] - 2000 );
  2146.  
  2147. #else
  2148.     // Base weapon delay
  2149.     amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
  2150.      ? (job_info[classidx].aspd_base[sd->status.weapon]) // Single weapon
  2151.      : (job_info[classidx].aspd_base[sd->weapontype1] + job_info[classidx].aspd_base[sd->weapontype2])*7/10; // Dual-wield
  2152.  
  2153.     // Percentual delay reduction from stats
  2154.     amotion -= amotion * (4*status->agi + status->dex)/1000;
  2155. #endif
  2156.     // Raw delay adjustment from bAspd bonus
  2157.     amotion += sd->bonus.aspd_add;
  2158.  
  2159.     return amotion;
  2160. }
  2161.  
  2162. /**
  2163.  * Base attack value calculated for units
  2164.  * @param bl: Object to get attack for [PC|HOM]
  2165.  * @param status: Object status
  2166.  * @return base attack
  2167.  * Note: Function only calculates Homunculus bATK in RENEWAL
  2168.  */
  2169. unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status)
  2170. {
  2171.     int flag = 0, str, dex, dstr;
  2172.  
  2173.     if(!(bl->type&battle_config.enable_baseatk))
  2174.         return 0;
  2175.  
  2176.     if (bl->type == BL_PC)
  2177.     switch(((TBL_PC*)bl)->status.weapon) {
  2178.         case W_BOW:
  2179.         case W_MUSICAL:
  2180.         case W_WHIP:
  2181.         case W_REVOLVER:
  2182.         case W_RIFLE:
  2183.         case W_GATLING:
  2184.         case W_SHOTGUN:
  2185.         case W_GRENADE:
  2186.             flag = 1;
  2187.     }
  2188.     if (flag) {
  2189. #ifdef RENEWAL
  2190.         dstr =
  2191. #endif
  2192.         str = status->dex;
  2193.         dex = status->str;
  2194.     } else {
  2195. #ifdef RENEWAL
  2196.         dstr =
  2197. #endif
  2198.         str = status->str;
  2199.         dex = status->dex;
  2200.     }
  2201.     /** [Skotlex]
  2202.     * Normally only players have base-atk, but homunc have a different batk
  2203.     * equation, hinting that perhaps non-players should use this for batk.
  2204.     **/
  2205. #ifdef RENEWAL
  2206.     if (bl->type == BL_HOM)
  2207.         str = 2 * ((((TBL_HOM*)bl)->homunculus.level) + status_get_homstr(bl));
  2208. #else
  2209.     dstr = str/10;
  2210.     str += dstr*dstr;
  2211. #endif
  2212.     if (bl->type == BL_PC)
  2213. #ifdef RENEWAL
  2214.         str = (dstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
  2215.     else if (bl->type == BL_MOB || bl->type == BL_MER)
  2216.         str = dstr + ((TBL_MOB*)bl)->level;
  2217. #else
  2218.         str+= dex/5 + status->luk/5;
  2219. #endif
  2220.     return cap_value(str, 0, USHRT_MAX);
  2221. }
  2222.  
  2223. #ifdef RENEWAL
  2224. /**
  2225.  * Weapon attack value calculated for Players
  2226.  * @param wa: Weapon attack
  2227.  * @param status: Player status
  2228.  * @return weapon attack
  2229.  */
  2230. unsigned int status_weapon_atk(struct weapon_atk wa, struct status_data *status)
  2231. {
  2232.     float str = status->str;
  2233.     if (wa.range > 3)
  2234.         str = status->dex;
  2235.     // wa.at2 = refinement, wa.atk = base equip atk, wa.atk*str/200 = bonus str
  2236.     return wa.atk + wa.atk2 + (int)(wa.atk * (str/200));
  2237. }
  2238. #endif
  2239.  
  2240. #ifndef RENEWAL
  2241.     unsigned short status_base_matk_min(const struct status_data* status) { return status->int_ + (status->int_ / 7) * (status->int_ / 7); }
  2242.     unsigned short status_base_matk_max(const struct status_data* status) { return status->int_ + (status->int_ / 5) * (status->int_ / 5); }
  2243. #endif
  2244.  
  2245. #ifdef RENEWAL
  2246. unsigned short status_base_matk(struct block_list *bl, const struct status_data* status, int level)
  2247. {
  2248.     switch (bl->type) {
  2249.         case BL_MOB:
  2250.             ///! TODO: Confirm these RENEWAL calculations. Currently is using previous calculation before 083cf5d9 (issue: #321) and until re/mob_db.txt is updated.
  2251.             //return status->int_ + level;
  2252.             return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4);
  2253.         case BL_HOM:
  2254.             return status_get_homint(bl) + level;
  2255.         case BL_MER:
  2256.             return status->int_ + status->int_ / 5 * status->int_ / 5;
  2257.         case BL_PC:
  2258.         default:
  2259.             return status->int_ + (status->int_ / 2) + (status->dex / 5) + (status->luk / 3) + (level / 4);
  2260.     }
  2261. }
  2262. #endif
  2263.  
  2264. /**
  2265.  * Fills in the misc data that can be calculated from the other status info (except for level)
  2266.  * @param bl: Object to calculate status on [PC|MOB|PET|HOM|MERC|ELEM]
  2267.  * @param status: Player status
  2268.  */
  2269. void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
  2270. {
  2271.     int stat;
  2272.  
  2273.     // Non players get the value set, players need to stack with previous bonuses.
  2274.     if( bl->type != BL_PC )
  2275.         status->batk =
  2276.         status->hit = status->flee =
  2277.         status->def2 = status->mdef2 =
  2278.         status->cri = status->flee2 = 0;
  2279.  
  2280. #ifdef RENEWAL // Renewal formulas
  2281.     if (bl->type == BL_HOM) {
  2282.         // Def2
  2283.         stat = status_get_homvit(bl) + status_get_homagi(bl) / 2;
  2284.         status->def2 = cap_value(stat, 0, SHRT_MAX);
  2285.         // Mdef2
  2286.         stat = (status_get_homvit(bl) + status_get_homint(bl)) / 2;
  2287.         status->mdef2 = cap_value(stat, 0, SHRT_MAX);
  2288.         // Def
  2289.         stat = status->def;
  2290.         stat += status_get_homvit(bl) + level / 2;
  2291.         status->def = cap_value(stat, 0, SHRT_MAX);
  2292.         // Mdef
  2293.         stat = (int)(((float)status_get_homvit(bl) + level) / 4 + (float)status_get_homint(bl) / 2);
  2294.         status->mdef = cap_value(stat, 0, SHRT_MAX);
  2295.         // Hit
  2296.         stat = level + status->dex + 150;
  2297.         status->hit = cap_value(stat, 1, SHRT_MAX);
  2298.         // Flee
  2299.         stat = level + status_get_homagi(bl);
  2300.         status->flee = cap_value(stat, 1, SHRT_MAX);
  2301.         // Atk
  2302.         stat = (status_get_homstr(bl) + status_get_homdex(bl)) / 5;
  2303.         status->rhw.atk = cap_value(stat, 0, SHRT_MAX);
  2304.         // Atk2
  2305.         stat = (status_get_homluk(bl) + status_get_homstr(bl) + status_get_homdex(bl)) / 3;
  2306.         status->rhw.atk2 = cap_value(stat, 0, SHRT_MAX);
  2307.     } else {
  2308.         // Hit
  2309.         stat = status->hit;
  2310.         stat += level + status->dex + (bl->type == BL_PC ? status->luk / 3 + 175 : 150); //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
  2311.         status->hit = cap_value(stat, 1, SHRT_MAX);
  2312.         // Flee
  2313.         stat = status->flee;
  2314.         stat += level + status->agi + (bl->type == BL_MER ? 0 : bl->type == BL_PC ? status->luk / 5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
  2315.         status->flee = cap_value(stat, 1, SHRT_MAX);
  2316.         // Def2
  2317.         if (bl->type == BL_MER)
  2318.             stat = (int)(status->vit + ((float)level / 10) + ((float)status->vit / 5));
  2319.         else {
  2320.             stat = status->def2;
  2321.             stat += (int)(((float)level + status->vit) / 2 + (bl->type == BL_PC ? ((float)status->agi / 5) : 0)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
  2322.         }
  2323.         status->def2 = cap_value(stat, 0, SHRT_MAX);
  2324.         // Mdef2
  2325.         if (bl->type == BL_MER)
  2326.             stat = (int)(((float)level / 10) + ((float)status->int_ / 5));
  2327.         else {
  2328.             stat = status->mdef2;
  2329.             stat += (int)(bl->type == BL_PC ? (status->int_ + ((float)level / 4) + ((float)(status->dex + status->vit) / 5)) : ((float)(status->int_ + level) / 4)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
  2330.         }
  2331.         status->mdef2 = cap_value(stat, 0, SHRT_MAX);
  2332.     }
  2333.  
  2334.     // MAtk
  2335.     status->matk_min = status->matk_max = status_base_matk(bl, status, level);
  2336.  
  2337.     ///! TODO: Confirm these RENEWAL calculations. Currently is using previous calculation before 083cf5d9 (issue: #321) and until re/mob_db.txt is updated.
  2338.     //switch (bl->type) {
  2339.     //  case BL_MOB:
  2340.     //      status->matk_min += 70 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
  2341.     //      status->matk_max += 130 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
  2342.     //      break;
  2343.     //  case BL_MER:
  2344.     //      status->matk_min += 70 * ((TBL_MER*)bl)->battle_status.rhw.atk2 / 100;
  2345.     //      status->matk_max += 130 * ((TBL_MER*)bl)->battle_status.rhw.atk2 / 100;
  2346.     //      break;
  2347.     //}
  2348. #else
  2349.     // Matk
  2350.     status->matk_min = status_base_matk_min(status);
  2351.     status->matk_max = status_base_matk_max(status);
  2352.     // Hit
  2353.     stat = status->hit;
  2354.     stat += level + status->dex;
  2355.     status->hit = cap_value(stat, 1, SHRT_MAX);
  2356.     // Flee
  2357.     stat = status->flee;
  2358.     stat += level + status->agi;
  2359.     status->flee = cap_value(stat, 1, SHRT_MAX);
  2360.     // Def2
  2361.     stat = status->def2;
  2362.     stat += status->vit;
  2363.     status->def2 = cap_value(stat, 0, SHRT_MAX);
  2364.     // Mdef2
  2365.     stat = status->mdef2;
  2366.     stat += status->int_ + (status->vit>>1);
  2367.     status->mdef2 = cap_value(stat, 0, SHRT_MAX);
  2368. #endif
  2369.  
  2370.     //Critical
  2371.     if( bl->type&battle_config.enable_critical ) {
  2372.         stat = status->cri;
  2373.         stat += 10 + (status->luk*10/3); // (every 1 luk = +0.3 critical)
  2374.         status->cri = cap_value(stat, 1, SHRT_MAX);
  2375.     } else
  2376.         status->cri = 0;
  2377.  
  2378.     if (bl->type&battle_config.enable_perfect_flee) {
  2379.         stat = status->flee2;
  2380.         stat += status->luk + 10; // (every 10 luk = +1 perfect flee)
  2381.         status->flee2 = cap_value(stat, 0, SHRT_MAX);
  2382.     } else
  2383.         status->flee2 = 0;
  2384.  
  2385.     if (status->batk) {
  2386.         int temp = status->batk + status_base_atk(bl, status);
  2387.         status->batk = cap_value(temp, 0, USHRT_MAX);
  2388.     } else
  2389.         status->batk = status_base_atk(bl, status);
  2390.  
  2391.     if (status->cri) {
  2392.         switch (bl->type) {
  2393.             case BL_MOB:
  2394.                 if(battle_config.mob_critical_rate != 100)
  2395.                     status->cri = cap_value(status->cri*battle_config.mob_critical_rate/100,1,SHRT_MAX);
  2396.                 if(!status->cri && battle_config.mob_critical_rate)
  2397.                     status->cri = 10;
  2398.                 break;
  2399.             case BL_PC:
  2400.                 // Players don't have a critical adjustment setting as of yet.
  2401.                 break;
  2402.             default:
  2403.                 if(battle_config.critical_rate != 100)
  2404.                     status->cri = cap_value(status->cri*battle_config.critical_rate/100,1,SHRT_MAX);
  2405.                 if (!status->cri && battle_config.critical_rate)
  2406.                     status->cri = 10;
  2407.         }
  2408.     }
  2409.  
  2410.     if(bl->type&BL_REGEN)
  2411.         status_calc_regen(bl, status, status_get_regen_data(bl));
  2412. }
  2413.  
  2414. /**
  2415.  * Calculates the initial status for the given mob
  2416.  * @param md: Mob object
  2417.  * @param opt: Whether or not it is the first calculation
  2418.         This will only be false when a mob levels up (Regular and WoE Guardians)
  2419.  * @return 1 for calculated special statuses or 0 for none
  2420.  * @author [Skotlex]
  2421.  */
  2422. int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt)
  2423. {
  2424.     struct status_data *status;
  2425.     struct block_list *mbl = NULL;
  2426.     int flag=0;
  2427.  
  2428.     if (opt&SCO_FIRST) { // Set basic level on respawn.
  2429.         if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv)
  2430.             ;
  2431.         else
  2432.             md->level = md->db->lv;
  2433.     }
  2434.  
  2435.     // Check if we need custom base-status
  2436.     if (battle_config.mobs_level_up && md->level > md->db->lv)
  2437.         flag|=1;
  2438.  
  2439.     if (md->special_state.size)
  2440.         flag|=2;
  2441.  
  2442.     if (md->guardian_data && md->guardian_data->guardup_lv)
  2443.         flag|=4;
  2444.     if (md->mob_id == MOBID_EMPERIUM)
  2445.         flag|=4;
  2446.  
  2447.     if (battle_config.slaves_inherit_speed && md->master_id)
  2448.         flag|=8;
  2449.  
  2450.     if (md->master_id && md->special_state.ai>AI_ATTACK)
  2451.         flag|=16;
  2452.  
  2453.     if (!flag) { // No special status required.
  2454.         if (md->base_status) {
  2455.             aFree(md->base_status);
  2456.             md->base_status = NULL;
  2457.         }
  2458.         if (opt&SCO_FIRST)
  2459.             memcpy(&md->status, &md->db->status, sizeof(struct status_data));
  2460.         return 0;
  2461.     }
  2462.     if (!md->base_status)
  2463.         md->base_status = (struct status_data*)aCalloc(1, sizeof(struct status_data));
  2464.  
  2465.     status = md->base_status;
  2466.     memcpy(status, &md->db->status, sizeof(struct status_data));
  2467.  
  2468.     if (flag&(8|16))
  2469.         mbl = map_id2bl(md->master_id);
  2470.  
  2471.     if (flag&8 && mbl) {
  2472.         struct status_data *mstatus = status_get_base_status(mbl);
  2473.  
  2474.         if (mstatus &&
  2475.             battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2))
  2476.             status->speed = mstatus->speed;
  2477.         if( status->speed < 2 ) // Minimum for the unit to function properly
  2478.             status->speed = 2;
  2479.     }
  2480.  
  2481.     if (flag&1) { // Increase from mobs leveling up [Valaris]
  2482.         int diff = md->level - md->db->lv;
  2483.  
  2484.         status->str += diff;
  2485.         status->agi += diff;
  2486.         status->vit += diff;
  2487.         status->int_ += diff;
  2488.         status->dex += diff;
  2489.         status->luk += diff;
  2490.         status->max_hp += diff * status->vit;
  2491.         status->max_sp += diff * status->int_;
  2492.         status->hp = status->max_hp;
  2493.         status->sp = status->max_sp;
  2494.         status->speed -= cap_value(diff, 0, status->speed - 10);
  2495.     }
  2496.  
  2497.     if (flag&2 && battle_config.mob_size_influence) { // Change for sized monsters [Valaris]
  2498.         if (md->special_state.size == SZ_MEDIUM) {
  2499.             status->max_hp >>= 1;
  2500.             status->max_sp >>= 1;
  2501.             if (!status->max_hp) status->max_hp = 1;
  2502.             if (!status->max_sp) status->max_sp = 1;
  2503.             status->hp = status->max_hp;
  2504.             status->sp = status->max_sp;
  2505.             status->str >>= 1;
  2506.             status->agi >>= 1;
  2507.             status->vit >>= 1;
  2508.             status->int_ >>= 1;
  2509.             status->dex >>= 1;
  2510.             status->luk >>= 1;
  2511.             if (!status->str) status->str = 1;
  2512.             if (!status->agi) status->agi = 1;
  2513.             if (!status->vit) status->vit = 1;
  2514.             if (!status->int_) status->int_ = 1;
  2515.             if (!status->dex) status->dex = 1;
  2516.             if (!status->luk) status->luk = 1;
  2517.         } else if (md->special_state.size == SZ_BIG) {
  2518.             status->max_hp <<= 1;
  2519.             status->max_sp <<= 1;
  2520.             status->hp = status->max_hp;
  2521.             status->sp = status->max_sp;
  2522.             status->str <<= 1;
  2523.             status->agi <<= 1;
  2524.             status->vit <<= 1;
  2525.             status->int_ <<= 1;
  2526.             status->dex <<= 1;
  2527.             status->luk <<= 1;
  2528.         }
  2529.     }
  2530.  
  2531.     status_calc_misc(&md->bl, status, md->level);
  2532.  
  2533.     if(flag&4) { // Strengthen Guardians - custom value +10% / lv
  2534.         struct guild_castle *gc;
  2535.  
  2536.         gc=guild_mapname2gc(map[md->bl.m].name);
  2537.         if (!gc)
  2538.             ShowError("status_calc_mob: No castle set at map %s\n", map[md->bl.m].name);
  2539.         else if(gc->castle_id < 24 || md->mob_id == MOBID_EMPERIUM) {
  2540. #ifdef RENEWAL
  2541.             status->max_hp += 50 * gc->defense;
  2542.             status->max_sp += 70 * gc->defense;
  2543. #else
  2544.             status->max_hp += 1000 * gc->defense;
  2545.             status->max_sp += 200 * gc->defense;
  2546. #endif
  2547.             status->hp = status->max_hp;
  2548.             status->sp = status->max_sp;
  2549.             status->def += (gc->defense+2)/3;
  2550.             status->mdef += (gc->defense+2)/3;
  2551.         }
  2552.         if(md->mob_id != MOBID_EMPERIUM) {
  2553.             status->batk += status->batk * 10*md->guardian_data->guardup_lv/100;
  2554.             status->rhw.atk += status->rhw.atk * 10*md->guardian_data->guardup_lv/100;
  2555.             status->rhw.atk2 += status->rhw.atk2 * 10*md->guardian_data->guardup_lv/100;
  2556.             status->aspd_rate -= 100*md->guardian_data->guardup_lv;
  2557.         }
  2558.     }
  2559.  
  2560.     if (flag&16 && mbl) { // Max HP setting from Summon Flora/marine Sphere
  2561.         struct unit_data *ud = unit_bl2ud(mbl);
  2562.         // Remove special AI when this is used by regular mobs.
  2563.         if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai)
  2564.             md->special_state.ai = AI_NONE;
  2565.         if (ud) {
  2566.             // Different levels of HP according to skill level
  2567.             if(!ud->skill_id) // !FIXME: We lost the unit data for magic decoy in somewhere before this
  2568.                 ud->skill_id = ((TBL_PC*)mbl)->menuskill_id;
  2569.             switch(ud->skill_id) {
  2570.                 case AM_SPHEREMINE:
  2571.                     status->max_hp = 2000 + 400*ud->skill_lv;
  2572.                     break;
  2573.                 case KO_ZANZOU:
  2574.                     status->max_hp = 3000 + 3000 * ud->skill_lv;
  2575.                     break;
  2576.                 case AM_CANNIBALIZE:
  2577.                     status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
  2578.                     status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
  2579.                     break;
  2580.                 case MH_SUMMON_LEGION:
  2581.                 {
  2582.                     int homblvl = status_get_lv(mbl);
  2583.  
  2584.                     status->max_hp = 10 * (100 * (ud->skill_lv + 2) + homblvl);
  2585.                     status->batk = 100 * (ud->skill_lv+5) / 2;
  2586.                     status->def = 10 * (100 * (ud->skill_lv+2) + homblvl);
  2587.                     // status->aspd_rate = 10 * (2 * (20 - ud->skill_lv) - homblvl/10);
  2588.                     // status->aspd_rate = max(100,status->aspd_rate);
  2589.                     break;
  2590.                 }
  2591.                 case NC_SILVERSNIPER:
  2592.                 {
  2593.                     struct status_data *mstatus = status_get_status_data(mbl);
  2594.                     if(!mstatus)
  2595.                         break;
  2596.                     status->max_hp = (1000 * ud->skill_lv) + (mstatus->hp / 3) + (status_get_lv(mbl) * 12);
  2597.                     status->batk = 200 * ud->skill_lv;
  2598.                     break;
  2599.                 }
  2600.                 case NC_MAGICDECOY:
  2601.                 {
  2602.                     struct status_data *mstatus = status_get_status_data(mbl);
  2603.                     if(!mstatus)
  2604.                         break;
  2605.                     status->max_hp = (1000 * ((TBL_PC*)mbl)->menuskill_val) + (mstatus->sp * 4) + (status_get_lv(mbl) * 12);
  2606.                     status->matk_min = status->matk_max = 250 + 50*((TBL_PC*)mbl)->menuskill_val;
  2607.                     break;
  2608.                 }
  2609.             }
  2610.             status->hp = status->max_hp;
  2611.         }
  2612.     }
  2613.  
  2614.     if (opt&SCO_FIRST) // Initial battle status
  2615.         memcpy(&md->status, status, sizeof(struct status_data));
  2616.  
  2617.     return 1;
  2618. }
  2619.  
  2620. /**
  2621.  * Calculates the stats of the given pet
  2622.  * @param pd: Pet object
  2623.  * @param opt: Whether or not it is the first calculation
  2624.         This will only be false when a pet levels up
  2625.  * @return 1
  2626.  * @author [Skotlex]
  2627.  */
  2628. void status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
  2629. {
  2630.     nullpo_retv(pd);
  2631.  
  2632.     if (opt&SCO_FIRST) {
  2633.         memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
  2634.         pd->status.mode = MD_CANMOVE; // Pets discard all modes, except walking
  2635.         pd->status.class_ = CLASS_NORMAL;
  2636.         pd->status.speed = pd->petDB->speed;
  2637.  
  2638.         if(battle_config.pet_attack_support || battle_config.pet_damage_support) {
  2639.             // Attack support requires the pet to be able to attack
  2640.             pd->status.mode |= MD_CANATTACK;
  2641.         }
  2642.     }
  2643.  
  2644.     if (battle_config.pet_lv_rate && pd->master) {
  2645.         struct map_session_data *sd = pd->master;
  2646.         int lv;
  2647.  
  2648.         lv =sd->status.base_level*battle_config.pet_lv_rate/100;
  2649.         if (lv < 0)
  2650.             lv = 1;
  2651.         if (lv != pd->pet.level || opt&SCO_FIRST) {
  2652.             struct status_data *bstat = &pd->db->status, *status = &pd->status;
  2653.  
  2654.             pd->pet.level = lv;
  2655.             if (!(opt&SCO_FIRST)) // Lv Up animation
  2656.                 clif_misceffect(&pd->bl, 0);
  2657.             status->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
  2658.             status->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv;
  2659.             status->str = (bstat->str*lv)/pd->db->lv;
  2660.             status->agi = (bstat->agi*lv)/pd->db->lv;
  2661.             status->vit = (bstat->vit*lv)/pd->db->lv;
  2662.             status->int_ = (bstat->int_*lv)/pd->db->lv;
  2663.             status->dex = (bstat->dex*lv)/pd->db->lv;
  2664.             status->luk = (bstat->luk*lv)/pd->db->lv;
  2665.  
  2666.             status->rhw.atk = cap_value(status->rhw.atk, 1, battle_config.pet_max_atk1);
  2667.             status->rhw.atk2 = cap_value(status->rhw.atk2, 2, battle_config.pet_max_atk2);
  2668.             status->str = cap_value(status->str,1,battle_config.pet_max_stats);
  2669.             status->agi = cap_value(status->agi,1,battle_config.pet_max_stats);
  2670.             status->vit = cap_value(status->vit,1,battle_config.pet_max_stats);
  2671.             status->int_= cap_value(status->int_,1,battle_config.pet_max_stats);
  2672.             status->dex = cap_value(status->dex,1,battle_config.pet_max_stats);
  2673.             status->luk = cap_value(status->luk,1,battle_config.pet_max_stats);
  2674.  
  2675.             status_calc_misc(&pd->bl, &pd->status, lv);
  2676.  
  2677.             if (!(opt&SCO_FIRST)) // Not done the first time because the pet is not visible yet
  2678.                 clif_send_petstatus(sd);
  2679.         }
  2680.     } else if (opt&SCO_FIRST) {
  2681.         status_calc_misc(&pd->bl, &pd->status, pd->db->lv);
  2682.         if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv)
  2683.             pd->pet.level = pd->db->lv;
  2684.     }
  2685.  
  2686.     // Support rate modifier (1000 = 100%)
  2687.     pd->rate_fix = min(1000 * (pd->pet.intimate - battle_config.pet_support_min_friendly) / (1000 - battle_config.pet_support_min_friendly) + 500, USHRT_MAX);
  2688.     pd->rate_fix = min(apply_rate(pd->rate_fix, battle_config.pet_support_rate), USHRT_MAX);
  2689. }
  2690.  
  2691. /**
  2692.  * Get HP bonus modifiers
  2693.  * @param bl: block_list that will be checked
  2694.  * @param type: type of e_status_bonus (STATUS_BONUS_FIX or STATUS_BONUS_RATE)
  2695.  * @return bonus: total bonus for HP
  2696.  * @author [Cydh]
  2697.  */
  2698. static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
  2699.     int bonus = 0;
  2700.  
  2701.     if (type == STATUS_BONUS_FIX) {
  2702.         struct status_change *sc = status_get_sc(bl);
  2703.  
  2704.         //Only for BL_PC
  2705.         if (bl->type == BL_PC) {
  2706.             struct map_session_data *sd = map_id2sd(bl->id);
  2707.             uint8 i;
  2708.  
  2709.             bonus += sd->bonus.hp;
  2710.             if ((i = pc_checkskill(sd,CR_TRUST)) > 0)
  2711.                 bonus += i * 200;
  2712. #ifndef HP_SP_TABLES
  2713.             if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
  2714.                 bonus += 2000; // Supernovice lvl99 hp bonus.
  2715. #endif
  2716.         }
  2717.  
  2718.         //Bonus by SC
  2719.         if (sc) {
  2720.             if(sc->data[SC_INCMHP])
  2721.                 bonus += sc->data[SC_INCMHP]->val1;
  2722.             if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
  2723.                 bonus += 500;
  2724.             if(sc->data[SC_LERADSDEW])
  2725.                 bonus += sc->data[SC_LERADSDEW]->val3;
  2726.             if(sc->data[SC_INSPIRATION])
  2727.                 bonus += (600 * sc->data[SC_INSPIRATION]->val1);
  2728.             if(sc->data[SC_SOLID_SKIN_OPTION])
  2729.                 bonus += 2000;
  2730.             if(sc->data[SC_MTF_MHP])
  2731.                 bonus += sc->data[SC_MTF_MHP]->val1;
  2732.             if(sc->data[SC_MARIONETTE])
  2733.                 bonus -= 1000;
  2734.         }
  2735.     } else if (type == STATUS_BONUS_RATE) {
  2736.         struct status_change *sc = status_get_sc(bl);
  2737.  
  2738.         //Only for BL_PC
  2739.         if (bl->type == BL_PC) {
  2740.             struct map_session_data *sd = map_id2sd(bl->id);
  2741.             bonus += sd->hprate;
  2742.             bonus -= 100; //Default hprate is 100, so it should be add 0%
  2743.  
  2744.             //+200% for top ranking Taekwons over level 90.
  2745.             if (pc_is_taekwon_ranker(sd))
  2746.                 bonus += 200;
  2747.         }
  2748.  
  2749.         //Bonus by SC
  2750.         if (sc) {
  2751.             //Increasing
  2752.             if(sc->data[SC_INCMHPRATE])
  2753.                 bonus += sc->data[SC_INCMHPRATE]->val1;
  2754.             if(sc->data[SC_APPLEIDUN])
  2755.                 bonus += sc->data[SC_APPLEIDUN]->val2;
  2756.             if(sc->data[SC_DELUGE])
  2757.                 bonus += sc->data[SC_DELUGE]->val2;
  2758.             if(sc->data[SC_BERSERK])
  2759.                 bonus += 200; //+200%
  2760.             if(sc->data[SC_MERC_HPUP])
  2761.                 bonus += sc->data[SC_MERC_HPUP]->val2;
  2762.             if(sc->data[SC_EPICLESIS])
  2763.                 bonus += sc->data[SC_EPICLESIS]->val2;
  2764.             if(sc->data[SC_FRIGG_SONG])
  2765.                 bonus += sc->data[SC_FRIGG_SONG]->val2;
  2766.             if(sc->data[SC_FORCEOFVANGUARD])
  2767.                 bonus += (3 * sc->data[SC_FORCEOFVANGUARD]->val1);
  2768.             if(sc->data[SC_INSPIRATION])
  2769.                 bonus += (5 * sc->data[SC_INSPIRATION]->val1);
  2770.             if(sc->data[SC_RAISINGDRAGON])
  2771.                 bonus += (2 + sc->data[SC_RAISINGDRAGON]->val1);
  2772.             if(sc->data[SC_GT_REVITALIZE])
  2773.                 bonus += sc->data[SC_GT_REVITALIZE]->val2;
  2774.             if(sc->data[SC_MUSTLE_M])
  2775.                 bonus += sc->data[SC_MUSTLE_M]->val1;
  2776.             if(sc->data[SC_ANGRIFFS_MODUS])
  2777.                 bonus += (5 * sc->data[SC_ANGRIFFS_MODUS]->val1);
  2778.             if(sc->data[SC_PETROLOGY_OPTION])
  2779.                 bonus += sc->data[SC_PETROLOGY_OPTION]->val2;
  2780.             if(sc->data[SC_POWER_OF_GAIA])
  2781.                 bonus += sc->data[SC_POWER_OF_GAIA]->val3;
  2782.             if(sc->data[SC_CURSED_SOIL_OPTION])
  2783.                 bonus += sc->data[SC_CURSED_SOIL_OPTION]->val2;
  2784.             if(sc->data[SC_UPHEAVAL_OPTION])
  2785.                 bonus += sc->data[SC_UPHEAVAL_OPTION]->val2;
  2786.  
  2787.             //Decreasing
  2788.             if(sc->data[SC_VENOMBLEED])
  2789.                 bonus -= 15;
  2790.             if(sc->data[SC_BEYONDOFWARCRY])
  2791.                 bonus -= sc->data[SC_BEYONDOFWARCRY]->val4;
  2792.             if(sc->data[SC__WEAKNESS])
  2793.                 bonus -= sc->data[SC__WEAKNESS]->val2;
  2794.             if(sc->data[SC_MYSTERIOUS_POWDER])
  2795.                 bonus -= sc->data[SC_MYSTERIOUS_POWDER]->val1;
  2796.             if(sc->data[SC_GT_CHANGE]) // Max HP decrease: [Skill Level x 4] %
  2797.                 bonus -= (4 * sc->data[SC_GT_CHANGE]->val1);
  2798.             if(sc->data[SC_EQC])
  2799.                 bonus -= sc->data[SC_EQC]->val4;
  2800.         }
  2801.         // Max rate reduce is -100%
  2802.         bonus = cap_value(bonus,-100,INT_MAX);
  2803.     }
  2804.  
  2805.     return min(bonus,INT_MAX);
  2806. }
  2807.  
  2808. /**
  2809.  * Get SP bonus modifiers
  2810.  * @param bl: block_list that will be checked
  2811.  * @param type: type of e_status_bonus (STATUS_BONUS_FIX or STATUS_BONUS_RATE)
  2812.  * @return bonus: total bonus for SP
  2813.  * @author [Cydh]
  2814.  */
  2815. static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
  2816.     int bonus = 0;
  2817.  
  2818.     if (type == STATUS_BONUS_FIX) {
  2819.         struct status_change *sc = status_get_sc(bl);
  2820.  
  2821.         //Only for BL_PC
  2822.         if (bl->type == BL_PC) {
  2823.             struct map_session_data *sd = map_id2sd(bl->id);
  2824.             uint8 i;
  2825.  
  2826.             bonus += sd->bonus.sp;
  2827.             if ((i = pc_checkskill(sd,SL_KAINA)) > 0)
  2828.                 bonus += 30 * i;
  2829.             if ((i = pc_checkskill(sd,RA_RESEARCHTRAP)) > 0)
  2830.                 bonus += 200 + 20 * i;
  2831.             if ((i = pc_checkskill(sd,WM_LESSON)) > 0)
  2832.                 bonus += 30 * i;
  2833.         }
  2834.  
  2835.         //Bonus by SC
  2836.         if (sc) {
  2837.             if(sc->data[SC_INCMSP])
  2838.                 bonus += sc->data[SC_INCMSP]->val1;
  2839.             if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
  2840.                 bonus += 50;
  2841.             if(sc->data[SC_MTF_MSP])
  2842.                 bonus += sc->data[SC_MTF_MSP]->val1;
  2843.         }
  2844.     } else if (type == STATUS_BONUS_RATE) {
  2845.         struct status_change *sc = status_get_sc(bl);
  2846.  
  2847.         //Only for BL_PC
  2848.         if (bl->type == BL_PC) {
  2849.             struct map_session_data *sd = map_id2sd(bl->id);
  2850.             uint8 i;
  2851.  
  2852.             bonus += sd->sprate;
  2853.             bonus -= 100; //Default sprate is 100, so it should be add 0%
  2854.  
  2855.             if((i = pc_checkskill(sd,HP_MEDITATIO)) > 0)
  2856.                 bonus += i;
  2857.             if((i = pc_checkskill(sd,HW_SOULDRAIN)) > 0)
  2858.                 bonus += 2 * i;
  2859.  
  2860.             //+200% for top ranking Taekwons over level 90.
  2861.             if (pc_is_taekwon_ranker(sd))
  2862.                 bonus += 200;
  2863.         }
  2864.  
  2865.         //Bonus by SC
  2866.         if (sc) {
  2867.             if(sc->data[SC_INCMSPRATE])
  2868.                 bonus += sc->data[SC_INCMSPRATE]->val1;
  2869.             if(sc->data[SC_RAISINGDRAGON])
  2870.                 bonus += (2 + sc->data[SC_RAISINGDRAGON]->val1);
  2871.             if(sc->data[SC_SERVICE4U])
  2872.                 bonus += sc->data[SC_SERVICE4U]->val2;
  2873.             if(sc->data[SC_MERC_SPUP])
  2874.                 bonus += sc->data[SC_MERC_SPUP]->val2;
  2875.             if(sc->data[SC_LIFE_FORCE_F])
  2876.                 bonus += sc->data[SC_LIFE_FORCE_F]->val1;
  2877.             if(sc->data[SC_VITATA_500])
  2878.                 bonus += sc->data[SC_VITATA_500]->val2;
  2879.         }
  2880.         // Max rate reduce is -100%
  2881.         bonus = cap_value(bonus,-100,INT_MAX);
  2882.     }
  2883.  
  2884.     return min(bonus,INT_MAX);
  2885. }
  2886.  
  2887. /**
  2888.  * Get final MaxHP or MaxSP for player. References: http://irowiki.org/wiki/Max_HP and http://irowiki.org/wiki/Max_SP
  2889.  * The calculation needs base_level, base_status/battle_status (vit or int), additive modifier, and multiplicative modifier
  2890.  * @param sd Player
  2891.  * @param stat Vit/Int of player as param modifier
  2892.  * @param isHP true - calculates Max HP, false - calculated Max SP
  2893.  * @return max The max value of HP or SP
  2894.  */
  2895. static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned int stat, bool isHP) {
  2896.     double max = 0;
  2897.     uint16 idx, level, job_id;
  2898.  
  2899.     nullpo_ret(sd);
  2900.  
  2901.     job_id = pc_mapid2jobid(sd->class_,sd->status.sex);
  2902.     idx = pc_class2idx(job_id);
  2903.     level = max(sd->status.base_level,1);
  2904.  
  2905.     if (isHP) { //Calculates MaxHP
  2906.         max = job_info[idx].base_hp[level-1] * (1 + (max(stat,1) * 0.01)) * ((sd->class_&JOBL_UPPER)?1.25:1);
  2907.         max += status_get_hpbonus(&sd->bl,STATUS_BONUS_FIX);
  2908.         max += (int64)(max * status_get_hpbonus(&sd->bl,STATUS_BONUS_RATE) / 100); //Aegis accuracy
  2909.     }
  2910.     else { //Calculates MaxSP
  2911.         max = job_info[idx].base_sp[level-1] * (1 + (max(stat,1) * 0.01)) * ((sd->class_&JOBL_UPPER)?1.25:1);
  2912.         max += status_get_spbonus(&sd->bl,STATUS_BONUS_FIX);
  2913.         max += (int64)(max * status_get_spbonus(&sd->bl,STATUS_BONUS_RATE) / 100); //Aegis accuracy
  2914.     }
  2915.  
  2916.     //Make sure it's not negative before casting to unsigned int
  2917.     if(max < 1) max = 1;
  2918.  
  2919.     return cap_value((unsigned int)max,1,UINT_MAX);
  2920. }
  2921.  
  2922. /**
  2923.  * Calculates player data from scratch without counting SC adjustments
  2924.  * Should be invoked whenever players raise stats, learn passive skills or change equipment
  2925.  * @param sd: Player object
  2926.  * @param opt: Whether it is first calc (login) or not
  2927.  * @return (-1) for too many recursive calls, (1) recursive call, (0) success
  2928.  */
  2929. int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
  2930. {
  2931.     static int calculating = 0; ///< Check for recursive call preemption. [Skotlex]
  2932.     struct status_data *status; ///< Pointer to the player's base status
  2933.     const struct status_change *sc = &sd->sc;
  2934.     struct s_skill b_skill[MAX_SKILL]; ///< Previous skill tree
  2935.     int b_weight, b_max_weight, b_cart_weight_max, ///< Previous weight
  2936.     i, skill,refinedef=0;
  2937.     short index = -1;
  2938.  
  2939.     if (++calculating > 10) // Too many recursive calls!
  2940.         return -1;
  2941.  
  2942.     // Remember player-specific values that are currently being shown to the client (for refresh purposes)
  2943.     memcpy(b_skill, &sd->status.skill, sizeof(b_skill));
  2944.     b_weight = sd->weight;
  2945.     b_max_weight = sd->max_weight;
  2946.     b_cart_weight_max = sd->cart_weight_max;
  2947.  
  2948.     pc_calc_skilltree(sd);  // SkillTree calculation
  2949.  
  2950.     sd->max_weight = job_info[pc_class2idx(sd->status.class_)].max_weight_base+sd->status.str*300;
  2951.  
  2952.     if (opt&SCO_FIRST) {
  2953.         // Load Hp/SP from char-received data.
  2954.         sd->battle_status.hp = sd->status.hp;
  2955.         sd->battle_status.sp = sd->status.sp;
  2956.         sd->regen.sregen = &sd->sregen;
  2957.         sd->regen.ssregen = &sd->ssregen;
  2958.         sd->weight=0;
  2959.         for(i=0;i<MAX_INVENTORY;i++) {
  2960.             if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
  2961.                 continue;
  2962.             sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
  2963.         }
  2964.         sd->cart_weight=0;
  2965.         sd->cart_num=0;
  2966.         for(i=0;i<MAX_CART;i++) {
  2967.             if(sd->status.cart[i].nameid==0)
  2968.                 continue;
  2969.             sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount;
  2970.             sd->cart_num++;
  2971.         }
  2972.     }
  2973.  
  2974.     status = &sd->base_status;
  2975.     // These are not zeroed. [zzo]
  2976.     sd->hprate = 100;
  2977.     sd->sprate = 100;
  2978.     sd->castrate = 100;
  2979.     sd->delayrate = 100;
  2980.     sd->dsprate = 100;
  2981.     sd->hprecov_rate = 100;
  2982.     sd->sprecov_rate = 100;
  2983.     sd->matk_rate = 100;
  2984.     sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
  2985.     sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
  2986.     sd->regen.state.block = 0;
  2987.  
  2988.     // Zeroed arrays, order follows the order in pc.h.
  2989.     // Add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
  2990.     memset (sd->param_bonus, 0, sizeof(sd->param_bonus)
  2991.         + sizeof(sd->param_equip)
  2992.         + sizeof(sd->subele)
  2993.         + sizeof(sd->subdefele)
  2994.         + sizeof(sd->subrace)
  2995.         + sizeof(sd->subclass)
  2996.         + sizeof(sd->subrace2)
  2997.         + sizeof(sd->subsize)
  2998.         + sizeof(sd->reseff)
  2999.         + sizeof(sd->coma_class)
  3000.         + sizeof(sd->coma_race)
  3001.         + sizeof(sd->weapon_coma_ele)
  3002.         + sizeof(sd->weapon_coma_race)
  3003.         + sizeof(sd->weapon_coma_class)
  3004.         + sizeof(sd->weapon_atk)
  3005.         + sizeof(sd->weapon_atk_rate)
  3006.         + sizeof(sd->arrow_addele)
  3007.         + sizeof(sd->arrow_addrace)
  3008.         + sizeof(sd->arrow_addclass)
  3009.         + sizeof(sd->arrow_addsize)
  3010.         + sizeof(sd->magic_addele)
  3011.         + sizeof(sd->magic_addrace)
  3012.         + sizeof(sd->magic_addclass)
  3013.         + sizeof(sd->magic_addsize)
  3014.         + sizeof(sd->magic_atk_ele)
  3015.         + sizeof(sd->critaddrace)
  3016.         + sizeof(sd->expaddrace)
  3017.         + sizeof(sd->expaddclass)
  3018.         + sizeof(sd->ignore_mdef_by_race)
  3019.         + sizeof(sd->ignore_mdef_by_class)
  3020.         + sizeof(sd->ignore_def_by_race)
  3021.         + sizeof(sd->sp_gain_race)
  3022.         );
  3023.  
  3024.     memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
  3025.     memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));
  3026.  
  3027.     if (sd->special_state.intravision && !sd->sc.data[SC_INTRAVISION]) // Clear intravision as long as nothing else is using it
  3028.         clif_status_load(&sd->bl, SI_INTRAVISION, 0);
  3029.  
  3030.     memset(&sd->special_state,0,sizeof(sd->special_state));
  3031.  
  3032.     if (!sd->state.permanent_speed) {
  3033.         memset(&status->max_hp, 0, sizeof(struct status_data)-(sizeof(status->hp)+sizeof(status->sp)));
  3034.         status->speed = DEFAULT_WALK_SPEED;
  3035.     } else {
  3036.         int pSpeed = status->speed;
  3037.  
  3038.         memset(&status->max_hp, 0, sizeof(struct status_data)-(sizeof(status->hp)+sizeof(status->sp)));
  3039.         status->speed = pSpeed;
  3040.     }
  3041.  
  3042.     // !FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
  3043.     // Give them all modes except these (useful for clones)
  3044.     status->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
  3045.  
  3046.     status->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM;
  3047.     if (battle_config.character_size && pc_isriding(sd)) { // [Lupus]
  3048.         if (sd->class_&JOBL_BABY) {
  3049.             if (battle_config.character_size&SZ_BIG)
  3050.                 status->size++;
  3051.         } else
  3052.         if(battle_config.character_size&SZ_MEDIUM)
  3053.             status->size++;
  3054.     }
  3055.     status->aspd_rate = 1000;
  3056.     status->ele_lv = 1;
  3057.     status->race = RC_PLAYER;
  3058.     status->class_ = CLASS_NORMAL;
  3059.  
  3060.     // Zero up structures...
  3061.     memset(&sd->autospell, 0, sizeof(sd->autospell)
  3062.         + sizeof(sd->autospell2)
  3063.         + sizeof(sd->autospell3)
  3064.         + sizeof(sd->addeff)
  3065.         + sizeof(sd->addeff2)
  3066.         + sizeof(sd->addeff3)
  3067.         + sizeof(sd->skillatk)
  3068.         + sizeof(sd->skillusesprate)
  3069.         + sizeof(sd->skillusesp)
  3070.         + sizeof(sd->skillheal)
  3071.         + sizeof(sd->skillheal2)
  3072.         + sizeof(sd->skillblown)
  3073.         + sizeof(sd->skillcastrate)
  3074.         + sizeof(sd->skillcooldown)
  3075.         + sizeof(sd->skillfixcast)
  3076.         + sizeof(sd->skillvarcast)
  3077.         + sizeof(sd->skillfixcastrate)
  3078.         + sizeof(sd->subskill)
  3079.         + sizeof(sd->hp_loss)
  3080.         + sizeof(sd->sp_loss)
  3081.         + sizeof(sd->hp_regen)
  3082.         + sizeof(sd->sp_regen)
  3083.         + sizeof(sd->add_def)
  3084.         + sizeof(sd->add_mdef)
  3085.         + sizeof(sd->add_mdmg)
  3086.         + sizeof(sd->add_drop)
  3087.         + sizeof(sd->itemhealrate)
  3088.         + sizeof(sd->subele2)
  3089.         + sizeof(sd->def_set_race)
  3090.         + sizeof(sd->mdef_set_race)
  3091.         + sizeof(sd->hp_vanish_race)
  3092.         + sizeof(sd->sp_vanish_race)
  3093.     );
  3094.  
  3095.     memset (&sd->bonus, 0, sizeof(sd->bonus));
  3096.  
  3097.     // Autobonus
  3098.     pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
  3099.     pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true);
  3100.     pc_delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true);
  3101.  
  3102.     pc_itemgrouphealrate_clear(sd);
  3103.  
  3104.     npc_script_event(sd, NPCE_STATCALC);
  3105.  
  3106.     // Parse equipment
  3107.     for (i = 0; i < EQI_MAX; i++) {
  3108.         current_equip_item_index = index = sd->equip_index[i]; // We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
  3109.         current_equip_combo_pos = 0;
  3110.         if (index < 0)
  3111.             continue;
  3112.         if (i == EQI_AMMO)
  3113.             continue;
  3114.         if (pc_is_same_equip_index((enum equip_index)i, sd->equip_index, index))
  3115.             continue;
  3116.         if (!sd->inventory_data[index])
  3117.             continue;
  3118.  
  3119.         status->def += sd->inventory_data[index]->def;
  3120.  
  3121.         // Items may be equipped, their effects however are nullified.
  3122.         if (opt&SCO_FIRST && sd->inventory_data[index]->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT)
  3123.             || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) { // Execute equip-script on login
  3124.             run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
  3125.             if (!calculating)
  3126.                 return 1;
  3127.         }
  3128.  
  3129.         // Sanitize the refine level in case someone decreased the value inbetween
  3130.         if (sd->status.inventory[index].refine > MAX_REFINE)
  3131.             sd->status.inventory[index].refine = MAX_REFINE;
  3132.  
  3133.         if (sd->inventory_data[index]->type == IT_WEAPON) {
  3134.             int r = sd->status.inventory[index].refine, wlv = sd->inventory_data[index]->wlv;
  3135.             struct weapon_data *wd;
  3136.             struct weapon_atk *wa;
  3137.  
  3138.             if(wlv >= REFINE_TYPE_MAX)
  3139.                 wlv = REFINE_TYPE_MAX - 1;
  3140.             if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
  3141.                 wd = &sd->left_weapon; // Left-hand weapon
  3142.                 wa = &status->lhw;
  3143.             } else {
  3144.                 wd = &sd->right_weapon;
  3145.                 wa = &status->rhw;
  3146.             }
  3147.             wa->atk += sd->inventory_data[index]->atk;
  3148.             if(r)
  3149.                 wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
  3150. #ifdef RENEWAL
  3151.             wa->matk += sd->inventory_data[index]->matk;
  3152.             wa->wlv = wlv;
  3153.             if(r && sd->weapontype1 != W_BOW) // Renewal magic attack refine bonus
  3154.                 wa->matk += refine_info[wlv].bonus[r-1] / 100;
  3155. #endif
  3156.             if(r) // Overrefine bonus.
  3157.                 wd->overrefine = refine_info[wlv].randombonus_max[r-1] / 100;
  3158.             wa->range += sd->inventory_data[index]->range;
  3159.             if(sd->inventory_data[index]->script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) {
  3160.                 if (wd == &sd->left_weapon) {
  3161.                     sd->state.lr_flag = 1;
  3162.                     run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  3163.                     sd->state.lr_flag = 0;
  3164.                 } else
  3165.                     run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  3166.                 if (!calculating) // Abort, run_script retriggered this. [Skotlex]
  3167.                     return 1;
  3168.             }
  3169.             if(sd->status.inventory[index].card[0]==CARD0_FORGE) { // Forged weapon
  3170.                 wd->star += (sd->status.inventory[index].card[1]>>8);
  3171.                 if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg
  3172.                 if(pc_famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
  3173.                     wd->star += 10;
  3174.                 if (!wa->ele) // Do not overwrite element from previous bonuses.
  3175.                     wa->ele = (sd->status.inventory[index].card[1]&0x0f);
  3176.             }
  3177.         } else if(sd->inventory_data[index]->type == IT_ARMOR) {
  3178.             int r;
  3179.  
  3180.             if ( (r = sd->status.inventory[index].refine) )
  3181.                 refinedef += refine_info[REFINE_TYPE_ARMOR].bonus[r-1];
  3182.             if(sd->inventory_data[index]->script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) {
  3183.                 if( i == EQI_HAND_L ) // Shield
  3184.                     sd->state.lr_flag = 3;
  3185.                 run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  3186.                 if( i == EQI_HAND_L ) // Shield
  3187.                     sd->state.lr_flag = 0;
  3188.                 if (!calculating) // Abort, run_script retriggered this. [Skotlex]
  3189.                     return 1;
  3190.             }
  3191.         } else if( sd->inventory_data[index]->type == IT_SHADOWGEAR ) { // Shadow System
  3192.             if (sd->inventory_data[index]->script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) {
  3193.                 run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  3194.                 if( !calculating )
  3195.                     return 1;
  3196.             }
  3197.         }
  3198.     }
  3199.  
  3200.     if(sd->equip_index[EQI_AMMO] >= 0) {
  3201.         index = sd->equip_index[EQI_AMMO];
  3202.         if(sd->inventory_data[index]) { // Arrows
  3203.             sd->bonus.arrow_atk += sd->inventory_data[index]->atk;
  3204.             sd->state.lr_flag = 2;
  3205.             if( !itemdb_is_GNthrowable(sd->inventory_data[index]->nameid) ) // Don't run scripts on throwable items
  3206.                 run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
  3207.             sd->state.lr_flag = 0;
  3208.             if (!calculating) // Abort, run_script retriggered status_calc_pc. [Skotlex]
  3209.                 return 1;
  3210.         }
  3211.     }
  3212.  
  3213.     // We've got combos to process and check
  3214.     if( sd->combos.count ) {
  3215.         for (i = 0; i < sd->combos.count; i++) {
  3216.             uint8 j = 0;
  3217.             bool no_run = false;
  3218.             struct item_combo *combo = NULL;
  3219.  
  3220.             current_equip_item_index = -1;
  3221.             current_equip_combo_pos = sd->combos.pos[i];
  3222.  
  3223.             if (!sd->combos.bonus[i] || !(combo = itemdb_combo_exists(sd->combos.id[i])))
  3224.                 continue;
  3225.             // Check combo items
  3226.             while (j < combo->count) {
  3227.                 struct item_data *id = itemdb_exists(combo->nameid[j]);
  3228.                 // Don't run the script if at least one of combo's pair has restriction
  3229.                 if (id && !pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(id, sd->bl.m)) {
  3230.                     no_run = true;
  3231.                     break;
  3232.                 }
  3233.                 j++;
  3234.             }
  3235.             if (no_run)
  3236.                 continue;
  3237.             run_script(sd->combos.bonus[i],0,sd->bl.id,0);
  3238.             if (!calculating) // Abort, run_script retriggered this
  3239.                 return 1;
  3240.         }
  3241.     }
  3242.  
  3243.     // Store equipment script bonuses
  3244.     memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
  3245.     memset(sd->param_bonus, 0, sizeof(sd->param_bonus));
  3246.  
  3247.     status->def += (refinedef+50)/100;
  3248.  
  3249.     // Parse Cards
  3250.     for (i = 0; i < EQI_MAX; i++) {
  3251.         current_equip_item_index = index = sd->equip_index[i]; // We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
  3252.         current_equip_combo_pos = 0;
  3253.         if (index < 0)
  3254.             continue;
  3255.         if (i == EQI_AMMO)
  3256.             continue;
  3257.         if (pc_is_same_equip_index((enum equip_index)i, sd->equip_index, index))
  3258.             continue;
  3259.  
  3260.         if (sd->inventory_data[index]) {
  3261.             int j;
  3262.             struct item_data *data;
  3263.  
  3264.             // Card script execution.
  3265.             if (itemdb_isspecial(sd->status.inventory[index].card[0]))
  3266.                 continue;
  3267.             for (j = 0; j < MAX_SLOTS; j++) { // Uses MAX_SLOTS to support Soul Bound system [Inkfish]
  3268.                 int c = sd->status.inventory[index].card[j];
  3269.                 current_equip_card_id= c;
  3270.                 if(!c)
  3271.                     continue;
  3272.                 data = itemdb_exists(c);
  3273.                 if(!data)
  3274.                     continue;
  3275.                 if (opt&SCO_FIRST && data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m))) {// Execute equip-script on login
  3276.                     run_script(data->equip_script,0,sd->bl.id,0);
  3277.                     if (!calculating)
  3278.                         return 1;
  3279.                 }
  3280.                 if(!data->script)
  3281.                     continue;
  3282.                 if(!pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) && itemdb_isNoEquip(data,sd->bl.m)) // Card restriction checks.
  3283.                     continue;
  3284.                 if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { // Left hand status.
  3285.                     sd->state.lr_flag = 1;
  3286.                     run_script(data->script,0,sd->bl.id,0);
  3287.                     sd->state.lr_flag = 0;
  3288.                 } else
  3289.                     run_script(data->script,0,sd->bl.id,0);
  3290.                 if (!calculating) // Abort, run_script his function. [Skotlex]
  3291.                     return 1;
  3292.             }
  3293.         }
  3294.     }
  3295.  
  3296.     if( sc->count && sc->data[SC_ITEMSCRIPT] ) {
  3297.         struct item_data *data = itemdb_exists(sc->data[SC_ITEMSCRIPT]->val1);
  3298.         if( data && data->script )
  3299.             run_script(data->script,0,sd->bl.id,0);
  3300.     }
  3301.  
  3302.     pc_bonus_script(sd);
  3303.  
  3304.     if( sd->pd ) { // Pet Bonus
  3305.         struct pet_data *pd = sd->pd;
  3306.         if( pd && pd->petDB && pd->petDB->pet_loyal_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
  3307.             run_script(pd->petDB->pet_loyal_script,0,sd->bl.id,0);
  3308.         if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
  3309.             pc_bonus(sd,pd->bonus->type, pd->bonus->val);
  3310.     }
  3311.  
  3312.     // param_bonus now holds card bonuses.
  3313.     if(status->rhw.range < 1) status->rhw.range = 1;
  3314.     if(status->lhw.range < 1) status->lhw.range = 1;
  3315.     if(status->rhw.range < status->lhw.range)
  3316.         status->rhw.range = status->lhw.range;
  3317.  
  3318.     sd->bonus.double_rate += sd->bonus.double_add_rate;
  3319.     sd->bonus.perfect_hit += sd->bonus.perfect_hit_add;
  3320.     sd->bonus.splash_range += sd->bonus.splash_add_range;
  3321.  
  3322.     // Damage modifiers from weapon type
  3323.     sd->right_weapon.atkmods[0] = atkmods[0][sd->weapontype1];
  3324.     sd->right_weapon.atkmods[1] = atkmods[1][sd->weapontype1];
  3325.     sd->right_weapon.atkmods[2] = atkmods[2][sd->weapontype1];
  3326.     sd->left_weapon.atkmods[0] = atkmods[0][sd->weapontype2];
  3327.     sd->left_weapon.atkmods[1] = atkmods[1][sd->weapontype2];
  3328.     sd->left_weapon.atkmods[2] = atkmods[2][sd->weapontype2];
  3329.  
  3330.     if((pc_isriding(sd) || pc_isridingdragon(sd)) &&
  3331.         (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR))
  3332.     {   // When Riding with spear, damage modifier to mid-class becomes
  3333.         // same as versus large size.
  3334.         sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
  3335.         sd->left_weapon.atkmods[1] = sd->left_weapon.atkmods[2];
  3336.     }
  3337.  
  3338. // ----- STATS CALCULATION -----
  3339.  
  3340.     // Job bonuses
  3341.     index = pc_class2idx(sd->status.class_);
  3342.     for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++) {
  3343.         if(!job_info[index].job_bonus[i])
  3344.             continue;
  3345.         switch(job_info[index].job_bonus[i]) {
  3346.             case 1: status->str++; break;
  3347.             case 2: status->agi++; break;
  3348.             case 3: status->vit++; break;
  3349.             case 4: status->int_++; break;
  3350.             case 5: status->dex++; break;
  3351.             case 6: status->luk++; break;
  3352.         }
  3353.     }
  3354.  
  3355.     // If a Super Novice has never died and is at least joblv 70, he gets all stats +10
  3356.     if(((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && (sd->status.job_level >= 70  || sd->class_&JOBL_THIRD)) && sd->die_counter == 0) {
  3357.         status->str += 10;
  3358.         status->agi += 10;
  3359.         status->vit += 10;
  3360.         status->int_+= 10;
  3361.         status->dex += 10;
  3362.         status->luk += 10;
  3363.     }
  3364.  
  3365.     // Absolute modifiers from passive skills
  3366.     if(pc_checkskill(sd,BS_HILTBINDING)>0)
  3367.         status->str++;
  3368.     if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0)
  3369.         status->int_ += (skill+1)/2; // +1 INT / 2 lv
  3370.     if((skill=pc_checkskill(sd,AC_OWL))>0)
  3371.         status->dex += skill;
  3372.     if((skill = pc_checkskill(sd,RA_RESEARCHTRAP))>0)
  3373.         status->int_ += skill;
  3374.  
  3375.     // Bonuses from cards and equipment as well as base stat, remember to avoid overflows.
  3376.     i = status->str + sd->status.str + sd->param_bonus[0] + sd->param_equip[0];
  3377.     status->str = cap_value(i,0,USHRT_MAX);
  3378.     i = status->agi + sd->status.agi + sd->param_bonus[1] + sd->param_equip[1];
  3379.     status->agi = cap_value(i,0,USHRT_MAX);
  3380.     i = status->vit + sd->status.vit + sd->param_bonus[2] + sd->param_equip[2];
  3381.     status->vit = cap_value(i,0,USHRT_MAX);
  3382.     i = status->int_+ sd->status.int_+ sd->param_bonus[3] + sd->param_equip[3];
  3383.     status->int_ = cap_value(i,0,USHRT_MAX);
  3384.     i = status->dex + sd->status.dex + sd->param_bonus[4] + sd->param_equip[4];
  3385.     status->dex = cap_value(i,0,USHRT_MAX);
  3386.     i = status->luk + sd->status.luk + sd->param_bonus[5] + sd->param_equip[5];
  3387.     status->luk = cap_value(i,0,USHRT_MAX);
  3388.  
  3389. // ------ ATTACK CALCULATION ------
  3390.  
  3391.     // Base batk value is set in status_calc_misc
  3392. #ifndef RENEWAL
  3393.     // !FIXME: Weapon-type bonus (Why is the weapon_atk bonus applied to base attack?)
  3394.     if (sd->status.weapon < MAX_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
  3395.         status->batk += sd->weapon_atk[sd->status.weapon];
  3396.     // Absolute modifiers from passive skills
  3397.     if((skill=pc_checkskill(sd,BS_HILTBINDING))>0)
  3398.         status->batk += 4;
  3399. #else
  3400.     status->watk = status_weapon_atk(status->rhw, status);
  3401.     status->watk2 = status_weapon_atk(status->lhw, status);
  3402.     status->eatk = max(sd->bonus.eatk,0);
  3403. #endif
  3404.  
  3405. // ----- HP MAX CALCULATION -----
  3406.     status->max_hp = sd->status.max_hp = status_calc_maxhpsp_pc(sd,status->vit,true);
  3407.  
  3408.     if(battle_config.hp_rate != 100)
  3409.         status->max_hp = (unsigned int)(battle_config.hp_rate * (status->max_hp/100.));
  3410.  
  3411.     status->max_hp = cap_value(status->max_hp,1,(unsigned int)battle_config.max_hp);
  3412.  
  3413. // ----- SP MAX CALCULATION -----
  3414.     status->max_sp = sd->status.max_sp = status_calc_maxhpsp_pc(sd,status->int_,false);
  3415.  
  3416.     if(battle_config.sp_rate != 100)
  3417.         status->max_sp = (unsigned int)(battle_config.sp_rate * (status->max_sp/100.));
  3418.  
  3419.     status->max_sp = cap_value(status->max_sp,1,(unsigned int)battle_config.max_sp);
  3420.  
  3421. // ----- RESPAWN HP/SP -----
  3422.  
  3423.     // Calc respawn hp and store it on base_status
  3424.     if (sd->special_state.restart_full_recover) {
  3425.         status->hp = status->max_hp;
  3426.         status->sp = status->max_sp;
  3427.     } else {
  3428.         if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
  3429.             && battle_config.restart_hp_rate < 50)
  3430.             status->hp = status->max_hp>>1;
  3431.         else
  3432.             status->hp = (int64)status->max_hp * battle_config.restart_hp_rate/100;
  3433.         if(!status->hp)
  3434.             status->hp = 1;
  3435.  
  3436.         status->sp = (int64)status->max_sp * battle_config.restart_sp_rate /100;
  3437.  
  3438.         if( !status->sp ) // The minimum for the respawn setting is SP:1
  3439.             status->sp = 1;
  3440.     }
  3441.  
  3442. // ----- MISC CALCULATION -----
  3443.     status_calc_misc(&sd->bl, status, sd->status.base_level);
  3444.  
  3445.     // Equipment modifiers for misc settings
  3446.     if(sd->matk_rate < 0)
  3447.         sd->matk_rate = 0;
  3448.  
  3449.     if(sd->matk_rate != 100) {
  3450.         status->matk_max = status->matk_max * sd->matk_rate/100;
  3451.         status->matk_min = status->matk_min * sd->matk_rate/100;
  3452.     }
  3453.  
  3454.     if(sd->hit_rate < 0)
  3455.         sd->hit_rate = 0;
  3456.     if(sd->hit_rate != 100)
  3457.         status->hit = status->hit * sd->hit_rate/100;
  3458.  
  3459.     if(sd->flee_rate < 0)
  3460.         sd->flee_rate = 0;
  3461.     if(sd->flee_rate != 100)
  3462.         status->flee = status->flee * sd->flee_rate/100;
  3463.  
  3464.     if(sd->def2_rate < 0)
  3465.         sd->def2_rate = 0;
  3466.     if(sd->def2_rate != 100)
  3467.         status->def2 = status->def2 * sd->def2_rate/100;
  3468.  
  3469.     if(sd->mdef2_rate < 0)
  3470.         sd->mdef2_rate = 0;
  3471.     if(sd->mdef2_rate != 100)
  3472.         status->mdef2 = status->mdef2 * sd->mdef2_rate/100;
  3473.  
  3474.     if(sd->critical_rate < 0)
  3475.         sd->critical_rate = 0;
  3476.     if(sd->critical_rate != 100)
  3477.         status->cri = cap_value(status->cri * sd->critical_rate/100,SHRT_MIN,SHRT_MAX);
  3478.  
  3479.     if(sd->flee2_rate < 0)
  3480.         sd->flee2_rate = 0;
  3481.     if(sd->flee2_rate != 100)
  3482.         status->flee2 = status->flee2 * sd->flee2_rate/100;
  3483.  
  3484. // ----- HIT CALCULATION -----
  3485.  
  3486.     // Absolute modifiers from passive skills
  3487. #ifndef RENEWAL
  3488.     if((skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0)
  3489.         status->hit += skill*2;
  3490. #endif
  3491.     if((skill=pc_checkskill(sd,AC_VULTURE))>0) {
  3492. #ifndef RENEWAL
  3493.         status->hit += skill;
  3494. #endif
  3495.         if(sd->status.weapon == W_BOW)
  3496.             status->rhw.range += skill;
  3497.     }
  3498.     if(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE) {
  3499.         if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0)
  3500.             status->hit += 2*skill;
  3501.         if((skill=pc_checkskill(sd,GS_SNAKEEYE))>0) {
  3502.             status->hit += skill;
  3503.             status->rhw.range += skill;
  3504.         }
  3505.     }
  3506.     if((sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0)
  3507.         status->hit += skill * 3;
  3508.     if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && (skill = pc_checkskill(sd,NC_TRAININGAXE)) > 0)
  3509.         status->hit += skill * 2;
  3510.  
  3511.  
  3512. // ----- FLEE CALCULATION -----
  3513.  
  3514.     // Absolute modifiers from passive skills
  3515.     if((skill=pc_checkskill(sd,TF_MISS))>0)
  3516.         status->flee += skill*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
  3517.     if((skill=pc_checkskill(sd,MO_DODGE))>0)
  3518.         status->flee += (skill*3)>>1;
  3519.  
  3520. // ----- EQUIPMENT-DEF CALCULATION -----
  3521.  
  3522.     // Apply relative modifiers from equipment
  3523.     if(sd->def_rate < 0)
  3524.         sd->def_rate = 0;
  3525.     if(sd->def_rate != 100) {
  3526.         i = status->def * sd->def_rate/100;
  3527.         status->def = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
  3528.     }
  3529.  
  3530.     if(pc_ismadogear(sd) && pc_checkskill(sd, NC_MAINFRAME) > 0)
  3531.         status->def += 20 + (pc_checkskill(sd, NC_MAINFRAME) * 20);
  3532.  
  3533. #ifndef RENEWAL
  3534.     if (!battle_config.weapon_defense_type && status->def > battle_config.max_def) {
  3535.         status->def2 += battle_config.over_def_bonus*(status->def -battle_config.max_def);
  3536.         status->def = (unsigned char)battle_config.max_def;
  3537.     }
  3538. #endif
  3539.  
  3540. // ----- EQUIPMENT-MDEF CALCULATION -----
  3541.  
  3542.     // Apply relative modifiers from equipment
  3543.     if(sd->mdef_rate < 0)
  3544.         sd->mdef_rate = 0;
  3545.     if(sd->mdef_rate != 100) {
  3546.         i =  status->mdef * sd->mdef_rate/100;
  3547.         status->mdef = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
  3548.     }
  3549.  
  3550. #ifndef RENEWAL
  3551.     if (!battle_config.magic_defense_type && status->mdef > battle_config.max_def) {
  3552.         status->mdef2 += battle_config.over_def_bonus*(status->mdef -battle_config.max_def);
  3553.         status->mdef = (signed char)battle_config.max_def;
  3554.     }
  3555. #endif
  3556.  
  3557. // ----- ASPD CALCULATION -----
  3558.  
  3559.     /// Unlike other stats, ASPD rate modifiers from skills/SCs/items/etc are first all added together, then the final modifier is applied
  3560.  
  3561.     // Basic ASPD value
  3562.     i = status_base_amotion_pc(sd,status);
  3563.     status->amotion = cap_value(i,pc_maxaspd(sd),2000);
  3564.  
  3565.     // Relative modifiers from passive skills
  3566. #ifndef RENEWAL_ASPD
  3567.     if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
  3568.         status->aspd_rate -= 5*skill;
  3569.     if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
  3570.         status->aspd_rate -= 30*skill;
  3571.     if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
  3572.         (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
  3573.         status->aspd_rate -= ((skill+1)/2) * 10;
  3574.     if(pc_isriding(sd))
  3575.         status->aspd_rate += 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
  3576.     else if(pc_isridingdragon(sd))
  3577.         status->aspd_rate += 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
  3578. #else // Needs more info
  3579.     if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
  3580.         status->aspd_rate += 5*skill;
  3581.     if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
  3582.         status->aspd_rate += 30*skill;
  3583.     if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
  3584.         (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
  3585.         status->aspd_rate += ((skill+1)/2) * 10;
  3586.     if(pc_isriding(sd))
  3587.         status->aspd_rate -= 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
  3588.     else if(pc_isridingdragon(sd))
  3589.         status->aspd_rate -= 250-50*pc_checkskill(sd,RK_DRAGONTRAINING);
  3590. #endif
  3591.     status->adelay = 2*status->amotion;
  3592.  
  3593.  
  3594. // ----- DMOTION -----
  3595.  
  3596.     i =  800-status->agi*4;
  3597.     status->dmotion = cap_value(i, 400, 800);
  3598.     if(battle_config.pc_damage_delay_rate != 100)
  3599.         status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
  3600.  
  3601. // ----- MISC CALCULATIONS -----
  3602.  
  3603.     // Weight
  3604.     if((skill=pc_checkskill(sd,MC_INCCARRY))>0)
  3605.         sd->max_weight += 2000*skill;
  3606.     if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
  3607.         sd->max_weight += 10000;
  3608.     else if(pc_isridingdragon(sd))
  3609.         sd->max_weight += 5000+2000*pc_checkskill(sd,RK_DRAGONTRAINING);
  3610.     if(sc->data[SC_KNOWLEDGE])
  3611.         sd->max_weight += sd->max_weight*sc->data[SC_KNOWLEDGE]->val1/10;
  3612.     if((skill=pc_checkskill(sd,ALL_INCCARRY))>0)
  3613.         sd->max_weight += 2000*skill;
  3614.  
  3615.     sd->cart_weight_max = battle_config.max_cart_weight + (pc_checkskill(sd, GN_REMODELING_CART)*5000);
  3616.  
  3617.     if (pc_checkskill(sd,SM_MOVINGRECOVERY)>0)
  3618.         sd->regen.state.walk = 1;
  3619.     else
  3620.         sd->regen.state.walk = 0;
  3621.  
  3622.     // Skill SP cost
  3623.     if((skill=pc_checkskill(sd,HP_MANARECHARGE))>0 )
  3624.         sd->dsprate -= 4*skill;
  3625.  
  3626.     if(sc->data[SC_SERVICE4U])
  3627.         sd->dsprate -= sc->data[SC_SERVICE4U]->val3;
  3628.  
  3629.     if(sc->data[SC_SPCOST_RATE])
  3630.         sd->dsprate -= sc->data[SC_SPCOST_RATE]->val1;
  3631.  
  3632.     // Underflow protections.
  3633.     if(sd->dsprate < 0)
  3634.         sd->dsprate = 0;
  3635.     if(sd->castrate < 0)
  3636.         sd->castrate = 0;
  3637.     if(sd->delayrate < 0)
  3638.         sd->delayrate = 0;
  3639.     if(sd->hprecov_rate < 0)
  3640.         sd->hprecov_rate = 0;
  3641.     if(sd->sprecov_rate < 0)
  3642.         sd->sprecov_rate = 0;
  3643.  
  3644.     // Anti-element and anti-race
  3645.     if((skill=pc_checkskill(sd,CR_TRUST))>0)
  3646.         sd->subele[ELE_HOLY] += skill*5;
  3647.     if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
  3648.         sd->subele[ELE_NEUTRAL] += skill;
  3649.         sd->subele[ELE_FIRE] += skill*4;
  3650.     }
  3651.     if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0) {
  3652. #ifdef RENEWAL
  3653.         skill = skill * 2;
  3654. #else
  3655.         skill = skill * 4;
  3656. #endif
  3657.         sd->right_weapon.addrace[RC_DRAGON]+=skill;
  3658.         sd->left_weapon.addrace[RC_DRAGON]+=skill;
  3659.         sd->magic_addrace[RC_DRAGON]+=skill;
  3660.         sd->subrace[RC_DRAGON]+=skill;
  3661.     }
  3662.     if((skill = pc_checkskill(sd, AB_EUCHARISTICA)) > 0) {
  3663.         sd->right_weapon.addrace[RC_DEMON] += skill;
  3664.         sd->right_weapon.addele[ELE_DARK] += skill;
  3665.         sd->left_weapon.addrace[RC_DEMON] += skill;
  3666.         sd->left_weapon.addele[ELE_DARK] += skill;
  3667.         sd->magic_addrace[RC_DEMON] += skill;
  3668.         sd->magic_addele[ELE_DARK] += skill;
  3669.         sd->subrace[RC_DEMON] += skill;
  3670.         sd->subele[ELE_DARK] += skill;
  3671.     }
  3672.  
  3673.     if(sc->count) {
  3674.         if(sc->data[SC_CONCENTRATE]) { // Update the card-bonus data
  3675.             sc->data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; // Agi
  3676.             sc->data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; // Dex
  3677.         }
  3678.         if(sc->data[SC_SIEGFRIED]) {
  3679.             i = sc->data[SC_SIEGFRIED]->val2;
  3680.             sd->subele[ELE_WATER] += i;
  3681.             sd->subele[ELE_EARTH] += i;
  3682.             sd->subele[ELE_FIRE] += i;
  3683.             sd->subele[ELE_WIND] += i;
  3684.             sd->subele[ELE_POISON] += i;
  3685.             sd->subele[ELE_HOLY] += i;
  3686.             sd->subele[ELE_DARK] += i;
  3687.             sd->subele[ELE_GHOST] += i;
  3688.             sd->subele[ELE_UNDEAD] += i;
  3689.         }
  3690.         if(sc->data[SC_PROVIDENCE]) {
  3691.             sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
  3692.             sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
  3693.         }
  3694.         if(sc->data[SC_ARMOR_ELEMENT]) {    // This status change should grant card-type elemental resist.
  3695.             sd->subele[ELE_WATER] += sc->data[SC_ARMOR_ELEMENT]->val1;
  3696.             sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_ELEMENT]->val2;
  3697.             sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
  3698.             sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
  3699.         }
  3700.         if(sc->data[SC_ARMOR_RESIST]) { // Undead Scroll
  3701.             sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
  3702.             sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_RESIST]->val2;
  3703.             sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
  3704.             sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
  3705.         }
  3706.         if( sc->data[SC_FIRE_CLOAK_OPTION] ) {
  3707.             i = sc->data[SC_FIRE_CLOAK_OPTION]->val2;
  3708.             sd->subele[ELE_FIRE] += i;
  3709.             sd->subele[ELE_WATER] -= i;
  3710.         }
  3711.         if( sc->data[SC_WATER_DROP_OPTION] ) {
  3712.             i = sc->data[SC_WATER_DROP_OPTION]->val2;
  3713.             sd->subele[ELE_WATER] += i;
  3714.             sd->subele[ELE_WIND] -= i;
  3715.         }
  3716.         if( sc->data[SC_WIND_CURTAIN_OPTION] ) {
  3717.             i = sc->data[SC_WIND_CURTAIN_OPTION]->val2;
  3718.             sd->subele[ELE_WIND] += i;
  3719.             sd->subele[ELE_EARTH] -= i;
  3720.         }
  3721.         if( sc->data[SC_STONE_SHIELD_OPTION] ) {
  3722.             i = sc->data[SC_STONE_SHIELD_OPTION]->val2;
  3723.             sd->subele[ELE_EARTH] += i;
  3724.             sd->subele[ELE_FIRE] -= i;
  3725.         }
  3726.         if (sc->data[SC_MTF_MLEATKED] )
  3727.             sd->subele[ELE_NEUTRAL] += sc->data[SC_MTF_MLEATKED]->val3;
  3728.         if (sc->data[SC_MTF_CRIDAMAGE])
  3729.             sd->bonus.crit_atk_rate += sc->data[SC_MTF_CRIDAMAGE]->val1;
  3730.         if( sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3 )
  3731.             sd->magic_addele[ELE_FIRE] += 25;
  3732.         if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 )
  3733.             sd->magic_addele[ELE_WATER] += 25;
  3734.         if( sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 )
  3735.             sd->magic_addele[ELE_WIND] += 25;
  3736.         if( sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3 )
  3737.             sd->magic_addele[ELE_EARTH] += 25;
  3738.     }
  3739.     status_cpy(&sd->battle_status, status);
  3740.  
  3741. // ----- CLIENT-SIDE REFRESH -----
  3742.     if(!sd->bl.prev) {
  3743.         // Will update on LoadEndAck
  3744.         calculating = 0;
  3745.         return 0;
  3746.     }
  3747.     if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
  3748.         clif_skillinfoblock(sd);
  3749.     if(b_weight != sd->weight)
  3750.         clif_updatestatus(sd,SP_WEIGHT);
  3751.     if(b_max_weight != sd->max_weight) {
  3752.         clif_updatestatus(sd,SP_MAXWEIGHT);
  3753.         pc_updateweightstatus(sd);
  3754.     }
  3755.     if( b_cart_weight_max != sd->cart_weight_max ) {
  3756.         clif_updatestatus(sd,SP_CARTINFO);
  3757.     }
  3758.  
  3759.     calculating = 0;
  3760.  
  3761.     return 0;
  3762. }
  3763.  
  3764. /**
  3765.  * Calculates Mercenary data
  3766.  * @param md: Mercenary object
  3767.  * @param opt: Whether it is first calc or not (0 on level up or status)
  3768.  * @return 0
  3769.  */
  3770. int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt)
  3771. {
  3772.     struct status_data *status = &md->base_status;
  3773.     struct s_mercenary *merc = &md->mercenary;
  3774.  
  3775.     if (opt&SCO_FIRST) {
  3776.         memcpy(status, &md->db->status, sizeof(struct status_data));
  3777.         status->class_ = CLASS_NORMAL;
  3778.         status->mode = MD_CANMOVE|MD_CANATTACK;
  3779.         status->hp = status->max_hp;
  3780.         status->sp = status->max_sp;
  3781.         md->battle_status.hp = merc->hp;
  3782.         md->battle_status.sp = merc->sp;
  3783.         if (md->master)
  3784.             status->speed = status_get_speed(&md->master->bl);
  3785.     }
  3786.  
  3787.     status_calc_misc(&md->bl, status, md->db->lv);
  3788.     status_cpy(&md->battle_status, status);
  3789.  
  3790.     return 0;
  3791. }
  3792.  
  3793. /**
  3794.  * Calculates Homunculus data
  3795.  * @param hd: Homunculus object
  3796.  * @param opt: Whether it is first calc or not (0 on level up or status)
  3797.  * @return 1
  3798.  */
  3799. int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
  3800. {
  3801.     struct status_data *status = &hd->base_status;
  3802.     struct s_homunculus *hom = &hd->homunculus;
  3803.     int skill_lv;
  3804.     int amotion;
  3805.  
  3806.     status->str = hom->str / 10;
  3807.     status->agi = hom->agi / 10;
  3808.     status->vit = hom->vit / 10;
  3809.     status->dex = hom->dex / 10;
  3810.     status->int_ = hom->int_ / 10;
  3811.     status->luk = hom->luk / 10;
  3812.  
  3813.     APPLY_HOMUN_LEVEL_STATWEIGHT();
  3814.  
  3815.     if (opt&SCO_FIRST) {
  3816.         const struct s_homunculus_db *db = hd->homunculusDB;
  3817.         status->def_ele = db->element;
  3818.         status->ele_lv = 1;
  3819.         status->race = db->race;
  3820.         status->class_ = CLASS_NORMAL;
  3821.         status->size = (hom->class_ == db->evo_class) ? db->evo_size : db->base_size;
  3822.         status->rhw.range = 1 + status->size;
  3823.         status->mode = MD_CANMOVE|MD_CANATTACK;
  3824.         status->speed = DEFAULT_WALK_SPEED;
  3825.         if (battle_config.hom_setting&HOMSET_COPY_SPEED && hd->master)
  3826.             status->speed = status_get_speed(&hd->master->bl);
  3827.  
  3828.         status->hp = 1;
  3829.         status->sp = 1;
  3830.     }
  3831.  
  3832.     status->aspd_rate = 1000;
  3833.  
  3834. #ifdef RENEWAL
  3835.     amotion = hd->homunculusDB->baseASPD;
  3836.     amotion = amotion - amotion * (status->dex + hom->dex_value) / 1000 - (status->agi + hom->agi_value) * amotion / 250;
  3837.     status->def = status->mdef = 0;
  3838. #else
  3839.     skill_lv = hom->level / 10 + status->vit / 5;
  3840.     status->def = cap_value(skill_lv, 0, 99);
  3841.  
  3842.     skill_lv = hom->level / 10 + status->int_ / 5;
  3843.     status->mdef = cap_value(skill_lv, 0, 99);
  3844.  
  3845.     amotion = (1000 - 4 * status->agi - status->dex) * hd->homunculusDB->baseASPD / 1000;
  3846. #endif
  3847.  
  3848.     status->amotion = cap_value(amotion, battle_config.max_aspd, 2000);
  3849.     status->adelay = status->amotion; //It seems adelay = amotion for Homunculus.
  3850.  
  3851.     status->max_hp = hom->max_hp;
  3852.     status->max_sp = hom->max_sp;
  3853.  
  3854.     hom_calc_skilltree(hd, 0);
  3855.  
  3856.     if((skill_lv = hom_checkskill(hd, HAMI_SKIN)) > 0)
  3857.         status->def += skill_lv * 4;
  3858.  
  3859.     if((skill_lv = hom_checkskill(hd, HVAN_INSTRUCT)) > 0) {
  3860.         status->int_ += 1 + skill_lv / 2 + skill_lv / 4 + skill_lv / 5;
  3861.         status->str += 1 + skill_lv / 3 + skill_lv / 3 + skill_lv / 4;
  3862.     }
  3863.  
  3864.     if((skill_lv = hom_checkskill(hd, HAMI_SKIN)) > 0)
  3865.         status->max_hp += skill_lv * 2 * status->max_hp / 100;
  3866.  
  3867.     if((skill_lv = hom_checkskill(hd, HLIF_BRAIN)) > 0)
  3868.         status->max_sp += (1 + skill_lv / 2 - skill_lv / 4 + skill_lv / 5) * status->max_sp / 100;
  3869.  
  3870.     if (opt&SCO_FIRST) {
  3871.         hd->battle_status.hp = hom->hp;
  3872.         hd->battle_status.sp = hom->sp;
  3873.         if(hom->class_ == 6052) // Eleanor
  3874.             sc_start(&hd->bl,&hd->bl, SC_STYLE_CHANGE, 100, MH_MD_FIGHTING, -1);
  3875.     }
  3876.  
  3877. #ifndef RENEWAL
  3878.     status->rhw.atk = status->dex;
  3879.     status->rhw.atk2 = status->str + hom->level;
  3880. #endif
  3881.  
  3882.     status_calc_misc(&hd->bl, status, hom->level);
  3883.  
  3884.     status_cpy(&hd->battle_status, status);
  3885.     return 1;
  3886. }
  3887.  
  3888. /**
  3889.  * Calculates Elemental data
  3890.  * @param ed: Elemental object
  3891.  * @param opt: Whether it is first calc or not (0 on status change)
  3892.  * @return 0
  3893.  */
  3894. int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt)
  3895. {
  3896.     struct status_data *status = &ed->base_status;
  3897.     struct s_elemental *ele = &ed->elemental;
  3898.     struct map_session_data *sd = ed->master;
  3899.  
  3900.     if( !sd )
  3901.         return 0;
  3902.  
  3903.     if (opt&SCO_FIRST) {
  3904.         memcpy(status, &ed->db->status, sizeof(struct status_data));
  3905.         if( !ele->mode )
  3906.             status->mode = EL_MODE_PASSIVE;
  3907.         else
  3908.             status->mode = ele->mode;
  3909.  
  3910.         status->class_ = CLASS_NORMAL;
  3911.         status_calc_misc(&ed->bl, status, 0);
  3912.  
  3913.         status->max_hp = ele->max_hp;
  3914.         status->max_sp = ele->max_sp;
  3915.         status->hp = ele->hp;
  3916.         status->sp = ele->sp;
  3917.         status->rhw.atk = ele->atk;
  3918.         status->rhw.atk2 = ele->atk2;
  3919.  
  3920.         status->matk_min += ele->matk;
  3921.         status->def += ele->def;
  3922.         status->mdef += ele->mdef;
  3923.         status->flee = ele->flee;
  3924.         status->hit = ele->hit;
  3925.  
  3926.         if (ed->master)
  3927.             status->speed = status_get_speed(&ed->master->bl);
  3928.  
  3929.         memcpy(&ed->battle_status,status,sizeof(struct status_data));
  3930.     } else {
  3931.         status_calc_misc(&ed->bl, status, 0);
  3932.         status_cpy(&ed->battle_status, status);
  3933.     }
  3934.  
  3935.     return 0;
  3936. }
  3937.  
  3938. /**
  3939.  * Calculates NPC data
  3940.  * @param nd: NPC object
  3941.  * @param opt: Whether it is first calc or not (what?)
  3942.  * @return 0
  3943.  */
  3944. int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
  3945. {
  3946.     struct status_data *status = &nd->status;
  3947.  
  3948.     if (!nd)
  3949.         return 0;
  3950.  
  3951.     if (opt&SCO_FIRST) {
  3952.         status->hp = 1;
  3953.         status->sp = 1;
  3954.         status->max_hp = 1;
  3955.         status->max_sp = 1;
  3956.  
  3957.         status->def_ele = ELE_NEUTRAL;
  3958.         status->ele_lv = 1;
  3959.         status->race = RC_DEMIHUMAN;
  3960.         status->class_ = CLASS_NORMAL;
  3961.         status->size = nd->size;
  3962.         status->rhw.range = 1 + status->size;
  3963.         status->mode = (MD_CANMOVE|MD_CANATTACK);
  3964.         status->speed = nd->speed;
  3965.     }
  3966.  
  3967.     status->str = nd->stat_point + nd->params.str;
  3968.     status->agi = nd->stat_point + nd->params.agi;
  3969.     status->vit = nd->stat_point + nd->params.vit;
  3970.     status->int_= nd->stat_point + nd->params.int_;
  3971.     status->dex = nd->stat_point + nd->params.dex;
  3972.     status->luk = nd->stat_point + nd->params.luk;
  3973.  
  3974.     status_calc_misc(&nd->bl, status, nd->level);
  3975.     status_cpy(&nd->status, status);
  3976.  
  3977.     return 0;
  3978. }
  3979.  
  3980. /**
  3981.  * Calculates regeneration values
  3982.  * Applies passive skill regeneration additions
  3983.  * @param bl: Object to calculate regen for [PC|HOM|MER|ELEM]
  3984.  * @param status: Object's status
  3985.  * @param regen: Object's base regeneration data
  3986.  */
  3987. void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen)
  3988. {
  3989.     struct map_session_data *sd;
  3990.     int val, skill, reg_flag;
  3991.  
  3992.     if( !(bl->type&BL_REGEN) || !regen )
  3993.         return;
  3994.  
  3995.     sd = BL_CAST(BL_PC,bl);
  3996.     val = 1 + (status->vit/5) + (status->max_hp/200);
  3997.  
  3998.     if( sd && sd->hprecov_rate != 100 )
  3999.         val = val*sd->hprecov_rate/100;
  4000.  
  4001.     reg_flag = bl->type == BL_PC ? 0 : 1;
  4002.  
  4003.     regen->hp = cap_value(val, reg_flag, SHRT_MAX);
  4004.  
  4005.     val = 1 + (status->int_/6) + (status->max_sp/100);
  4006.     if( status->int_ >= 120 )
  4007.         val += ((status->int_-120)>>1) + 4;
  4008.  
  4009.     if( sd && sd->sprecov_rate != 100 )
  4010.         val = val*sd->sprecov_rate/100;
  4011.  
  4012.     regen->sp = cap_value(val, reg_flag, SHRT_MAX);
  4013.  
  4014.     if( sd ) {
  4015.         struct regen_data_sub *sregen;
  4016.         if( (skill=pc_checkskill(sd,HP_MEDITATIO)) > 0 ) {
  4017.             val = regen->sp*(100+3*skill)/100;
  4018.             regen->sp = cap_value(val, 1, SHRT_MAX);
  4019.         }
  4020.         // Only players have skill/sitting skill regen for now.
  4021.         sregen = regen->sregen;
  4022.  
  4023.         val = 0;
  4024.         if( (skill=pc_checkskill(sd,SM_RECOVERY)) > 0 )
  4025.             val += skill*5 + skill*status->max_hp/500;
  4026.         sregen->hp = cap_value(val, 0, SHRT_MAX);
  4027.  
  4028.         val = 0;
  4029.         if( (skill=pc_checkskill(sd,MG_SRECOVERY)) > 0 )
  4030.             val += skill*3 + skill*status->max_sp/500;
  4031.         if( (skill=pc_checkskill(sd,NJ_NINPOU)) > 0 )
  4032.             val += skill*3 + skill*status->max_sp/500;
  4033.         if( (skill=pc_checkskill(sd,WM_LESSON)) > 0 )
  4034.             val += 3 + 3 * skill;
  4035.  
  4036.         sregen->sp = cap_value(val, 0, SHRT_MAX);
  4037.  
  4038.         // Skill-related recovery (only when sit)
  4039.         sregen = regen->ssregen;
  4040.  
  4041.         val = 0;
  4042.         if( (skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 )
  4043.             val += skill*4 + skill*status->max_hp/500;
  4044.  
  4045.         if( (skill=pc_checkskill(sd,TK_HPTIME)) > 0 && sd->state.rest )
  4046.             val += skill*30 + skill*status->max_hp/500;
  4047.         sregen->hp = cap_value(val, 0, SHRT_MAX);
  4048.  
  4049.         val = 0;
  4050.         if( (skill=pc_checkskill(sd,TK_SPTIME)) > 0 && sd->state.rest ) {
  4051.             val += skill*3 + skill*status->max_sp/500;
  4052.             if ((skill=pc_checkskill(sd,SL_KAINA)) > 0) // Power up Enjoyable Rest
  4053.                 val += (30+10*skill)*val/100;
  4054.         }
  4055.         if( (skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0 )
  4056.             val += skill*2 + skill*status->max_sp/500;
  4057.         sregen->sp = cap_value(val, 0, SHRT_MAX);
  4058.     }
  4059.  
  4060.     if( bl->type == BL_HOM ) {
  4061.         struct homun_data *hd = (TBL_HOM*)bl;
  4062.         if( (skill = hom_checkskill(hd,HAMI_SKIN)) > 0 ) {
  4063.             val = regen->hp*(100+5*skill)/100;
  4064.             regen->hp = cap_value(val, 1, SHRT_MAX);
  4065.         }
  4066.         if( (skill = hom_checkskill(hd,HLIF_BRAIN)) > 0 ) {
  4067.             val = regen->sp*(100+3*skill)/100;
  4068.             regen->sp = cap_value(val, 1, SHRT_MAX);
  4069.         }
  4070.     } else if( bl->type == BL_MER ) {
  4071.         val = (status->max_hp * status->vit / 10000 + 1) * 6;
  4072.         regen->hp = cap_value(val, 1, SHRT_MAX);
  4073.  
  4074.         val = (status->max_sp * (status->int_ + 10) / 750) + 1;
  4075.         regen->sp = cap_value(val, 1, SHRT_MAX);
  4076.     } else if( bl->type == BL_ELEM ) {
  4077.         val = (status->max_hp * status->vit / 10000 + 1) * 6;
  4078.         regen->hp = cap_value(val, 1, SHRT_MAX);
  4079.  
  4080.         val = (status->max_sp * (status->int_ + 10) / 750) + 1;
  4081.         regen->sp = cap_value(val, 1, SHRT_MAX);
  4082.     }
  4083. }
  4084.  
  4085. /**
  4086.  * Calculates SC (Status Changes) regeneration values
  4087.  * @param bl: Object to calculate regen for [PC|HOM|MER|ELEM]
  4088.  * @param regen: Object's base regeneration data
  4089.  * @param sc: Object's status change data
  4090.  */
  4091. void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
  4092. {
  4093.     if (!(bl->type&BL_REGEN) || !regen)
  4094.         return;
  4095.  
  4096.     regen->flag = RGN_HP|RGN_SP;
  4097.     if(regen->sregen) {
  4098.         if (regen->sregen->hp)
  4099.             regen->flag |= RGN_SHP;
  4100.  
  4101.         if (regen->sregen->sp)
  4102.             regen->flag |= RGN_SSP;
  4103.         regen->sregen->rate.hp = regen->sregen->rate.sp = 100;
  4104.     }
  4105.     if (regen->ssregen) {
  4106.         if (regen->ssregen->hp)
  4107.             regen->flag |= RGN_SHP;
  4108.  
  4109.         if (regen->ssregen->sp)
  4110.             regen->flag |= RGN_SSP;
  4111.         regen->ssregen->rate.hp = regen->ssregen->rate.sp = 100;
  4112.     }
  4113.     regen->rate.hp = regen->rate.sp = 100;
  4114.  
  4115.     if (!sc || !sc->count)
  4116.         return;
  4117.  
  4118.     // No HP or SP regen
  4119.     if ((sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
  4120.         || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
  4121.         || sc->data[SC_BERSERK]
  4122.         || sc->data[SC_TRICKDEAD]
  4123.         || sc->data[SC_BLEEDING]
  4124.         || sc->data[SC_MAGICMUSHROOM]
  4125.         || sc->data[SC_SATURDAYNIGHTFEVER]
  4126.         || sc->data[SC_REBOUND])
  4127.         regen->flag = RGN_NONE;
  4128.  
  4129.     // No natural SP regen
  4130.     if (sc->data[SC_DANCING] ||
  4131. #ifdef RENEWAL
  4132.         sc->data[SC_MAXIMIZEPOWER] ||
  4133. #endif
  4134. #ifndef RENEWAL
  4135.         (bl->type == BL_PC && (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
  4136.         (sc->data[SC_EXTREMITYFIST] || sc->data[SC_EXPLOSIONSPIRITS]) && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)) ||
  4137. #else
  4138.         (bl->type == BL_PC && (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
  4139.         sc->data[SC_EXTREMITYFIST] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)) ||
  4140. #endif
  4141.         sc->data[SC_OBLIVIONCURSE] || sc->data[SC_VITALITYACTIVATION])
  4142.         regen->flag &= ~RGN_SP;
  4143.  
  4144.     if (sc->data[SC_TENSIONRELAX]) {
  4145.         if (sc->data[SC_WEIGHT50] || sc->data[SC_WEIGHT90])
  4146.             regen->state.overweight = 0; // 1x HP regen
  4147.         else {
  4148.             regen->rate.hp += 200;
  4149.             if (regen->sregen)
  4150.                 regen->sregen->rate.hp += 200;
  4151.         }
  4152.     }
  4153.  
  4154.     if (sc->data[SC_MAGNIFICAT])
  4155.         regen->rate.sp += 100;
  4156.  
  4157.     if (sc->data[SC_REGENERATION]) {
  4158.         const struct status_change_entry *sce = sc->data[SC_REGENERATION];
  4159.         if (!sce->val4) {
  4160.             regen->rate.hp += (sce->val2*100);
  4161.             regen->rate.sp += (sce->val3*100);
  4162.         } else
  4163.             regen->flag &= ~sce->val4; // Remove regen as specified by val4
  4164.     }
  4165.     if(sc->data[SC_GT_REVITALIZE]) {
  4166.         regen->hp += cap_value(regen->hp * sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
  4167.         regen->state.walk = 1;
  4168.     }
  4169.     if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) // If insignia lvl 1
  4170.         || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
  4171.         || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
  4172.         || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
  4173.         regen->rate.hp *= 2;
  4174.     if (sc->data[SC_EXTRACT_WHITE_POTION_Z])
  4175.         regen->rate.hp += (unsigned short)(regen->rate.hp * sc->data[SC_EXTRACT_WHITE_POTION_Z]->val1 / 100.);
  4176.     if (sc->data[SC_VITATA_500])
  4177.         regen->rate.sp += (unsigned short)(regen->rate.sp * sc->data[SC_VITATA_500]->val1 / 100.);
  4178. }
  4179.  
  4180. /**
  4181.  * Applies a state to a unit - See [StatusChangeStateTable]
  4182.  * @param bl: Object to change state on [PC|MOB|HOM|MER|ELEM]
  4183.  * @param sc: Object's status change data
  4184.  * @param flag: Which state to apply to bl
  4185.  * @param start: (1) start state, (0) remove state
  4186.  */
  4187. void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start )
  4188. {
  4189.  
  4190.     /// No sc at all, we can zero without any extra weight over our conciousness
  4191.     if( !sc->count ) {
  4192.         memset(&sc->cant, 0, sizeof (sc->cant));
  4193.         return;
  4194.     }
  4195.  
  4196.     // Can't move
  4197.     if( flag&SCS_NOMOVE ) {
  4198.         if( !(flag&SCS_NOMOVECOND) )
  4199.             sc->cant.move += ( start ? 1 : -1 );
  4200.         else if(
  4201.                      (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
  4202.                   || (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
  4203.                   || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
  4204.                   || (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)
  4205.                   || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3)
  4206.                   || (sc->data[SC_MAGNETICFIELD] && sc->data[SC_MAGNETICFIELD]->val2 != bl->id)
  4207.                  )
  4208.             sc->cant.move += ( start ? 1 : -1 );
  4209.         sc->cant.move = max(sc->cant.move,0); // safecheck
  4210.     }
  4211.  
  4212.     // Can't use skills
  4213.     if( flag&SCS_NOCAST ) {
  4214.         if( !(flag&SCS_NOCASTCOND) )
  4215.             sc->cant.cast += ( start ? 1 : -1 );
  4216.         else if( (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB) )
  4217.             sc->cant.cast += ( start ? 1 : -1 );
  4218.     }
  4219.  
  4220.     // Can't chat
  4221.     if( flag&SCS_NOCHAT ) {
  4222.         if( !(flag&SCS_NOCHATCOND) )
  4223.             sc->cant.chat += ( start ? 1 : -1 );
  4224.         else if(sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOCHAT)
  4225.             sc->cant.chat += ( start ? 1 : -1 );
  4226.     }
  4227.  
  4228.     // Player-only states
  4229.     if( bl->type == BL_PC ) {
  4230.         // Can't pick-up items
  4231.         if( flag&SCS_NOPICKITEM ) {
  4232.             if( !(flag&SCS_NOPICKITEMCOND) )
  4233.                 sc->cant.pickup += ( start ? 1 : -1 );
  4234.             else if( (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM) )
  4235.                 sc->cant.pickup += ( start ? 1 : -1 );
  4236.         }
  4237.  
  4238.         // Can't drop items
  4239.         if( flag&SCS_NODROPITEM ) {
  4240.             if( !(flag&SCS_NODROPITEMCOND) )
  4241.                 sc->cant.drop += ( start ? 1 : -1 );
  4242.             else if( (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOITEM) )
  4243.                 sc->cant.drop += ( start ? 1 : -1 );
  4244.         }
  4245.     }
  4246.  
  4247.     return;
  4248. }
  4249.  
  4250. /**
  4251.  * Recalculates parts of an objects status according to specified flags
  4252.  * See [set_sc] [add_sc]
  4253.  * @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM]
  4254.  * @param flag: Which status has changed on bl
  4255.  */
  4256. void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
  4257. {
  4258.     const struct status_data *b_status = status_get_base_status(bl);
  4259.     struct status_data *status = status_get_status_data(bl);
  4260.     struct status_change *sc = status_get_sc(bl);
  4261.     TBL_PC *sd = BL_CAST(BL_PC,bl);
  4262.     int temp;
  4263.  
  4264.     if (!b_status || !status)
  4265.         return;
  4266.  
  4267.     /** [Playtester]
  4268.     * This needs to be done even if there is currently no status change active, because
  4269.     * we need to update the speed on the client when the last status change ends.
  4270.     **/
  4271.     if(flag&SCB_SPEED) {
  4272.         struct unit_data *ud = unit_bl2ud(bl);
  4273.         /** [Skotlex]
  4274.         * Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
  4275.         * because if you step on something while walking, the moment this
  4276.         * piece of code triggers the walk-timer is set on INVALID_TIMER)
  4277.         **/
  4278.         if (ud)
  4279.             ud->state.change_walk_target = ud->state.speed_changed = 1;
  4280.     }
  4281.  
  4282.     if((!(bl->type&BL_REGEN)) && (!sc || !sc->count)) { // No difference.
  4283.         status_cpy(status, b_status);
  4284.         return;
  4285.     }
  4286.  
  4287.     if(flag&SCB_STR) {
  4288.         status->str = status_calc_str(bl, sc, b_status->str);
  4289.         flag|=SCB_BATK;
  4290.         if( bl->type&BL_HOM )
  4291.             flag |= SCB_WATK;
  4292.     }
  4293.  
  4294.     if(flag&SCB_AGI) {
  4295.         status->agi = status_calc_agi(bl, sc, b_status->agi);
  4296.         flag|=SCB_FLEE
  4297. #ifdef RENEWAL
  4298.             |SCB_DEF2
  4299. #endif
  4300.             ;
  4301.         if( bl->type&(BL_PC|BL_HOM) )
  4302.             flag |= SCB_ASPD|SCB_DSPD;
  4303.     }
  4304.  
  4305.     if(flag&SCB_VIT) {
  4306.         status->vit = status_calc_vit(bl, sc, b_status->vit);
  4307.         flag|=SCB_DEF2|SCB_MDEF2;
  4308.         if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
  4309.             flag |= SCB_MAXHP;
  4310.         if( bl->type&BL_HOM )
  4311.             flag |= SCB_DEF;
  4312.     }
  4313.  
  4314.     if(flag&SCB_INT) {
  4315.         status->int_ = status_calc_int(bl, sc, b_status->int_);
  4316.         flag|=SCB_MATK|SCB_MDEF2;
  4317.         if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
  4318.             flag |= SCB_MAXSP;
  4319.         if( bl->type&BL_HOM )
  4320.             flag |= SCB_MDEF;
  4321.     }
  4322.  
  4323.     if(flag&SCB_DEX) {
  4324.         status->dex = status_calc_dex(bl, sc, b_status->dex);
  4325.         flag|=SCB_BATK|SCB_HIT
  4326. #ifdef RENEWAL
  4327.             |SCB_MATK|SCB_MDEF2
  4328. #endif
  4329.             ;
  4330.         if( bl->type&(BL_PC|BL_HOM) )
  4331.             flag |= SCB_ASPD;
  4332.         if( bl->type&BL_HOM )
  4333.             flag |= SCB_WATK;
  4334.     }
  4335.  
  4336.     if(flag&SCB_LUK) {
  4337.         status->luk = status_calc_luk(bl, sc, b_status->luk);
  4338.         flag|=SCB_BATK|SCB_CRI|SCB_FLEE2
  4339. #ifdef RENEWAL
  4340.             |SCB_MATK|SCB_HIT|SCB_FLEE
  4341. #endif
  4342.             ;
  4343.     }
  4344.  
  4345.     if(flag&SCB_BATK && b_status->batk) {
  4346.         status->batk = status_base_atk(bl,status);
  4347.         temp = b_status->batk - status_base_atk(bl,b_status);
  4348.         if (temp) {
  4349.             temp += status->batk;
  4350.             status->batk = cap_value(temp, 0, USHRT_MAX);
  4351.         }
  4352.         status->batk = status_calc_batk(bl, sc, status->batk);
  4353.     }
  4354.  
  4355.     if(flag&SCB_WATK) {
  4356. #ifndef RENEWAL
  4357.         status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk);
  4358.         if (!sd) // Should not affect weapon refine bonus
  4359.             status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
  4360.  
  4361.         if(b_status->lhw.atk) {
  4362.             if (sd) {
  4363.                 sd->state.lr_flag = 1;
  4364.                 status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
  4365.                 sd->state.lr_flag = 0;
  4366.             } else {
  4367.                 status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
  4368.                 status->lhw.atk2= status_calc_watk(bl, sc, b_status->lhw.atk2);
  4369.             }
  4370.         }
  4371. #else
  4372.         if(!b_status->watk) { // We only have left-hand weapon
  4373.             status->watk = 0;
  4374.             status->watk2 = status_calc_watk(bl, sc, b_status->watk2);
  4375.         }
  4376.         else status->watk = status_calc_watk(bl, sc, b_status->watk);
  4377. #endif
  4378.     }
  4379.  
  4380.     if(flag&SCB_HIT) {
  4381.         if (status->dex == b_status->dex
  4382. #ifdef RENEWAL
  4383.             && status->luk == b_status->luk
  4384. #endif
  4385.             )
  4386.             status->hit = status_calc_hit(bl, sc, b_status->hit);
  4387.         else
  4388.             status->hit = status_calc_hit(bl, sc, b_status->hit + (status->dex - b_status->dex)
  4389. #ifdef RENEWAL
  4390.              + (status->luk/3 - b_status->luk/3)
  4391. #endif
  4392.              );
  4393.     }
  4394.  
  4395.     if(flag&SCB_FLEE) {
  4396.         if (status->agi == b_status->agi
  4397. #ifdef RENEWAL
  4398.             && status->luk == b_status->luk
  4399. #endif
  4400.             )
  4401.             status->flee = status_calc_flee(bl, sc, b_status->flee);
  4402.         else
  4403.             status->flee = status_calc_flee(bl, sc, b_status->flee +(status->agi - b_status->agi)
  4404. #ifdef RENEWAL
  4405.             + (status->luk/5 - b_status->luk/5)
  4406. #endif
  4407.             );
  4408.     }
  4409.  
  4410.     if(flag&SCB_DEF) {
  4411.         status->def = status_calc_def(bl, sc, b_status->def);
  4412.  
  4413.         if( bl->type&BL_HOM )
  4414.             status->def += (status->vit/5 - b_status->vit/5);
  4415.     }
  4416.  
  4417.     if(flag&SCB_DEF2) {
  4418.         if (status->vit == b_status->vit
  4419. #ifdef RENEWAL
  4420.             && status->agi == b_status->agi
  4421. #endif
  4422.             )
  4423.             status->def2 = status_calc_def2(bl, sc, b_status->def2);
  4424.         else
  4425.             status->def2 = status_calc_def2(bl, sc, b_status->def2
  4426. #ifdef RENEWAL
  4427.             + (int)( ((float)status->vit/2 - (float)b_status->vit/2) + ((float)status->agi/5 - (float)b_status->agi/5) )
  4428. #else
  4429.             + (status->vit - b_status->vit)
  4430. #endif
  4431.         );
  4432.     }
  4433.  
  4434.     if(flag&SCB_MDEF) {
  4435.         status->mdef = status_calc_mdef(bl, sc, b_status->mdef);
  4436.  
  4437.         if( bl->type&BL_HOM )
  4438.             status->mdef += (status->int_/5 - b_status->int_/5);
  4439.     }
  4440.  
  4441.     if(flag&SCB_MDEF2) {
  4442.         if (status->int_ == b_status->int_ && status->vit == b_status->vit
  4443. #ifdef RENEWAL
  4444.             && status->dex == b_status->dex
  4445. #endif
  4446.             )
  4447.             status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2);
  4448.         else
  4449.             status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2 +(status->int_ - b_status->int_)
  4450. #ifdef RENEWAL
  4451.             + (int)( ((float)status->dex/5 - (float)b_status->dex/5) + ((float)status->vit/5 - (float)b_status->vit/5) )
  4452. #else
  4453.             + ((status->vit - b_status->vit)>>1)
  4454. #endif
  4455.             );
  4456.     }
  4457.  
  4458.     if(flag&SCB_SPEED) {
  4459.         status->speed = status_calc_speed(bl, sc, b_status->speed);
  4460.  
  4461.         if( bl->type&BL_PC && !(sd && sd->state.permanent_speed) && status->speed < battle_config.max_walk_speed )
  4462.             status->speed = battle_config.max_walk_speed;
  4463.  
  4464.         if( bl->type&BL_HOM && battle_config.hom_setting&HOMSET_COPY_SPEED && ((TBL_HOM*)bl)->master)
  4465.             status->speed = status_get_speed(&((TBL_HOM*)bl)->master->bl);
  4466.         if( bl->type&BL_MER && ((TBL_MER*)bl)->master)
  4467.             status->speed = status_get_speed(&((TBL_MER*)bl)->master->bl);
  4468.         if( bl->type&BL_ELEM && ((TBL_ELEM*)bl)->master)
  4469.             status->speed = status_get_speed(&((TBL_ELEM*)bl)->master->bl);
  4470.     }
  4471.  
  4472.     if(flag&SCB_CRI && b_status->cri) {
  4473.         if (status->luk == b_status->luk)
  4474.             status->cri = status_calc_critical(bl, sc, b_status->cri);
  4475.         else
  4476.             status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk));
  4477.  
  4478.         /// After status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240
  4479.         if( bl->type == BL_PC && ((TBL_PC*)bl)->status.weapon == W_KATAR )
  4480.             status->cri <<= 1;
  4481.     }
  4482.  
  4483.     if(flag&SCB_FLEE2 && b_status->flee2) {
  4484.         if (status->luk == b_status->luk)
  4485.             status->flee2 = status_calc_flee2(bl, sc, b_status->flee2);
  4486.         else
  4487.             status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk));
  4488.     }
  4489.  
  4490.     if(flag&SCB_ATK_ELE) {
  4491.         status->rhw.ele = status_calc_attack_element(bl, sc, b_status->rhw.ele);
  4492.         if (sd) sd->state.lr_flag = 1;
  4493.         status->lhw.ele = status_calc_attack_element(bl, sc, b_status->lhw.ele);
  4494.         if (sd) sd->state.lr_flag = 0;
  4495.     }
  4496.  
  4497.     if(flag&SCB_DEF_ELE) {
  4498.         status->def_ele = status_calc_element(bl, sc, b_status->def_ele);
  4499.         status->ele_lv = status_calc_element_lv(bl, sc, b_status->ele_lv);
  4500.     }
  4501.  
  4502.     if(flag&SCB_MODE) {
  4503.         status->mode = status_calc_mode(bl, sc, b_status->mode);
  4504.         // Since mode changed, reset their state.
  4505.         if (!(status->mode&MD_CANATTACK))
  4506.             unit_stop_attack(bl);
  4507.         if (!(status->mode&MD_CANMOVE))
  4508.             unit_stop_walking(bl,1);
  4509.     }
  4510.  
  4511.     /**
  4512.     * No status changes alter these yet.
  4513.     * if(flag&SCB_SIZE)
  4514.     * if(flag&SCB_RACE)
  4515.     * if(flag&SCB_RANGE)
  4516.     **/
  4517.  
  4518.     if(flag&SCB_MAXHP) {
  4519.         if( bl->type&BL_PC ) {
  4520.             status->max_hp = status_calc_maxhpsp_pc(sd,status->vit,true);
  4521.  
  4522.             if(battle_config.hp_rate != 100)
  4523.                 status->max_hp = (unsigned int)(battle_config.hp_rate * (status->max_hp/100.));
  4524.  
  4525.             status->max_hp = min(status->max_hp,(unsigned int)battle_config.max_hp);
  4526.         }
  4527.         else
  4528.             status->max_hp = status_calc_maxhp(bl, b_status->max_hp);
  4529.  
  4530.         if( status->hp > status->max_hp ) { // !FIXME: Should perhaps a status_zap should be issued?
  4531.             status->hp = status->max_hp;
  4532.             if( sd ) clif_updatestatus(sd,SP_HP);
  4533.         }
  4534.     }
  4535.  
  4536.     if(flag&SCB_MAXSP) {
  4537.         if( bl->type&BL_PC ) {
  4538.             status->max_sp = status_calc_maxhpsp_pc(sd,status->int_,false);
  4539.  
  4540.             if(battle_config.sp_rate != 100)
  4541.                 status->max_sp = (unsigned int)(battle_config.sp_rate * (status->max_sp/100.));
  4542.  
  4543.             status->max_sp = min(status->max_sp,(unsigned int)battle_config.max_sp);
  4544.         }
  4545.         else
  4546.             status->max_sp = status_calc_maxsp(bl, b_status->max_sp);
  4547.  
  4548.         if( status->sp > status->max_sp ) {
  4549.             status->sp = status->max_sp;
  4550.             if( sd ) clif_updatestatus(sd,SP_SP);
  4551.         }
  4552.     }
  4553.  
  4554.     if(flag&SCB_MATK) {
  4555. #ifndef RENEWAL
  4556.         status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
  4557.         status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
  4558. #else
  4559.         /**
  4560.          * RE MATK Formula (from irowiki:http:// irowiki.org/wiki/MATK)
  4561.          * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
  4562.          **/
  4563.         status->matk_min = status->matk_max = status_base_matk(bl, status, status_get_lv(bl));
  4564.  
  4565.         switch( bl->type ) {
  4566.             case BL_PC: {
  4567.                 int wMatk = 0;
  4568.                 int variance = 0;
  4569.  
  4570.                 // Any +MATK you get from skills and cards, including cards in weapon, is added here.
  4571.                 if (sd->bonus.ematk > 0)
  4572.                     status->matk_min += sd->bonus.ematk;
  4573.  
  4574.                 status->matk_min = status_calc_ematk(bl, sc, status->matk_min);
  4575.                 status->matk_max = status->matk_min;
  4576.  
  4577.                 // This is the only portion in MATK that varies depending on the weapon level and refinement rate.
  4578.                 if (b_status->lhw.matk) {
  4579.                     if (sd) {
  4580.                         //sd->state.lr_flag = 1; //?? why was that set here
  4581.                         status->lhw.matk = b_status->lhw.matk;
  4582.                         sd->state.lr_flag = 0;
  4583.                     } else {
  4584.                         status->lhw.matk = b_status->lhw.matk;
  4585.                     }
  4586.                 }
  4587.  
  4588.                 if (b_status->rhw.matk) {
  4589.                     status->rhw.matk = b_status->rhw.matk;
  4590.                 }
  4591.  
  4592.                 if (status->rhw.matk) {
  4593.                     wMatk += status->rhw.matk;
  4594.                     variance += wMatk * status->rhw.wlv / 10;
  4595.                 }
  4596.  
  4597.                 if (status->lhw.matk) {
  4598.                     wMatk += status->lhw.matk;
  4599.                     variance += status->lhw.matk * status->lhw.wlv / 10;
  4600.                 }
  4601.  
  4602.                 status->matk_min += wMatk - variance;
  4603.                 status->matk_max += wMatk + variance;
  4604.                 }
  4605.                 break;
  4606.             case BL_HOM:
  4607.                 status->matk_min += (status_get_homint(bl) + status_get_homdex(bl)) / 5;
  4608.                 status->matk_max += (status_get_homluk(bl) + status_get_homint(bl) + status_get_homdex(bl)) / 3;
  4609.                 break;
  4610.         }
  4611. #endif
  4612.  
  4613.         if (bl->type&BL_PC && sd->matk_rate != 100) {
  4614.             status->matk_max = status->matk_max * sd->matk_rate/100;
  4615.             status->matk_min = status->matk_min * sd->matk_rate/100;
  4616.         }
  4617.  
  4618.         if ((bl->type&BL_HOM && battle_config.hom_setting&HOMSET_SAME_MATK)  /// Hom Min Matk is always the same as Max Matk
  4619.                 || (sc && sc->data[SC_RECOGNIZEDSPELL]))
  4620.             status->matk_min = status->matk_max;
  4621.  
  4622. #ifdef RENEWAL
  4623.         if( sd && sd->right_weapon.overrefine > 0) {
  4624.             status->matk_min++;
  4625.             status->matk_max += sd->right_weapon.overrefine - 1;
  4626.         }
  4627. #endif
  4628.  
  4629.         status->matk_max = status_calc_matk(bl, sc, status->matk_max);
  4630.         status->matk_min = status_calc_matk(bl, sc, status->matk_min);
  4631.     }
  4632.  
  4633.     if(flag&SCB_ASPD) {
  4634.         int amotion;
  4635.  
  4636.         if ( bl->type&BL_HOM ) {
  4637. #ifdef RENEWAL_ASPD
  4638.             amotion = ((TBL_HOM*)bl)->homunculusDB->baseASPD;
  4639.             amotion = amotion - amotion * status_get_homdex(bl) / 1000 - status_get_homagi(bl) * amotion / 250;
  4640.             amotion = (amotion * status_calc_aspd(bl, sc, 1) + status_calc_aspd(bl, sc, 2)) / - 100 + amotion;
  4641. #else
  4642.             amotion = (1000 - 4 * status->agi - status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD / 1000;
  4643.  
  4644.             amotion = status_calc_aspd_rate(bl, sc, amotion);
  4645.  
  4646.             if (status->aspd_rate != 1000)
  4647.                 amotion = amotion * status->aspd_rate / 1000;
  4648. #endif
  4649.  
  4650.             amotion = status_calc_fix_aspd(bl, sc, amotion);
  4651.             status->amotion = cap_value(amotion, battle_config.max_aspd, 2000);
  4652.  
  4653.             status->adelay = status->amotion;
  4654.         } else if ( bl->type&BL_PC ) {
  4655.             amotion = status_base_amotion_pc(sd,status);
  4656. #ifndef RENEWAL_ASPD
  4657.             status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
  4658.  
  4659.             if(status->aspd_rate != 1000)
  4660.                 amotion = amotion*status->aspd_rate/1000;
  4661. #else
  4662.             /// aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
  4663.             amotion -= (int)(sqrt( (pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5) ) / 4 + (status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
  4664.  
  4665.             if( (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) != 0 ) // RE ASPD percertage modifier
  4666.                 amotion -= ( amotion - pc_maxaspd(sd) ) * (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 100;
  4667.  
  4668.             if(status->aspd_rate != 1000) // Absolute percentage modifier
  4669.                 amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
  4670. #endif
  4671.             amotion = status_calc_fix_aspd(bl, sc, amotion);
  4672.             status->amotion = cap_value(amotion,pc_maxaspd(sd),2000);
  4673.  
  4674.             status->adelay = 2*status->amotion;
  4675.         } else { // Mercenary and mobs
  4676.             amotion = b_status->amotion;
  4677.             status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
  4678.  
  4679.             if(status->aspd_rate != 1000)
  4680.                 amotion = amotion*status->aspd_rate/1000;
  4681.  
  4682.             amotion = status_calc_fix_aspd(bl, sc, amotion);
  4683.             status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
  4684.  
  4685.             temp = b_status->adelay*status->aspd_rate/1000;
  4686.             status->adelay = cap_value(temp, battle_config.monster_max_aspd*2, 4000);
  4687.         }
  4688.     }
  4689.  
  4690.     if(flag&SCB_DSPD) {
  4691.         int dmotion;
  4692.         if( bl->type&BL_PC ) {
  4693.             if (b_status->agi == status->agi)
  4694.                 status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
  4695.             else {
  4696.                 dmotion = 800-status->agi*4;
  4697.                 status->dmotion = cap_value(dmotion, 400, 800);
  4698.                 if(battle_config.pc_damage_delay_rate != 100)
  4699.                     status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
  4700.                 // It's safe to ignore b_status->dmotion since no bonus affects it.
  4701.                 status->dmotion = status_calc_dmotion(bl, sc, status->dmotion);
  4702.             }
  4703.         } else if( bl->type&BL_HOM ) {
  4704.             dmotion = 800-status->agi*4;
  4705.             status->dmotion = cap_value(dmotion, 400, 800);
  4706.             status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
  4707.         } else { // Mercenary and mobs
  4708.             status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
  4709.         }
  4710.     }
  4711.  
  4712.     if(flag&(SCB_VIT|SCB_MAXHP|SCB_INT|SCB_MAXSP) && bl->type&BL_REGEN)
  4713.         status_calc_regen(bl, status, status_get_regen_data(bl));
  4714.  
  4715.     if(flag&SCB_REGEN && bl->type&BL_REGEN)
  4716.         status_calc_regen_rate(bl, status_get_regen_data(bl), sc);
  4717. }
  4718.  
  4719. /**
  4720.  * Recalculates parts of an objects status according to specified flags
  4721.  * Also sends updates to the client when necessary
  4722.  * See [set_sc] [add_sc]
  4723.  * @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM]
  4724.  * @param flag: Which status has changed on bl
  4725.  * @param opt: If true, will cause status_calc_* functions to run their base status initialization code
  4726.  */
  4727. void status_calc_bl_(struct block_list* bl, enum scb_flag flag, enum e_status_calc_opt opt)
  4728. {
  4729.     struct status_data b_status; // Previous battle status
  4730.     struct status_data* status; // Pointer to current battle status
  4731.  
  4732.     if (bl->type == BL_PC && ((TBL_PC*)bl)->delayed_damage != 0) {
  4733.         if (opt&SCO_FORCE)
  4734.             ((TBL_PC*)bl)->state.hold_recalc = 0; /* Clear and move on */
  4735.         else {
  4736.             ((TBL_PC*)bl)->state.hold_recalc = 1; /* Flag and stop */
  4737.             return;
  4738.         }
  4739.     }
  4740.  
  4741.     // Remember previous values
  4742.     status = status_get_status_data(bl);
  4743.     memcpy(&b_status, status, sizeof(struct status_data));
  4744.  
  4745.     if( flag&SCB_BASE ) { // Calculate the object's base status too
  4746.         switch( bl->type ) {
  4747.         case BL_PC:  status_calc_pc_(BL_CAST(BL_PC,bl), opt);          break;
  4748.         case BL_MOB: status_calc_mob_(BL_CAST(BL_MOB,bl), opt);        break;
  4749.         case BL_PET: status_calc_pet_(BL_CAST(BL_PET,bl), opt);        break;
  4750.         case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), opt); break;
  4751.         case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), opt);  break;
  4752.         case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), opt);  break;
  4753.         case BL_NPC: status_calc_npc_(BL_CAST(BL_NPC,bl), opt); break;
  4754.         }
  4755.     }
  4756.  
  4757.     if( bl->type == BL_PET )
  4758.         return; // Pets are not affected by statuses
  4759.  
  4760.     if (opt&SCO_FIRST && bl->type == BL_MOB)
  4761.         return; // Assume there will be no statuses active
  4762.  
  4763.     status_calc_bl_main(bl, flag);
  4764.  
  4765.     if (opt&SCO_FIRST && bl->type == BL_HOM)
  4766.         return; // Client update handled by caller
  4767.  
  4768.     // Compare against new values and send client updates
  4769.     if( bl->type == BL_PC ) {
  4770.         TBL_PC* sd = BL_CAST(BL_PC, bl);
  4771.  
  4772.         if(b_status.str != status->str)
  4773.             clif_updatestatus(sd,SP_STR);
  4774.         if(b_status.agi != status->agi)
  4775.             clif_updatestatus(sd,SP_AGI);
  4776.         if(b_status.vit != status->vit)
  4777.             clif_updatestatus(sd,SP_VIT);
  4778.         if(b_status.int_ != status->int_)
  4779.             clif_updatestatus(sd,SP_INT);
  4780.         if(b_status.dex != status->dex)
  4781.             clif_updatestatus(sd,SP_DEX);
  4782.         if(b_status.luk != status->luk)
  4783.             clif_updatestatus(sd,SP_LUK);
  4784.         if(b_status.hit != status->hit)
  4785.             clif_updatestatus(sd,SP_HIT);
  4786.         if(b_status.flee != status->flee)
  4787.             clif_updatestatus(sd,SP_FLEE1);
  4788.         if(b_status.amotion != status->amotion)
  4789.             clif_updatestatus(sd,SP_ASPD);
  4790.         if(b_status.speed != status->speed)
  4791.             clif_updatestatus(sd,SP_SPEED);
  4792.  
  4793.         if(b_status.batk != status->batk
  4794. #ifndef RENEWAL
  4795.             || b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk
  4796. #endif
  4797.             )
  4798.             clif_updatestatus(sd,SP_ATK1);
  4799.  
  4800.         if(b_status.def != status->def) {
  4801.             clif_updatestatus(sd,SP_DEF1);
  4802. #ifdef RENEWAL
  4803.             clif_updatestatus(sd,SP_DEF2);
  4804. #endif
  4805.         }
  4806.  
  4807.         if(
  4808. #ifdef RENEWAL
  4809.             b_status.watk != status->watk || b_status.watk2 != status->watk2 || b_status.eatk != status->eatk
  4810. #else
  4811.             b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2
  4812. #endif
  4813.             )
  4814.             clif_updatestatus(sd,SP_ATK2);
  4815.  
  4816.         if(b_status.def2 != status->def2) {
  4817.             clif_updatestatus(sd,SP_DEF2);
  4818. #ifdef RENEWAL
  4819.             clif_updatestatus(sd,SP_DEF1);
  4820. #endif
  4821.         }
  4822.         if(b_status.flee2 != status->flee2)
  4823.             clif_updatestatus(sd,SP_FLEE2);
  4824.         if(b_status.cri != status->cri)
  4825.             clif_updatestatus(sd,SP_CRITICAL);
  4826. #ifndef RENEWAL
  4827.         if(b_status.matk_max != status->matk_max)
  4828.             clif_updatestatus(sd,SP_MATK1);
  4829.         if(b_status.matk_min != status->matk_min)
  4830.             clif_updatestatus(sd,SP_MATK2);
  4831. #else
  4832.         if(b_status.matk_max != status->matk_max || b_status.matk_min != status->matk_min) {
  4833.             clif_updatestatus(sd,SP_MATK2);
  4834.             clif_updatestatus(sd,SP_MATK1);
  4835.         }
  4836. #endif
  4837.         if(b_status.mdef != status->mdef) {
  4838.             clif_updatestatus(sd,SP_MDEF1);
  4839. #ifdef RENEWAL
  4840.             clif_updatestatus(sd,SP_MDEF2);
  4841. #endif
  4842.         }
  4843.         if(b_status.mdef2 != status->mdef2) {
  4844.             clif_updatestatus(sd,SP_MDEF2);
  4845. #ifdef RENEWAL
  4846.             clif_updatestatus(sd,SP_MDEF1);
  4847. #endif
  4848.         }
  4849.         if(b_status.rhw.range != status->rhw.range)
  4850.             clif_updatestatus(sd,SP_ATTACKRANGE);
  4851.         if(b_status.max_hp != status->max_hp)
  4852.             clif_updatestatus(sd,SP_MAXHP);
  4853.         if(b_status.max_sp != status->max_sp)
  4854.             clif_updatestatus(sd,SP_MAXSP);
  4855.         if(b_status.hp != status->hp)
  4856.             clif_updatestatus(sd,SP_HP);
  4857.         if(b_status.sp != status->sp)
  4858.             clif_updatestatus(sd,SP_SP);
  4859.     } else if( bl->type == BL_HOM ) {
  4860.         TBL_HOM* hd = BL_CAST(BL_HOM, bl);
  4861.  
  4862.         if( hd->master && memcmp(&b_status, status, sizeof(struct status_data)) != 0 )
  4863.             clif_hominfo(hd->master,hd,0);
  4864.     } else if( bl->type == BL_MER ) {
  4865.         TBL_MER* md = BL_CAST(BL_MER, bl);
  4866.  
  4867.         if (!md->master)
  4868.             return;
  4869.  
  4870.         if( b_status.rhw.atk != status->rhw.atk || b_status.rhw.atk2 != status->rhw.atk2 )
  4871.             clif_mercenary_updatestatus(md->master, SP_ATK1);
  4872.         if( b_status.matk_max != status->matk_max )
  4873.             clif_mercenary_updatestatus(md->master, SP_MATK1);
  4874.         if( b_status.hit != status->hit )
  4875.             clif_mercenary_updatestatus(md->master, SP_HIT);
  4876.         if( b_status.cri != status->cri )
  4877.             clif_mercenary_updatestatus(md->master, SP_CRITICAL);
  4878.         if( b_status.def != status->def )
  4879.             clif_mercenary_updatestatus(md->master, SP_DEF1);
  4880.         if( b_status.mdef != status->mdef )
  4881.             clif_mercenary_updatestatus(md->master, SP_MDEF1);
  4882.         if( b_status.flee != status->flee )
  4883.             clif_mercenary_updatestatus(md->master, SP_MERCFLEE);
  4884.         if( b_status.amotion != status->amotion )
  4885.             clif_mercenary_updatestatus(md->master, SP_ASPD);
  4886.         if( b_status.max_hp != status->max_hp )
  4887.             clif_mercenary_updatestatus(md->master, SP_MAXHP);
  4888.         if( b_status.max_sp != status->max_sp )
  4889.             clif_mercenary_updatestatus(md->master, SP_MAXSP);
  4890.         if( b_status.hp != status->hp )
  4891.             clif_mercenary_updatestatus(md->master, SP_HP);
  4892.         if( b_status.sp != status->sp )
  4893.             clif_mercenary_updatestatus(md->master, SP_SP);
  4894.     } else if( bl->type == BL_ELEM ) {
  4895.         TBL_ELEM* ed = BL_CAST(BL_ELEM, bl);
  4896.  
  4897.         if (!ed->master)
  4898.             return;
  4899.  
  4900.         if( b_status.max_hp != status->max_hp )
  4901.             clif_elemental_updatestatus(ed->master, SP_MAXHP);
  4902.         if( b_status.max_sp != status->max_sp )
  4903.             clif_elemental_updatestatus(ed->master, SP_MAXSP);
  4904.         if( b_status.hp != status->hp )
  4905.             clif_elemental_updatestatus(ed->master, SP_HP);
  4906.         if( b_status.sp != status->sp )
  4907.             clif_mercenary_updatestatus(ed->master, SP_SP);
  4908.     }
  4909. }
  4910.  
  4911. /**
  4912.  * Adds strength modifications based on status changes
  4913.  * @param bl: Object to change str [PC|MOB|HOM|MER|ELEM]
  4914.  * @param sc: Object's status change information
  4915.  * @param str: Initial str
  4916.  * @return modified str with cap_value(str,0,USHRT_MAX)
  4917.  */
  4918. static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
  4919. {
  4920.     if(!sc || !sc->count)
  4921.         return cap_value(str,0,USHRT_MAX);
  4922.  
  4923.     if(sc->data[SC_HARMONIZE]) {
  4924.         str -= sc->data[SC_HARMONIZE]->val2;
  4925.         return (unsigned short)cap_value(str,0,USHRT_MAX);
  4926.     }
  4927.     if(sc->data[SC_INCALLSTATUS])
  4928.         str += sc->data[SC_INCALLSTATUS]->val1;
  4929.     if(sc->data[SC_CHASEWALK2])
  4930.         str += sc->data[SC_CHASEWALK2]->val1;
  4931.     if(sc->data[SC_INCSTR])
  4932.         str += sc->data[SC_INCSTR]->val1;
  4933.     if(sc->data[SC_STRFOOD])
  4934.         str += sc->data[SC_STRFOOD]->val1;
  4935.     if(sc->data[SC_FOOD_STR_CASH])
  4936.         str += sc->data[SC_FOOD_STR_CASH]->val1;
  4937.     if(sc->data[SC_BATTLEORDERS])
  4938.         str += 5;
  4939.     if(sc->data[SC_LEADERSHIP])
  4940.         str += sc->data[SC_LEADERSHIP]->val1;
  4941.     if(sc->data[SC_LOUD])
  4942.         str += 4;
  4943.     if(sc->data[SC_TRUESIGHT])
  4944.         str += 5;
  4945.     if(sc->data[SC_SPURT])
  4946.         str += 10;
  4947.     if(sc->data[SC_NEN])
  4948.         str += sc->data[SC_NEN]->val1;
  4949.     if(sc->data[SC_BLESSING]) {
  4950.         if(sc->data[SC_BLESSING]->val2)
  4951.             str += sc->data[SC_BLESSING]->val2;
  4952.         else
  4953.             str >>= 1;
  4954.     }
  4955.     if(sc->data[SC_MARIONETTE])
  4956.         str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
  4957.     if(sc->data[SC_MARIONETTE2])
  4958.         str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
  4959.     if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  4960.         str += ((sc->data[SC_SPIRIT]->val3)>>16)&0xFF;
  4961.     if(sc->data[SC_GIANTGROWTH])
  4962.         str += 30;
  4963.     if(sc->data[SC_BEYONDOFWARCRY])
  4964.         str -= sc->data[SC_BEYONDOFWARCRY]->val3;
  4965.     if(sc->data[SC_SAVAGE_STEAK])
  4966.         str += sc->data[SC_SAVAGE_STEAK]->val1;
  4967.     if(sc->data[SC_INSPIRATION])
  4968.         str += sc->data[SC_INSPIRATION]->val3;
  4969.     if(sc->data[SC_2011RWC_SCROLL])
  4970.         str += sc->data[SC_2011RWC_SCROLL]->val1;
  4971.     if(sc->data[SC_STOMACHACHE])
  4972.         str -= sc->data[SC_STOMACHACHE]->val1;
  4973.     if(sc->data[SC_KYOUGAKU])
  4974.         str -= sc->data[SC_KYOUGAKU]->val2;
  4975.     if(sc->data[SC_FULL_THROTTLE])
  4976.         str += str * sc->data[SC_FULL_THROTTLE]->val3 / 100;
  4977.  
  4978.     return (unsigned short)cap_value(str,0,USHRT_MAX);
  4979. }
  4980.  
  4981. /**
  4982.  * Adds agility modifications based on status changes
  4983.  * @param bl: Object to change agi [PC|MOB|HOM|MER|ELEM]
  4984.  * @param sc: Object's status change information
  4985.  * @param agi: Initial agi
  4986.  * @return modified agi with cap_value(agi,0,USHRT_MAX)
  4987.  */
  4988. static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
  4989. {
  4990.     if(!sc || !sc->count)
  4991.         return cap_value(agi,0,USHRT_MAX);
  4992.  
  4993.     if(sc->data[SC_HARMONIZE]) {
  4994.         agi -= sc->data[SC_HARMONIZE]->val2;
  4995.         return (unsigned short)cap_value(agi,0,USHRT_MAX);
  4996.     }
  4997.     if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
  4998.         agi += (agi-sc->data[SC_CONCENTRATE]->val3)*sc->data[SC_CONCENTRATE]->val2/100;
  4999.     if(sc->data[SC_INCALLSTATUS])
  5000.         agi += sc->data[SC_INCALLSTATUS]->val1;
  5001.     if(sc->data[SC_INCAGI])
  5002.         agi += sc->data[SC_INCAGI]->val1;
  5003.     if(sc->data[SC_AGIFOOD])
  5004.         agi += sc->data[SC_AGIFOOD]->val1;
  5005.     if(sc->data[SC_FOOD_AGI_CASH])
  5006.         agi += sc->data[SC_FOOD_AGI_CASH]->val1;
  5007.     if(sc->data[SC_SOULCOLD])
  5008.         agi += sc->data[SC_SOULCOLD]->val1;
  5009.     if(sc->data[SC_TRUESIGHT])
  5010.         agi += 5;
  5011.     if(sc->data[SC_INCREASEAGI])
  5012.         agi += sc->data[SC_INCREASEAGI]->val2;
  5013.     if(sc->data[SC_INCREASING])
  5014.         agi += 4; // Added based on skill updates [Reddozen]
  5015.     if(sc->data[SC_2011RWC_SCROLL])
  5016.         agi += sc->data[SC_2011RWC_SCROLL]->val1;
  5017.     if(sc->data[SC_DECREASEAGI])
  5018.         agi -= sc->data[SC_DECREASEAGI]->val2;
  5019.     if(sc->data[SC_QUAGMIRE])
  5020.         agi -= sc->data[SC_QUAGMIRE]->val2;
  5021.     if(sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
  5022.         agi -= sc->data[SC_SUITON]->val2;
  5023.     if(sc->data[SC_MARIONETTE])
  5024.         agi -= ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
  5025.     if(sc->data[SC_MARIONETTE2])
  5026.         agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
  5027.     if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  5028.         agi += ((sc->data[SC_SPIRIT]->val3)>>8)&0xFF;
  5029.     if(sc->data[SC_ADORAMUS])
  5030.         agi -= sc->data[SC_ADORAMUS]->val2;
  5031.     if(sc->data[SC_MARSHOFABYSS])
  5032.         agi -= agi * sc->data[SC_MARSHOFABYSS]->val2 / 100;
  5033.     if(sc->data[SC_DROCERA_HERB_STEAMED])
  5034.         agi += sc->data[SC_DROCERA_HERB_STEAMED]->val1;
  5035.     if(sc->data[SC_INSPIRATION])
  5036.         agi += sc->data[SC_INSPIRATION]->val3;
  5037.     if(sc->data[SC_STOMACHACHE])
  5038.         agi -= sc->data[SC_STOMACHACHE]->val1;
  5039.     if(sc->data[SC_KYOUGAKU])
  5040.         agi -= sc->data[SC_KYOUGAKU]->val2;
  5041.     if(sc->data[SC_FULL_THROTTLE])
  5042.         agi += agi * sc->data[SC_FULL_THROTTLE]->val3 / 100;
  5043.  
  5044.     return (unsigned short)cap_value(agi,0,USHRT_MAX);
  5045. }
  5046.  
  5047. /**
  5048.  * Adds vitality modifications based on status changes
  5049.  * @param bl: Object to change vit [PC|MOB|HOM|MER|ELEM]
  5050.  * @param sc: Object's status change information
  5051.  * @param vit: Initial vit
  5052.  * @return modified vit with cap_value(vit,0,USHRT_MAX)
  5053.  */
  5054. static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
  5055. {
  5056.     if(!sc || !sc->count)
  5057.         return cap_value(vit,0,USHRT_MAX);
  5058.  
  5059.     if(sc->data[SC_HARMONIZE]) {
  5060.         vit -= sc->data[SC_HARMONIZE]->val2;
  5061.         return (unsigned short)cap_value(vit,0,USHRT_MAX);
  5062.     }
  5063.     if(sc->data[SC_INCALLSTATUS])
  5064.         vit += sc->data[SC_INCALLSTATUS]->val1;
  5065.     if(sc->data[SC_INCVIT])
  5066.         vit += sc->data[SC_INCVIT]->val1;
  5067.     if(sc->data[SC_VITFOOD])
  5068.         vit += sc->data[SC_VITFOOD]->val1;
  5069.     if(sc->data[SC_FOOD_VIT_CASH])
  5070.         vit += sc->data[SC_FOOD_VIT_CASH]->val1;
  5071.     if(sc->data[SC_CHANGE])
  5072.         vit += sc->data[SC_CHANGE]->val2;
  5073.     if(sc->data[SC_GLORYWOUNDS])
  5074.         vit += sc->data[SC_GLORYWOUNDS]->val1;
  5075.     if(sc->data[SC_TRUESIGHT])
  5076.         vit += 5;
  5077.     if(sc->data[SC_MARIONETTE])
  5078.         vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
  5079.     if(sc->data[SC_MARIONETTE2])
  5080.         vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
  5081.     if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  5082.         vit += sc->data[SC_SPIRIT]->val3&0xFF;
  5083.     if(sc->data[SC_LAUDAAGNUS])
  5084.         vit += 4 + sc->data[SC_LAUDAAGNUS]->val1;
  5085.     if(sc->data[SC_MINOR_BBQ])
  5086.         vit += sc->data[SC_MINOR_BBQ]->val1;
  5087.     if(sc->data[SC_INSPIRATION])
  5088.         vit += sc->data[SC_INSPIRATION]->val3;
  5089.     if(sc->data[SC_2011RWC_SCROLL])
  5090.         vit += sc->data[SC_2011RWC_SCROLL]->val1;
  5091.     if(sc->data[SC_STOMACHACHE])
  5092.         vit -= sc->data[SC_STOMACHACHE]->val1;
  5093.     if(sc->data[SC_KYOUGAKU])
  5094.         vit -= sc->data[SC_KYOUGAKU]->val2;
  5095.     if(sc->data[SC_STRIPARMOR] && bl->type != BL_PC)
  5096.         vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
  5097.     if(sc->data[SC_FULL_THROTTLE])
  5098.         vit += vit * sc->data[SC_FULL_THROTTLE]->val3 / 100;
  5099. #ifdef RENEWAL
  5100.     if(sc->data[SC_DEFENCE])
  5101.         vit += sc->data[SC_DEFENCE]->val2;
  5102. #endif
  5103.  
  5104.     return (unsigned short)cap_value(vit,0,USHRT_MAX);
  5105. }
  5106.  
  5107. /**
  5108.  * Adds intelligence modifications based on status changes
  5109.  * @param bl: Object to change int [PC|MOB|HOM|MER|ELEM]
  5110.  * @param sc: Object's status change information
  5111.  * @param int_: Initial int
  5112.  * @return modified int with cap_value(int_,0,USHRT_MAX)
  5113.  */
  5114. static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
  5115. {
  5116.     if(!sc || !sc->count)
  5117.         return cap_value(int_,0,USHRT_MAX);
  5118.  
  5119.     if(sc->data[SC_HARMONIZE]) {
  5120.         int_ -= sc->data[SC_HARMONIZE]->val2;
  5121.         return (unsigned short)cap_value(int_,0,USHRT_MAX);
  5122.     }
  5123.     if(sc->data[SC_INCALLSTATUS])
  5124.         int_ += sc->data[SC_INCALLSTATUS]->val1;
  5125.     if(sc->data[SC_INCINT])
  5126.         int_ += sc->data[SC_INCINT]->val1;
  5127.     if(sc->data[SC_INTFOOD])
  5128.         int_ += sc->data[SC_INTFOOD]->val1;
  5129.     if(sc->data[SC_FOOD_INT_CASH])
  5130.         int_ += sc->data[SC_FOOD_INT_CASH]->val1;
  5131.     if(sc->data[SC_CHANGE])
  5132.         int_ += sc->data[SC_CHANGE]->val3;
  5133.     if(sc->data[SC_BATTLEORDERS])
  5134.         int_ += 5;
  5135.     if(sc->data[SC_TRUESIGHT])
  5136.         int_ += 5;
  5137.     if(sc->data[SC_BLESSING]) {
  5138.         if (sc->data[SC_BLESSING]->val2)
  5139.             int_ += sc->data[SC_BLESSING]->val2;
  5140.         else
  5141.             int_ >>= 1;
  5142.     }
  5143.     if(sc->data[SC_NEN])
  5144.         int_ += sc->data[SC_NEN]->val1;
  5145.     if(sc->data[SC_MARIONETTE])
  5146.         int_ -= ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
  5147.     if(sc->data[SC_2011RWC_SCROLL])
  5148.         int_ += sc->data[SC_2011RWC_SCROLL]->val1;
  5149.     if(sc->data[SC_MARIONETTE2])
  5150.         int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
  5151.     if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  5152.         int_ += ((sc->data[SC_SPIRIT]->val4)>>16)&0xFF;
  5153.     if(sc->data[SC_INSPIRATION])
  5154.         int_ += sc->data[SC_INSPIRATION]->val3;
  5155.     if(sc->data[SC_MELODYOFSINK])
  5156.         int_ -= sc->data[SC_MELODYOFSINK]->val3;
  5157.     if(sc->data[SC_MANDRAGORA])
  5158.         int_ -= 4 * sc->data[SC_MANDRAGORA]->val1;
  5159.     if(sc->data[SC_COCKTAIL_WARG_BLOOD])
  5160.         int_ += sc->data[SC_COCKTAIL_WARG_BLOOD]->val1;
  5161.     if(sc->data[SC_STOMACHACHE])
  5162.         int_ -= sc->data[SC_STOMACHACHE]->val1;
  5163.     if(sc->data[SC_KYOUGAKU])
  5164.         int_ -= sc->data[SC_KYOUGAKU]->val2;
  5165.     if(sc->data[SC_FULL_THROTTLE])
  5166.         int_ += int_ * sc->data[SC_FULL_THROTTLE]->val3 / 100;
  5167.  
  5168.     if(bl->type != BL_PC) {
  5169.         if(sc->data[SC_STRIPHELM])
  5170.             int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
  5171.         if(sc->data[SC__STRIPACCESSORY])
  5172.             int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
  5173.     }
  5174.  
  5175.     return (unsigned short)cap_value(int_,0,USHRT_MAX);
  5176. }
  5177.  
  5178. /**
  5179.  * Adds dexterity modifications based on status changes
  5180.  * @param bl: Object to change dex [PC|MOB|HOM|MER|ELEM]
  5181.  * @param sc: Object's status change information
  5182.  * @param dex: Initial dex
  5183.  * @return modified dex with cap_value(dex,0,USHRT_MAX)
  5184.  */
  5185. static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
  5186. {
  5187.     if(!sc || !sc->count)
  5188.         return cap_value(dex,0,USHRT_MAX);
  5189.  
  5190.     if(sc->data[SC_HARMONIZE]) {
  5191.         dex -= sc->data[SC_HARMONIZE]->val2;
  5192.         return (unsigned short)cap_value(dex,0,USHRT_MAX);
  5193.     }
  5194.     if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
  5195.         dex += (dex-sc->data[SC_CONCENTRATE]->val4)*sc->data[SC_CONCENTRATE]->val2/100;
  5196.     if(sc->data[SC_INCALLSTATUS])
  5197.         dex += sc->data[SC_INCALLSTATUS]->val1;
  5198.     if(sc->data[SC_INCDEX])
  5199.         dex += sc->data[SC_INCDEX]->val1;
  5200.     if(sc->data[SC_DEXFOOD])
  5201.         dex += sc->data[SC_DEXFOOD]->val1;
  5202.     if(sc->data[SC_FOOD_DEX_CASH])
  5203.         dex += sc->data[SC_FOOD_DEX_CASH]->val1;
  5204.     if(sc->data[SC_BATTLEORDERS])
  5205.         dex += 5;
  5206.     if(sc->data[SC_HAWKEYES])
  5207.         dex += sc->data[SC_HAWKEYES]->val1;
  5208.     if(sc->data[SC_TRUESIGHT])
  5209.         dex += 5;
  5210.     if(sc->data[SC_QUAGMIRE])
  5211.         dex -= sc->data[SC_QUAGMIRE]->val2;
  5212.     if(sc->data[SC_BLESSING]) {
  5213.         if (sc->data[SC_BLESSING]->val2)
  5214.             dex += sc->data[SC_BLESSING]->val2;
  5215.         else
  5216.             dex >>= 1;
  5217.     }
  5218.     if(sc->data[SC_INCREASING])
  5219.         dex += 4; // Added based on skill updates [Reddozen]
  5220.     if(sc->data[SC_MARIONETTE])
  5221.         dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
  5222.     if(sc->data[SC_2011RWC_SCROLL])
  5223.         dex += sc->data[SC_2011RWC_SCROLL]->val1;
  5224.     if(sc->data[SC_MARIONETTE2])
  5225.         dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
  5226.     if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  5227.         dex += ((sc->data[SC_SPIRIT]->val4)>>8)&0xFF;
  5228.     if(sc->data[SC_SIROMA_ICE_TEA])
  5229.         dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
  5230.     if(sc->data[SC_INSPIRATION])
  5231.         dex += sc->data[SC_INSPIRATION]->val3;
  5232.     if(sc->data[SC_STOMACHACHE])
  5233.         dex -= sc->data[SC_STOMACHACHE]->val1;
  5234.     if(sc->data[SC_KYOUGAKU])
  5235.         dex -= sc->data[SC_KYOUGAKU]->val2;
  5236.  
  5237.     if(sc->data[SC__STRIPACCESSORY] && bl->type != BL_PC)
  5238.         dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
  5239.     if(sc->data[SC_MARSHOFABYSS])
  5240.         dex -= dex * sc->data[SC_MARSHOFABYSS]->val2 / 100;
  5241.     if(sc->data[SC_FULL_THROTTLE])
  5242.         dex += dex * sc->data[SC_FULL_THROTTLE]->val3 / 100;
  5243.  
  5244.     return (unsigned short)cap_value(dex,0,USHRT_MAX);
  5245. }
  5246.  
  5247. /**
  5248.  * Adds luck modifications based on status changes
  5249.  * @param bl: Object to change luk [PC|MOB|HOM|MER|ELEM]
  5250.  * @param sc: Object's status change information
  5251.  * @param luk: Initial luk
  5252.  * @return modified luk with cap_value(luk,0,USHRT_MAX)
  5253.  */
  5254. static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
  5255. {
  5256.     if(!sc || !sc->count)
  5257.         return cap_value(luk,0,USHRT_MAX);
  5258.  
  5259.     if(sc->data[SC_HARMONIZE]) {
  5260.         luk -= sc->data[SC_HARMONIZE]->val2;
  5261.         return (unsigned short)cap_value(luk,0,USHRT_MAX);
  5262.     }
  5263.     if(sc->data[SC_CURSE])
  5264.         return 0;
  5265.     if(sc->data[SC_INCALLSTATUS])
  5266.         luk += sc->data[SC_INCALLSTATUS]->val1;
  5267.     if(sc->data[SC_INCLUK])
  5268.         luk += sc->data[SC_INCLUK]->val1;
  5269.     if(sc->data[SC_LUKFOOD])
  5270.         luk += sc->data[SC_LUKFOOD]->val1;
  5271.     if(sc->data[SC_FOOD_LUK_CASH])
  5272.         luk += sc->data[SC_FOOD_LUK_CASH]->val1;
  5273.     if(sc->data[SC_TRUESIGHT])
  5274.         luk += 5;
  5275.     if(sc->data[SC_GLORIA])
  5276.         luk += 30;
  5277.     if(sc->data[SC_MARIONETTE])
  5278.         luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
  5279.     if(sc->data[SC_MARIONETTE2])
  5280.         luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
  5281.     if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  5282.         luk += sc->data[SC_SPIRIT]->val4&0xFF;
  5283.     if(sc->data[SC_PUTTI_TAILS_NOODLES])
  5284.         luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
  5285.     if(sc->data[SC_INSPIRATION])
  5286.         luk += sc->data[SC_INSPIRATION]->val3;
  5287.     if(sc->data[SC_STOMACHACHE])
  5288.         luk -= sc->data[SC_STOMACHACHE]->val1;
  5289.     if(sc->data[SC_KYOUGAKU])
  5290.         luk -= sc->data[SC_KYOUGAKU]->val2;
  5291.     if(sc->data[SC_LAUDARAMUS])
  5292.         luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
  5293.     if(sc->data[SC_2011RWC_SCROLL])
  5294.         luk += sc->data[SC_2011RWC_SCROLL]->val1;
  5295.     if(sc->data[SC__STRIPACCESSORY] && bl->type != BL_PC)
  5296.         luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
  5297.     if(sc->data[SC_BANANA_BOMB])
  5298.         luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
  5299.     if(sc->data[SC_FULL_THROTTLE])
  5300.         luk += luk * sc->data[SC_FULL_THROTTLE]->val3 / 100;
  5301.  
  5302.     return (unsigned short)cap_value(luk,0,USHRT_MAX);
  5303. }
  5304.  
  5305. /**
  5306.  * Adds base attack modifications based on status changes
  5307.  * @param bl: Object to change batk [PC|MOB|HOM|MER|ELEM]
  5308.  * @param sc: Object's status change information
  5309.  * @param batk: Initial batk
  5310.  * @return modified batk with cap_value(batk,0,USHRT_MAX)
  5311.  */
  5312. static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk)
  5313. {
  5314.     if(!sc || !sc->count)
  5315.         return cap_value(batk,0,USHRT_MAX);
  5316.  
  5317.     if(sc->data[SC_ATKPOTION])
  5318.         batk += sc->data[SC_ATKPOTION]->val1;
  5319.     if(sc->data[SC_BATKFOOD])
  5320.         batk += sc->data[SC_BATKFOOD]->val1;
  5321. #ifndef RENEWAL
  5322.     if(sc->data[SC_GATLINGFEVER])
  5323.         batk += sc->data[SC_GATLINGFEVER]->val3;
  5324.     if(sc->data[SC_MADNESSCANCEL])
  5325.         batk += 100;
  5326. #endif
  5327.     if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
  5328.         batk += 50;
  5329.     if(bl->type == BL_ELEM
  5330.        && ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1)
  5331.            || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 1)
  5332.            || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
  5333.            || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
  5334.        )
  5335.         batk += batk / 5;
  5336.     if(sc->data[SC_FULL_SWING_K])
  5337.         batk += sc->data[SC_FULL_SWING_K]->val1;
  5338.     if(sc->data[SC_ASH])
  5339.         batk -= batk * sc->data[SC_ASH]->val4 / 100;
  5340.     if(bl->type == BL_HOM && sc->data[SC_PYROCLASTIC])
  5341.         batk += sc->data[SC_PYROCLASTIC]->val2;
  5342.     if (sc->data[SC_ANGRIFFS_MODUS])
  5343.         batk += sc->data[SC_ANGRIFFS_MODUS]->val2;
  5344.     if(sc->data[SC_2011RWC_SCROLL])
  5345.         batk += 30;
  5346.     if(sc->data[SC_INCATKRATE])
  5347.         batk += batk * sc->data[SC_INCATKRATE]->val1/100;
  5348.     if(sc->data[SC_PROVOKE])
  5349.         batk += batk * sc->data[SC_PROVOKE]->val3/100;
  5350. #ifndef RENEWAL
  5351.     if(sc->data[SC_CONCENTRATION])
  5352.         batk += batk * sc->data[SC_CONCENTRATION]->val2/100;
  5353. #endif
  5354.     if(sc->data[SC_SKE])
  5355.         batk += batk * 3;
  5356.     if(sc->data[SC_BLOODLUST])
  5357.         batk += batk * sc->data[SC_BLOODLUST]->val2/100;
  5358.     if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST)
  5359.         batk -= batk * 25/100;
  5360.     if(sc->data[SC_CURSE])
  5361.         batk -= batk * 25/100;
  5362.     /* Curse shouldn't effect on this? <- Curse OR Bleeding??
  5363.     if(sc->data[SC_BLEEDING])
  5364.         batk -= batk * 25 / 100; */
  5365.     if(sc->data[SC_FLEET])
  5366.         batk += batk * sc->data[SC_FLEET]->val3/100;
  5367.     if(sc->data[SC__ENERVATION])
  5368.         batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
  5369.     if(sc->data[SC_SATURDAYNIGHTFEVER])
  5370.         batk += 100 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
  5371.     if( sc->data[SC_ZANGETSU] )
  5372.         batk += sc->data[SC_ZANGETSU]->val2;
  5373.     if(sc->data[SC_EQC])
  5374.         batk -= batk * sc->data[SC_EQC]->val3 / 100;
  5375.     if(sc->data[SC_QUEST_BUFF1])
  5376.         batk += sc->data[SC_QUEST_BUFF1]->val1;
  5377.     if(sc->data[SC_QUEST_BUFF2])
  5378.         batk += sc->data[SC_QUEST_BUFF2]->val1;
  5379.     if(sc->data[SC_QUEST_BUFF3])
  5380.         batk += sc->data[SC_QUEST_BUFF3]->val1;
  5381.  
  5382.     return (unsigned short)cap_value(batk,0,USHRT_MAX);
  5383. }
  5384.  
  5385. /**
  5386.  * Adds weapon attack modifications based on status changes
  5387.  * @param bl: Object to change watk [PC]
  5388.  * @param sc: Object's status change information
  5389.  * @param watk: Initial watk
  5390.  * @return modified watk with cap_value(watk,0,USHRT_MAX)
  5391.  */
  5392. static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk)
  5393. {
  5394.     if(!sc || !sc->count)
  5395.         return cap_value(watk,0,USHRT_MAX);
  5396.  
  5397. #ifndef RENEWAL
  5398.     if(sc->data[SC_IMPOSITIO])
  5399.         watk += sc->data[SC_IMPOSITIO]->val2;
  5400.     if(sc->data[SC_DRUMBATTLE])
  5401.         watk += sc->data[SC_DRUMBATTLE]->val2;
  5402. #endif
  5403.     if(sc->data[SC_WATKFOOD])
  5404.         watk += sc->data[SC_WATKFOOD]->val1;
  5405.     if(sc->data[SC_VOLCANO])
  5406.         watk += sc->data[SC_VOLCANO]->val2;
  5407.     if(sc->data[SC_MERC_ATKUP])
  5408.         watk += sc->data[SC_MERC_ATKUP]->val2;
  5409.     if(sc->data[SC_WATER_BARRIER])
  5410.         watk -= sc->data[SC_WATER_BARRIER]->val2;
  5411. #ifndef RENEWAL
  5412.     if(sc->data[SC_NIBELUNGEN]) {
  5413.         if (bl->type != BL_PC)
  5414.             watk += sc->data[SC_NIBELUNGEN]->val2;
  5415.         else {
  5416.             TBL_PC *sd = (TBL_PC*)bl;
  5417.             short index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
  5418.  
  5419.             if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
  5420.                 watk += sc->data[SC_NIBELUNGEN]->val2;
  5421.         }
  5422.     }
  5423.     if(sc->data[SC_CONCENTRATION])
  5424.         watk += watk * sc->data[SC_CONCENTRATION]->val2 / 100;
  5425. #endif
  5426.     if(sc->data[SC_INCATKRATE])
  5427.         watk += watk * sc->data[SC_INCATKRATE]->val1/100;
  5428.     if(sc->data[SC_PROVOKE])
  5429.         watk += watk * sc->data[SC_PROVOKE]->val3/100;
  5430.     if(sc->data[SC_SKE])
  5431.         watk += watk * 3;
  5432.     if(sc->data[SC_FLEET])
  5433.         watk += watk * sc->data[SC_FLEET]->val3/100;
  5434.     if(sc->data[SC_CURSE])
  5435.         watk -= watk * 25/100;
  5436.     if(sc->data[SC_STRIPWEAPON] && bl->type != BL_PC)
  5437.         watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
  5438.     if(sc->data[SC_FIGHTINGSPIRIT])
  5439.         watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
  5440.     if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
  5441.         watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
  5442.     if(sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1)
  5443.         watk += (10 + 10 * sc->data[SC_BANDING]->val1) * sc->data[SC_BANDING]->val2;
  5444.     if(sc->data[SC_INSPIRATION])
  5445.         watk += 40 * sc->data[SC_INSPIRATION]->val1 + 3 * sc->data[SC_INSPIRATION]->val2;
  5446.     if(sc->data[SC_GT_CHANGE])
  5447.         watk += sc->data[SC_GT_CHANGE]->val2;
  5448.     if(sc->data[SC__ENERVATION])
  5449.         watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
  5450.     if(sc->data[SC_STRIKING])
  5451.         watk += sc->data[SC_STRIKING]->val2;
  5452.     if(sc->data[SC_RUSHWINDMILL])
  5453.         watk += sc->data[SC_RUSHWINDMILL]->val3;
  5454.     if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
  5455.        || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
  5456.        || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
  5457.        || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2))
  5458.         watk += watk / 10;
  5459.     if(sc->data[SC_PYROTECHNIC_OPTION])
  5460.         watk += sc->data[SC_PYROTECHNIC_OPTION]->val2;
  5461.     if(sc->data[SC_HEATER_OPTION])
  5462.         watk += sc->data[SC_HEATER_OPTION]->val2;
  5463.     if(sc->data[SC_TROPIC_OPTION])
  5464.         watk += sc->data[SC_TROPIC_OPTION]->val2;
  5465.     if( sc && sc->data[SC_TIDAL_WEAPON] )
  5466.         watk += watk * sc->data[SC_TIDAL_WEAPON]->val2 / 100;
  5467.     if(bl->type == BL_PC && sc->data[SC_PYROCLASTIC])
  5468.         watk += sc->data[SC_PYROCLASTIC]->val2;
  5469.     if(sc->data[SC_ANGRIFFS_MODUS])
  5470.         watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
  5471.     if(sc->data[SC_ODINS_POWER])
  5472.         watk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1;
  5473.  
  5474.     return (unsigned short)cap_value(watk,0,USHRT_MAX);
  5475. }
  5476.  
  5477. #ifdef RENEWAL
  5478. /**
  5479.  * Adds equip magic attack modifications based on status changes [RENEWAL]
  5480.  * @param bl: Object to change matk [PC]
  5481.  * @param sc: Object's status change information
  5482.  * @param matk: Initial matk
  5483.  * @return modified matk with cap_value(matk,0,USHRT_MAX)
  5484.  */
  5485. static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
  5486. {
  5487.     if (!sc || !sc->count)
  5488.         return cap_value(matk,0,USHRT_MAX);
  5489.  
  5490.     if (sc->data[SC_MATKPOTION])
  5491.         matk += sc->data[SC_MATKPOTION]->val1;
  5492.     if (sc->data[SC_MATKFOOD])
  5493.         matk += sc->data[SC_MATKFOOD]->val1;
  5494.     if(sc->data[SC_MANA_PLUS])
  5495.         matk += sc->data[SC_MANA_PLUS]->val1;
  5496.     if(sc->data[SC_COOLER_OPTION])
  5497.         matk += sc->data[SC_COOLER_OPTION]->val2;
  5498.     if(sc->data[SC_AQUAPLAY_OPTION])
  5499.         matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
  5500.     if(sc->data[SC_CHILLY_AIR_OPTION])
  5501.         matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
  5502.     if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
  5503.         matk += 50;
  5504.     if(sc->data[SC_ODINS_POWER])
  5505.         matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; // 70 lvl1, 100lvl2
  5506.     if(sc->data[SC_MOONLITSERENADE])
  5507.         matk += sc->data[SC_MOONLITSERENADE]->val3;
  5508.     if(sc->data[SC_IZAYOI])
  5509.         matk += 25 * sc->data[SC_IZAYOI]->val1;
  5510.     if(sc->data[SC_ZANGETSU])
  5511.         matk += sc->data[SC_ZANGETSU]->val3;
  5512.     if(sc->data[SC_QUEST_BUFF1])
  5513.         matk += sc->data[SC_QUEST_BUFF1]->val1;
  5514.     if(sc->data[SC_QUEST_BUFF2])
  5515.         matk += sc->data[SC_QUEST_BUFF2]->val1;
  5516.     if(sc->data[SC_QUEST_BUFF3])
  5517.         matk += sc->data[SC_QUEST_BUFF3]->val1;
  5518.     if(sc->data[SC_MTF_MATK2])
  5519.         matk += sc->data[SC_MTF_MATK2]->val1;
  5520.     if(sc->data[SC_2011RWC_SCROLL])
  5521.         matk += 30;
  5522.  
  5523.     return (unsigned short)cap_value(matk,0,USHRT_MAX);
  5524. }
  5525. #endif
  5526.  
  5527. /**
  5528.  * Adds magic attack modifications based on status changes
  5529.  * @param bl: Object to change matk [PC|MOB|HOM|MER|ELEM]
  5530.  * @param sc: Object's status change information
  5531.  * @param matk: Initial matk
  5532.  * @return modified matk with cap_value(matk,0,USHRT_MAX)
  5533.  */
  5534. static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk)
  5535. {
  5536.     if(!sc || !sc->count)
  5537.         return cap_value(matk,0,USHRT_MAX);
  5538. #ifndef RENEWAL
  5539.     /// Take note fixed value first before % modifiers [PRE-RENEWAL]
  5540.     if (sc->data[SC_MATKPOTION])
  5541.         matk += sc->data[SC_MATKPOTION]->val1;
  5542.     if (sc->data[SC_MATKFOOD])
  5543.         matk += sc->data[SC_MATKFOOD]->val1;
  5544.     if (sc->data[SC_MANA_PLUS])
  5545.         matk += sc->data[SC_MANA_PLUS]->val1;
  5546.     if (sc->data[SC_AQUAPLAY_OPTION])
  5547.         matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
  5548.     if (sc->data[SC_CHILLY_AIR_OPTION])
  5549.         matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
  5550.     if (sc->data[SC_COOLER_OPTION])
  5551.         matk += sc->data[SC_COOLER_OPTION]->val2;
  5552.     if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
  5553.         matk += 50;
  5554.     if (sc->data[SC_ODINS_POWER])
  5555.         matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; // 70 lvl1, 100lvl2
  5556.     if (sc->data[SC_IZAYOI])
  5557.         matk += 25 * sc->data[SC_IZAYOI]->val1;
  5558.     if (sc->data[SC_MTF_MATK2])
  5559.         matk += sc->data[SC_MTF_MATK2]->val1;
  5560.     if (sc->data[SC_2011RWC_SCROLL])
  5561.         matk += 30;
  5562. #endif
  5563.     if (sc->data[SC_ZANGETSU])
  5564.         matk += sc->data[SC_ZANGETSU]->val3;
  5565.     if (sc->data[SC_QUEST_BUFF1])
  5566.         matk += sc->data[SC_QUEST_BUFF1]->val1;
  5567.     if (sc->data[SC_QUEST_BUFF2])
  5568.         matk += sc->data[SC_QUEST_BUFF2]->val1;
  5569.     if (sc->data[SC_QUEST_BUFF3])
  5570.         matk += sc->data[SC_QUEST_BUFF3]->val1;
  5571.     if (sc->data[SC_MAGICPOWER] && sc->data[SC_MAGICPOWER]->val4)
  5572.         matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
  5573.     if (sc->data[SC_MINDBREAKER])
  5574.         matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
  5575.     if (sc->data[SC_INCMATKRATE])
  5576.         matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
  5577.     if (sc->data[SC_MOONLITSERENADE])
  5578.         matk += sc->data[SC_MOONLITSERENADE]->val3/100;
  5579.     if (sc->data[SC_MTF_MATK])
  5580.         matk += matk * sc->data[SC_MTF_MATK]->val1 / 100;
  5581.     if(sc->data[SC_2011RWC_SCROLL])
  5582.         matk += 30;
  5583.  
  5584.     return (unsigned short)cap_value(matk,0,USHRT_MAX);
  5585. }
  5586.  
  5587. /**
  5588.  * Adds critical modifications based on status changes
  5589.  * @param bl: Object to change critical [PC|MOB|HOM|MER|ELEM]
  5590.  * @param sc: Object's status change information
  5591.  * @param critical: Initial critical
  5592.  * @return modified critical with cap_value(critical,10,USHRT_MAX)
  5593.  */
  5594. static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical)
  5595. {
  5596.     if(!sc || !sc->count)
  5597.         return cap_value(critical,10,SHRT_MAX);
  5598.  
  5599.     if (sc->data[SC_INCCRI])
  5600.         critical += sc->data[SC_INCCRI]->val1;
  5601.     if (sc->data[SC_CRIFOOD])
  5602.         critical += sc->data[SC_CRIFOOD]->val1;
  5603.     if (sc->data[SC_EXPLOSIONSPIRITS])
  5604.         critical += sc->data[SC_EXPLOSIONSPIRITS]->val2;
  5605.     if (sc->data[SC_FORTUNE])
  5606.         critical += sc->data[SC_FORTUNE]->val2;
  5607.     if (sc->data[SC_TRUESIGHT])
  5608.         critical += sc->data[SC_TRUESIGHT]->val2;
  5609.     if (sc->data[SC_CLOAKING])
  5610.         critical += critical;
  5611.     if (sc->data[SC_STRIKING])
  5612.         critical += critical * sc->data[SC_STRIKING]->val1 / 100;
  5613. #ifdef RENEWAL
  5614.     if (sc->data[SC_SPEARQUICKEN])
  5615.         critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10;
  5616. #endif
  5617.     if (sc->data[SC__INVISIBILITY])
  5618.         critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
  5619.     if (sc->data[SC__UNLUCKY])
  5620.         critical -= sc->data[SC__UNLUCKY]->val2;
  5621.     if(sc->data[SC_BEYONDOFWARCRY])
  5622.         critical += sc->data[SC_BEYONDOFWARCRY]->val3;
  5623.  
  5624.     return (short)cap_value(critical,10,SHRT_MAX);
  5625. }
  5626.  
  5627. /**
  5628.  * Adds hit modifications based on status changes
  5629.  * @param bl: Object to change hit [PC|MOB|HOM|MER|ELEM]
  5630.  * @param sc: Object's status change information
  5631.  * @param hit: Initial hit
  5632.  * @return modified hit with cap_value(hit,1,USHRT_MAX)
  5633.  */
  5634. static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit)
  5635. {
  5636.     if(!sc || !sc->count)
  5637.         return cap_value(hit,1,SHRT_MAX);
  5638.  
  5639.     if(sc->data[SC_INCHIT])
  5640.         hit += sc->data[SC_INCHIT]->val1;
  5641.     if(sc->data[SC_HITFOOD])
  5642.         hit += sc->data[SC_HITFOOD]->val1;
  5643.     if(sc->data[SC_TRUESIGHT])
  5644.         hit += sc->data[SC_TRUESIGHT]->val3;
  5645.     if(sc->data[SC_HUMMING])
  5646.         hit += sc->data[SC_HUMMING]->val2;
  5647.     if(sc->data[SC_CONCENTRATION])
  5648.         hit += sc->data[SC_CONCENTRATION]->val3;
  5649.     if(sc->data[SC_INSPIRATION])
  5650.         hit += 5 * sc->data[SC_INSPIRATION]->val1 + sc->data[SC_INSPIRATION]->val2 / 2;
  5651.     if(sc->data[SC_ADJUSTMENT])
  5652.         hit -= 30;
  5653.     if(sc->data[SC_INCREASING])
  5654.         hit += 20; // RockmanEXE; changed based on updated [Reddozen]
  5655.     if(sc->data[SC_MERC_HITUP])
  5656.         hit += sc->data[SC_MERC_HITUP]->val2;
  5657.     if(sc->data[SC_MTF_HITFLEE])
  5658.         hit += sc->data[SC_MTF_HITFLEE]->val1;
  5659.     if(sc->data[SC_INCHITRATE])
  5660.         hit += hit * sc->data[SC_INCHITRATE]->val1/100;
  5661.     if(sc->data[SC_BLIND])
  5662.         hit -= hit * 25/100;
  5663.     if(sc->data[SC__GROOMY])
  5664.         hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
  5665.     if(sc->data[SC_FEAR])
  5666.         hit -= hit * 20 / 100;
  5667.     if (sc->data[SC_ASH])
  5668.         hit -= hit * sc->data[SC_ASH]->val2 / 100;
  5669.     if (sc->data[SC_TEARGAS])
  5670.         hit -= hit * 50 / 100;
  5671.     if(sc->data[SC_ILLUSIONDOPING])
  5672.         hit -= sc->data[SC_ILLUSIONDOPING]->val2;
  5673.     if (sc->data[SC_MTF_ASPD])
  5674.         hit += sc->data[SC_MTF_ASPD]->val2;
  5675.  
  5676.     return (short)cap_value(hit,1,SHRT_MAX);
  5677. }
  5678.  
  5679. /**
  5680.  * Adds flee modifications based on status changes
  5681.  * @param bl: Object to change flee [PC|MOB|HOM|MER|ELEM]
  5682.  * @param sc: Object's status change information
  5683.  * @param flee: Initial flee
  5684.  * @return modified flee with cap_value(flee,1,USHRT_MAX)
  5685.  */
  5686. static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee)
  5687. {
  5688.     if( bl->type == BL_PC ) {
  5689.         if( map_flag_gvg(bl->m) )
  5690.             flee -= flee * battle_config.gvg_flee_penalty/100;
  5691.         else if( map[bl->m].flag.battleground )
  5692.             flee -= flee * battle_config.bg_flee_penalty/100;
  5693.     }
  5694.  
  5695.     if(!sc || !sc->count)
  5696.         return cap_value(flee,1,SHRT_MAX);
  5697.     if(sc->data[SC_OVERED_BOOST]) //Should be final and unmodifiable by any means
  5698.         return sc->data[SC_OVERED_BOOST]->val2;
  5699.     if(sc->data[SC_TINDER_BREAKER] || sc->data[SC_TINDER_BREAKER2])
  5700.         return 1; // 1 = min flee
  5701.  
  5702.     // Fixed value
  5703.     if(sc->data[SC_INCFLEE])
  5704.         flee += sc->data[SC_INCFLEE]->val1;
  5705.     if(sc->data[SC_FLEEFOOD])
  5706.         flee += sc->data[SC_FLEEFOOD]->val1;
  5707.     if(sc->data[SC_WHISTLE])
  5708.         flee += sc->data[SC_WHISTLE]->val2;
  5709.     if(sc->data[SC_WINDWALK])
  5710.         flee += sc->data[SC_WINDWALK]->val2;
  5711.     if(sc->data[SC_VIOLENTGALE])
  5712.         flee += sc->data[SC_VIOLENTGALE]->val2;
  5713.     if(sc->data[SC_MOON_COMFORT]) // SG skill [Komurka]
  5714.         flee += sc->data[SC_MOON_COMFORT]->val2;
  5715.     if(sc->data[SC_CLOSECONFINE])
  5716.         flee += 10;
  5717.     if (sc->data[SC_ANGRIFFS_MODUS])
  5718.         flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
  5719.     if(sc->data[SC_ADJUSTMENT])
  5720.         flee += 30;
  5721.     if(sc->data[SC_SPEED])
  5722.         flee += 10 + sc->data[SC_SPEED]->val1 * 10;
  5723.     if(sc->data[SC_GATLINGFEVER])
  5724.         flee -= sc->data[SC_GATLINGFEVER]->val4;
  5725.     if(sc->data[SC_PARTYFLEE])
  5726.         flee += sc->data[SC_PARTYFLEE]->val1 * 10;
  5727.     if(sc->data[SC_MERC_FLEEUP])
  5728.         flee += sc->data[SC_MERC_FLEEUP]->val2;
  5729.     if( sc->data[SC_HALLUCINATIONWALK] )
  5730.         flee += sc->data[SC_HALLUCINATIONWALK]->val2;
  5731.     if(sc->data[SC_MTF_HITFLEE])
  5732.         flee += sc->data[SC_MTF_HITFLEE]->val2;
  5733.     if( sc->data[SC_WATER_BARRIER] )
  5734.         flee -= sc->data[SC_WATER_BARRIER]->val2;
  5735.     if( sc->data[SC_C_MARKER] )
  5736.         flee -= sc->data[SC_C_MARKER]->val3;
  5737. #ifdef RENEWAL
  5738.     if( sc->data[SC_SPEARQUICKEN] )
  5739.         flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
  5740. #endif
  5741.  
  5742.     // Rate value
  5743.     if(sc->data[SC_INCFLEERATE])
  5744.         flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
  5745.     if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
  5746.         flee -= flee * 50/100;
  5747.     if(sc->data[SC_BERSERK])
  5748.         flee -= flee * 50/100;
  5749.     if(sc->data[SC_BLIND])
  5750.         flee -= flee * 25/100;
  5751.     if(sc->data[SC_FEAR])
  5752.         flee -= flee * 20 / 100;
  5753.     if(sc->data[SC_PARALYSE])
  5754.         flee -= flee * 10 / 100;
  5755.     if(sc->data[SC_INFRAREDSCAN])
  5756.         flee -= flee * 30 / 100;
  5757.     if( sc->data[SC__LAZINESS] )
  5758.         flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
  5759.     if( sc->data[SC_GLOOMYDAY] )
  5760.         flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
  5761.     if( sc->data[SC_SATURDAYNIGHTFEVER] )
  5762.         flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
  5763.     if( sc->data[SC_WIND_STEP_OPTION] )
  5764.         flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
  5765.     if( sc->data[SC_ZEPHYR] )
  5766.         flee += sc->data[SC_ZEPHYR]->val2;
  5767.     if(sc->data[SC_ASH])
  5768.         flee -= flee * sc->data[SC_ASH]->val4 / 100;
  5769.     if (sc->data[SC_GOLDENE_FERSE])
  5770.         flee += flee * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
  5771.     if (sc->data[SC_SMOKEPOWDER])
  5772.         flee += flee * 20 / 100;
  5773.     if (sc->data[SC_TEARGAS])
  5774.         flee -= flee * 50 / 100;
  5775.     //if( sc->data[SC_C_MARKER] )
  5776.     //  flee -= (flee * sc->data[SC_C_MARKER]->val3) / 100;
  5777.     if(sc->data[SC_HEAT_BARREL])
  5778.         flee -= sc->data[SC_HEAT_BARREL]->val4;
  5779.  
  5780.     return (short)cap_value(flee,1,SHRT_MAX);
  5781. }
  5782.  
  5783. /**
  5784.  * Adds perfect flee modifications based on status changes
  5785.  * @param bl: Object to change flee2 [PC|MOB|HOM|MER|ELEM]
  5786.  * @param sc: Object's status change information
  5787.  * @param flee2: Initial flee2
  5788.  * @return modified flee2 with cap_value(flee2,10,USHRT_MAX)
  5789.  */
  5790. static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2)
  5791. {
  5792.     if(!sc || !sc->count)
  5793.         return cap_value(flee2,10,SHRT_MAX);
  5794.  
  5795.     if(sc->data[SC_INCFLEE2])
  5796.         flee2 += sc->data[SC_INCFLEE2]->val1;
  5797.     if(sc->data[SC_WHISTLE])
  5798.         flee2 += sc->data[SC_WHISTLE]->val3*10;
  5799.     if(sc->data[SC__UNLUCKY])
  5800.         flee2 -= flee2 * sc->data[SC__UNLUCKY]->val2 / 100;
  5801.  
  5802.     return (short)cap_value(flee2,10,SHRT_MAX);
  5803. }
  5804.  
  5805. /**
  5806.  * Adds defense (left-side) modifications based on status changes
  5807.  * @param bl: Object to change def [PC|MOB|HOM|MER|ELEM]
  5808.  * @param sc: Object's status change information
  5809.  * @param def: Initial def
  5810.  * @return modified def with cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX)
  5811.  */
  5812. static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def)
  5813. {
  5814.     if(!sc || !sc->count)
  5815.         return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
  5816.  
  5817.     if(sc->data[SC_BERSERK])
  5818.         return 0;
  5819.     if(sc->data[SC_SKA])
  5820.         return sc->data[SC_SKA]->val3;
  5821.     if(sc->data[SC_BARRIER])
  5822.         return 100;
  5823.     if(sc->data[SC_KEEPING])
  5824.         return 90;
  5825. #ifndef RENEWAL /// Steel Body does not provide 90 DEF in [RENEWAL]
  5826.     if(sc->data[SC_STEELBODY])
  5827.         return 90;
  5828. #endif
  5829.     if(sc->data[SC_DEFSET])
  5830.         return sc->data[SC_DEFSET]->val1;
  5831.  
  5832.     if(sc->data[SC_DRUMBATTLE])
  5833.         def += sc->data[SC_DRUMBATTLE]->val3;
  5834. #ifndef RENEWAL
  5835.     if(sc->data[SC_DEFENCE])
  5836.         def += sc->data[SC_DEFENCE]->val2 ;
  5837. #endif
  5838.     if(sc->data[SC_INCDEFRATE])
  5839.         def += def * sc->data[SC_INCDEFRATE]->val1/100;
  5840.     if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
  5841.         def += 50;
  5842.     if(sc->data[SC_ODINS_POWER])
  5843.         def -= 20 * sc->data[SC_ODINS_POWER]->val1;
  5844.     if( sc->data[SC_ANGRIFFS_MODUS] )
  5845.         def -= 30 + 20 * sc->data[SC_ANGRIFFS_MODUS]->val1;
  5846.     if(sc->data[SC_STONEHARDSKIN])
  5847.         def += sc->data[SC_STONEHARDSKIN]->val1;
  5848.     if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  5849.         def >>=1;
  5850.     if(sc->data[SC_FREEZE])
  5851.         def >>=1;
  5852.     if(sc->data[SC_SIGNUMCRUCIS])
  5853.         def -= def * sc->data[SC_SIGNUMCRUCIS]->val2/100;
  5854.     if(sc->data[SC_CONCENTRATION])
  5855.         def -= def * sc->data[SC_CONCENTRATION]->val4/100;
  5856.     if(sc->data[SC_SKE])
  5857.         def >>=1;
  5858.     if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
  5859.         def -= def * sc->data[SC_PROVOKE]->val4/100;
  5860.     if(sc->data[SC_STRIPSHIELD] && bl->type != BL_PC) // Player doesn't have def reduction only equip removed
  5861.         def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
  5862.     if (sc->data[SC_FLING])
  5863.         def -= def * (sc->data[SC_FLING]->val2)/100;
  5864.     if( sc->data[SC_FREEZING] )
  5865.         def -= def * 10 / 100;
  5866.     if( sc->data[SC_ANALYZE] )
  5867.         def -= def * (14 * sc->data[SC_ANALYZE]->val1) / 100;
  5868.     if( sc->data[SC_NEUTRALBARRIER] )
  5869.         def += def * (10 + sc->data[SC_NEUTRALBARRIER]->val1 * 5) / 100;
  5870.     if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 )
  5871.         def += sc->data[SC_SHIELDSPELL_REF]->val2;
  5872.     if( sc->data[SC_PRESTIGE] )
  5873.         def += sc->data[SC_PRESTIGE]->val1;
  5874.     if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1 )
  5875.         def += (5 + sc->data[SC_BANDING]->val1) * sc->data[SC_BANDING]->val2 / 10;
  5876.     if( sc->data[SC_ECHOSONG] )
  5877.         def += def * sc->data[SC_ECHOSONG]->val3 / 100;
  5878.     if( sc->data[SC_SATURDAYNIGHTFEVER] )
  5879.         def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
  5880.     if( sc->data[SC_EARTHDRIVE] )
  5881.         def -= def * 25 / 100;
  5882.     if( sc->data[SC_CAMOUFLAGE] )
  5883.         def -= def * 5 * sc->data[SC_CAMOUFLAGE]->val3 / 100;
  5884.     if( sc->data[SC_SOLID_SKIN_OPTION] )
  5885.         def += def * sc->data[SC_SOLID_SKIN_OPTION]->val2 / 100;
  5886.     if( sc->data[SC_ROCK_CRUSHER] )
  5887.         def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100;
  5888.     if( sc->data[SC_POWER_OF_GAIA] )
  5889.         def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
  5890.     if(sc->data[SC_ASH])
  5891.         def -= def * sc->data[SC_ASH]->val3/100;
  5892.     if( sc->data[SC_OVERED_BOOST] && bl->type == BL_HOM )
  5893.         def -= def * sc->data[SC_OVERED_BOOST]->val4 / 100;
  5894.  
  5895.     return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
  5896. }
  5897.  
  5898. /**
  5899.  * Adds defense (right-side) modifications based on status changes
  5900.  * @param bl: Object to change def2 [PC|MOB|HOM|MER|ELEM]
  5901.  * @param sc: Object's status change information
  5902.  * @param def2: Initial def2
  5903.  * @return modified def2 with cap_value(def2,SHRT_MIN,SHRT_MAX)
  5904.  */
  5905. static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2)
  5906. {
  5907.     if(!sc || !sc->count)
  5908. #ifdef RENEWAL
  5909.         return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
  5910. #else
  5911.         return (short)cap_value(def2,1,SHRT_MAX);
  5912. #endif
  5913.  
  5914.     if(sc->data[SC_BERSERK])
  5915.         return 0;
  5916.     if(sc->data[SC_ETERNALCHAOS])
  5917.         return 0;
  5918.     if(sc->data[SC_DEFSET])
  5919.         return sc->data[SC_DEFSET]->val1;
  5920.  
  5921.     if(sc->data[SC_SUN_COMFORT])
  5922.         def2 += sc->data[SC_SUN_COMFORT]->val2;
  5923.     if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1 )
  5924.         def2 += (5 + sc->data[SC_BANDING]->val1) * sc->data[SC_BANDING]->val2;
  5925.  
  5926.     if(sc->data[SC_ANGELUS])
  5927. #ifdef RENEWAL /// The VIT stat bonus is boosted by angelus [RENEWAL]
  5928.         def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100;
  5929. #else
  5930.         def2 += def2 * sc->data[SC_ANGELUS]->val2/100;
  5931.     if(sc->data[SC_CONCENTRATION])
  5932.         def2 -= def2 * sc->data[SC_CONCENTRATION]->val4/100;
  5933. #endif
  5934.     if(sc->data[SC_POISON])
  5935.         def2 -= def2 * 25/100;
  5936.     if(sc->data[SC_DPOISON])
  5937.         def2 -= def2 * 25/100;
  5938.     if(sc->data[SC_SKE])
  5939.         def2 -= def2 * 50/100;
  5940.     if(sc->data[SC_PROVOKE])
  5941.         def2 -= def2 * sc->data[SC_PROVOKE]->val4/100;
  5942.     if(sc->data[SC_JOINTBEAT])
  5943.         def2 -= def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_SHOULDER ? 50 : 0 ) / 100
  5944.               + def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST ? 25 : 0 ) / 100;
  5945.     if(sc->data[SC_FLING])
  5946.         def2 -= def2 * (sc->data[SC_FLING]->val3)/100;
  5947.     if( sc->data[SC_FREEZING] )
  5948.         def2 -= def2 * 10 / 100;
  5949.     if(sc->data[SC_ANALYZE])
  5950.         def2 -= def2 * (14 * sc->data[SC_ANALYZE]->val1) / 100;
  5951.     if(sc->data[SC_ASH])
  5952.         def2 -= def2 * sc->data[SC_ASH]->val3/100;
  5953.     if (sc->data[SC_PARALYSIS])
  5954.         def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
  5955.     if(sc->data[SC_EQC])
  5956.         def2 -= def2 * sc->data[SC_EQC]->val2 / 100;
  5957.     if( sc->data[SC_CAMOUFLAGE] )
  5958.         def2 -= def2 * 5 * sc->data[SC_CAMOUFLAGE]->val3 / 100;
  5959.  
  5960. #ifdef RENEWAL
  5961.     return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
  5962. #else
  5963.     return (short)cap_value(def2,1,SHRT_MAX);
  5964. #endif
  5965. }
  5966.  
  5967. /**
  5968.  * Adds magic defense (left-side) modifications based on status changes
  5969.  * @param bl: Object to change mdef [PC|MOB|HOM|MER|ELEM]
  5970.  * @param sc: Object's status change information
  5971.  * @param mdef: Initial mdef
  5972.  * @return modified mdef with cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX)
  5973.  */
  5974. static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef)
  5975. {
  5976.     if(!sc || !sc->count)
  5977.         return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
  5978.  
  5979.     if(sc->data[SC_BERSERK])
  5980.         return 0;
  5981.     if(sc->data[SC_BARRIER])
  5982.         return 100;
  5983.  
  5984. #ifndef RENEWAL /// Steel Body does not provide 90 MDEF in [RENEWAL]
  5985.     if(sc->data[SC_STEELBODY])
  5986.         return 90;
  5987. #endif
  5988.     if(sc->data[SC_MDEFSET])
  5989.         return sc->data[SC_MDEFSET]->val1;
  5990.  
  5991.     if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
  5992.         mdef += 50;
  5993.     if(sc->data[SC_ENDURE]) // It has been confirmed that Eddga card grants 1 MDEF, not 0, not 10, but 1.
  5994.         mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
  5995.     if(sc->data[SC_STONEHARDSKIN])
  5996.         mdef += sc->data[SC_STONEHARDSKIN]->val1;
  5997.     if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  5998.         mdef += 25 * mdef / 100;
  5999.     if(sc->data[SC_FREEZE])
  6000.         mdef += 25 * mdef / 100;
  6001.     if(sc->data[SC_BURNING])
  6002.         mdef -= 25 * mdef / 100;
  6003.     if( sc->data[SC_NEUTRALBARRIER] )
  6004.         mdef += mdef * (10 + sc->data[SC_NEUTRALBARRIER]->val1 * 5) / 100;
  6005.     if(sc->data[SC_ANALYZE])
  6006.         mdef -= mdef * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
  6007.     if(sc->data[SC_SYMPHONYOFLOVER])
  6008.         mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val3 / 100;
  6009.     if(sc->data[SC_GT_CHANGE]) {
  6010.         mdef -= sc->data[SC_GT_CHANGE]->val4;
  6011.         if (mdef < 0)
  6012.             return 0;
  6013.     }
  6014.     if (sc->data[SC_ODINS_POWER])
  6015.         mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
  6016.  
  6017.     return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
  6018. }
  6019.  
  6020. /**
  6021.  * Adds magic defense (right-side) modifications based on status changes
  6022.  * @param bl: Object to change mdef2 [PC|MOB|HOM|MER|ELEM]
  6023.  * @param sc: Object's status change information
  6024.  * @param mdef2: Initial mdef2
  6025.  * @return modified mdef2 with cap_value(mdef2,SHRT_MIN,SHRT_MAX)
  6026.  */
  6027. static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2)
  6028. {
  6029.     if(!sc || !sc->count)
  6030. #ifdef RENEWAL
  6031.         return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
  6032. #else
  6033.         return (short)cap_value(mdef2,1,SHRT_MAX);
  6034. #endif
  6035.  
  6036.     if(sc->data[SC_BERSERK])
  6037.         return 0;
  6038.     if(sc->data[SC_SKA])
  6039.         return 90;
  6040.     if(sc->data[SC_MDEFSET])
  6041.         return sc->data[SC_MDEFSET]->val1;
  6042.  
  6043.     if(sc->data[SC_MINDBREAKER])
  6044.         mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
  6045.     if(sc->data[SC_BURNING])
  6046.         mdef2 -= mdef2 * 25 / 100;
  6047.     if(sc->data[SC_ANALYZE])
  6048.         mdef2 -= mdef2 * (14 * sc->data[SC_ANALYZE]->val1) / 100;
  6049.  
  6050. #ifdef RENEWAL
  6051.     return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
  6052. #else
  6053.     return (short)cap_value(mdef2,1,SHRT_MAX);
  6054. #endif
  6055. }
  6056.  
  6057. /**
  6058.  * Adds speed modifications based on status changes
  6059.  * @param bl: Object to change speed [PC|MOB|HOM|MER|ELEM]
  6060.  * @param sc: Object's status change information
  6061.  * @param speed: Initial speed
  6062.  * @return modified speed with cap_value(speed,10,USHRT_MAX)
  6063.  */
  6064. static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
  6065. {
  6066.     TBL_PC* sd = BL_CAST(BL_PC, bl);
  6067.     int speed_rate = 100;
  6068.  
  6069.     if (sc == NULL || (sd && sd->state.permanent_speed))
  6070.         return (unsigned short)cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
  6071.  
  6072.     if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc_checkskill(sd,SA_FREECAST) > 0 || sd->ud.skill_id == LG_EXEEDBREAK) ) {
  6073.         if( sd->ud.skill_id == LG_EXEEDBREAK )
  6074.             speed_rate = 160 - 10 * sd->ud.skill_lv;
  6075.         else
  6076.             speed_rate = 175 - 5 * pc_checkskill(sd,SA_FREECAST);
  6077.     } else {
  6078.         int val = 0;
  6079.  
  6080.         // GetMoveHasteValue2()
  6081.         if( sc->data[SC_FUSION] )
  6082.             val = 25;
  6083.         else if( sd ) {
  6084.             if( pc_isriding(sd) || sd->sc.option&OPTION_DRAGON )
  6085.                 val = 25; // Same bonus
  6086.             else if( pc_isridingwug(sd) )
  6087.                 val = 15 + 5 * pc_checkskill(sd, RA_WUGRIDER);
  6088.             else if( pc_ismadogear(sd) ) {
  6089.                 val = -(50 - 10 * pc_checkskill(sd,NC_MADOLICENCE));
  6090.                 if( sc->data[SC_ACCELERATION] )
  6091.                     val += 25;
  6092.             }
  6093.             else if( sc->data[SC_ALL_RIDING] )
  6094.                 val = battle_config.rental_mount_speed_boost;
  6095.         }
  6096.         speed_rate -= val;
  6097.  
  6098.         // GetMoveSlowValue()
  6099.         if( sd && sc->data[SC_HIDING] && pc_checkskill(sd,RG_TUNNELDRIVE) > 0 )
  6100.             val = 120 - 6 * pc_checkskill(sd,RG_TUNNELDRIVE);
  6101.         else if( sd && sc->data[SC_CHASEWALK] && sc->data[SC_CHASEWALK]->val3 < 0 )
  6102.             val = sc->data[SC_CHASEWALK]->val3;
  6103.         else {
  6104.             val = 0;
  6105.             // Longing for Freedom cancels song/dance penalty
  6106.             if( sc->data[SC_LONGING] )
  6107.                 val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
  6108.             else
  6109.             if( sd && sc->data[SC_DANCING] )
  6110.                 val = max( val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
  6111.  
  6112.             if( sc->data[SC_DECREASEAGI] || sc->data[SC_ADORAMUS] )
  6113.                 val = max( val, 25 );
  6114.             if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] || (sc->data[SC_GLOOMYDAY] && sc->data[SC_GLOOMYDAY]->val4) )
  6115.                 val = max( val, 50 );
  6116.             if( sc->data[SC_DONTFORGETME] )
  6117.                 val = max( val, sc->data[SC_DONTFORGETME]->val3 );
  6118.             if( sc->data[SC_CURSE] )
  6119.                 val = max( val, 300 );
  6120.             if( sc->data[SC_CHASEWALK] )
  6121.                 val = max( val, sc->data[SC_CHASEWALK]->val3 );
  6122.             if( sc->data[SC_WEDDING] )
  6123.                 val = max( val, 100 );
  6124.             if( sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&(BREAK_ANKLE|BREAK_KNEE) )
  6125.                 val = max( val, (sc->data[SC_JOINTBEAT]->val2&BREAK_ANKLE ? 50 : 0) + (sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE ? 30 : 0) );
  6126.             if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 0 )
  6127.                 val = max( val, sc->data[SC_CLOAKING]->val1 < 3 ? 300 : 30 - 3 * sc->data[SC_CLOAKING]->val1 );
  6128.             if( sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY )
  6129.                 val = max( val, 75 );
  6130.             if( sc->data[SC_SLOWDOWN] ) // Slow Potion
  6131.                 val = max( val, sc->data[SC_SLOWDOWN]->val1 );
  6132.             if( sc->data[SC_GATLINGFEVER] )
  6133.                 val = max( val, 100 );
  6134.             if( sc->data[SC_SUITON] )
  6135.                 val = max( val, sc->data[SC_SUITON]->val3 );
  6136.             if( sc->data[SC_SWOO] )
  6137.                 val = max( val, 300 );
  6138.             if( sc->data[SC_SKA] )
  6139.                 val = max( val, 25 );
  6140.             if( sc->data[SC_FREEZING] )
  6141.                 val = max( val, 50 );
  6142.             if( sc->data[SC_MARSHOFABYSS] )
  6143.                 val = max( val, sc->data[SC_MARSHOFABYSS]->val3 );
  6144.             if( sc->data[SC_CAMOUFLAGE] && (sc->data[SC_CAMOUFLAGE]->val3&1) == 0 )
  6145.                 val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1) );
  6146.             if( sc->data[SC_STEALTHFIELD] )
  6147.                 val = max( val, sc->data[SC_STEALTHFIELD]->val2 );
  6148.             if( sc->data[SC__LAZINESS] )
  6149.                 val = max( val, 25 );
  6150.             if( sc->data[SC_BANDING_DEFENCE] )
  6151.                 val = max( val, sc->data[SC_BANDING_DEFENCE]->val1 ); // +90% walking speed.
  6152.             if( sc->data[SC_ROCK_CRUSHER_ATK] )
  6153.                 val = max( val, sc->data[SC_ROCK_CRUSHER_ATK]->val2 );
  6154.             if( sc->data[SC_POWER_OF_GAIA] )
  6155.                 val = max( val, sc->data[SC_POWER_OF_GAIA]->val2 );
  6156.             if( sc->data[SC_MELON_BOMB] )
  6157.                 val = max( val, sc->data[SC_MELON_BOMB]->val1 );
  6158.             if( sc->data[SC_REBOUND] )
  6159.                 val = max( val, 25 );
  6160.             if( sc->data[SC_B_TRAP] )
  6161.                 val = max( val, sc->data[SC_B_TRAP]->val3 );
  6162.  
  6163.             if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // Permanent item-based speedup
  6164.                 val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
  6165.         }
  6166.         speed_rate += val;
  6167.         val = 0;
  6168.  
  6169.         if( sc->data[SC_MARSHOFABYSS] && speed_rate > 150 )
  6170.             speed_rate = 150;
  6171.  
  6172.         // GetMoveHasteValue1()
  6173.         if( sc->data[SC_SPEEDUP1] ) // !FIXME: used both by NPC_AGIUP and Speed Potion script
  6174.             val = max( val, sc->data[SC_SPEEDUP1]->val1 );
  6175.         if( sc->data[SC_INCREASEAGI] )
  6176.             val = max( val, 25 );
  6177.         if( sc->data[SC_WINDWALK] )
  6178.             val = max( val, 2 * sc->data[SC_WINDWALK]->val1 );
  6179.         if( sc->data[SC_CARTBOOST] )
  6180.             val = max( val, 20 );
  6181.         if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && pc_checkskill(sd,TF_MISS) > 0 )
  6182.             val = max( val, 1 * pc_checkskill(sd,TF_MISS) );
  6183.         if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 )
  6184.             val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 );
  6185.         if( sc->data[SC_BERSERK] )
  6186.             val = max( val, 25 );
  6187.         if( sc->data[SC_RUN] )
  6188.             val = max( val, 55 );
  6189.         if( sc->data[SC_AVOID] )
  6190.             val = max( val, 10 * sc->data[SC_AVOID]->val1 );
  6191.         if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
  6192.             val = max( val, 75 );
  6193.         if( sc->data[SC_CLOAKINGEXCEED] )
  6194.             val = max( val, sc->data[SC_CLOAKINGEXCEED]->val3);
  6195.         if( sc->data[SC_HOVERING] )
  6196.             val = max( val, 10 );
  6197.         if( sc->data[SC_GN_CARTBOOST] )
  6198.             val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
  6199.         if( sc->data[SC_SWINGDANCE] )
  6200.             val = max( val, sc->data[SC_SWINGDANCE]->val3 );
  6201.         if( sc->data[SC_WIND_STEP_OPTION] )
  6202.             val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 );
  6203.         if( sc->data[SC_FULL_THROTTLE] )
  6204.             val = max( val, 25 );
  6205.  
  6206.         // !FIXME: official items use a single bonus for this [ultramage]
  6207.         if( sc->data[SC_SPEEDUP0] ) // Temporary item-based speedup
  6208.             val = max( val, sc->data[SC_SPEEDUP0]->val1 );
  6209.         if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // Permanent item-based speedup
  6210.             val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
  6211.  
  6212.         speed_rate -= val;
  6213.  
  6214.         if( speed_rate < 40 )
  6215.             speed_rate = 40;
  6216.     }
  6217.  
  6218.     // GetSpeed()
  6219.     if( sd && pc_iscarton(sd) )
  6220.         speed += speed * (50 - 5 * pc_checkskill(sd,MC_PUSHCART)) / 100;
  6221.     if( sc->data[SC_PARALYSE] )
  6222.         speed += speed * 50 / 100;
  6223.     if( speed_rate != 100 )
  6224.         speed = speed * speed_rate / 100;
  6225.     if( sc->data[SC_STEELBODY] )
  6226.         speed = 200;
  6227.     if( sc->data[SC_DEFENDER] )
  6228.         speed = max(speed, 200);
  6229.     if( sc->data[SC_WALKSPEED] && sc->data[SC_WALKSPEED]->val1 > 0 ) // ChangeSpeed
  6230.         speed = speed * 100 / sc->data[SC_WALKSPEED]->val1;
  6231.  
  6232.     return (unsigned short)cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
  6233. }
  6234.  
  6235. #ifdef RENEWAL_ASPD
  6236. /**
  6237.  * Renewal attack speed modifiers based on status changes
  6238.  * This function only affects RENEWAL players and comes after base calculation
  6239.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6240.  * @param sc: Object's status change information
  6241.  * @param flag: flag&1 - fixed value [malufett]
  6242.  *              flag&2 - percentage value
  6243.  * @return modified aspd
  6244.  */
  6245. static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
  6246. {
  6247.     int i, pots = 0, skills1 = 0, skills2 = 0;
  6248.  
  6249.     if(!sc || !sc->count)
  6250.         return 0;
  6251.  
  6252.     if(sc->data[i=SC_ASPDPOTION3] ||
  6253.         sc->data[i=SC_ASPDPOTION2] ||
  6254.         sc->data[i=SC_ASPDPOTION1] ||
  6255.         sc->data[i=SC_ASPDPOTION0])
  6256.         pots += sc->data[i]->val1;
  6257.  
  6258.     if( !sc->data[SC_QUAGMIRE] ) {
  6259.         if(sc->data[SC_TWOHANDQUICKEN] && skills1 < 7)
  6260.             skills1 = 7;
  6261.  
  6262.         if(sc->data[SC_ONEHAND] && skills1 < 7)
  6263.             skills1 = 7;
  6264.  
  6265.         if(sc->data[SC_MERC_QUICKEN] && skills1 < 7) // Needs more info
  6266.             skills1 = 7;
  6267.  
  6268.         if(sc->data[SC_ADRENALINE2] && skills1 < 6)
  6269.             skills1 = 6;
  6270.  
  6271.         if(sc->data[SC_ADRENALINE] && skills1 < 7)
  6272.             skills1 = 7;
  6273.  
  6274.         if(sc->data[SC_SPEARQUICKEN] && skills1 < 7)
  6275.             skills1 = 7;
  6276.  
  6277.         if(sc->data[SC_FLEET] && skills1 < 5)
  6278.             skills1 = 5;
  6279.     }
  6280.  
  6281.     if(sc->data[SC_BERSERK] && skills1 < 15)
  6282.         skills1 = 15;
  6283.     else if(sc->data[SC_MADNESSCANCEL] && skills1 < 20)
  6284.         skills1 = 20;
  6285.  
  6286.     if(sc->data[SC_DONTFORGETME])
  6287.         skills2 -= sc->data[SC_DONTFORGETME]->val2 / 10;
  6288.     if(sc->data[SC_LONGING])
  6289.         skills2 -= sc->data[SC_LONGING]->val2 / 10;
  6290.     if(sc->data[SC_STEELBODY])
  6291.         skills2 -= 25;
  6292.     if(sc->data[SC_SKA])
  6293.         skills2 -= 25;
  6294.     if(sc->data[SC_DEFENDER])
  6295.         skills2 -= sc->data[SC_DEFENDER]->val4 / 10;
  6296.     if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
  6297.         skills2 -= 75;
  6298.     if(sc->data[SC_GRAVITATION])
  6299.         skills2 -= sc->data[SC_GRAVITATION]->val2 / 10; // Needs more info
  6300.     if(sc->data[SC_JOINTBEAT]) { // Needs more info
  6301.         if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
  6302.             skills2 -= 25;
  6303.         if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
  6304.             skills2 -= 10;
  6305.     }
  6306.     if( sc->data[SC_FREEZING] )
  6307.         skills2 -= 15;
  6308.     if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
  6309.         skills2 -= 50;
  6310.     if( sc->data[SC_PARALYSE] )
  6311.         skills2 -= 10;
  6312.     if( sc->data[SC__BODYPAINT] )
  6313.         skills2 -= 5 * sc->data[SC__BODYPAINT]->val1;
  6314.     if( sc->data[SC__INVISIBILITY] )
  6315.         skills2 -= sc->data[SC__INVISIBILITY]->val2;
  6316.     if( sc->data[SC__GROOMY] )
  6317.         skills2 -= sc->data[SC__GROOMY]->val2;
  6318.     if( sc->data[SC_SWINGDANCE] )
  6319.         skills2 += sc->data[SC_SWINGDANCE]->val2;
  6320.     if( sc->data[SC_DANCEWITHWUG] )
  6321.         skills2 += sc->data[SC_DANCEWITHWUG]->val3;
  6322.     if( sc->data[SC_GLOOMYDAY] )
  6323.         skills2 -= sc->data[SC_GLOOMYDAY]->val3;
  6324.     if( sc->data[SC_EARTHDRIVE] )
  6325.         skills2 -= 25;
  6326.     if( sc->data[SC_GT_CHANGE] )
  6327.         skills2 += sc->data[SC_GT_CHANGE]->val3;
  6328.     if( sc->data[SC_MELON_BOMB] )
  6329.         skills2 -= sc->data[SC_MELON_BOMB]->val1;
  6330.     if( sc->data[SC_PAIN_KILLER] )
  6331.         skills2 -= sc->data[SC_PAIN_KILLER]->val2;
  6332.     if( sc->data[SC_BOOST500] )
  6333.         skills2 += sc->data[SC_BOOST500]->val1;
  6334.     if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
  6335.         skills2 += sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1;
  6336.     if( sc->data[SC_GOLDENE_FERSE] )
  6337.         skills2 += sc->data[SC_GOLDENE_FERSE]->val3;
  6338.     if( sc->data[SC_INCASPDRATE] )
  6339.         skills2 += sc->data[SC_INCASPDRATE]->val1;
  6340.     if( sc->data[SC_GATLINGFEVER] )
  6341.         skills2 += sc->data[SC_GATLINGFEVER]->val1;
  6342.     if( sc->data[SC_STAR_COMFORT] )
  6343.         skills2 += sc->data[SC_STAR_COMFORT]->val1;
  6344.     if( sc->data[SC_HEAT_BARREL] )
  6345.         skills2 += sc->data[SC_HEAT_BARREL]->val3;
  6346.  
  6347.     if(sc->data[SC_ASSNCROS] && !skills1) {
  6348.         if (bl->type!=BL_PC)
  6349.             skills2 += sc->data[SC_ASSNCROS]->val2/10;
  6350.         else
  6351.             switch(((TBL_PC*)bl)->status.weapon) {
  6352.                 case W_BOW:
  6353.                 case W_REVOLVER:
  6354.                 case W_RIFLE:
  6355.                 case W_GATLING:
  6356.                 case W_SHOTGUN:
  6357.                 case W_GRENADE:
  6358.                     break;
  6359.                 default:
  6360.                     skills2 += sc->data[SC_ASSNCROS]->val2/10;
  6361.                     break;
  6362.             }
  6363.     }
  6364.  
  6365.     return ( flag&1? (skills1 + pots) : skills2 );
  6366. }
  6367. #endif
  6368.  
  6369. /**
  6370.  * Modifies ASPD by a number, rather than a percentage (10 = 1 ASPD)
  6371.  * A subtraction reduces the delay, meaning an increase in ASPD
  6372.  * This comes after the percentage changes and is based on status changes
  6373.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6374.  * @param sc: Object's status change information
  6375.  * @param aspd: Object's current ASPD
  6376.  * @return modified aspd
  6377.  */
  6378. static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd)
  6379. {
  6380.     if (!sc || !sc->count)
  6381.         return cap_value(aspd, 0, 2000);
  6382.     if (sc->data[SC_OVERED_BOOST])
  6383.         return cap_value(2000 - sc->data[SC_OVERED_BOOST]->val3 * 10, 0, 2000);
  6384.  
  6385.     if ((sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION]
  6386.         || sc->data[SC_WILD_STORM_OPTION]))
  6387.         aspd -= 50; // +5 ASPD
  6388.     if (sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2)
  6389.         aspd -= sc->data[SC_FIGHTINGSPIRIT]->val2;
  6390.     if (sc->data[SC_MTF_ASPD])
  6391.         aspd -= sc->data[SC_MTF_ASPD]->val1;
  6392.     if (sc->data[SC_MTF_ASPD2])
  6393.         aspd -= sc->data[SC_MTF_ASPD2]->val1;
  6394.  
  6395.     return cap_value(aspd, 0, 2000); // Will be recap for proper bl anyway
  6396. }
  6397.  
  6398. /**
  6399.  * Calculates an object's ASPD modifier based on status changes (alters amotion value)
  6400.  * Note: The scale of aspd_rate is 1000 = 100%
  6401.  * Note2: This only affects Homunculus, Mercenaries, and Pre-renewal Players
  6402.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6403.  * @param sc: Object's status change information
  6404.  * @param aspd_rate: Object's current ASPD
  6405.  * @return modified aspd_rate
  6406.  */
  6407. static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
  6408. {
  6409.     int i;
  6410.  
  6411.     if(!sc || !sc->count)
  6412.         return cap_value(aspd_rate,0,SHRT_MAX);
  6413.  
  6414.     if( !sc->data[SC_QUAGMIRE] ) {
  6415.         int max = 0;
  6416.         if(sc->data[SC_STAR_COMFORT])
  6417.             max = sc->data[SC_STAR_COMFORT]->val2;
  6418.  
  6419.         if(sc->data[SC_TWOHANDQUICKEN] &&
  6420.             max < sc->data[SC_TWOHANDQUICKEN]->val2)
  6421.             max = sc->data[SC_TWOHANDQUICKEN]->val2;
  6422.  
  6423.         if(sc->data[SC_ONEHAND] &&
  6424.             max < sc->data[SC_ONEHAND]->val2)
  6425.             max = sc->data[SC_ONEHAND]->val2;
  6426.  
  6427.         if(sc->data[SC_MERC_QUICKEN] &&
  6428.             max < sc->data[SC_MERC_QUICKEN]->val2)
  6429.             max = sc->data[SC_MERC_QUICKEN]->val2;
  6430.  
  6431.         if(sc->data[SC_ADRENALINE2] &&
  6432.             max < sc->data[SC_ADRENALINE2]->val3)
  6433.             max = sc->data[SC_ADRENALINE2]->val3;
  6434.  
  6435.         if(sc->data[SC_ADRENALINE] &&
  6436.             max < sc->data[SC_ADRENALINE]->val3)
  6437.             max = sc->data[SC_ADRENALINE]->val3;
  6438.  
  6439.         if(sc->data[SC_SPEARQUICKEN] &&
  6440.             max < sc->data[SC_SPEARQUICKEN]->val2)
  6441.             max = sc->data[SC_SPEARQUICKEN]->val2;
  6442.  
  6443.         if(sc->data[SC_GATLINGFEVER] &&
  6444.             max < sc->data[SC_GATLINGFEVER]->val2)
  6445.             max = sc->data[SC_GATLINGFEVER]->val2;
  6446.  
  6447.         if(sc->data[SC_FLEET] &&
  6448.             max < sc->data[SC_FLEET]->val2)
  6449.             max = sc->data[SC_FLEET]->val2;
  6450.  
  6451.         if(sc->data[SC_ASSNCROS] && max < sc->data[SC_ASSNCROS]->val2) {
  6452.             if (bl->type!=BL_PC)
  6453.                 max = sc->data[SC_ASSNCROS]->val2;
  6454.             else
  6455.                 switch(((TBL_PC*)bl)->status.weapon) {
  6456.                     case W_BOW:
  6457.                     case W_REVOLVER:
  6458.                     case W_RIFLE:
  6459.                     case W_GATLING:
  6460.                     case W_SHOTGUN:
  6461.                     case W_GRENADE:
  6462.                         break;
  6463.                     default:
  6464.                         max = sc->data[SC_ASSNCROS]->val2;
  6465.             }
  6466.         }
  6467.         aspd_rate -= max;
  6468.  
  6469.         if(sc->data[SC_BERSERK])
  6470.             aspd_rate -= 300;
  6471.         else if(sc->data[SC_MADNESSCANCEL])
  6472.             aspd_rate -= 200;
  6473.     }
  6474.  
  6475.     if( sc->data[i=SC_ASPDPOTION3] ||
  6476.         sc->data[i=SC_ASPDPOTION2] ||
  6477.         sc->data[i=SC_ASPDPOTION1] ||
  6478.         sc->data[i=SC_ASPDPOTION0] )
  6479.         aspd_rate -= sc->data[i]->val2;
  6480.  
  6481.     if(sc->data[SC_DONTFORGETME])
  6482.         aspd_rate += sc->data[SC_DONTFORGETME]->val2;
  6483.     if(sc->data[SC_LONGING])
  6484.         aspd_rate += sc->data[SC_LONGING]->val2;
  6485.     if(sc->data[SC_STEELBODY])
  6486.         aspd_rate += 250;
  6487.     if(sc->data[SC_SKA])
  6488.         aspd_rate += 250;
  6489.     if(sc->data[SC_DEFENDER])
  6490.         aspd_rate += sc->data[SC_DEFENDER]->val4;
  6491.     if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
  6492.         aspd_rate += 250;
  6493.     if(sc->data[SC_GRAVITATION])
  6494.         aspd_rate += sc->data[SC_GRAVITATION]->val2;
  6495.     if(sc->data[SC_JOINTBEAT]) {
  6496.         if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
  6497.             aspd_rate += 250;
  6498.         if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
  6499.             aspd_rate += 100;
  6500.     }
  6501.     if( sc->data[SC_FREEZING] )
  6502.         aspd_rate += 150;
  6503.     if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
  6504.         aspd_rate += 500;
  6505.     if( sc->data[SC_PARALYSE] )
  6506.         aspd_rate += 100;
  6507.     if( sc->data[SC__BODYPAINT] )
  6508.         aspd_rate +=  50 * sc->data[SC__BODYPAINT]->val1;
  6509.     if( sc->data[SC__INVISIBILITY] )
  6510.         aspd_rate += sc->data[SC__INVISIBILITY]->val2 * 10;
  6511.     if( sc->data[SC__GROOMY] )
  6512.         aspd_rate += sc->data[SC__GROOMY]->val2 * 10;
  6513.     if( sc->data[SC_SWINGDANCE] )
  6514.         aspd_rate -= sc->data[SC_SWINGDANCE]->val2 * 10;
  6515.     if( sc->data[SC_DANCEWITHWUG] )
  6516.         aspd_rate -= sc->data[SC_DANCEWITHWUG]->val3 * 10;
  6517.     if( sc->data[SC_GLOOMYDAY] )
  6518.         aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10;
  6519.     if( sc->data[SC_EARTHDRIVE] )
  6520.         aspd_rate += 250;
  6521.     if( sc->data[SC_GT_CHANGE] )
  6522.         aspd_rate -= sc->data[SC_GT_CHANGE]->val3 * 10;
  6523.     if( sc->data[SC_MELON_BOMB] )
  6524.         aspd_rate += sc->data[SC_MELON_BOMB]->val1 * 10;
  6525.     if( sc->data[SC_BOOST500] )
  6526.         aspd_rate -= sc->data[SC_BOOST500]->val1 *10;
  6527.     if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
  6528.         aspd_rate -= sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1 * 10;
  6529.     if( sc->data[SC_INCASPDRATE] )
  6530.         aspd_rate -= sc->data[SC_INCASPDRATE]->val1 * 10;
  6531.     if( sc->data[SC_PAIN_KILLER])
  6532.         aspd_rate += sc->data[SC_PAIN_KILLER]->val2 * 10;
  6533.     if( sc->data[SC_GOLDENE_FERSE])
  6534.         aspd_rate -= sc->data[SC_GOLDENE_FERSE]->val3 * 10;
  6535.     if( sc->data[SC_HEAT_BARREL] )
  6536.         aspd_rate -= sc->data[SC_HEAT_BARREL]->val3 * 10;
  6537.  
  6538.     return (short)cap_value(aspd_rate,0,SHRT_MAX);
  6539. }
  6540.  
  6541. /**
  6542.  * Modifies the damage delay time based on status changes
  6543.  * The lower your delay, the quicker you can act after taking damage
  6544.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6545.  * @param sc: Object's status change information
  6546.  * @param dmotion: Object's current damage delay
  6547.  * @return modified delay rate
  6548.  */
  6549. static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
  6550. {
  6551.     if( !sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground )
  6552.         return cap_value(dmotion,0,USHRT_MAX);
  6553.  
  6554.     /// It has been confirmed on official servers that MvP mobs have no dmotion even without endure
  6555.     if( sc->data[SC_ENDURE] || ( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) )
  6556.         return 0;
  6557.     if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] )
  6558.         return 0;
  6559.  
  6560.     return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
  6561. }
  6562.  
  6563. /**
  6564.  * Calculates a max HP based on status changes
  6565.  * Values can either be percentages or fixed, based on how equations are formulated
  6566.  * @param bl: Object's block_list data
  6567.  * @param maxhp: Object's current max HP
  6568.  * @return modified maxhp
  6569.  */
  6570. static unsigned int status_calc_maxhp(struct block_list *bl, uint64 maxhp)
  6571. {
  6572.     int rate = 100;
  6573.  
  6574.     maxhp += status_get_hpbonus(bl,STATUS_BONUS_FIX);
  6575.  
  6576.     if ((rate += status_get_hpbonus(bl,STATUS_BONUS_RATE)) != 100)
  6577.         maxhp = maxhp * rate / 100;
  6578.  
  6579.     return (unsigned int)cap_value(maxhp,1,UINT_MAX);
  6580. }
  6581.  
  6582. /**
  6583.  * Calculates a max SP based on status changes
  6584.  * Values can either be percentages or fixed, bas ed on how equations are formulated
  6585.  * @param bl: Object's block_list data
  6586.  * @param maxsp: Object's current max SP
  6587.  * @return modified maxsp
  6588.  */
  6589. static unsigned int status_calc_maxsp(struct block_list *bl, uint64 maxsp)
  6590. {
  6591.     int rate = 100;
  6592.  
  6593.     maxsp += status_get_spbonus(bl,STATUS_BONUS_FIX);
  6594.    
  6595.     if ((rate += status_get_spbonus(bl,STATUS_BONUS_RATE)) != 100)
  6596.         maxsp = maxsp * rate / 100;
  6597.    
  6598.     return (unsigned int)cap_value(maxsp,1,UINT_MAX);
  6599. }
  6600.  
  6601. /**
  6602.  * Changes a player's element based on status changes
  6603.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6604.  * @param sc: Object's status change information
  6605.  * @param element: Object's current element
  6606.  * @return new element
  6607.  */
  6608. static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
  6609. {
  6610.     if(!sc || !sc->count)
  6611.         return cap_value(element, 0, UCHAR_MAX);
  6612.  
  6613.     if(sc->data[SC_FREEZE])
  6614.         return ELE_WATER;
  6615.     if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  6616.         return ELE_EARTH;
  6617.     if(sc->data[SC_BENEDICTIO])
  6618.         return ELE_HOLY;
  6619.     if(sc->data[SC_CHANGEUNDEAD])
  6620.         return ELE_UNDEAD;
  6621.     if(sc->data[SC_ELEMENTALCHANGE])
  6622.         return sc->data[SC_ELEMENTALCHANGE]->val2;
  6623.     if(sc->data[SC_SHAPESHIFT])
  6624.         return sc->data[SC_SHAPESHIFT]->val2;
  6625.  
  6626.     return (unsigned char)cap_value(element,0,UCHAR_MAX);
  6627. }
  6628.  
  6629. /**
  6630.  * Changes a player's element level based on status changes
  6631.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6632.  * @param sc: Object's status change information
  6633.  * @param lv: Object's current element level
  6634.  * @return new element level
  6635.  */
  6636. static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
  6637. {
  6638.     if(!sc || !sc->count)
  6639.         return cap_value(lv, 1, 4);
  6640.  
  6641.     if(sc->data[SC_FREEZE])
  6642.         return 1;
  6643.     if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  6644.         return 1;
  6645.     if(sc->data[SC_BENEDICTIO])
  6646.         return 1;
  6647.     if(sc->data[SC_CHANGEUNDEAD])
  6648.         return 1;
  6649.     if(sc->data[SC_ELEMENTALCHANGE])
  6650.         return sc->data[SC_ELEMENTALCHANGE]->val1;
  6651.     if(sc->data[SC_SHAPESHIFT])
  6652.         return 1;
  6653.     if(sc->data[SC__INVISIBILITY])
  6654.         return 1;
  6655.  
  6656.     return (unsigned char)cap_value(lv,1,4);
  6657. }
  6658.  
  6659. /**
  6660.  * Changes a player's attack element based on status changes
  6661.  * @param bl: Object to change aspd [PC|MOB|HOM|MER|ELEM]
  6662.  * @param sc: Object's status change information
  6663.  * @param element: Object's current attack element
  6664.  * @return new attack element
  6665.  */
  6666. unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
  6667. {
  6668.     if(!sc || !sc->count)
  6669.         return cap_value(element, 0, UCHAR_MAX);
  6670.     if(sc->data[SC_ENCHANTARMS])
  6671.         return sc->data[SC_ENCHANTARMS]->val2;
  6672.     if(sc->data[SC_WATERWEAPON]
  6673.         || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) )
  6674.         return ELE_WATER;
  6675.     if(sc->data[SC_EARTHWEAPON]
  6676.         || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) )
  6677.         return ELE_EARTH;
  6678.     if(sc->data[SC_FIREWEAPON]
  6679.         || (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) )
  6680.         return ELE_FIRE;
  6681.     if(sc->data[SC_WINDWEAPON]
  6682.         || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) )
  6683.         return ELE_WIND;
  6684.     if(sc->data[SC_ENCPOISON])
  6685.         return ELE_POISON;
  6686.     if(sc->data[SC_ASPERSIO])
  6687.         return ELE_HOLY;
  6688.     if(sc->data[SC_SHADOWWEAPON])
  6689.         return ELE_DARK;
  6690.     if(sc->data[SC_GHOSTWEAPON] || sc->data[SC__INVISIBILITY])
  6691.         return ELE_GHOST;
  6692.     if(sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON] )
  6693.         return ELE_WATER;
  6694.     if(sc->data[SC_PYROCLASTIC])
  6695.         return ELE_FIRE;
  6696.     return (unsigned char)cap_value(element,0,UCHAR_MAX);
  6697. }
  6698.  
  6699. /**
  6700.  * Changes the mode of an object
  6701.  * @param bl: Object whose mode to change [PC|MOB|PET|HOM|NPC]
  6702.  * @param sc: Object's status change data
  6703.  * @param mode: Original mode
  6704.  * @return mode with cap_value(mode,0,USHRT_MAX)
  6705.  */
  6706. static unsigned short status_calc_mode(struct block_list *bl, struct status_change *sc, int mode)
  6707. {
  6708.     if(!sc || !sc->count)
  6709.         return cap_value(mode, 0, USHRT_MAX);
  6710.     if(sc->data[SC_MODECHANGE]) {
  6711.         if (sc->data[SC_MODECHANGE]->val2)
  6712.             mode = sc->data[SC_MODECHANGE]->val2; // Set mode
  6713.         if (sc->data[SC_MODECHANGE]->val3)
  6714.             mode|= sc->data[SC_MODECHANGE]->val3; // Add mode
  6715.         if (sc->data[SC_MODECHANGE]->val4)
  6716.             mode&=~sc->data[SC_MODECHANGE]->val4; // Del mode
  6717.     }
  6718.     return cap_value(mode,0,USHRT_MAX);
  6719. }
  6720.  
  6721. /**
  6722.  * Gets the name of the given bl
  6723.  * @param bl: Object whose name to get [PC|MOB|PET|HOM|NPC]
  6724.  * @return name or "Unknown" if any other bl->type than noted above
  6725.  */
  6726. const char* status_get_name(struct block_list *bl)
  6727. {
  6728.     nullpo_ret(bl);
  6729.     switch (bl->type) {
  6730.         case BL_PC: return ((TBL_PC *)bl)->fakename[0] != '\0' ? ((TBL_PC*)bl)->fakename : ((TBL_PC*)bl)->status.name;
  6731.         case BL_MOB:    return ((TBL_MOB*)bl)->name;
  6732.         case BL_PET:    return ((TBL_PET*)bl)->pet.name;
  6733.         case BL_HOM:    return ((TBL_HOM*)bl)->homunculus.name;
  6734.         //case BL_MER: // They only have database names which are global, not specific to GID.
  6735.         case BL_NPC:    return ((TBL_NPC*)bl)->name;
  6736.         //case BL_ELEM: // They only have database names which are global, not specific to GID.
  6737.     }
  6738.     return "Unknown";
  6739. }
  6740.  
  6741. /**
  6742.  * Gets the class/sprite id of the given bl
  6743.  * @param bl: Object whose class to get [PC|MOB|PET|HOM|MER|NPC|ELEM]
  6744.  * @return class or 0 if any other bl->type than noted above
  6745.  */
  6746. int status_get_class(struct block_list *bl)
  6747. {
  6748.     nullpo_ret(bl);
  6749.     switch( bl->type ) {
  6750.         case BL_PC: return ((TBL_PC*)bl)->status.class_;
  6751.         case BL_MOB:    return ((TBL_MOB*)bl)->vd->class_; // Class used on all code should be the view class of the mob.
  6752.         case BL_PET:    return ((TBL_PET*)bl)->pet.class_;
  6753.         case BL_HOM:    return ((TBL_HOM*)bl)->homunculus.class_;
  6754.         case BL_MER:    return ((TBL_MER*)bl)->mercenary.class_;
  6755.         case BL_NPC:    return ((TBL_NPC*)bl)->class_;
  6756.         case BL_ELEM:   return ((TBL_ELEM*)bl)->elemental.class_;
  6757.     }
  6758.     return 0;
  6759. }
  6760.  
  6761. /**
  6762.  * Gets the base level of the given bl
  6763.  * @param bl: Object whose base level to get [PC|MOB|PET|HOM|MER|NPC|ELEM]
  6764.  * @return base level or 1 if any other bl->type than noted above
  6765.  */
  6766. int status_get_lv(struct block_list *bl)
  6767. {
  6768.     nullpo_ret(bl);
  6769.     switch (bl->type) {
  6770.         case BL_PC: return ((TBL_PC*)bl)->status.base_level;
  6771.         case BL_MOB:    return ((TBL_MOB*)bl)->level;
  6772.         case BL_PET:    return ((TBL_PET*)bl)->pet.level;
  6773.         case BL_HOM:    return ((TBL_HOM*)bl)->homunculus.level;
  6774.         case BL_MER:    return ((TBL_MER*)bl)->db->lv;
  6775.         case BL_ELEM:   return ((TBL_ELEM*)bl)->db->lv;
  6776.         case BL_NPC:    return ((TBL_NPC*)bl)->level;
  6777.     }
  6778.     return 1;
  6779. }
  6780.  
  6781. /**
  6782.  * Gets the regeneration info of the given bl
  6783.  * @param bl: Object whose regen info to get [PC|HOM|MER|ELEM]
  6784.  * @return regen data or NULL if any other bl->type than noted above
  6785.  */
  6786. struct regen_data *status_get_regen_data(struct block_list *bl)
  6787. {
  6788.     nullpo_retr(NULL, bl);
  6789.     switch (bl->type) {
  6790.         case BL_PC: return &((TBL_PC*)bl)->regen;
  6791.         case BL_HOM:    return &((TBL_HOM*)bl)->regen;
  6792.         case BL_MER:    return &((TBL_MER*)bl)->regen;
  6793.         case BL_ELEM:   return &((TBL_ELEM*)bl)->regen;
  6794.         default:
  6795.             return NULL;
  6796.     }
  6797. }
  6798.  
  6799. /**
  6800.  * Gets the status data of the given bl
  6801.  * @param bl: Object whose status to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
  6802.  * @return status or "dummy_status" if any other bl->type than noted above
  6803.  */
  6804. struct status_data *status_get_status_data(struct block_list *bl)
  6805. {
  6806.     nullpo_retr(&dummy_status, bl);
  6807.  
  6808.     switch (bl->type) {
  6809.         case BL_PC:     return &((TBL_PC*)bl)->battle_status;
  6810.         case BL_MOB:    return &((TBL_MOB*)bl)->status;
  6811.         case BL_PET:    return &((TBL_PET*)bl)->status;
  6812.         case BL_HOM:    return &((TBL_HOM*)bl)->battle_status;
  6813.         case BL_MER:    return &((TBL_MER*)bl)->battle_status;
  6814.         case BL_ELEM:   return &((TBL_ELEM*)bl)->battle_status;
  6815.         case BL_NPC:    return ((mobdb_checkid(((TBL_NPC*)bl)->class_) == 0) ? &((TBL_NPC*)bl)->status : &dummy_status);
  6816.         default:
  6817.             return &dummy_status;
  6818.     }
  6819. }
  6820.  
  6821. /**
  6822.  * Gets the base status data of the given bl
  6823.  * @param bl: Object whose status to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
  6824.  * @return base_status or NULL if any other bl->type than noted above
  6825.  */
  6826. struct status_data *status_get_base_status(struct block_list *bl)
  6827. {
  6828.     nullpo_retr(NULL, bl);
  6829.     switch (bl->type) {
  6830.         case BL_PC: return &((TBL_PC*)bl)->base_status;
  6831.         case BL_MOB:    return ((TBL_MOB*)bl)->base_status ? ((TBL_MOB*)bl)->base_status : &((TBL_MOB*)bl)->db->status;
  6832.         case BL_PET:    return &((TBL_PET*)bl)->db->status;
  6833.         case BL_HOM:    return &((TBL_HOM*)bl)->base_status;
  6834.         case BL_MER:    return &((TBL_MER*)bl)->base_status;
  6835.         case BL_ELEM:   return &((TBL_ELEM*)bl)->base_status;
  6836.         case BL_NPC:    return ((mobdb_checkid(((TBL_NPC*)bl)->class_) == 0) ? &((TBL_NPC*)bl)->status : NULL);
  6837.         default:
  6838.             return NULL;
  6839.     }
  6840. }
  6841.  
  6842. /**
  6843.  * Gets the defense of the given bl
  6844.  * @param bl: Object whose defense to get [PC|MOB|HOM|MER|ELEM]
  6845.  * @return defense with cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX)
  6846.  */
  6847. defType status_get_def(struct block_list *bl)
  6848. {
  6849.     struct unit_data *ud;
  6850.     struct status_data *status = status_get_status_data(bl);
  6851.     int def = status?status->def:0;
  6852.     ud = unit_bl2ud(bl);
  6853.     if (ud && ud->skilltimer != INVALID_TIMER)
  6854.         def -= def * skill_get_castdef(ud->skill_id)/100;
  6855.  
  6856.     return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
  6857. }
  6858.  
  6859. /**
  6860.  * Gets the walking speed of the given bl
  6861.  * @param bl: Object whose speed to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
  6862.  * @return speed
  6863.  */
  6864. unsigned short status_get_speed(struct block_list *bl)
  6865. {
  6866.     if(bl->type==BL_NPC)// Only BL with speed data but no status_data [Skotlex]
  6867.         return ((struct npc_data *)bl)->speed;
  6868.     return status_get_status_data(bl)->speed;
  6869. }
  6870.  
  6871. /**
  6872.  * Gets the party ID of the given bl
  6873.  * @param bl: Object whose party ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM]
  6874.  * @return party ID
  6875.  */
  6876. int status_get_party_id(struct block_list *bl)
  6877. {
  6878.     nullpo_ret(bl);
  6879.     switch (bl->type) {
  6880.         case BL_PC:
  6881.             return ((TBL_PC*)bl)->status.party_id;
  6882.         case BL_PET:
  6883.             if (((TBL_PET*)bl)->master)
  6884.                 return ((TBL_PET*)bl)->master->status.party_id;
  6885.             break;
  6886.         case BL_MOB: {
  6887.                 struct mob_data *md=(TBL_MOB*)bl;
  6888.                 if( md->master_id > 0 ) {
  6889.                     struct map_session_data *msd;
  6890.                     if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
  6891.                         return msd->status.party_id;
  6892.                     return -md->master_id;
  6893.                 }
  6894.             }
  6895.             break;
  6896.         case BL_HOM:
  6897.             if (((TBL_HOM*)bl)->master)
  6898.                 return ((TBL_HOM*)bl)->master->status.party_id;
  6899.             break;
  6900.         case BL_MER:
  6901.             if (((TBL_MER*)bl)->master)
  6902.                 return ((TBL_MER*)bl)->master->status.party_id;
  6903.             break;
  6904.         case BL_SKILL:
  6905.             if (((TBL_SKILL*)bl)->group)
  6906.                 return ((TBL_SKILL*)bl)->group->party_id;
  6907.             break;
  6908.         case BL_ELEM:
  6909.             if (((TBL_ELEM*)bl)->master)
  6910.                 return ((TBL_ELEM*)bl)->master->status.party_id;
  6911.             break;
  6912.     }
  6913.     return 0;
  6914. }
  6915.  
  6916. /**
  6917.  * Gets the guild ID of the given bl
  6918.  * @param bl: Object whose guild ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM|NPC]
  6919.  * @return guild ID
  6920.  */
  6921. int status_get_guild_id(struct block_list *bl)
  6922. {
  6923.     nullpo_ret(bl);
  6924.     switch (bl->type) {
  6925.         case BL_PC:
  6926.             return ((TBL_PC*)bl)->status.guild_id;
  6927.         case BL_PET:
  6928.             if (((TBL_PET*)bl)->master)
  6929.                 return ((TBL_PET*)bl)->master->status.guild_id;
  6930.             break;
  6931.         case BL_MOB:
  6932.             {
  6933.                 struct map_session_data *msd;
  6934.                 struct mob_data *md = (struct mob_data *)bl;
  6935.                 if (md->guardian_data)  // Guardian's guild [Skotlex]
  6936.                     return md->guardian_data->guild_id;
  6937.                 if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
  6938.                     return msd->status.guild_id; // Alchemist's mobs [Skotlex]
  6939.             }
  6940.             break;
  6941.         case BL_HOM:
  6942.             if (((TBL_HOM*)bl)->master)
  6943.                 return ((TBL_HOM*)bl)->master->status.guild_id;
  6944.             break;
  6945.         case BL_MER:
  6946.             if (((TBL_MER*)bl)->master)
  6947.                 return ((TBL_MER*)bl)->master->status.guild_id;
  6948.             break;
  6949.         case BL_NPC:
  6950.             if (((TBL_NPC*)bl)->subtype == NPCTYPE_SCRIPT)
  6951.                 return ((TBL_NPC*)bl)->u.scr.guild_id;
  6952.             break;
  6953.         case BL_SKILL:
  6954.             if (((TBL_SKILL*)bl)->group)
  6955.                 return ((TBL_SKILL*)bl)->group->guild_id;
  6956.             break;
  6957.         case BL_ELEM:
  6958.             if (((TBL_ELEM*)bl)->master)
  6959.                 return ((TBL_ELEM*)bl)->master->status.guild_id;
  6960.             break;
  6961.     }
  6962.     return 0;
  6963. }
  6964.  
  6965. /**
  6966.  * Gets the guild emblem ID of the given bl
  6967.  * @param bl: Object whose emblem ID to get [PC|MOB|PET|HOM|MER|SKILL|ELEM|NPC]
  6968.  * @return guild emblem ID
  6969.  */
  6970. int status_get_emblem_id(struct block_list *bl)
  6971. {
  6972.     nullpo_ret(bl);
  6973.     switch (bl->type) {
  6974.         case BL_PC:
  6975.             return ((TBL_PC*)bl)->guild_emblem_id;
  6976.         case BL_PET:
  6977.             if (((TBL_PET*)bl)->master)
  6978.                 return ((TBL_PET*)bl)->master->guild_emblem_id;
  6979.             break;
  6980.         case BL_MOB:
  6981.             {
  6982.                 struct map_session_data *msd;
  6983.                 struct mob_data *md = (struct mob_data *)bl;
  6984.                 if (md->guardian_data)  // Guardian's guild [Skotlex]
  6985.                     return md->guardian_data->emblem_id;
  6986.                 if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
  6987.                     return msd->guild_emblem_id; // Alchemist's mobs [Skotlex]
  6988.             }
  6989.             break;
  6990.         case BL_HOM:
  6991.             if (((TBL_HOM*)bl)->master)
  6992.                 return ((TBL_HOM*)bl)->master->guild_emblem_id;
  6993.             break;
  6994.         case BL_MER:
  6995.             if (((TBL_MER*)bl)->master)
  6996.                 return ((TBL_MER*)bl)->master->guild_emblem_id;
  6997.             break;
  6998.         case BL_NPC:
  6999.             if (((TBL_NPC*)bl)->subtype == NPCTYPE_SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
  7000.                 struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
  7001.                 if (g)
  7002.                     return g->emblem_id;
  7003.             }
  7004.             break;
  7005.         case BL_ELEM:
  7006.             if (((TBL_ELEM*)bl)->master)
  7007.                 return ((TBL_ELEM*)bl)->master->guild_emblem_id;
  7008.             break;
  7009.     }
  7010.     return 0;
  7011. }
  7012.  
  7013. /**
  7014.  * Gets the race of a mob or pet
  7015.  * @param bl: Object whose race to get [MOB|PET]
  7016.  * @return race
  7017.  */
  7018. int status_get_race2(struct block_list *bl)
  7019. {
  7020.     nullpo_ret(bl);
  7021.     if(bl->type == BL_MOB)
  7022.         return ((struct mob_data *)bl)->db->race2;
  7023.     if(bl->type == BL_PET)
  7024.         return ((struct pet_data *)bl)->db->race2;
  7025.     return 0;
  7026. }
  7027.  
  7028. /**
  7029.  * Checks if an object is dead
  7030.  * @param bl: Object to check [PC|MOB|HOM|MER|ELEM]
  7031.  * @return 1: Is dead or 0: Is alive
  7032.  */
  7033. int status_isdead(struct block_list *bl)
  7034. {
  7035.     nullpo_ret(bl);
  7036.     return status_get_status_data(bl)->hp == 0;
  7037. }
  7038.  
  7039. /**
  7040.  * Checks if an object is immune to magic
  7041.  * @param bl: Object to check [PC|MOB|HOM|MER|ELEM]
  7042.  * @return value of magic damage to be blocked
  7043.  */
  7044. int status_isimmune(struct block_list *bl)
  7045. {
  7046.     struct status_change *sc =status_get_sc(bl);
  7047.     if (sc && sc->data[SC_HERMODE])
  7048.         return 100;
  7049.  
  7050.     if (bl->type == BL_PC &&
  7051.         ((TBL_PC*)bl)->special_state.no_magic_damage >= battle_config.gtb_sc_immunity)
  7052.         return ((TBL_PC*)bl)->special_state.no_magic_damage;
  7053.     return 0;
  7054. }
  7055.  
  7056. /**
  7057.  * Get view data of an object
  7058.  * @param bl: Object whose view data to get [PC|MOB|PET|HOM|MER|ELEM|NPC]
  7059.  * @return view data structure bl->vd
  7060.  */
  7061. struct view_data* status_get_viewdata(struct block_list *bl)
  7062. {
  7063.     nullpo_retr(NULL, bl);
  7064.     switch (bl->type) {
  7065.         case BL_PC:  return &((TBL_PC*)bl)->vd;
  7066.         case BL_MOB: return ((TBL_MOB*)bl)->vd;
  7067.         case BL_PET: return &((TBL_PET*)bl)->vd;
  7068.         case BL_NPC: return ((TBL_NPC*)bl)->vd;
  7069.         case BL_HOM: return ((TBL_HOM*)bl)->vd;
  7070.         case BL_MER: return ((TBL_MER*)bl)->vd;
  7071.         case BL_ELEM: return ((TBL_ELEM*)bl)->vd;
  7072.     }
  7073.     return NULL;
  7074. }
  7075.  
  7076. /**
  7077.  * Set view data of an object
  7078.  * This function deals with class, mount, and item views
  7079.  * SC views are set in clif_getareachar_unit()
  7080.  * @param bl: Object whose view data to set [PC|MOB|PET|HOM|MER|ELEM|NPC]
  7081.  * @param class_: class of the object
  7082.  */
  7083. void status_set_viewdata(struct block_list *bl, int class_)
  7084. {
  7085.     struct view_data* vd;
  7086.     nullpo_retv(bl);
  7087.     if (mobdb_checkid(class_) || mob_is_clone(class_))
  7088.         vd = mob_get_viewdata(class_);
  7089.     else if (npcdb_checkid(class_) || (bl->type == BL_NPC && class_ == WARP_CLASS))
  7090.         vd = npc_get_viewdata(class_);
  7091.     else if (homdb_checkid(class_))
  7092.         vd = hom_get_viewdata(class_);
  7093.     else if (mercenary_class(class_))
  7094.         vd = mercenary_get_viewdata(class_);
  7095.     else if (elemental_class(class_))
  7096.         vd = elemental_get_viewdata(class_);
  7097.     else
  7098.         vd = NULL;
  7099.  
  7100.     switch (bl->type) {
  7101.     case BL_PC:
  7102.         {
  7103.             TBL_PC* sd = (TBL_PC*)bl;
  7104.             if (pcdb_checkid(class_)) {
  7105.                 if (sd->sc.option&OPTION_RIDING) {
  7106.                     switch (class_) { // Adapt class to a Mounted one.
  7107.                         case JOB_KNIGHT:
  7108.                             class_ = JOB_KNIGHT2;
  7109.                             break;
  7110.                         case JOB_CRUSADER:
  7111.                             class_ = JOB_CRUSADER2;
  7112.                             break;
  7113.                         case JOB_LORD_KNIGHT:
  7114.                             class_ = JOB_LORD_KNIGHT2;
  7115.                             break;
  7116.                         case JOB_PALADIN:
  7117.                             class_ = JOB_PALADIN2;
  7118.                             break;
  7119.                         case JOB_BABY_KNIGHT:
  7120.                             class_ = JOB_BABY_KNIGHT2;
  7121.                             break;
  7122.                         case JOB_BABY_CRUSADER:
  7123.                             class_ = JOB_BABY_CRUSADER2;
  7124.                             break;
  7125.                     }
  7126.                 }
  7127.                 sd->vd.class_ = class_;
  7128.                 clif_get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
  7129.                 sd->vd.head_top = sd->status.head_top;
  7130.                 sd->vd.head_mid = sd->status.head_mid;
  7131.                 sd->vd.head_bottom = sd->status.head_bottom;
  7132.                 sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style);
  7133.                 sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
  7134.                 sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
  7135.                 sd->vd.sex = sd->status.sex;
  7136.  
  7137.                 if (sd->vd.cloth_color) {
  7138.                     if(sd->sc.option&OPTION_WEDDING && battle_config.wedding_ignorepalette)
  7139.                         sd->vd.cloth_color = 0;
  7140.                     if(sd->sc.option&OPTION_XMAS && battle_config.xmas_ignorepalette)
  7141.                         sd->vd.cloth_color = 0;
  7142.                     if(sd->sc.option&OPTION_SUMMER && battle_config.summer_ignorepalette)
  7143.                         sd->vd.cloth_color = 0;
  7144.                     if(sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette)
  7145.                         sd->vd.cloth_color = 0;
  7146.                     if(sd->sc.option&OPTION_OKTOBERFEST && battle_config.oktoberfest_ignorepalette)
  7147.                         sd->vd.cloth_color = 0;
  7148.                 }
  7149.             } else if (vd)
  7150.                 memcpy(&sd->vd, vd, sizeof(struct view_data));
  7151.             else
  7152.                 ShowError("status_set_viewdata (PC): No view data for class %d\n", class_);
  7153.         }
  7154.     break;
  7155.     case BL_MOB:
  7156.         {
  7157.             TBL_MOB* md = (TBL_MOB*)bl;
  7158.             if (vd)
  7159.                 md->vd = vd;
  7160.             else
  7161.                 ShowError("status_set_viewdata (MOB): No view data for class %d\n", class_);
  7162.         }
  7163.     break;
  7164.     case BL_PET:
  7165.         {
  7166.             TBL_PET* pd = (TBL_PET*)bl;
  7167.             if (vd) {
  7168.                 memcpy(&pd->vd, vd, sizeof(struct view_data));
  7169.                 if (!pcdb_checkid(vd->class_)) {
  7170.                     pd->vd.hair_style = battle_config.pet_hair_style;
  7171.                     if(pd->pet.equip) {
  7172.                         pd->vd.head_bottom = itemdb_viewid(pd->pet.equip);
  7173.                         if (!pd->vd.head_bottom)
  7174.                             pd->vd.head_bottom = pd->pet.equip;
  7175.                     }
  7176.                 }
  7177.             } else
  7178.                 ShowError("status_set_viewdata (PET): No view data for class %d\n", class_);
  7179.         }
  7180.     break;
  7181.     case BL_NPC:
  7182.         {
  7183.             TBL_NPC* nd = (TBL_NPC*)bl;
  7184.             if (vd)
  7185.                 nd->vd = vd;
  7186.             else
  7187.                 ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_);
  7188.         }
  7189.     break;
  7190.     case BL_HOM:
  7191.         {
  7192.             struct homun_data *hd = (struct homun_data*)bl;
  7193.             if (vd)
  7194.                 hd->vd = vd;
  7195.             else
  7196.                 ShowError("status_set_viewdata (HOMUNCULUS): No view data for class %d\n", class_);
  7197.         }
  7198.         break;
  7199.     case BL_MER:
  7200.         {
  7201.             struct mercenary_data *md = (struct mercenary_data*)bl;
  7202.             if (vd)
  7203.                 md->vd = vd;
  7204.             else
  7205.                 ShowError("status_set_viewdata (MERCENARY): No view data for class %d\n", class_);
  7206.         }
  7207.         break;
  7208.     case BL_ELEM:
  7209.         {
  7210.             struct elemental_data *ed = (struct elemental_data*)bl;
  7211.             if (vd)
  7212.                 ed->vd = vd;
  7213.             else
  7214.                 ShowError("status_set_viewdata (ELEMENTAL): No view data for class %d\n", class_);
  7215.         }
  7216.         break;
  7217.     }
  7218. }
  7219.  
  7220. /**
  7221.  * Get status change data of an object
  7222.  * @param bl: Object whose sc data to get [PC|MOB|HOM|MER|ELEM|NPC]
  7223.  * @return status change data structure bl->sc
  7224.  */
  7225. struct status_change *status_get_sc(struct block_list *bl)
  7226. {
  7227.     if( bl )
  7228.     switch (bl->type) {
  7229.         case BL_PC:  return &((TBL_PC*)bl)->sc;
  7230.         case BL_MOB: return &((TBL_MOB*)bl)->sc;
  7231.         case BL_NPC: return &((TBL_NPC*)bl)->sc;
  7232.         case BL_HOM: return &((TBL_HOM*)bl)->sc;
  7233.         case BL_MER: return &((TBL_MER*)bl)->sc;
  7234.         case BL_ELEM: return &((TBL_ELEM*)bl)->sc;
  7235.     }
  7236.     return NULL;
  7237. }
  7238.  
  7239. /**
  7240.  * Initiate (memset) the status change data of an object
  7241.  * @param bl: Object whose sc data to memset [PC|MOB|HOM|MER|ELEM|NPC]
  7242.  */
  7243. void status_change_init(struct block_list *bl)
  7244. {
  7245.     struct status_change *sc = status_get_sc(bl);
  7246.     nullpo_retv(sc);
  7247.     memset(sc, 0, sizeof (struct status_change));
  7248. }
  7249.  
  7250. /**
  7251.  * Get base level of bl, cap the value by level_limit
  7252.  * @param bl Object [BL_PC|BL_MOB|BL_HOM|BL_MER|BL_ELEM]
  7253.  * @param level_limit Level cap
  7254.  * @return Base level or level_limit
  7255.  **/
  7256. int status_get_baselevel_limit(struct block_list *bl, int level_limit) {
  7257.     int lvl = status_get_lv(bl);
  7258.     return min(lvl, level_limit);
  7259. }
  7260.  
  7261. /**
  7262.  * Get job level of player, cap the value by level_limit.
  7263.  * @param sd Player
  7264.  * @param level_limit Level cap
  7265.  * @return Job level or level_limit or 0 if not a player
  7266.  **/
  7267. int status_get_joblevel_limit(struct map_session_data *sd, int level_limit) {
  7268.     int lvl = sd ? sd->status.job_level : 0;
  7269.     return min(lvl, level_limit);
  7270. }
  7271.  
  7272. /**
  7273.  * Applies SC defense to a given status change
  7274.  * This function also determines whether or not the status change will be applied
  7275.  * @param src: Source of the status change [PC|MOB|HOM|MER|ELEM|NPC]
  7276.  * @param bl: Target of the status change
  7277.  * @param type: Status change (SC_*)
  7278.  * @param rate: Initial percentage rate of affecting bl
  7279.  * @param tick: Initial duration that the status change affects bl
  7280.  * @param flag: Value which determines what parts to calculate. See e_status_change_start_flags
  7281.  * @return adjusted duration based on flag values
  7282.  */
  7283. int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag)
  7284. {
  7285.     /// Resistance rate: 10000 = 100%
  7286.     /// Example:    50% (5000) -> sc_def = 5000 -> 25%;
  7287.     ///             5000ms -> tick_def = 5000 -> 2500ms
  7288.     int sc_def = 0, tick_def = -1; // -1 = use sc_def
  7289.     /// Fixed resistance value (after rate calculation)
  7290.     /// Example:    25% (2500) -> sc_def2 = 2000 -> 5%;
  7291.     ///             2500ms -> tick_def2=2000 -> 500ms
  7292.     int sc_def2 = 0, tick_def2 = 0;
  7293.  
  7294.     struct status_data *status, *status_src, *b_status;
  7295.     struct status_change *sc;
  7296.     struct map_session_data *sd;
  7297.  
  7298.     nullpo_ret(bl);
  7299.     if (src == NULL)
  7300.         return tick?tick:1; // This should not happen in current implementation, but leave it anyway
  7301.  
  7302.     // Status that are blocked by Golden Thief Bug card or Wand of Hermod
  7303.     if (status_isimmune(bl)) {
  7304.         switch (type) {
  7305.             case SC_DECREASEAGI:
  7306.             case SC_SILENCE:
  7307.             case SC_COMA:
  7308.             case SC_INCREASEAGI:
  7309.             case SC_BLESSING:
  7310.             case SC_SLOWPOISON:
  7311.             case SC_IMPOSITIO:
  7312.             case SC_AETERNA:
  7313.             case SC_SUFFRAGIUM:
  7314.             case SC_BENEDICTIO:
  7315.             case SC_PROVIDENCE:
  7316.             case SC_KYRIE:
  7317.             case SC_ASSUMPTIO:
  7318.             case SC_ANGELUS:
  7319.             case SC_MAGNIFICAT:
  7320.             case SC_GLORIA:
  7321.             case SC_WINDWALK:
  7322.             case SC_MAGICROD:
  7323.             case SC_HALLUCINATION:
  7324.             case SC_STONE:
  7325.             case SC_QUAGMIRE:
  7326.             case SC_SUITON:
  7327.             case SC_SWINGDANCE:
  7328.             case SC__ENERVATION:
  7329.             case SC__GROOMY:
  7330.             case SC__IGNORANCE:
  7331.             case SC__LAZINESS:
  7332.             case SC__UNLUCKY:
  7333.             case SC__WEAKNESS:
  7334.                 return 0;
  7335.         }
  7336.     }
  7337.  
  7338.     sd = BL_CAST(BL_PC,bl);
  7339.     status = status_get_status_data(bl);
  7340.     status_src = status_get_status_data(src);
  7341.     b_status = status_get_base_status(bl);
  7342.     sc = status_get_sc(bl);
  7343.     if( sc && !sc->count )
  7344.         sc = NULL;
  7345.  
  7346.     switch (type) {
  7347.         case SC_POISON:
  7348.         case SC_DPOISON:
  7349.             sc_def = status->vit*100;
  7350.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7351.             if (sd) {
  7352.                 // For players: 60000 - 450*vit - 100*luk
  7353.                 tick_def = status->vit*75;
  7354.                 tick_def2 = status->luk*100;
  7355.             } else {
  7356.                 // For monsters: 30000 - 200*vit
  7357.                 tick>>=1;
  7358.                 tick_def = (status->vit*200)/3;
  7359.             }
  7360.             break;
  7361.         case SC_STUN:
  7362.             sc_def = status->vit*100;
  7363.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7364.             tick_def2 = status->luk*10;
  7365.             break;
  7366.         case SC_SILENCE:
  7367. #ifndef RENEWAL
  7368.             sc_def = status->vit*100;
  7369.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7370. #else
  7371.             sc_def = status->int_*100;
  7372.             sc_def2 = (status->vit + status->luk) * 5 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7373. #endif
  7374.             tick_def2 = status->luk*10;
  7375.             break;
  7376.         case SC_BLEEDING:
  7377. #ifndef RENEWAL
  7378.             sc_def = status->vit*100;
  7379.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7380. #else
  7381.             sc_def = status->agi*100;
  7382.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7383. #endif
  7384.             tick_def2 = status->luk*10;
  7385.             break;
  7386.         case SC_SLEEP:
  7387. #ifndef RENEWAL
  7388.             sc_def = status->int_*100;
  7389.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7390. #else
  7391.             sc_def = status->agi*100;
  7392.             sc_def2 = (status->int_ + status->luk) * 5 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7393. #endif
  7394.             tick_def2 = status->luk*10;
  7395.             break;
  7396.         case SC_STONE:
  7397.             sc_def = status->mdef*100;
  7398.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7399.             tick_def = 0; // No duration reduction
  7400.             break;
  7401.         case SC_FREEZE:
  7402.             sc_def = status->mdef*100;
  7403.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7404.             tick_def2 = status_src->luk*-10; // Caster can increase final duration with luk
  7405.             break;
  7406.         case SC_CURSE:
  7407.             // Special property: immunity when luk is zero
  7408.             if (status->luk == 0)
  7409.                 return 0;
  7410.             sc_def = status->luk*100;
  7411.             sc_def2 = status->luk*10 - status_get_lv(src)*10; // Curse only has a level penalty and no resistance
  7412.             tick_def = status->vit*100;
  7413.             tick_def2 = status->luk*10;
  7414.             break;
  7415.         case SC_BLIND:
  7416.             sc_def = (status->vit + status->int_)*50;
  7417.             sc_def2 = status->luk*10 + status_get_lv(bl)*10 - status_get_lv(src)*10;
  7418.             tick_def2 = status->luk*10;
  7419.             break;
  7420.         case SC_CONFUSION:
  7421.             sc_def = (status->str + status->int_)*50;
  7422.             sc_def2 = status_get_lv(src)*10 - status_get_lv(bl)*10 - status->luk*10; // Reversed sc_def2
  7423.             tick_def2 = status->luk*10;
  7424.             break;
  7425.         case SC_DECREASEAGI:
  7426.         case SC_ADORAMUS: // Arch Bishop
  7427.             if (sd)
  7428.                 tick >>= 1; // Half duration for players.
  7429.             sc_def = status->mdef*100;
  7430.             tick_def = 0; // No duration reduction
  7431.             break;
  7432.         case SC_ANKLE:
  7433.             if(status->mode&MD_BOSS) // Lasts 5 times less on bosses
  7434.                 tick /= 5;
  7435.             sc_def = status->agi*50;
  7436.             break;
  7437.         case SC_DEEPSLEEP:
  7438.             sc_def = b_status->int_*50;
  7439.             tick_def = 0; // Linear reduction instead
  7440.             tick_def2 = (b_status->int_ + status_get_lv(bl))*50; // kRO balance update lists this formula
  7441.             break;
  7442.         case SC_NETHERWORLD:
  7443.             // Resistance: {(TargetÓ³ Base Level / 50) + (TargetÓ³ Job Level / 10)} seconds
  7444.             tick_def2 = status_get_baselevel_limit(bl, 150) * 20 + status_get_joblevel_limit(sd, 50) * 100;
  7445.             break;
  7446.         case SC_MARSHOFABYSS:
  7447.             // 5 second (Fixed) + 25 second - {( INT + LUK ) / 20 second }
  7448.             tick_def2 = (status->int_ + status->luk)*50;
  7449.             break;
  7450.         case SC_STASIS:
  7451.             // 5 second (fixed) + { Stasis Skill level * 5 - (Target's VIT + DEX) / 20 }
  7452.             tick_def2 = (status->vit + status->dex)*50;
  7453.             break;
  7454.         case SC_WHITEIMPRISON:
  7455.             if( tick == 5000 ) // 100% on caster
  7456.                 break;
  7457.             if( bl->type == BL_PC )
  7458.                 tick_def2 = status_get_lv(bl)*20 + status->vit*25 + status->agi*10;
  7459.             else
  7460.                 tick_def2 = (status->vit + status->luk)*50;
  7461.             break;
  7462.         case SC_BURNING:
  7463.             tick_def2 = 75*status->luk + 125*status->agi;
  7464.             break;
  7465.         case SC_FREEZING:
  7466.             tick_def2 = (status->vit + status->dex)*50;
  7467.             break;
  7468.         case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
  7469.             sc_def = status->int_*80;
  7470.             sc_def = max(sc_def, 500); // minimum of 5% resist
  7471.             break;
  7472.         case SC_BITE: // {(Base Success chance) - (Target's AGI / 4)}
  7473.             sc_def2 = status->agi*25;
  7474.             break;
  7475.         case SC_ELECTRICSHOCKER:
  7476.             tick_def2 = (status->vit + status->agi) * 70;
  7477.             break;
  7478.         case SC_CRYSTALIZE:
  7479.             tick_def2 = b_status->vit*100;
  7480.             break;
  7481.         case SC_VACUUM_EXTREME:
  7482.             tick_def2 = b_status->str*50;
  7483.             break;
  7484.         case SC_KYOUGAKU:
  7485.             tick_def2 = 30*status->int_;
  7486.             break;
  7487.         case SC_PARALYSIS:
  7488.             tick_def2 = (status->vit + status->luk)*50;
  7489.             break;
  7490.         case SC_VOICEOFSIREN:
  7491.             // Resistance: {(TargetÓ³ Base Level / 10) + (TargetÓ³ Job Level / 5)} seconds
  7492.             tick_def2 = status_get_baselevel_limit(bl, 150) * 100 + status_get_joblevel_limit(sd, 50) * 200;
  7493.             break;
  7494.         case SC_B_TRAP:
  7495.             tick_def = b_status->str * 50; // (custom)
  7496.             break;
  7497.         default:
  7498.             // Effect that cannot be reduced? Likely a buff.
  7499.             if (!(rnd()%10000 < rate))
  7500.                 return 0;
  7501.             return tick ? tick : 1;
  7502.     }
  7503.  
  7504.     if (sd) {
  7505.  
  7506.         if (battle_config.pc_sc_def_rate != 100) {
  7507.             sc_def = sc_def*battle_config.pc_sc_def_rate/100;
  7508.             sc_def2 = sc_def2*battle_config.pc_sc_def_rate/100;
  7509.         }
  7510.  
  7511.         sc_def = min(sc_def, battle_config.pc_max_sc_def*100);
  7512.         sc_def2 = min(sc_def2, battle_config.pc_max_sc_def*100);
  7513.  
  7514.         if (tick_def > 0 && battle_config.pc_sc_def_rate != 100) {
  7515.             tick_def = tick_def*battle_config.pc_sc_def_rate/100;
  7516.             tick_def2 = tick_def2*battle_config.pc_sc_def_rate/100;
  7517.         }
  7518.     } else {
  7519.  
  7520.         if (battle_config.mob_sc_def_rate != 100) {
  7521.             sc_def = sc_def*battle_config.mob_sc_def_rate/100;
  7522.             sc_def2 = sc_def2*battle_config.mob_sc_def_rate/100;
  7523.         }
  7524.  
  7525.         sc_def = min(sc_def, battle_config.mob_max_sc_def*100);
  7526.         sc_def2 = min(sc_def2, battle_config.mob_max_sc_def*100);
  7527.  
  7528.         if (tick_def > 0 && battle_config.mob_sc_def_rate != 100) {
  7529.             tick_def = tick_def*battle_config.mob_sc_def_rate/100;
  7530.             tick_def2 = tick_def2*battle_config.mob_sc_def_rate/100;
  7531.         }
  7532.     }
  7533.  
  7534.     if (sc) {
  7535.         if (sc->data[SC_SCRESIST])
  7536.             sc_def += sc->data[SC_SCRESIST]->val1*100; // Status resist
  7537.         else if (sc->data[SC_SIEGFRIED])
  7538.             sc_def += sc->data[SC_SIEGFRIED]->val3*100; // Status resistance.
  7539.         else if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2)
  7540.             sc_def += sc->data[SC_SHIELDSPELL_REF]->val3*100;
  7541.     }
  7542.  
  7543.     // When tick def not set, reduction is the same for both.
  7544.     if(tick_def == -1)
  7545.         tick_def = sc_def;
  7546.  
  7547.     // Natural resistance
  7548.     if (!(flag&SCSTART_NORATEDEF)) {
  7549.         rate -= rate*sc_def/10000;
  7550.         rate -= sc_def2;
  7551.  
  7552.         // Minimum chances
  7553.         switch (type) {
  7554.             case SC_BITE:
  7555.                 rate = max(rate, 5000); // Minimum of 50%
  7556.                 break;
  7557.         }
  7558.  
  7559.         // Item resistance (only applies to rate%)
  7560.         if(sd && SC_COMMON_MIN <= type && type <= SC_COMMON_MAX) {
  7561.             if( sd->reseff[type-SC_COMMON_MIN] > 0 )
  7562.                 rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000;
  7563.             if( sd->sc.data[SC_COMMONSC_RESIST] )
  7564.                 rate -= rate*sd->sc.data[SC_COMMONSC_RESIST]->val1/100;
  7565.         }
  7566.  
  7567.         // Aegis accuracy
  7568.         if(rate > 0 && rate%10 != 0) rate += (10 - rate%10);
  7569.     }
  7570.  
  7571.     if (!(rnd()%10000 < rate))
  7572.         return 0;
  7573.  
  7574.     // Even if a status change doesn't have a duration, it should still trigger
  7575.     if (tick < 1)
  7576.         return 1;
  7577.  
  7578.     // Duration cannot be reduced
  7579.     if (flag&SCSTART_NOTICKDEF)
  7580.         return tick;
  7581.  
  7582.     tick -= tick*tick_def/10000;
  7583.     tick -= tick_def2;
  7584.  
  7585.     // Minimum durations
  7586.     switch (type) {
  7587.         case SC_ANKLE:
  7588.         case SC_BURNING:
  7589.         case SC_MARSHOFABYSS:
  7590.         case SC_STASIS:
  7591.         case SC_DEEPSLEEP:
  7592.             tick = max(tick, 5000); // Minimum duration 5s
  7593.             break;
  7594.         case SC_FREEZING:
  7595.             tick = max(tick, 6000); // Minimum duration 6s
  7596.             break;
  7597.         default:
  7598.             // Skills need to trigger even if the duration is reduced below 1ms
  7599.             tick = max(tick, 1);
  7600.             break;
  7601.     }
  7602.  
  7603.     return tick;
  7604. }
  7605.  
  7606. /**
  7607.  * Applies SC effect to the player
  7608.  * @param sd: Source to apply effect [PC]
  7609.  * @param type: Status change (SC_*)
  7610.  * @param dval1~3: Depends on type of status change
  7611.  * Author: Ind
  7612.  */
  7613. void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) {
  7614.     struct sc_display_entry *entry;
  7615.     int i;
  7616.  
  7617.     for( i = 0; i < sd->sc_display_count; i++ ) {
  7618.         if( sd->sc_display[i]->type == type )
  7619.             break;
  7620.     }
  7621.  
  7622.     if( i != sd->sc_display_count ) {
  7623.         sd->sc_display[i]->val1 = dval1;
  7624.         sd->sc_display[i]->val2 = dval2;
  7625.         sd->sc_display[i]->val3 = dval3;
  7626.         return;
  7627.     }
  7628.  
  7629.     entry = ers_alloc(pc_sc_display_ers, struct sc_display_entry);
  7630.  
  7631.     entry->type = type;
  7632.     entry->val1 = dval1;
  7633.     entry->val2 = dval2;
  7634.     entry->val3 = dval3;
  7635.  
  7636.     RECREATE(sd->sc_display, struct sc_display_entry *, ++sd->sc_display_count);
  7637.     sd->sc_display[sd->sc_display_count - 1] = entry;
  7638. }
  7639.  
  7640. /**
  7641.  * Removes SC effect of the player
  7642.  * @param sd: Source to remove effect [PC]
  7643.  * @param type: Status change (SC_*)
  7644.  * Author: Ind
  7645.  */
  7646. void status_display_remove(struct map_session_data *sd, enum sc_type type) {
  7647.     int i;
  7648.  
  7649.     for( i = 0; i < sd->sc_display_count; i++ ) {
  7650.         if( sd->sc_display[i]->type == type )
  7651.             break;
  7652.     }
  7653.  
  7654.     if( i != sd->sc_display_count ) {
  7655.         int cursor;
  7656.  
  7657.         ers_free(pc_sc_display_ers, sd->sc_display[i]);
  7658.         sd->sc_display[i] = NULL;
  7659.  
  7660.         /* The all-mighty compact-o-matic */
  7661.         for( i = 0, cursor = 0; i < sd->sc_display_count; i++ ) {
  7662.             if( sd->sc_display[i] == NULL )
  7663.                 continue;
  7664.  
  7665.             if( i != cursor )
  7666.                 sd->sc_display[cursor] = sd->sc_display[i];
  7667.  
  7668.             cursor++;
  7669.         }
  7670.  
  7671.         if( !(sd->sc_display_count = cursor) ) {
  7672.             aFree(sd->sc_display);
  7673.             sd->sc_display = NULL;
  7674.         }
  7675.     }
  7676. }
  7677.  
  7678. /**
  7679.  * Applies SC defense to a given status change
  7680.  * This function also determines whether or not the status change will be applied
  7681.  * @param src: Source of the status change [PC|MOB|HOM|MER|ELEM|NPC]
  7682.  * @param bl: Target of the status change (See: enum sc_type)
  7683.  * @param type: Status change (SC_*)
  7684.  * @param rate: Initial percentage rate of affecting bl (0~10000)
  7685.  * @param val1~4: Depends on type of status change
  7686.  * @param tick: Initial duration that the status change affects bl
  7687.  * @param flag: Value which determines what parts to calculate. See e_status_change_start_flags
  7688.  * @return adjusted duration based on flag values
  7689.  */
  7690. int status_change_start(struct block_list* src, struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,unsigned char flag) {
  7691.     struct map_session_data *sd = NULL;
  7692.     struct status_change* sc;
  7693.     struct status_change_entry* sce;
  7694.     struct status_data *status;
  7695.     struct view_data *vd;
  7696.     int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0;
  7697.     bool sc_isnew = true;
  7698.  
  7699.     nullpo_ret(bl);
  7700.     sc = status_get_sc(bl);
  7701.     status = status_get_status_data(bl);
  7702.  
  7703.     if( type <= SC_NONE || type >= SC_MAX ) {
  7704.         ShowError("status_change_start: invalid status change (%d)!\n", type);
  7705.         return 0;
  7706.     }
  7707.  
  7708.     if( !sc )
  7709.         return 0; // Unable to receive status changes
  7710.  
  7711.     if( status_isdead(bl) && type != SC_NOCHAT ) // SC_NOCHAT should work even on dead characters
  7712.         return 0;
  7713.  
  7714.     if( bl->type == BL_MOB) {
  7715.         struct mob_data *md = BL_CAST(BL_MOB,bl);
  7716.         if(md && (md->mob_id == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA)
  7717.             return 0; // Emperium/BG Monsters can't be afflicted by status changes
  7718.         // Uncomment to prevent status adding hp to gvg mob (like bloodylust=hp*3 etc...
  7719.         // if(md && mob_is_gvg(md) && status_sc2scb_flag(type)&SCB_MAXHP) return 0;
  7720.     }
  7721.  
  7722.     if( sc->data[SC_REFRESH] ) {
  7723.         if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
  7724.             return 0; // Immune to status ailements
  7725.         switch( type ) {
  7726.             case SC_DEEPSLEEP:
  7727.             case SC_BURNING:
  7728.             case SC_FREEZING:
  7729.             case SC_CRYSTALIZE:
  7730.             case SC_TOXIN:
  7731.             case SC_PARALYSE:
  7732.             case SC_VENOMBLEED:
  7733.             case SC_MAGICMUSHROOM:
  7734.             case SC_DEATHHURT:
  7735.             case SC_PYREXIA:
  7736.             case SC_OBLIVIONCURSE:
  7737.             case SC_MARSHOFABYSS:
  7738.             case SC_MANDRAGORA:
  7739.                 return 0;
  7740.         }
  7741.     }
  7742.     else if( sc->data[SC_INSPIRATION] ) {
  7743.         if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
  7744.             return 0; // Immune to status ailements
  7745.         switch( type ) {
  7746.             case SC_BURNING:
  7747.             case SC_FREEZING:
  7748.             case SC_CRYSTALIZE:
  7749.             case SC_FEAR:
  7750.             case SC_TOXIN:
  7751.             case SC_PARALYSE:
  7752.             case SC_VENOMBLEED:
  7753.             case SC_MAGICMUSHROOM:
  7754.             case SC_DEATHHURT:
  7755.             case SC_PYREXIA:
  7756.             case SC_OBLIVIONCURSE:
  7757.             case SC_LEECHESEND:
  7758.             case SC_DEEPSLEEP:
  7759.             case SC_SATURDAYNIGHTFEVER:
  7760.             case SC__BODYPAINT:
  7761.             case SC__ENERVATION:
  7762.             case SC__GROOMY:
  7763.             case SC__IGNORANCE:
  7764.             case SC__LAZINESS:
  7765.             case SC__UNLUCKY:
  7766.             case SC__WEAKNESS:
  7767.                 return 0;
  7768.         }
  7769.     }
  7770.     else if( sc->data[SC_KINGS_GRACE] ) {
  7771.         if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
  7772.             return 0; // Immune to status ailements
  7773.         switch( type ) {
  7774.             case SC_HALLUCINATION:
  7775.             case SC_BURNING:
  7776.             case SC_CRYSTALIZE:
  7777.             case SC_FREEZING:
  7778.             case SC_DEEPSLEEP:
  7779.             case SC_FEAR:
  7780.             case SC_MANDRAGORA:
  7781.                 return 0;
  7782.         }
  7783.     }
  7784.  
  7785.     sd = BL_CAST(BL_PC, bl);
  7786.  
  7787.     // Adjust tick according to status resistances
  7788.     if( !(flag&(SCSTART_NOAVOID|SCSTART_LOADED)) ) {
  7789.         tick = status_get_sc_def(src, bl, type, rate, tick, flag);
  7790.         if( !tick )
  7791.             return 0;
  7792.     }
  7793.  
  7794.     vd = status_get_viewdata(bl);
  7795.  
  7796.     undead_flag = battle_check_undead(status->race,status->def_ele);
  7797.     // Check for immunities / sc fails
  7798.     switch (type) {
  7799.     case SC_DECREASEAGI:
  7800.     case SC_QUAGMIRE:
  7801.     case SC_DONTFORGETME:
  7802.     case SC_ADORAMUS:
  7803.         if(sc->data[SC_SPEEDUP1])
  7804.             return 0;
  7805.         break;
  7806.     case SC_ANGRIFFS_MODUS:
  7807.     case SC_GOLDENE_FERSE:
  7808.         if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
  7809.         || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
  7810.         )
  7811.             return 0;
  7812.     case SC_VACUUM_EXTREME:
  7813.         if (sc && (sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HOVERING] || sc->data[SC_VACUUM_EXTREME] ||
  7814.             (sc->data[SC_VACUUM_EXTREME_POSTDELAY] && sc->data[SC_VACUUM_EXTREME_POSTDELAY]->val2 == val2))) // Ignore post delay from other vacuum (this will make stack effect enabled)
  7815.             return 0;
  7816.         break;
  7817.     case SC_STONE:
  7818.         if(sc->data[SC_POWER_OF_GAIA])
  7819.             return 0;
  7820.     case SC_FREEZE:
  7821.         // Undead are immune to Freeze/Stone
  7822.         if (undead_flag && !(flag&SCSTART_NOAVOID))
  7823.             return 0;
  7824.     case SC_DEEPSLEEP:
  7825.     case SC_SLEEP:
  7826.     case SC_STUN:
  7827.     case SC_FREEZING:
  7828.     case SC_CRYSTALIZE:
  7829.         if (sc->opt1)
  7830.             return 0; // Cannot override other opt1 status changes. [Skotlex]
  7831.         if((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
  7832.             return 0; // Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
  7833.     break;
  7834.  
  7835.     case SC_ALL_RIDING:
  7836.         if( !sd || !&sd->sc || sc->option&(OPTION_RIDING|OPTION_DRAGON|OPTION_WUGRIDER|OPTION_MADOGEAR) )
  7837.             return 0;
  7838.         if( sc->data[type] )
  7839.         {   // Already mounted, just dismount.
  7840.             status_change_end(bl, SC_ALL_RIDING, INVALID_TIMER);
  7841.             return 0;
  7842.         }
  7843.     break;
  7844.  
  7845.     // They're all like berserk, do not everlap each other
  7846.     case SC_BERSERK:
  7847.         if(sc->data[SC_SATURDAYNIGHTFEVER])
  7848.             return 0;
  7849.         break;
  7850.  
  7851.     case SC_BURNING:
  7852.         if(sc->opt1 || sc->data[SC_FREEZING])
  7853.             return 0;
  7854.     break;
  7855.  
  7856.     case SC_SIGNUMCRUCIS:
  7857.         // Only affects demons and undead element (but not players)
  7858.         if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
  7859.             return 0;
  7860.     break;
  7861.     case SC_AETERNA:
  7862.         if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
  7863.             return 0;
  7864.     break;
  7865.     case SC_KYRIE:
  7866.         if (bl->type == BL_MOB)
  7867.             return 0;
  7868.     break;
  7869.     case SC_OVERTHRUST:
  7870.         if (sc->data[SC_MAXOVERTHRUST])
  7871.             return 0; // Overthrust can't take effect if under Max Overthrust. [Skotlex]
  7872.     case SC_MAXOVERTHRUST:
  7873.         if( sc->option&OPTION_MADOGEAR )
  7874.             return 0; // Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
  7875.     break;
  7876.     case SC_ADRENALINE:
  7877.         if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE)))
  7878.             return 0;
  7879.         if (sc->data[SC_QUAGMIRE] ||
  7880.             sc->data[SC_DECREASEAGI] ||
  7881.             sc->data[SC_ADORAMUS] ||
  7882.             sc->option&OPTION_MADOGEAR // Adrenaline doesn't affect Mado Gear [Ind]
  7883.         )
  7884.             return 0;
  7885.     break;
  7886.     case SC_ADRENALINE2:
  7887.         if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE2)))
  7888.             return 0;
  7889.         if (sc->data[SC_QUAGMIRE] ||
  7890.             sc->data[SC_DECREASEAGI] ||
  7891.             sc->data[SC_ADORAMUS]
  7892.         )
  7893.             return 0;
  7894.     break;
  7895.     case SC_MAGNIFICAT:
  7896.         if( sc->option&OPTION_MADOGEAR ) // Mado is immune to magnificat
  7897.             return 0;
  7898.         break;
  7899.     case SC_ONEHAND:
  7900.     case SC_MERC_QUICKEN:
  7901.     case SC_TWOHANDQUICKEN:
  7902.         if(sc->data[SC_DECREASEAGI] || sc->data[SC_ADORAMUS])
  7903.             return 0;
  7904.  
  7905.     case SC_INCREASEAGI:
  7906.     case SC_CONCENTRATE:
  7907.     case SC_SPEARQUICKEN:
  7908.     case SC_TRUESIGHT:
  7909.     case SC_WINDWALK:
  7910.     case SC_CARTBOOST:
  7911.     case SC_ASSNCROS:
  7912.         if (sc->data[SC_QUAGMIRE])
  7913.             return 0;
  7914.         if(sc->option&OPTION_MADOGEAR)
  7915.             return 0; // Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
  7916.     break;
  7917.     case SC_CLOAKING:
  7918.         // Avoid cloaking with no wall and low skill level. [Skotlex]
  7919.         // Due to the cloaking card, we have to check the wall versus to known
  7920.         // skill level rather than the used one. [Skotlex]
  7921.         // if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
  7922.         if( sd && pc_checkskill(sd, AS_CLOAKING) < 3 && !skill_check_cloaking(bl,NULL) )
  7923.             return 0;
  7924.     break;
  7925.     case SC_MODECHANGE:
  7926.     {
  7927.         int mode;
  7928.         struct status_data *bstatus = status_get_base_status(bl);
  7929.         if (!bstatus) return 0;
  7930.         if (sc->data[type]) { // Pile up with previous values.
  7931.             if(!val2) val2 = sc->data[type]->val2;
  7932.             val3 |= sc->data[type]->val3;
  7933.             val4 |= sc->data[type]->val4;
  7934.         }
  7935.         mode = val2?val2:bstatus->mode; // Base mode
  7936.         if (val4) mode&=~val4; // Del mode
  7937.         if (val3) mode|= val3; // Add mode
  7938.         if (mode == bstatus->mode) { // No change.
  7939.             if (sc->data[type]) // Abort previous status
  7940.                 return status_change_end(bl, type, INVALID_TIMER);
  7941.             return 0;
  7942.         }
  7943.     }
  7944.     break;
  7945.     // Strip skills, need to divest something or it fails.
  7946.     case SC_STRIPWEAPON:
  7947.         if (sd && !(flag&SCSTART_LOADED)) { // Apply sc anyway if loading saved sc_data
  7948.             short i;
  7949.             opt_flag = 0; // Reuse to check success condition.
  7950.             if(sd->bonus.unstripable_equip&EQP_WEAPON)
  7951.                 return 0;
  7952.             i = sd->equip_index[EQI_HAND_L];
  7953.             if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
  7954.                 opt_flag|=1;
  7955.                 pc_unequipitem(sd,i,3); // Left-hand weapon
  7956.             }
  7957.  
  7958.             i = sd->equip_index[EQI_HAND_R];
  7959.             if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
  7960.                 opt_flag|=2;
  7961.                 pc_unequipitem(sd,i,3);
  7962.             }
  7963.             if (!opt_flag) return 0;
  7964.         }
  7965.         if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
  7966.     break;
  7967.     case SC_STRIPSHIELD:
  7968.         if( val2 == 1 ) val2 = 0; // GX effect. Do not take shield off..
  7969.         else
  7970.         if (sd && !(flag&SCSTART_LOADED)) {
  7971.             short i;
  7972.             if(sd->bonus.unstripable_equip&EQP_SHIELD)
  7973.                 return 0;
  7974.             i = sd->equip_index[EQI_HAND_L];
  7975.             if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
  7976.                 return 0;
  7977.             pc_unequipitem(sd,i,3);
  7978.         }
  7979.         if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
  7980.     break;
  7981.     case SC_STRIPARMOR:
  7982.         if (sd && !(flag&SCSTART_LOADED)) {
  7983.             short i;
  7984.             if(sd->bonus.unstripable_equip&EQP_ARMOR)
  7985.                 return 0;
  7986.             i = sd->equip_index[EQI_ARMOR];
  7987.             if ( i < 0 || !sd->inventory_data[i] )
  7988.                 return 0;
  7989.             pc_unequipitem(sd,i,3);
  7990.         }
  7991.         if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
  7992.     break;
  7993.     case SC_STRIPHELM:
  7994.         if (sd && !(flag&SCSTART_LOADED)) {
  7995.             short i;
  7996.             if(sd->bonus.unstripable_equip&EQP_HELM)
  7997.                 return 0;
  7998.             i = sd->equip_index[EQI_HEAD_TOP];
  7999.             if ( i < 0 || !sd->inventory_data[i] )
  8000.                 return 0;
  8001.             pc_unequipitem(sd,i,3);
  8002.         }
  8003.         if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
  8004.     break;
  8005.     case SC_MERC_FLEEUP:
  8006.     case SC_MERC_ATKUP:
  8007.     case SC_MERC_HPUP:
  8008.     case SC_MERC_SPUP:
  8009.     case SC_MERC_HITUP:
  8010.         if( bl->type != BL_MER )
  8011.             return 0; // Stats only for Mercenaries
  8012.     break;
  8013.     case SC_STRFOOD:
  8014.         if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
  8015.             return 0;
  8016.     break;
  8017.     case SC_AGIFOOD:
  8018.         if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
  8019.             return 0;
  8020.     break;
  8021.     case SC_VITFOOD:
  8022.         if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
  8023.             return 0;
  8024.     break;
  8025.     case SC_INTFOOD:
  8026.         if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
  8027.             return 0;
  8028.     break;
  8029.     case SC_DEXFOOD:
  8030.         if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
  8031.             return 0;
  8032.     break;
  8033.     case SC_LUKFOOD:
  8034.         if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
  8035.             return 0;
  8036.     break;
  8037.     case SC_FOOD_STR_CASH:
  8038.         if ((sc->data[SC_STRFOOD] && sc->data[SC_STRFOOD]->val1 > val1) || sc->data[SC_2011RWC_SCROLL])
  8039.             return 0;
  8040.     break;
  8041.     case SC_FOOD_AGI_CASH:
  8042.         if ((sc->data[SC_AGIFOOD] && sc->data[SC_AGIFOOD]->val1 > val1) || sc->data[SC_2011RWC_SCROLL])
  8043.             return 0;
  8044.     break;
  8045.     case SC_FOOD_VIT_CASH:
  8046.         if ((sc->data[SC_VITFOOD] && sc->data[SC_VITFOOD]->val1 > val1) || sc->data[SC_2011RWC_SCROLL])
  8047.             return 0;
  8048.     break;
  8049.     case SC_FOOD_INT_CASH:
  8050.         if ((sc->data[SC_INTFOOD] && sc->data[SC_INTFOOD]->val1 > val1) || sc->data[SC_2011RWC_SCROLL])
  8051.             return 0;
  8052.     break;
  8053.     case SC_FOOD_DEX_CASH:
  8054.         if ((sc->data[SC_DEXFOOD] && sc->data[SC_DEXFOOD]->val1 > val1) || sc->data[SC_2011RWC_SCROLL])
  8055.             return 0;
  8056.     break;
  8057.     case SC_FOOD_LUK_CASH:
  8058.         if ((sc->data[SC_LUKFOOD] && sc->data[SC_LUKFOOD]->val1 > val1) || sc->data[SC_2011RWC_SCROLL])
  8059.             return 0;
  8060.     break;
  8061.     case SC_CAMOUFLAGE:
  8062.         if( sd && pc_checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill_check_camouflage(bl,NULL) )
  8063.             return 0;
  8064.     break;
  8065.     case SC__STRIPACCESSORY:
  8066.         if( sd ) {
  8067.             short i = -1;
  8068.             if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) {
  8069.                 i = sd->equip_index[EQI_ACC_L];
  8070.                 if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
  8071.                     pc_unequipitem(sd,i,3); // Left-Accessory
  8072.             }
  8073.             if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) {
  8074.                 i = sd->equip_index[EQI_ACC_R];
  8075.                 if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
  8076.                     pc_unequipitem(sd,i,3); // Right-Accessory
  8077.             }
  8078.             if( i < 0 )
  8079.                 return 0;
  8080.         }
  8081.         if (tick == 1) return 1; // Minimal duration: Only strip without causing the SC
  8082.     break;
  8083.     case SC_TOXIN:
  8084.     case SC_PARALYSE:
  8085.     case SC_VENOMBLEED:
  8086.     case SC_MAGICMUSHROOM:
  8087.     case SC_DEATHHURT:
  8088.     case SC_PYREXIA:
  8089.     case SC_OBLIVIONCURSE:
  8090.     case SC_LEECHESEND:
  8091.         { // It doesn't stack or even renew
  8092.             int i = SC_TOXIN;
  8093.             for(; i<= SC_LEECHESEND; i++)
  8094.                 if(sc->data[i]) return 0;
  8095.         }
  8096.     break;
  8097.     case SC_SATURDAYNIGHTFEVER:
  8098.         if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION])
  8099.             return 0;
  8100.         break;
  8101.     case SC_MAGNETICFIELD: // This skill does not affect players using Hover. [Lighta]
  8102.         if(sc->data[SC_HOVERING])
  8103.             return 0;
  8104.         break;
  8105.     case SC_HEAT_BARREL:
  8106.         //kRO Update 2014-02-12
  8107.         //- Cannot be stacked with Platinum Alter and Madness Canceler (and otherwise?) [Cydh]
  8108.         if (sc->data[SC_P_ALTER] || sc->data[SC_MADNESSCANCEL])
  8109.             return 0;
  8110.         break;
  8111.     case SC_P_ALTER:
  8112.         if (sc->data[SC_HEAT_BARREL] || sc->data[SC_MADNESSCANCEL])
  8113.             return 0;
  8114.         break;
  8115.     case SC_MADNESSCANCEL:
  8116.         if (sc->data[SC_P_ALTER] || sc->data[SC_HEAT_BARREL])
  8117.             return 0;
  8118.         break;
  8119.     case SC_KINGS_GRACE:
  8120.         if (sc->data[SC_DEVOTION] || sc->data[SC_WHITEIMPRISON])
  8121.             return 0;
  8122.         break;
  8123.  
  8124.     case SC_WEDDING:
  8125.     case SC_XMAS:
  8126.     case SC_SUMMER:
  8127.     case SC_HANBOK:
  8128.     case SC_OKTOBERFEST:
  8129.         if (!vd)
  8130.             return 0;
  8131.         break;
  8132.     }
  8133.  
  8134.     // Check for BOSS resistances
  8135.     if(status->mode&MD_BOSS && !(flag&SCSTART_NOAVOID)) {
  8136.         if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
  8137.             return 0;
  8138.         switch (type) {
  8139.             case SC_BLESSING:
  8140.             case SC_DECREASEAGI:
  8141.             case SC_PROVOKE:
  8142.             case SC_COMA:
  8143.             case SC_GRAVITATION:
  8144.             case SC_SUITON:
  8145.             case SC_RICHMANKIM:
  8146.             case SC_ROKISWEIL:
  8147.             case SC_FOGWALL:
  8148.             case SC_FREEZING:
  8149.             case SC_BURNING:
  8150.             case SC_MARSHOFABYSS:
  8151.             case SC_ADORAMUS:
  8152.             case SC_PARALYSIS:
  8153.             case SC_DEEPSLEEP:
  8154.             case SC_CRYSTALIZE:
  8155.             case SC__ENERVATION:
  8156.             case SC__GROOMY:
  8157.             case SC__IGNORANCE:
  8158.             case SC__LAZINESS:
  8159.             case SC__UNLUCKY:
  8160.             case SC__WEAKNESS:
  8161.             case SC_TEARGAS:
  8162.             case SC_TEARGAS_SOB:
  8163.             case SC_PYREXIA:
  8164.             case SC_DEATHHURT:
  8165.             case SC_TOXIN:
  8166.             case SC_PARALYSE:
  8167.             case SC_VENOMBLEED:
  8168.             case SC_MAGICMUSHROOM:
  8169.             case SC_OBLIVIONCURSE:
  8170.             case SC_LEECHESEND:
  8171.             case SC_BITE:
  8172.             case SC_ELECTRICSHOCKER:
  8173.             case SC_MAGNETICFIELD:
  8174.             case SC_NETHERWORLD:
  8175.             case SC_VACUUM_EXTREME:
  8176.                 return 0;
  8177.         }
  8178.     }
  8179.     // Check for mvp resistance // atm only those who OS
  8180.     if(status->mode&MD_MVP && !(flag&SCSTART_NOAVOID)) {
  8181.          switch (type) {
  8182.          case SC_COMA:
  8183.         // continue list...
  8184.              return 0;
  8185.         }
  8186.     }
  8187.  
  8188.     // Before overlapping fail, one must check for status cured.
  8189.     switch (type) {
  8190.     case SC_BLESSING:
  8191.         // !TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
  8192.         // !but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
  8193.         if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
  8194.             status_change_end(bl, SC_CURSE, INVALID_TIMER);
  8195.             if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
  8196.                 status_change_end(bl, SC_STONE, INVALID_TIMER);
  8197.         }
  8198.         if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  8199.             status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
  8200.         break;
  8201.     case SC_INCREASEAGI:
  8202.         status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
  8203.         status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
  8204.         if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH)
  8205.             status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
  8206.         break;
  8207.     case SC_QUAGMIRE:
  8208.         status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
  8209.         status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
  8210.         status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
  8211.         status_change_end(bl, SC_MAGNETICFIELD, INVALID_TIMER);
  8212.         // Also blocks the ones below...
  8213.     case SC_DECREASEAGI:
  8214.     case SC_ADORAMUS:
  8215.         status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
  8216.         status_change_end(bl, SC_GN_CARTBOOST, INVALID_TIMER);
  8217.         // Also blocks the ones below...
  8218.     case SC_DONTFORGETME:
  8219.         status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
  8220.         status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
  8221.         status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
  8222.         status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
  8223.         status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
  8224.         status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
  8225.         status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
  8226.         status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
  8227.         break;
  8228.     case SC_ONEHAND:
  8229.         // Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
  8230.         status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
  8231.         status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
  8232.         status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
  8233.         status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
  8234.         break;
  8235.     case SC_MAXOVERTHRUST:
  8236.         // Cancels Normal Overthrust. [Skotlex]
  8237.         status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
  8238.         break;
  8239.     case SC_MAGNIFICAT:
  8240.         status_change_end(bl,SC_OFFERTORIUM,INVALID_TIMER);
  8241.         break;
  8242.     case SC_OFFERTORIUM:
  8243.         status_change_end(bl,SC_MAGNIFICAT,INVALID_TIMER);
  8244.         break;
  8245.     case SC_KYRIE:
  8246.         // Cancels Assumptio
  8247.         status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
  8248.         break;
  8249.     case SC_DELUGE:
  8250.         if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
  8251.             status_change_end(bl, SC_BLIND, INVALID_TIMER);
  8252.         break;
  8253.     case SC_SILENCE:
  8254.         if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
  8255.             status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
  8256.         break;
  8257.     case SC_HIDING:
  8258.         status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
  8259.         status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
  8260.         break;
  8261.     case SC_BERSERK:
  8262.         if( val3 == SC__BLOODYLUST )
  8263.             break;
  8264.         if(battle_config.berserk_cancels_buffs) {
  8265.             status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
  8266.             status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
  8267.             status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
  8268.             status_change_end(bl, SC_PARRYING, INVALID_TIMER);
  8269.             status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
  8270.             status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
  8271.         }
  8272. #ifdef RENEWAL
  8273.         else {
  8274.             status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
  8275.         }
  8276. #endif
  8277.         break;
  8278.     case SC_ASSUMPTIO:
  8279.         status_change_end(bl, SC_KYRIE, INVALID_TIMER);
  8280.         status_change_end(bl, SC_KAITE, INVALID_TIMER);
  8281.         break;
  8282.     case SC_KAITE:
  8283.         status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
  8284.         break;
  8285.     case SC_GN_CARTBOOST:
  8286.     case SC_CARTBOOST:
  8287.         if(sc->data[SC_DECREASEAGI] || sc->data[SC_ADORAMUS]) { // Cancel Decrease Agi, but take no further effect [Skotlex]
  8288.             status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
  8289.             status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
  8290.             return 0;
  8291.         }
  8292.         //Cart Boost cannot be affected by Slow grace. Assumed if player got Slow Grace first, Cart Boost is failed
  8293.         //since Cart Boost don't cancel Slow Grace effect
  8294.         //http://irowiki.org/wiki/Cart_Boost_%28Genetic%29 (view date: 2014-01-26)
  8295.         //http://irowiki.org/wiki/Cart_Boost (view date: 2014-01-26)
  8296.         if(sc->data[SC_DONTFORGETME])
  8297.             return 0;
  8298.         break;
  8299.     case SC_FUSION:
  8300.         status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
  8301.         break;
  8302.     case SC_ADJUSTMENT:
  8303.         status_change_end(bl, SC_MADNESSCANCEL, INVALID_TIMER);
  8304.         break;
  8305.     case SC_MADNESSCANCEL:
  8306.         status_change_end(bl, SC_ADJUSTMENT, INVALID_TIMER);
  8307.         break;
  8308.     // NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
  8309.     case SC_CHANGEUNDEAD:
  8310.         status_change_end(bl, SC_BLESSING, INVALID_TIMER);
  8311.         status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
  8312.         break;
  8313.     case SC_STRFOOD:
  8314.         status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
  8315.         break;
  8316.     case SC_AGIFOOD:
  8317.         status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
  8318.         break;
  8319.     case SC_VITFOOD:
  8320.         status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
  8321.         break;
  8322.     case SC_INTFOOD:
  8323.         status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
  8324.         break;
  8325.     case SC_DEXFOOD:
  8326.         status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
  8327.         break;
  8328.     case SC_LUKFOOD:
  8329.         status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
  8330.         break;
  8331.     case SC_FOOD_STR_CASH:
  8332.         status_change_end(bl, SC_STRFOOD, INVALID_TIMER);
  8333.         break;
  8334.     case SC_FOOD_AGI_CASH:
  8335.         status_change_end(bl, SC_AGIFOOD, INVALID_TIMER);
  8336.         break;
  8337.     case SC_FOOD_VIT_CASH:
  8338.         status_change_end(bl, SC_VITFOOD, INVALID_TIMER);
  8339.         break;
  8340.     case SC_FOOD_INT_CASH:
  8341.         status_change_end(bl, SC_INTFOOD, INVALID_TIMER);
  8342.         break;
  8343.     case SC_FOOD_DEX_CASH:
  8344.         status_change_end(bl, SC_DEXFOOD, INVALID_TIMER);
  8345.         break;
  8346.     case SC_FOOD_LUK_CASH:
  8347.         status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
  8348.         break;
  8349.     case SC_FIGHTINGSPIRIT:
  8350.     case SC_OVERED_BOOST:
  8351.         status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
  8352.         break;
  8353.     case SC_MARSHOFABYSS:
  8354.         status_change_end(bl, SC_INCAGI, INVALID_TIMER);
  8355.         status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
  8356.         status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
  8357.         status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
  8358.         status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
  8359.         status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
  8360.         break;
  8361.     case SC_SWINGDANCE:
  8362.     case SC_SYMPHONYOFLOVER:
  8363.     case SC_MOONLITSERENADE:
  8364.     case SC_RUSHWINDMILL:
  8365.     case SC_ECHOSONG:
  8366.     case SC_HARMONIZE:
  8367.     case SC_FRIGG_SONG: // Group A doesn't overlap
  8368.         if (type != SC_SWINGDANCE) status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
  8369.         if (type != SC_SYMPHONYOFLOVER) status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
  8370.         if (type != SC_MOONLITSERENADE) status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
  8371.         if (type != SC_RUSHWINDMILL) status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
  8372.         if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
  8373.         if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
  8374.         if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
  8375.         break;
  8376.     case SC_VOICEOFSIREN:
  8377.     case SC_DEEPSLEEP:
  8378.     case SC_GLOOMYDAY:
  8379.     case SC_SONGOFMANA:
  8380.     case SC_DANCEWITHWUG:
  8381.     case SC_SATURDAYNIGHTFEVER:
  8382.     case SC_LERADSDEW:
  8383.     case SC_MELODYOFSINK:
  8384.     case SC_BEYONDOFWARCRY:
  8385.     case SC_UNLIMITEDHUMMINGVOICE:
  8386.     case SC_SIRCLEOFNATURE: // Group B
  8387.         if (type != SC_VOICEOFSIREN) status_change_end(bl, SC_VOICEOFSIREN, INVALID_TIMER);
  8388.         if (type != SC_DEEPSLEEP) status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER);
  8389.         if (type != SC_LERADSDEW) status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
  8390.         if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
  8391.         if (type != SC_BEYONDOFWARCRY) status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
  8392.         if (type != SC_UNLIMITEDHUMMINGVOICE) status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
  8393.         if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
  8394.         if (type != SC_GLOOMYDAY) {
  8395.             status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
  8396.             status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
  8397.         }
  8398.         if (type != SC_SONGOFMANA) status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
  8399.         if (type != SC_DANCEWITHWUG) status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
  8400.         if (type != SC_SATURDAYNIGHTFEVER) {
  8401.             if (sc->data[SC_SATURDAYNIGHTFEVER]) {
  8402.                 sc->data[SC_SATURDAYNIGHTFEVER]->val2 = 0; // Mark to not lose hp
  8403.                 status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
  8404.             }
  8405.         }
  8406.         break;
  8407.     case SC_REFLECTSHIELD:
  8408.         status_change_end(bl, SC_REFLECTDAMAGE, INVALID_TIMER);
  8409.         break;
  8410.     case SC_REFLECTDAMAGE:
  8411.         status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
  8412.         break;
  8413.     case SC_SHIELDSPELL_DEF:
  8414.     case SC_SHIELDSPELL_MDEF:
  8415.     case SC_SHIELDSPELL_REF:
  8416.         status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
  8417.         if( type != SC_SHIELDSPELL_DEF )
  8418.             status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
  8419.         if( type != SC_SHIELDSPELL_MDEF )
  8420.             status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
  8421.         if( type != SC_SHIELDSPELL_REF )
  8422.             status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
  8423.         break;
  8424.     case SC_GT_ENERGYGAIN:
  8425.     case SC_GT_CHANGE:
  8426.     case SC_GT_REVITALIZE:
  8427.         if( type != SC_GT_REVITALIZE )
  8428.             status_change_end(bl, SC_GT_REVITALIZE, INVALID_TIMER);
  8429.         if( type != SC_GT_ENERGYGAIN )
  8430.             status_change_end(bl, SC_GT_ENERGYGAIN, INVALID_TIMER);
  8431.         if( type != SC_GT_CHANGE )
  8432.             status_change_end(bl, SC_GT_CHANGE, INVALID_TIMER);
  8433.         break;
  8434.     case SC_WARMER:
  8435.         status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
  8436.         status_change_end(bl, SC_FREEZING, INVALID_TIMER);
  8437.         status_change_end(bl, SC_FREEZE, INVALID_TIMER);
  8438.         break;
  8439.     case SC_INVINCIBLE:
  8440.         status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
  8441.         break;
  8442.     case SC_INVINCIBLEOFF:
  8443.         status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
  8444.         break;
  8445.     case SC_MAGICPOWER:
  8446.         status_change_end(bl, type, INVALID_TIMER);
  8447.         break;
  8448.     case SC_WHITEIMPRISON:
  8449.         status_change_end(bl, SC_BURNING, INVALID_TIMER);
  8450.         status_change_end(bl, SC_FREEZING, INVALID_TIMER);
  8451.         status_change_end(bl, SC_FREEZE, INVALID_TIMER);
  8452.         status_change_end(bl, SC_STONE, INVALID_TIMER);
  8453.         break;
  8454.     case SC_FREEZING:
  8455.         status_change_end(bl, SC_BURNING, INVALID_TIMER);
  8456.         break;
  8457.     case SC_KINGS_GRACE:
  8458.         status_change_end(bl,SC_POISON,INVALID_TIMER);
  8459.         status_change_end(bl,SC_BLIND,INVALID_TIMER);
  8460.         status_change_end(bl,SC_FREEZE,INVALID_TIMER);
  8461.         status_change_end(bl,SC_STONE,INVALID_TIMER);
  8462.         status_change_end(bl,SC_STUN,INVALID_TIMER);
  8463.         status_change_end(bl,SC_SLEEP,INVALID_TIMER);
  8464.         status_change_end(bl,SC_BLEEDING,INVALID_TIMER);
  8465.         status_change_end(bl,SC_CURSE,INVALID_TIMER);
  8466.         status_change_end(bl,SC_CONFUSION,INVALID_TIMER);
  8467.         status_change_end(bl,SC_HALLUCINATION,INVALID_TIMER);
  8468.         status_change_end(bl,SC_SILENCE,INVALID_TIMER);
  8469.         status_change_end(bl,SC_BURNING,INVALID_TIMER);
  8470.         status_change_end(bl,SC_CRYSTALIZE,INVALID_TIMER);
  8471.         status_change_end(bl,SC_FREEZING,INVALID_TIMER);
  8472.         status_change_end(bl,SC_DEEPSLEEP,INVALID_TIMER);
  8473.         status_change_end(bl,SC_FEAR,INVALID_TIMER);
  8474.         status_change_end(bl,SC_MANDRAGORA,INVALID_TIMER);
  8475.         break;
  8476.     case SC_2011RWC_SCROLL:
  8477.         status_change_end(bl,SC_FOOD_STR_CASH,INVALID_TIMER);
  8478.         status_change_end(bl,SC_FOOD_AGI_CASH,INVALID_TIMER);
  8479.         status_change_end(bl,SC_FOOD_VIT_CASH,INVALID_TIMER);
  8480.         status_change_end(bl,SC_FOOD_INT_CASH,INVALID_TIMER);
  8481.         status_change_end(bl,SC_FOOD_DEX_CASH,INVALID_TIMER);
  8482.         status_change_end(bl,SC_FOOD_LUK_CASH,INVALID_TIMER);
  8483.         break;
  8484.     case SC_EQC:
  8485.         status_change_end(bl,SC_TINDER_BREAKER2,INVALID_TIMER);
  8486.         break;
  8487.     }
  8488.  
  8489.     // Check for overlapping fails
  8490.     if( (sce = sc->data[type]) ) {
  8491.         switch( type ) {
  8492.             case SC_MERC_FLEEUP:
  8493.             case SC_MERC_ATKUP:
  8494.             case SC_MERC_HPUP:
  8495.             case SC_MERC_SPUP:
  8496.             case SC_MERC_HITUP:
  8497.                 if( sce->val1 > val1 )
  8498.                     val1 = sce->val1;
  8499.                 break;
  8500.             case SC_ADRENALINE:
  8501.             case SC_ADRENALINE2:
  8502.             case SC_WEAPONPERFECTION:
  8503.             case SC_OVERTHRUST:
  8504.                 if (sce->val2 > val2)
  8505.                     return 0;
  8506.                 break;
  8507.             case SC_S_LIFEPOTION:
  8508.             case SC_L_LIFEPOTION:
  8509.             case SC_BOSSMAPINFO:
  8510.             case SC_STUN:
  8511.             case SC_SLEEP:
  8512.             case SC_POISON:
  8513.             case SC_CURSE:
  8514.             case SC_SILENCE:
  8515.             case SC_CONFUSION:
  8516.             case SC_BLIND:
  8517.             case SC_BLEEDING:
  8518.             case SC_DPOISON:
  8519.             case SC_CLOSECONFINE2: // Can't be re-closed in.
  8520.             case SC_TINDER_BREAKER2:
  8521.             case SC_MARIONETTE:
  8522.             case SC_MARIONETTE2:
  8523.             case SC_NOCHAT:
  8524.             case SC_ABUNDANCE:
  8525.             case SC_FEAR:
  8526.             case SC_TOXIN:
  8527.             case SC_PARALYSE:
  8528.             case SC_VENOMBLEED:
  8529.             case SC_MAGICMUSHROOM:
  8530.             case SC_DEATHHURT:
  8531.             case SC_PYREXIA:
  8532.             case SC_OBLIVIONCURSE:
  8533.             case SC_LEECHESEND:
  8534.             case SC__INVISIBILITY:
  8535.             case SC__ENERVATION:
  8536.             case SC__GROOMY:
  8537.             case SC__IGNORANCE:
  8538.             case SC__LAZINESS:
  8539.             case SC__WEAKNESS:
  8540.             case SC__UNLUCKY:
  8541.             //case SC__CHAOS:
  8542.                 return 0;
  8543.             case SC_COMBO:
  8544.             case SC_DANCING:
  8545.             case SC_DEVOTION:
  8546.             case SC_ASPDPOTION0:
  8547.             case SC_ASPDPOTION1:
  8548.             case SC_ASPDPOTION2:
  8549.             case SC_ASPDPOTION3:
  8550.             case SC_ATKPOTION:
  8551.             case SC_MATKPOTION:
  8552.             case SC_ENCHANTARMS:
  8553.             case SC_ARMOR_ELEMENT:
  8554.             case SC_ARMOR_RESIST:
  8555.                 break;
  8556.             case SC_GOSPEL:
  8557.                  // Must not override a casting gospel char.
  8558.                 if(sce->val4 == BCT_SELF)
  8559.                     return 0;
  8560.                 if(sce->val1 > val1)
  8561.                     return 1;
  8562.                 break;
  8563.             case SC_ENDURE:
  8564.                 if(sce->val4 && !val4)
  8565.                     return 1; // Don't let you override infinite endure.
  8566.                 if(sce->val1 > val1)
  8567.                     return 1;
  8568.                 break;
  8569.             case SC_JAILED:
  8570.                 // When a player is already jailed, do not edit the jail data.
  8571.                 val2 = sce->val2;
  8572.                 val3 = sce->val3;
  8573.                 val4 = sce->val4;
  8574.                 break;
  8575.             case SC_LERADSDEW:
  8576.                 if (sc && sc->data[SC_BERSERK])
  8577.                     return 0;
  8578.             case SC_SHAPESHIFT:
  8579.             case SC_PROPERTYWALK:
  8580.                 break;
  8581.             case SC_LEADERSHIP:
  8582.             case SC_GLORYWOUNDS:
  8583.             case SC_SOULCOLD:
  8584.             case SC_HAWKEYES:
  8585.                 if( sce->val4 && !val4 ) // You cannot override master guild aura
  8586.                     return 0;
  8587.                 break;
  8588.             case SC_JOINTBEAT:
  8589.                 val2 |= sce->val2; // Stackable ailments
  8590.             default:
  8591.                 if(sce->val1 > val1)
  8592.                     return 1; // Return true to not mess up skill animations. [Skotlex]
  8593.         }
  8594.     }
  8595.  
  8596.     calc_flag = StatusChangeFlagTable[type];
  8597.     if(!(flag&SCSTART_LOADED)) // &4 - Do not parse val settings when loading SCs
  8598.     switch(type)
  8599.     {
  8600.         /* Permanent effects */
  8601.         case SC_AETERNA:
  8602.         case SC_MODECHANGE:
  8603.         case SC_WEIGHT50:
  8604.         case SC_WEIGHT90:
  8605.         case SC_BROKENWEAPON:
  8606.         case SC_BROKENARMOR:
  8607.         case SC_READYSTORM:
  8608.         case SC_READYDOWN:
  8609.         case SC_READYCOUNTER:
  8610.         case SC_READYTURN:
  8611.         case SC_DODGE:
  8612.         case SC_PUSH_CART:
  8613.             tick = -1;
  8614.             break;
  8615.  
  8616.         case SC_DECREASEAGI:
  8617.         case SC_INCREASEAGI:
  8618.         case SC_ADORAMUS:
  8619.             val2 = 2 + val1; // Agi change
  8620.             if( type == SC_ADORAMUS )
  8621.                 sc_start(src,bl,SC_BLIND,val1 * 4 + (sd ? sd->status.job_level : 50) / 2,val1,skill_get_time(status_sc2skill(type),val1));
  8622.             break;
  8623.         case SC_ENDURE:
  8624.             val2 = 7; // Hit-count [Celest]
  8625.             if( !(flag&SCSTART_NOAVOID) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && !val4 ) {
  8626.                 struct map_session_data *tsd;
  8627.                 if( sd ) {
  8628.                     int i;
  8629.                     for( i = 0; i < MAX_DEVOTION; i++ ) {
  8630.                         if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
  8631.                             status_change_start(src,&tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCSTART_NOAVOID|SCSTART_NOICON);
  8632.                     }
  8633.                 }
  8634.                 else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
  8635.                     status_change_start(src,&tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCSTART_NOAVOID|SCSTART_NOICON);
  8636.             }
  8637.             // val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
  8638.             if( val4 )
  8639.                 tick = -1;
  8640.             break;
  8641.         case SC_AUTOBERSERK:
  8642.             if (status->hp < status->max_hp>>2 &&
  8643.                 (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
  8644.                     sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000);
  8645.             tick = -1;
  8646.             break;
  8647.         case SC_SIGNUMCRUCIS:
  8648.             val2 = 10 + 4*val1; // Def reduction
  8649.             tick = -1;
  8650.             clif_emotion(bl,E_SWT);
  8651.             break;
  8652.         case SC_MAXIMIZEPOWER:
  8653.             tick_time = val2 = tick>0?tick:60000;
  8654.             tick = -1; // Duration sent to the client should be infinite
  8655.             break;
  8656.         case SC_EDP:
  8657.             val2 = val1 + 2; // Chance to Poison enemies.
  8658. #ifndef RENEWAL
  8659.             val3 = 50*(val1+1); // Damage increase (+50 +50*lv%)
  8660. #endif
  8661.             if( sd )// [Ind] - iROwiki says each level increases its duration by 3 seconds
  8662.                 tick += pc_checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
  8663.             break;
  8664.         case SC_POISONREACT:
  8665.             val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
  8666.             val3=50; // + 5*val1; // Chance to counter. [Skotlex]
  8667.             break;
  8668.         case SC_MAGICROD:
  8669.             val2 = val1*20; // SP gained
  8670.             break;
  8671.         case SC_KYRIE:
  8672.             if( val4 ) { // Formulas for Praefatio
  8673.                 val2 = (status->max_hp * (val1 * 2 + 10) / 100) + val4 * 2; //%Max HP to absorb
  8674.                 val3 = 6 + val1; //Hits
  8675.             } else { // Formulas for Kyrie Eleison
  8676.                 val2 = status->max_hp * (val1 * 2 + 10) / 100;
  8677.                 val3 = (val1 / 2 + 5);
  8678.             }
  8679.             break;
  8680.         case SC_MAGICPOWER:
  8681.             // val1: Skill lv
  8682.             val2 = 1; // Lasts 1 invocation
  8683.             val3 = 5*val1; // Matk% increase
  8684.             val4 = 0; // 0 = ready to be used, 1 = activated and running
  8685.             break;
  8686.         case SC_SACRIFICE:
  8687.             val2 = 5; // Lasts 5 hits
  8688.             tick = -1;
  8689.             break;
  8690.         case SC_ENCPOISON:
  8691.             val2= 250+50*val1; // Poisoning Chance (2.5+0.5%) in 1/10000 rate
  8692.         case SC_ASPERSIO:
  8693.         case SC_FIREWEAPON:
  8694.         case SC_WATERWEAPON:
  8695.         case SC_WINDWEAPON:
  8696.         case SC_EARTHWEAPON:
  8697.         case SC_SHADOWWEAPON:
  8698.         case SC_GHOSTWEAPON:
  8699.             skill_enchant_elemental_end(bl,type);
  8700.             break;
  8701.         case SC_ELEMENTALCHANGE:
  8702.             // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
  8703.             // val2 : Element (When no element, random one is picked)
  8704.             // val3 : 0 = called by skill 1 = called by script (fixed level)
  8705.             if( !val2 ) val2 = rnd()%ELE_ALL;
  8706.  
  8707.             if( val1 == 1 && val3 == 0 )
  8708.                 val1 = 1 + rnd()%4;
  8709.             else if( val1 > 4 )
  8710.                 val1 = 4; // Max Level
  8711.             val3 = 0; // Not need to keep this info.
  8712.             break;
  8713.         case SC_PROVIDENCE:
  8714.             val2 = val1*5; // Race/Ele resist
  8715.             break;
  8716.         case SC_REFLECTSHIELD:
  8717.             val2 = 10+val1*3; // %Dmg reflected
  8718.             // val4 used to mark if reflect shield is an inheritance bonus from Devotion
  8719.             if( !(flag&SCSTART_NOAVOID) && (bl->type&(BL_PC|BL_MER)) ) {
  8720.                 struct map_session_data *tsd;
  8721.                 if( sd ) {
  8722.                     int i;
  8723.                     for( i = 0; i < MAX_DEVOTION; i++ ) {
  8724.                         if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
  8725.                             status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 1, tick, SCSTART_NOAVOID|SCSTART_NOICON);
  8726.                     }
  8727.                 }
  8728.                 else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
  8729.                     status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 1, tick, SCSTART_NOAVOID|SCSTART_NOICON);
  8730.             }
  8731.             break;
  8732.         case SC_STRIPWEAPON:
  8733.             if (!sd) // Watk reduction
  8734.                 val2 = 25;
  8735.             break;
  8736.         case SC_STRIPSHIELD:
  8737.             if (!sd) // Def reduction
  8738.                 val2 = 15;
  8739.             break;
  8740.         case SC_STRIPARMOR:
  8741.             if (!sd) // Vit reduction
  8742.                 val2 = 40;
  8743.             break;
  8744.         case SC_STRIPHELM:
  8745.             if (!sd) // Int reduction
  8746.                 val2 = 40;
  8747.             break;
  8748.         case SC_AUTOSPELL:
  8749.             // Val1 Skill LV of Autospell
  8750.             // Val2 Skill ID to cast
  8751.             // Val3 Max Lv to cast
  8752.             val4 = 5 + val1*2; // Chance of casting
  8753.             break;
  8754.         case SC_VOLCANO:
  8755.             {
  8756.                 int8 enchant_eff[] = { 10, 14, 17, 19, 20 }; // Enchant addition
  8757.                 uint8 i = max((val1-1)%5, 0);
  8758.  
  8759.                 val2 = val1*10; // Watk increase
  8760. #ifndef RENEWAL
  8761.                 if (status->def_ele != ELE_FIRE)
  8762.                     val2 = 0;
  8763. #endif
  8764.                 val3 = enchant_eff[i];
  8765.             }
  8766.             break;
  8767.         case SC_VIOLENTGALE:
  8768.             {
  8769.                 int8 enchant_eff[] = { 10, 14, 17, 19, 20 }; // Enchant addition
  8770.                 uint8 i = max((val1-1)%5, 0);
  8771.  
  8772.                 val2 = val1*3; // Flee increase
  8773. #ifndef RENEWAL
  8774.                 if (status->def_ele != ELE_WIND)
  8775.                     val2 = 0;
  8776. #endif
  8777.                 val3 = enchant_eff[i];
  8778.             }
  8779.             break;
  8780.         case SC_DELUGE:
  8781.             {
  8782.                 int8 deluge_eff[]  = {  5,  9, 12, 14, 15 }; // HP addition rate n/100
  8783.                 int8 enchant_eff[] = { 10, 14, 17, 19, 20 }; // Enchant addition
  8784.                 uint8 i = max((val1-1)%5, 0);
  8785.  
  8786.                 val2 = deluge_eff[i]; // HP increase
  8787. #ifndef RENEWAL
  8788.                 if (status->def_ele != ELE_WATER)
  8789.                     val2 = 0;
  8790. #endif
  8791.                 val3 = enchant_eff[i];
  8792.             }
  8793.             break;
  8794.         case SC_SUITON:
  8795.             if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) {
  8796.                 // No penalties.
  8797.                 val2 = 0; // Agi penalty
  8798.                 val3 = 0; // Walk speed penalty
  8799.                 break;
  8800.             }
  8801.             val3 = 50;
  8802.             val2 = 3*((val1+1)/3);
  8803.             if (val1 > 4) val2--;
  8804.             break;
  8805.         case SC_ONEHAND:
  8806.         case SC_TWOHANDQUICKEN:
  8807.             val2 = 300;
  8808.             if (val1 > 10) // For boss casted skills [Skotlex]
  8809.                 val2 += 20*(val1-10);
  8810.             break;
  8811.         case SC_MERC_QUICKEN:
  8812.             val2 = 300;
  8813.             break;
  8814. #ifndef RENEWAL_ASPD
  8815.         case SC_SPEARQUICKEN:
  8816.             val2 = 200+10*val1;
  8817.             break;
  8818. #endif
  8819.         case SC_DANCING:
  8820.             // val1 : Skill ID + LV
  8821.             // val2 : Skill Group of the Dance.
  8822.             // val3 : Brings the skill_lv (merged into val1 here)
  8823.             // val4 : Partner
  8824.             if (val1 == CG_MOONLIT)
  8825.                 clif_status_change(bl,SI_MOONLIT,1,tick,0, 0, 0);
  8826.             val1|= (val3<<16);
  8827.             val3 = tick/1000; // Tick duration
  8828.             tick_time = 1000; // [GodLesZ] tick time
  8829.             break;
  8830.         case SC_LONGING:
  8831.             val2 = 500-100*val1; // Aspd penalty.
  8832.             break;
  8833.         case SC_EXPLOSIONSPIRITS:
  8834.             val2 = 75 + 25*val1; // Cri bonus
  8835.             break;
  8836.  
  8837.         case SC_ASPDPOTION0:
  8838.         case SC_ASPDPOTION1:
  8839.         case SC_ASPDPOTION2:
  8840.         case SC_ASPDPOTION3:
  8841.             val2 = 50*(2+type-SC_ASPDPOTION0);
  8842.             break;
  8843.  
  8844.         case SC_NOCHAT:
  8845.             // A hardcoded interval of 60 seconds is expected, as the time that SC_NOCHAT uses is defined by
  8846.             // mmocharstatus.manner, each negative point results in 1 minute with this status activated.
  8847.             // This is done this way because the message that the client displays is hardcoded, and only
  8848.             // shows how many minutes are remaining. [Panikon]
  8849.             tick = 60000;
  8850.             val1 = battle_config.manner_system; // Mute filters.
  8851.             if (sd) {
  8852.                 clif_changestatus(sd,SP_MANNER,sd->status.manner);
  8853.                 clif_updatestatus(sd,SP_MANNER);
  8854.             }
  8855.             break;
  8856.  
  8857.         case SC_STONE:
  8858.             val3 = tick/1000; // Petrified HP-damage iterations.
  8859.             if(val3 < 1) val3 = 1;
  8860.             tick = val4; // Petrifying time.
  8861.             tick = max(tick, 1000); // Min time
  8862.             calc_flag = 0; // Actual status changes take effect on petrified state.
  8863.             break;
  8864.  
  8865.         case SC_DPOISON:
  8866.             // Lose 10/15% of your life as long as it doesn't brings life below 25%
  8867.             if (status->hp > status->max_hp>>2) {
  8868.                 int diff = status->max_hp*(bl->type==BL_PC?10:15)/100;
  8869.                 if (status->hp - diff < status->max_hp>>2)
  8870.                     diff = status->hp - (status->max_hp>>2);
  8871.                 if( val2 && bl->type == BL_MOB ) {
  8872.                     struct block_list* src2 = map_id2bl(val2);
  8873.                     if( src2 )
  8874.                         mob_log_damage((TBL_MOB*)bl,src2,diff);
  8875.                 }
  8876.                 status_zap(bl, diff, 0);
  8877.             }
  8878.         case SC_POISON:
  8879.             // Fall through
  8880.             val3 = tick/1000; // Damage iterations
  8881.             if(val3 < 1) val3 = 1;
  8882.             tick_time = 1000; // [GodLesZ] tick time
  8883.             // val4: HP damage
  8884.             if (bl->type == BL_PC)
  8885.                 val4 = (type == SC_DPOISON) ? 2 + status->max_hp/50 : 2 + status->max_hp*3/200;
  8886.             else
  8887.                 val4 = (type == SC_DPOISON) ? 2 + status->max_hp/100 : 2 + status->max_hp/200;
  8888.             break;
  8889.  
  8890.         case SC_CONFUSION:
  8891.             if (!val4)
  8892.                 clif_emotion(bl,E_WHAT);
  8893.             break;
  8894.         case SC_BLEEDING:
  8895.             val4 = tick/10000;
  8896.             if (!val4) val4 = 1;
  8897.             tick_time = 10000; // [GodLesZ] tick time
  8898.             break;
  8899.         case SC_S_LIFEPOTION:
  8900.         case SC_L_LIFEPOTION:
  8901.             if( val1 == 0 ) return 0;
  8902.             // val1 = heal percent/amout
  8903.             // val2 = seconds between heals
  8904.             // val4 = total of heals
  8905.             if( val2 < 1 ) val2 = 1;
  8906.             if( (val4 = tick/(val2 * 1000)) < 1 )
  8907.                 val4 = 1;
  8908.             tick_time = val2 * 1000; // [GodLesZ] tick time
  8909.             break;
  8910.         case SC_BOSSMAPINFO:
  8911.             if( sd != NULL ) {
  8912.                 struct mob_data *boss_md = map_getmob_boss(bl->m); // Search for Boss on this Map
  8913.                 if( boss_md == NULL || boss_md->bl.prev == NULL ) { // No MVP on this map - MVP is dead
  8914.                     clif_bossmapinfo(sd->fd, boss_md, 1);
  8915.                     return 0; // No need to start SC
  8916.                 }
  8917.                 val1 = boss_md->bl.id;
  8918.                 if( (val4 = tick/1000) < 1 )
  8919.                     val4 = 1;
  8920.                 tick_time = 1000; // [GodLesZ] tick time
  8921.             }
  8922.             break;
  8923.         case SC_HIDING:
  8924.             val2 = tick/1000;
  8925.             tick_time = 1000; // [GodLesZ] tick time
  8926.             val3 = 0; // Unused, previously speed adjustment
  8927.             val4 = val1+3; // Seconds before SP substraction happen.
  8928.             break;
  8929.         case SC_CHASEWALK:
  8930.             val2 = tick>0?tick:10000; // Interval at which SP is drained.
  8931.             val3 = 35 - 5 * val1; // Speed adjustment.
  8932.             if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE)
  8933.                 val3 -= 40;
  8934.             val4 = 10+val1*2; // SP cost.
  8935.             if (map_flag_gvg(bl->m) || map[bl->m].flag.battleground) val4 *= 5;
  8936.             break;
  8937.         case SC_CLOAKING:
  8938.             if (!sd) // Monsters should be able to walk with no penalties. [Skotlex]
  8939.                 val1 = 10;
  8940.             tick_time = val2 = tick>0?tick:60000; // SP consumption rate.
  8941.             tick = -1; // Duration sent to the client should be infinite
  8942.             val3 = 0; // Unused, previously walk speed adjustment
  8943.             // val4&1 signals the presence of a wall.
  8944.             // val4&2 makes cloak not end on normal attacks [Skotlex]
  8945.             // val4&4 makes cloak not end on using skills
  8946.             if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) )  // Standard cloaking.
  8947.                 val4 |= battle_config.pc_cloak_check_type&7;
  8948.             else
  8949.                 val4 |= battle_config.monster_cloak_check_type&7;
  8950.             break;
  8951.         case SC_SIGHT:          /* splash status */
  8952.         case SC_RUWACH:
  8953.         case SC_SIGHTBLASTER:
  8954.             val3 = skill_get_splash(val2, val1); // Val2 should bring the skill-id.
  8955.             val2 = tick/20;
  8956.             tick_time = 20; // [GodLesZ] tick time
  8957.             break;
  8958.  
  8959.         case SC_AUTOGUARD:
  8960.             if( !(flag&SCSTART_NOAVOID) ) {
  8961.                 struct map_session_data *tsd;
  8962.                 int i;
  8963.                 for( i = val2 = 0; i < val1; i++) {
  8964.                     int t = 5-(i>>1);
  8965.                     val2 += (t < 0)? 1:t;
  8966.                 }
  8967.  
  8968.                 if( bl->type&(BL_PC|BL_MER) ) {
  8969.                     if( sd ) {
  8970.                         for( i = 0; i < MAX_DEVOTION; i++ ) {
  8971.                             if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) )
  8972.                                 status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCSTART_NOAVOID|SCSTART_NOICON);
  8973.                         }
  8974.                     }
  8975.                     else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
  8976.                         status_change_start(src,&tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCSTART_NOAVOID|SCSTART_NOICON);
  8977.                 }
  8978.             }
  8979.             break;
  8980.  
  8981.         case SC_DEFENDER:
  8982.             if (!(flag&SCSTART_NOAVOID)) {
  8983.                 val2 = 5 + 15*val1; // Damage reduction
  8984.                 val3 = 0; // Unused, previously speed adjustment
  8985.                 val4 = 250 - 50*val1; // Aspd adjustment
  8986.  
  8987.                 if (sd) {
  8988.                     struct map_session_data *tsd;
  8989.                     int i;
  8990.                     for (i = 0; i < MAX_DEVOTION; i++) { // See if there are devoted characters, and pass the status to them. [Skotlex]
  8991.                         if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
  8992.                             status_change_start(src,&tsd->bl,type,10000,val1,val2,val3,val4,tick,SCSTART_NOAVOID);
  8993.                     }
  8994.                 }
  8995.             }
  8996.             break;
  8997.  
  8998.         case SC_TENSIONRELAX:
  8999.             if (sd) {
  9000.                 pc_setsit(sd);
  9001.                 skill_sit(sd, 1);
  9002.                 clif_sitting(&sd->bl);
  9003.             }
  9004.             val2 = 12; // SP cost
  9005.             tick_time = 10000; // Decrease at 10secs intervals.
  9006.             val3 = tick / tick_time;
  9007.             tick = -1; // Duration sent to the client should be infinite
  9008.             break;
  9009.         case SC_PARRYING:
  9010.             val2 = 20 + val1*3; // Block Chance
  9011.             break;
  9012.  
  9013.         case SC_WINDWALK:
  9014.             val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5
  9015.             break;
  9016.  
  9017.         case SC_JOINTBEAT:
  9018.             if( val2&BREAK_NECK )
  9019.                 sc_start2(src,bl,SC_BLEEDING,100,val1,val3,skill_get_time2(status_sc2skill(type),val1));
  9020.             break;
  9021.  
  9022.         case SC_BERSERK:
  9023.             if( val3 == SC__BLOODYLUST )
  9024.                 sc_start(src,bl,(sc_type)val3,100,val1,tick);
  9025.             if (!val3 && !(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4))
  9026.                 sc_start4(src,bl, SC_ENDURE, 100,10,0,0,2, tick);
  9027.             // HP healing is performing after the calc_status call.
  9028.             // Val2 holds HP penalty
  9029.             if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
  9030.             if (!val4) val4 = 10000; // Val4 holds damage interval
  9031.             val3 = tick/val4; // val3 holds skill duration
  9032.             tick_time = val4; // [GodLesZ] tick time
  9033.             break;
  9034.  
  9035.         case SC_GOSPEL:
  9036.             if(val4 == BCT_SELF) {  // Self effect
  9037.                 val2 = tick/10000;
  9038.                 tick_time = 10000; // [GodLesZ] tick time
  9039.                 status_change_clear_buffs(bl,3); // Remove buffs/debuffs
  9040.             }
  9041.             break;
  9042.  
  9043.         case SC_MARIONETTE:
  9044.         {
  9045.             int stat;
  9046.  
  9047.             val3 = 0;
  9048.             val4 = 0;
  9049.             stat = ( sd ? sd->status.str : status_get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16;
  9050.             stat = ( sd ? sd->status.agi : status_get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8;
  9051.             stat = ( sd ? sd->status.vit : status_get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF);
  9052.             stat = ( sd ? sd->status.int_: status_get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16;
  9053.             stat = ( sd ? sd->status.dex : status_get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8;
  9054.             stat = ( sd ? sd->status.luk : status_get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF);
  9055.             break;
  9056.         }
  9057.         case SC_MARIONETTE2:
  9058.         {
  9059.             int stat,max_stat;
  9060.             // Fetch caster information
  9061.             struct block_list *pbl = map_id2bl(val1);
  9062.             struct status_change *psc = pbl?status_get_sc(pbl):NULL;
  9063.             struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL;
  9064.             // Fetch target's stats
  9065.             struct status_data* status2 = status_get_status_data(bl); // Battle status
  9066.  
  9067.             if (!psce)
  9068.                 return 0;
  9069.  
  9070.             val3 = 0;
  9071.             val4 = 0;
  9072.             max_stat = battle_config.max_parameter; // Cap to 99 (default)
  9073.             stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - status2->str ); val3 |= cap_value(stat,0,0xFF)<<16;
  9074.             stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - status2->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
  9075.             stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - status2->vit ); val3 |= cap_value(stat,0,0xFF);
  9076.             stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - status2->int_); val4 |= cap_value(stat,0,0xFF)<<16;
  9077.             stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - status2->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
  9078.             stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - status2->luk ); val4 |= cap_value(stat,0,0xFF);
  9079.             break;
  9080.         }
  9081.         case SC_SPIRIT:
  9082.             //1st Transcendent Spirit works similar to Marionette Control
  9083.             if(sd && val2 == SL_HIGH) {
  9084.                 int stat,max_stat;
  9085.                 // Fetch target's stats
  9086.                 struct status_data* status2 = status_get_status_data(bl); // Battle status
  9087.                 val3 = 0;
  9088.                 val4 = 0;
  9089.                 max_stat = (status_get_lv(bl)-10<50)?status_get_lv(bl)-10:50;
  9090.                 stat = max(0, max_stat - status2->str ); val3 |= cap_value(stat,0,0xFF)<<16;
  9091.                 stat = max(0, max_stat - status2->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
  9092.                 stat = max(0, max_stat - status2->vit ); val3 |= cap_value(stat,0,0xFF);
  9093.                 stat = max(0, max_stat - status2->int_); val4 |= cap_value(stat,0,0xFF)<<16;
  9094.                 stat = max(0, max_stat - status2->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
  9095.                 stat = max(0, max_stat - status2->luk ); val4 |= cap_value(stat,0,0xFF);
  9096.             }
  9097.             break;
  9098.  
  9099.         case SC_REJECTSWORD:
  9100.             val2 = 15*val1; // Reflect chance
  9101.             val3 = 3; // Reflections
  9102.             tick = -1;
  9103.             break;
  9104.  
  9105.         case SC_MEMORIZE:
  9106.             val2 = 5; // Memorized casts.
  9107.             tick = -1;
  9108.             break;
  9109.  
  9110.         case SC_GRAVITATION:
  9111.             val2 = 50*val1; // aspd reduction
  9112.             break;
  9113.  
  9114.         case SC_REGENERATION:
  9115.             if (val1 == 1)
  9116.                 val2 = 2;
  9117.             else
  9118.                 val2 = val1; // HP Regerenation rate: 200% 200% 300%
  9119.             val3 = val1; // SP Regeneration Rate: 100% 200% 300%
  9120.             // If val4 comes set, this blocks regen rather than increase it.
  9121.             break;
  9122.  
  9123.         case SC_DEVOTION:
  9124.         {
  9125.             struct block_list *d_bl;
  9126.             struct status_change *d_sc;
  9127.  
  9128.             if( (d_bl = map_id2bl(val1)) && (d_sc = status_get_sc(d_bl)) && d_sc->count ) { // Inherits Status From Source
  9129.                 const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE };
  9130.                 int i = (map_flag_gvg(bl->m) || map[bl->m].flag.battleground)?2:3;
  9131.                 while( i >= 0 ) {
  9132.                     enum sc_type type2 = types[i];
  9133.                     if( d_sc->data[type2] )
  9134.                         status_change_start(d_bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, (type2 == SC_REFLECTSHIELD ? 1 : 0), skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1), (type2 == SC_DEFENDER) ? 1 : SCSTART_NOAVOID|SCSTART_NOICON);
  9135.                     i--;
  9136.                 }
  9137.             }
  9138.             break;
  9139.         }
  9140.  
  9141.         case SC_COMA: // Coma. Sends a char to 1HP. If val2, do not zap sp
  9142.             if( val3 && bl->type == BL_MOB ) {
  9143.                 struct block_list* src2 = map_id2bl(val3);
  9144.                 if( src2 )
  9145.                     mob_log_damage((TBL_MOB*)bl,src2,status->hp - 1);
  9146.             }
  9147.             status_zap(bl, status->hp-1, val2?0:status->sp);
  9148.             return 1;
  9149.             break;
  9150.         case SC_TINDER_BREAKER2:
  9151.         case SC_CLOSECONFINE2:
  9152.         {
  9153.             struct block_list *src2 = val2?map_id2bl(val2):NULL;
  9154.             struct status_change *sc2 = src2?status_get_sc(src2):NULL;
  9155.             enum sc_type type2 = ((type == SC_TINDER_BREAKER2)?SC_TINDER_BREAKER:SC_CLOSECONFINE);
  9156.             struct status_change_entry *sce2 = sc2?sc2->data[type2]:NULL;
  9157.  
  9158.             if (src2 && sc2) {
  9159.                 if (!sce2) // Start lock on caster.
  9160.                     sc_start4(src2,src2,type2,100,val1,1,0,0,tick+1000);
  9161.                 else { // Increase count of locked enemies and refresh time.
  9162.                     (sce2->val2)++;
  9163.                     delete_timer(sce2->timer, status_change_timer);
  9164.                     sce2->timer = add_timer(gettick()+tick+1000, status_change_timer, src2->id, type2);
  9165.                 }
  9166.             } else // Status failed.
  9167.                 return 0;
  9168.         }
  9169.             break;
  9170.         case SC_KAITE:
  9171.             val2 = 1+val1/5; // Number of bounces: 1 + skill_lv/5
  9172.             break;
  9173.         case SC_KAUPE:
  9174.             switch (val1) {
  9175.                 case 3: // 33*3 + 1 -> 100%
  9176.                     val2++;
  9177.                 case 1:
  9178.                 case 2: // 33, 66%
  9179.                     val2 += 33*val1;
  9180.                     val3 = 1; // Dodge 1 attack total.
  9181.                     break;
  9182.                 default: // Custom. For high level mob usage, higher level means more blocks. [Skotlex]
  9183.                     val2 = 100;
  9184.                     val3 = val1-2;
  9185.                     break;
  9186.             }
  9187.             break;
  9188.  
  9189.         case SC_COMBO:
  9190.         {
  9191.             // val1: Skill ID
  9192.             // val2: When given, target (for autotargetting skills)
  9193.             // val3: When set, this combo time should NOT delay attack/movement
  9194.             // val3: If set to 2 this combo will delay ONLY attack
  9195.             // val3: TK: Last used kick
  9196.             // val4: TK: Combo time
  9197.             struct unit_data *ud = unit_bl2ud(bl);
  9198.             if ( ud && (!val3 || val3 == 2) ) {
  9199.                 tick += 300 * battle_config.combo_delay_rate/100;
  9200.                 ud->attackabletime = gettick()+tick;
  9201.                 if( !val3 )
  9202.                     unit_set_walkdelay(bl, gettick(), tick, 1);
  9203.             }
  9204.             val3 = 0;
  9205.             val4 = tick;
  9206.             break;
  9207.         }
  9208.         case SC_EARTHSCROLL:
  9209.             val2 = 11-val1; // Chance to consume: 11-skill_lv%
  9210.             break;
  9211.         case SC_RUN:
  9212.             val4 = gettick(); // Store time at which you started running.
  9213.             tick = -1;
  9214.             break;
  9215.         case SC_KAAHI:
  9216.             val2 = 200*val1; // HP heal
  9217.             val3 = 5*val1; // SP cost
  9218.             break;
  9219.         case SC_BLESSING:
  9220.             if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
  9221.                 val2 = val1;
  9222.             else
  9223.                 val2 = 0; // 0 -> Half stat.
  9224.             break;
  9225.         case SC_TRICKDEAD:
  9226.             if (vd) vd->dead_sit = 1;
  9227.             tick = -1;
  9228.             break;
  9229.         case SC_CONCENTRATE:
  9230.             val2 = 2 + val1;
  9231.             if (sd) { // Store the card-bonus data that should not count in the %
  9232.                 val3 = sd->param_bonus[1]; // Agi
  9233.                 val4 = sd->param_bonus[4]; // Dex
  9234.             } else
  9235.                 val3 = val4 = 0;
  9236.             break;
  9237.         case SC_MAXOVERTHRUST:
  9238.             val2 = 20*val1; // Power increase
  9239.             break;
  9240.         case SC_OVERTHRUST:
  9241.             // val2 holds if it was casted on self, or is bonus received from others
  9242.             val3 = 5*val1; // Power increase
  9243.             if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
  9244.                 tick += tick / 10;
  9245.             break;
  9246.         case SC_ADRENALINE2:
  9247.         case SC_ADRENALINE:
  9248.             val3 = (val2) ? 300 : 200; // aspd increase
  9249.         case SC_WEAPONPERFECTION:
  9250.             if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
  9251.                 tick += tick / 10;
  9252.             break;
  9253.         case SC_CONCENTRATION:
  9254.             val2 = 5*val1; // Batk/Watk Increase
  9255.             val3 = 10*val1; // Hit Increase
  9256.             val4 = 5*val1; // Def reduction
  9257.             sc_start(src, bl, SC_ENDURE, 100, 1, tick); // Level 1 Endure effect
  9258.             break;
  9259.         case SC_ANGELUS:
  9260.             val2 = 5*val1; // def increase
  9261.             break;
  9262.         case SC_IMPOSITIO:
  9263.             val2 = 5*val1; // Watk increase
  9264.             break;
  9265.         case SC_MELTDOWN:
  9266.             val2 = 100*val1; // Chance to break weapon
  9267.             val3 = 70*val1; // Change to break armor
  9268.             break;
  9269.         case SC_TRUESIGHT:
  9270.             val2 = 10*val1; // Critical increase
  9271.             val3 = 3*val1; // Hit increase
  9272.             break;
  9273.         case SC_SUN_COMFORT:
  9274.             val2 = (status_get_lv(bl) + status->dex + status->luk)/2; // def increase
  9275.             break;
  9276.         case SC_MOON_COMFORT:
  9277.             val2 = (status_get_lv(bl) + status->dex + status->luk)/10; // flee increase
  9278.             break;
  9279.         case SC_STAR_COMFORT:
  9280.             val2 = (status_get_lv(bl) + status->dex + status->luk); // Aspd increase
  9281.             break;
  9282.         case SC_QUAGMIRE:
  9283.             val2 = (sd?5:10)*val1; // Agi/Dex decrease.
  9284.             break;
  9285.  
  9286.         // gs_something1 [Vicious]
  9287.         case SC_GATLINGFEVER:
  9288.             val2 = 20*val1; // Aspd increase
  9289. #ifndef RENEWAL
  9290.             val3 = 20+10*val1; // Atk increase
  9291. #endif
  9292.             val4 = 5*val1; // Flee decrease
  9293.             break;
  9294.  
  9295.         case SC_FLING:
  9296.             if (bl->type == BL_PC)
  9297.                 val2 = 0; // No armor reduction to players.
  9298.             else
  9299.                 val2 = 5*val1; // Def reduction
  9300.             val3 = 5*val1; // Def2 reduction
  9301.             break;
  9302.         case SC_PROVOKE:
  9303.             // val2 signals autoprovoke.
  9304.             val3 = 2+3*val1; // Atk increase
  9305.             val4 = 5+5*val1; // Def reduction.
  9306.             break;
  9307.         case SC_AVOID:
  9308.             // val2 = 10*val1; // Speed change rate.
  9309.             break;
  9310.         case SC_DEFENCE:
  9311. #ifdef RENEWAL
  9312.             val2 = 5 + (val1 * 5); // Vit bonus
  9313. #else
  9314.             val2 = 2*val1; // Def bonus
  9315. #endif
  9316.             break;
  9317.         case SC_BLOODLUST:
  9318.             val2 = 20+10*val1; // Atk rate change.
  9319.             val3 = 3*val1; // Leech chance
  9320.             val4 = 20; // Leech percent
  9321.             break;
  9322.         case SC_FLEET:
  9323.             val2 = 30*val1; // Aspd change
  9324.             val3 = 5+5*val1; // bAtk/wAtk rate change
  9325.             break;
  9326.         case SC_MINDBREAKER:
  9327.             val2 = 20*val1; // matk increase.
  9328.             val3 = 12*val1; // mdef2 reduction.
  9329.             break;
  9330.         case SC_SKA:
  9331.             val2 = tick/1000;
  9332.             val3 = rnd()%100; // Def changes randomly every second...
  9333.             tick_time = 1000; // [GodLesZ] tick time
  9334.             break;
  9335.         case SC_JAILED:
  9336.             // Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
  9337.             tick = val1>0?1000:250;
  9338.             if (sd) {
  9339.                 if (sd->mapindex != val2) {
  9340.                     int pos =  (bl->x&0xFFFF)|(bl->y<<16), // Current Coordinates
  9341.                     map_idx =  sd->mapindex; // Current Map
  9342.                     // 1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
  9343.                     pc_setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
  9344.                     // 2. Set restore point (val3 -> return map, val4 return coords
  9345.                     val3 = map_idx;
  9346.                     val4 = pos;
  9347.                 } else if (!val3 || val3 == sd->mapindex) { // Use save point.
  9348.                     val3 = sd->status.save_point.map;
  9349.                     val4 = (sd->status.save_point.x&0xFFFF)
  9350.                         |(sd->status.save_point.y<<16);
  9351.                 }
  9352.             }
  9353.             break;
  9354.         case SC_UTSUSEMI:
  9355.             val2=(val1+1)/2; // Number of hits blocked
  9356.             val3=skill_get_blewcount(NJ_UTSUSEMI, val1); // knockback value.
  9357.             break;
  9358.         case SC_BUNSINJYUTSU:
  9359.             val2=(val1+1)/2; // Number of hits blocked
  9360.             break;
  9361.         case SC_CHANGE:
  9362.             val2= 30*val1; // Vit increase
  9363.             val3= 20*val1; // Int increase
  9364.             break;
  9365.         case SC_SWOO:
  9366.             if(status->mode&MD_BOSS)
  9367.                 tick /= 5; // !TODO: Reduce skill's duration. But for how long?
  9368.             break;
  9369.         case SC_SPIDERWEB:
  9370.             if( bl->type == BL_PC )
  9371.                 tick /= 2;
  9372.             break;
  9373.         case SC_ARMOR:
  9374.             // NPC_DEFENDER:
  9375.             val2 = 80; // Damage reduction
  9376.             // Attack requirements to be blocked:
  9377.             val3 = BF_LONG; // Range
  9378.             val4 = BF_WEAPON|BF_MISC; // Type
  9379.             break;
  9380.         case SC_ENCHANTARMS:
  9381.             // end previous enchants
  9382.             skill_enchant_elemental_end(bl,type);
  9383.             // Make sure the received element is valid.
  9384.             if (val2 >= ELE_ALL)
  9385.                 val2 = val2%ELE_ALL;
  9386.             else if (val2 < 0)
  9387.                 val2 = rnd()%ELE_ALL;
  9388.             break;
  9389.         case SC_CRITICALWOUND:
  9390.             val2 = 20*val1; // Heal effectiveness decrease
  9391.             break;
  9392.         case SC_MAGICMIRROR:
  9393.             // Level 1 ~ 5 & 6 ~ 10 has different duration
  9394.             // Level 6 ~ 10 use effect of level 1 ~ 5
  9395.             val1 = 1 + ((val1-1)%5);
  9396.         case SC_SLOWCAST:
  9397.             val2 = 20*val1; // Magic reflection/cast rate
  9398.             break;
  9399.  
  9400.         case SC_ARMORCHANGE:
  9401.             if (val2 == NPC_ANTIMAGIC) { // Boost mdef
  9402.                 val2 =-20;
  9403.                 val3 = 20;
  9404.             } else { // Boost def
  9405.                 val2 = 20;
  9406.                 val3 =-20;
  9407.             }
  9408.             // Level 1 ~ 5 & 6 ~ 10 has different duration
  9409.             // Level 6 ~ 10 use effect of level 1 ~ 5
  9410.             val1 = 1 + ((val1-1)%5);
  9411.             val2 *= val1; // 20% per level
  9412.             val3 *= val1;
  9413.             break;
  9414.         case SC_EXPBOOST:
  9415.         case SC_JEXPBOOST:
  9416.         case SC_JP_EVENT04:
  9417.             if (val1 < 0)
  9418.                 val1 = 0;
  9419.             break;
  9420.         case SC_INCFLEE2:
  9421.         case SC_INCCRI:
  9422.             val2 = val1*10; // Actual boost (since 100% = 1000)
  9423.             break;
  9424.         case SC_SUFFRAGIUM:
  9425.             val2 = 15 * val1; // Speed cast decrease
  9426.             break;
  9427.         case SC_INCHEALRATE:
  9428.             if (val1 < 1)
  9429.                 val1 = 1;
  9430.             break;
  9431.         case SC_HALLUCINATION:
  9432.             val2 = 5+val1; // Factor by which displayed damage is increased by
  9433.             break;
  9434.         case SC_DOUBLECAST:
  9435.             val2 = 30+10*val1; // Trigger rate
  9436.             break;
  9437.         case SC_KAIZEL:
  9438.             val2 = 10*val1; // % of life to be revived with
  9439.             break;
  9440.         // case SC_ARMOR_ELEMENT:
  9441.         // case SC_ARMOR_RESIST:
  9442.             // Mod your resistance against elements:
  9443.             // val1 = water | val2 = earth | val3 = fire | val4 = wind
  9444.             // break;
  9445.         // case ????:
  9446.             // Place here SCs that have no SCB_* data, no skill associated, no ICON
  9447.             // associated, and yet are not wrong/unknown. [Skotlex]
  9448.             // break;
  9449.  
  9450.         case SC_MERC_FLEEUP:
  9451.         case SC_MERC_ATKUP:
  9452.         case SC_MERC_HITUP:
  9453.             val2 = 15 * val1;
  9454.             break;
  9455.         case SC_MERC_HPUP:
  9456.         case SC_MERC_SPUP:
  9457.             val2 = 5 * val1;
  9458.             break;
  9459.         case SC_REBIRTH:
  9460.             val2 = 20*val1; // % of life to be revived with
  9461.             break;
  9462.  
  9463.         case SC_MANU_DEF:
  9464.         case SC_MANU_ATK:
  9465.         case SC_MANU_MATK:
  9466.             val2 = 1; // Manuk group
  9467.             break;
  9468.         case SC_SPL_DEF:
  9469.         case SC_SPL_ATK:
  9470.         case SC_SPL_MATK:
  9471.             val2 = 2; // Splendide group
  9472.             break;
  9473.  
  9474.         /* General */
  9475.         case SC_FEAR:
  9476.             val2 = 2;
  9477.             val4 = tick / 1000;
  9478.             tick_time = 1000; // [GodLesZ] tick time
  9479.             break;
  9480.         case SC_BURNING:
  9481.             val4 = tick / 2000; // Total Ticks to Burn!!
  9482.             tick_time = 2000; // [GodLesZ] tick time
  9483.             break;
  9484.  
  9485.         /* Rune Knight */
  9486.         case SC_DEATHBOUND:
  9487.             val2 = 500 + 100 * val1;
  9488.             break;
  9489.         case SC_STONEHARDSKIN:
  9490.             if( sd )
  9491.                 val1 = sd->status.job_level * pc_checkskill(sd, RK_RUNEMASTERY) / 4; // DEF/MDEF Increase
  9492.             break;
  9493.         case SC_ABUNDANCE:
  9494.             val4 = tick / 10000;
  9495.             tick_time = 10000; // [GodLesZ] tick time
  9496.             break;
  9497.         case SC_GIANTGROWTH:
  9498.             val2 = 15; // Triple damage success rate.
  9499.             break;
  9500.  
  9501.         /* Arch Bishop */
  9502.         case SC_RENOVATIO:
  9503.             val4 = tick / 5000;
  9504.             tick_time = 5000;
  9505.             break;
  9506.         case SC_SECRAMENT:
  9507.             val2 = 10 * val1;
  9508.             break;
  9509.         case SC_VENOMIMPRESS:
  9510.             val2 = 10 * val1;
  9511.             break;
  9512.         case SC_WEAPONBLOCKING:
  9513.             val2 = 10 + 2 * val1; // Chance
  9514.             val4 = tick / 5000;
  9515.             tick_time = 5000; // [GodLesZ] tick time
  9516.             break;
  9517.         case SC_TOXIN:
  9518.             val4 = tick / 10000;
  9519.             tick_time = 10000; // [GodLesZ] tick time
  9520.             break;
  9521.         case SC_MAGICMUSHROOM:
  9522.             val4 = tick / 4000;
  9523.             tick_time = 4000; // [GodLesZ] tick time
  9524.             break;
  9525.         case SC_PYREXIA:
  9526.             status_change_start(src,bl,SC_BLIND,10000,val1,0,0,0,30000,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF); // Blind status that last for 30 seconds
  9527.             val4 = tick / 3000;
  9528.             tick_time = 3000; // [GodLesZ] tick time
  9529.             break;
  9530.         case SC_LEECHESEND:
  9531.             val4 = tick / 1000;
  9532.             tick_time = 1000; // [GodLesZ] tick time
  9533.             break;
  9534.         case SC_OBLIVIONCURSE:
  9535.             val4 = tick / 3000;
  9536.             tick_time = 3000; // [GodLesZ] tick time
  9537.             break;
  9538.         case SC_CLOAKINGEXCEED:
  9539.             val2 = (val1 + 1) / 2; // Hits
  9540.             val3 = (val1 - 1) * 10; // Walk speed
  9541.             if (bl->type == BL_PC)
  9542.                 val4 |= battle_config.pc_cloak_check_type&7;
  9543.             else
  9544.                 val4 |= battle_config.monster_cloak_check_type&7;
  9545.             tick_time = 1000; // [GodLesZ] tick time
  9546.             break;
  9547.         case SC_HALLUCINATIONWALK:
  9548.             val2 = 50 * val1; // Evasion rate of physical attacks. Flee
  9549.             val3 = 10 * val1; // Evasion rate of magical attacks.
  9550.             break;
  9551.         case SC_MARSHOFABYSS:
  9552.             if( bl->type == BL_PC )
  9553.                 val2 = 3 * val1; // AGI and DEX Reduction
  9554.             else // BL_MOB
  9555.                 val2 = 6 * val1; // AGI and DEX Reduction
  9556.             val3 = 10 * val1; // Movement Speed Reduction
  9557.             break;
  9558.         case SC_FREEZE_SP:
  9559.             // val2 = sp drain per 10 seconds
  9560.             tick_time = 10000; // [GodLesZ] tick time
  9561.             break;
  9562.         case SC_SPHERE_1:
  9563.         case SC_SPHERE_2:
  9564.         case SC_SPHERE_3:
  9565.         case SC_SPHERE_4:
  9566.         case SC_SPHERE_5:
  9567.             if( !sd )
  9568.                 return 0;   // Should only work on players.
  9569.             val4 = tick / 1000;
  9570.             if( val4 < 1 )
  9571.                 val4 = 1;
  9572.             tick_time = 1000; // [GodLesZ] tick time
  9573.             break;
  9574.         case SC_SHAPESHIFT:
  9575.             switch( val1 ) {
  9576.                 case 1: val2 = ELE_FIRE; break;
  9577.                 case 2: val2 = ELE_EARTH; break;
  9578.                 case 3: val2 = ELE_WIND; break;
  9579.                 case 4: val2 = ELE_WATER; break;
  9580.             }
  9581.             break;
  9582.         case SC_ELECTRICSHOCKER:
  9583.         case SC_CRYSTALIZE:
  9584.             val4 = tick / 1000;
  9585.             if( val4 < 1 )
  9586.                 val4 = 1;
  9587.             tick_time = 1000; // [GodLesZ] tick time
  9588.             break;
  9589.         case SC_MEIKYOUSISUI:
  9590.             val2 = val1 * 2; // % HP each sec
  9591.             val3 = val1; // % SP each sec
  9592.             val4 = tick / 1000;
  9593.             if( val4 < 1 )
  9594.                 val4 = 1;
  9595.             tick_time = 1000;
  9596.             break;
  9597.         case SC_CAMOUFLAGE:
  9598.             val4 = tick/1000;
  9599.             tick_time = 1000; // [GodLesZ] tick time
  9600.             break;
  9601.         case SC_WUGDASH:
  9602.             val4 = gettick(); // Store time at which you started running.
  9603.             tick = -1;
  9604.             break;
  9605.         case SC__SHADOWFORM:
  9606.             {
  9607.                 struct map_session_data * s_sd = map_id2sd(val2);
  9608.                 if( s_sd )
  9609.                     s_sd->shadowform_id = bl->id;
  9610.                 val4 = tick / 1000;
  9611.                 tick_time = 1000; // [GodLesZ] tick time
  9612.             }
  9613.             break;
  9614.         case SC__STRIPACCESSORY:
  9615.             if (!sd)
  9616.                 val2 = 20;
  9617.             break;
  9618.         case SC__INVISIBILITY:
  9619.             val2 = 50 - 10 * val1; // ASPD
  9620.             val3 = 20 * val1; // CRITICAL
  9621.             val4 = tick / 1000;
  9622.             tick = -1; // Duration sent to the client should be infinite
  9623.             tick_time = 1000; // [GodLesZ] tick time
  9624.             break;
  9625.         case SC__ENERVATION:
  9626.             val2 = 20 + 10 * val1; // ATK Reduction
  9627.             if (sd) {
  9628.                 pc_delspiritball(sd,sd->spiritball,0);
  9629.                 pc_delspiritcharm(sd,sd->spiritcharm,sd->spiritcharm_type);
  9630.             }
  9631.             break;
  9632.         case SC__GROOMY:
  9633.             val2 = 20 + 10 * val1; // ASPD
  9634.             val3 = 20 * val1; // HIT
  9635.             if( sd ) { // Removes Animals
  9636.                 if( pc_isriding(sd) ) pc_setriding(sd, 0);
  9637.                 if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
  9638.                 if( pc_iswug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
  9639.                 if( pc_isridingwug(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
  9640.                 if( pc_isfalcon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
  9641.                 if( sd->status.pet_id > 0 ) pet_menu(sd, 3);
  9642.                 if( hom_is_active(sd->hd) ) hom_vaporize(sd, HOM_ST_ACTIVE);
  9643.                 //if( sd->md ) mercenary_delete(sd->md,3); // Are Mercenaries removed? [aleos]
  9644.             }
  9645.             break;
  9646.         case SC__LAZINESS:
  9647.             val2 = 10 + 10 * val1; // Cast Increase
  9648.             val3 = 10 * val1; // Flee Reduction
  9649.             break;
  9650.         case SC__UNLUCKY:
  9651.         {
  9652.             sc_type rand_eff;
  9653.             switch(rnd() % 3) {
  9654.                 case 1: rand_eff = SC_BLIND; break;
  9655.                 case 2: rand_eff = SC_SILENCE; break;
  9656.                 default: rand_eff = SC_POISON; break;
  9657.             }
  9658.             val2 = 10 * val1; // Crit and Flee2 Reduction
  9659.             status_change_start(src,bl,rand_eff,10000,val1,0,0,0,tick,SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
  9660.             break;
  9661.         }
  9662.         case SC__WEAKNESS:
  9663.             val2 = 10 * val1;
  9664.             // Bypasses coating protection and MADO
  9665.             sc_start(src,bl,SC_STRIPWEAPON,100,val1,tick);
  9666.             sc_start(src,bl,SC_STRIPSHIELD,100,val1,tick);
  9667.             break;
  9668.         case SC__FEINTBOMB:
  9669.             val2 = 1; // -1 SP each iteration
  9670.             val4 = tick / 1000;
  9671.             tick_time = 1000;
  9672.             val_flag |= 1|2;
  9673.             break;
  9674.         case SC_GN_CARTBOOST:
  9675.             if( val1 < 3 )
  9676.                 val2 = 50;
  9677.             else if( val1 > 2 && val1 < 5 )
  9678.                 val2 = 75;
  9679.             else
  9680.                 val2 = 100;
  9681.             break;
  9682.         case SC_PROPERTYWALK:
  9683.             val3 = 0;
  9684.             break;
  9685.         case SC_STRIKING:
  9686.             // val2 = watk bonus already calc
  9687.             val3 = 6 - val1;// spcost = 6 - level (lvl1:5 ... lvl 5: 1)
  9688.             val4 = tick / 1000;
  9689.             tick_time = 1000; // [GodLesZ] tick time
  9690.             break;
  9691.         case SC_BLOODSUCKER:
  9692.             val4 = tick / 1000;
  9693.             tick_time = 1000; // [GodLesZ] tick time
  9694.             break;
  9695.         case SC_SWINGDANCE:
  9696.             val3 = 5 * val1 + val2; // Walk speed and aspd reduction.
  9697.             break;
  9698.         case SC_SYMPHONYOFLOVER:
  9699.             val3 = 12 * val1 + val2 + (sd?sd->status.job_level:50) / 4; // MDEF Increase in %
  9700.             break;
  9701.         case SC_MOONLITSERENADE: // MATK Increase
  9702.         case SC_RUSHWINDMILL: // ATK Increase
  9703.             val3 = 6 * val1 + val2 + (sd?sd->status.job_level:50) / 5;
  9704.             break;
  9705.         case SC_ECHOSONG:
  9706.             val3 = 6 * val1 + val2 + (sd?sd->status.job_level:50) / 4; // DEF Increase in %
  9707.             break;
  9708.         case SC_HARMONIZE:
  9709.             val2 = 5 + 5 * val1;
  9710.             break;
  9711.         case SC_VOICEOFSIREN:
  9712.             val4 = tick / 2000;
  9713.             tick_time = 2000; // [GodLesZ] tick time
  9714.             break;
  9715.         case SC_DEEPSLEEP:
  9716.             val4 = tick / 2000;
  9717.             tick_time = 2000; // [GodLesZ] tick time
  9718.             break;
  9719.         case SC_SIRCLEOFNATURE:
  9720.             val2 = 40 * val1; // HP recovery
  9721.             val3 = 4 * val1;    // SP consume
  9722.             val4 = tick / 1000;
  9723.             tick_time = 1000; // [GodLesZ] tick time
  9724.             break;
  9725.         case SC_SONGOFMANA:
  9726.             val3 = 10 + min(5 * val2, 35);
  9727.             val4 = tick/5000;
  9728.             tick_time = 5000; // [GodLesZ] tick time
  9729.             break;
  9730.         case SC_SATURDAYNIGHTFEVER:
  9731.             if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
  9732.             if (!val4) val4 = 3000;
  9733.             val3 = tick/val4;
  9734.             tick_time = val4; // [GodLesZ] tick time
  9735.             break;
  9736.         case SC_GLOOMYDAY:
  9737.             val2 = 20 + 5 * val1; // Flee reduction.
  9738.             val3 = 15 + 5 * val1; // ASPD reduction.
  9739.             if( sd && rnd()%100 < val1 ) { // (Skill Lv) %
  9740.                 val4 = 1; // Reduce walk speed by half.
  9741.                 if( pc_isriding(sd) ) pc_setriding(sd, 0);
  9742.                 if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
  9743.             }
  9744.             break;
  9745.         case SC_GLOOMYDAY_SK:
  9746.             // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
  9747.             val2 = 15 + rnd()%( (sd?pc_checkskill(sd, WM_LESSON)*5:0) + val1*10 );
  9748.             break;
  9749.         case SC_SITDOWN_FORCE:
  9750.         case SC_BANANA_BOMB_SITDOWN:
  9751.             if( sd && !pc_issit(sd) ) {
  9752.                 pc_setsit(sd);
  9753.                 skill_sit(sd, 1);
  9754.                 clif_sitting(bl);
  9755.             }
  9756.             break;
  9757.         case SC_DANCEWITHWUG:
  9758.             val3 = 5 + 5 * val2; // ASPD Increase
  9759.             val4 = 20 + 10 * val2; // Fixed Cast Time Reduction
  9760.             break;
  9761.         case SC_LERADSDEW:
  9762.             val3 = 200 * val1 + min(300 * val2, 2500); // MaxHP Increase
  9763.             break;
  9764.         case SC_MELODYOFSINK:
  9765.             val3 = val1 * val2; // INT Reduction.
  9766.             val4 = tick/1000;
  9767.             tick_time = 1000;
  9768.             break;
  9769.         case SC_BEYONDOFWARCRY:
  9770.             val3 = val1 * val2; // STR and CRIT Reduction
  9771.             val4 = 4 * val1 + min(4 * (val2 - 2), 40); // MaxHP Reduction
  9772.             break;
  9773.         case SC_UNLIMITEDHUMMINGVOICE:
  9774.             {
  9775.                 struct unit_data *ud = unit_bl2ud(bl);
  9776.                 if( ud == NULL ) return 0;
  9777.                 ud->state.skillcastcancel = 0;
  9778.                 val3 = 15 - min(3 * val2, 15);
  9779.             }
  9780.             break;
  9781.         case SC_REFLECTDAMAGE:
  9782.             val2 = 15 + 5 * val1; // Reflect amount
  9783.             val3 = val1*5 + 25; // Number of reflects
  9784.             val4 = tick/1000; // Number of SP cycles (duration)
  9785.             tick_time = 1000; // [GodLesZ] tick time
  9786.             break;
  9787.         case SC_FORCEOFVANGUARD:
  9788.             val2 = 8 + 12 * val1; // Chance
  9789.             val3 = 5 + 2 * val1; // Max rage counters
  9790.             tick = -1; // Endless duration in the client
  9791.             tick_time = 10000; // [GodLesZ] tick time
  9792.             break;
  9793.         case SC_EXEEDBREAK:
  9794.             {
  9795.                 short idx = -1;
  9796.                 val1 *= 100; // 100 * skill_lv
  9797.                 if( sd && (idx = sd->equip_index[EQI_HAND_R]) >= 0 && sd->inventory_data[idx] ) {
  9798.                     val1 += (sd->inventory_data[idx]->weight/10 * sd->inventory_data[idx]->wlv * status_get_lv(bl) / 100);
  9799.                     val1 += 10 * sd->status.job_level;
  9800.                 }
  9801.             }
  9802.             break;
  9803.         case SC_PRESTIGE:
  9804.             val2 = (status->int_ + status->luk) * val1 / 20 * status_get_lv(bl) / 200 + val1;   // Chance to evade magic damage.
  9805.             val1 = ((val1 * 15) + (10 * (sd?pc_checkskill(sd,CR_DEFENDER):skill_get_max(CR_DEFENDER)))) * status_get_lv(bl) / 100; // Defence added
  9806.             break;
  9807.         case SC_BANDING:
  9808.             tick_time = 5000; // [GodLesZ] tick time
  9809.             break;
  9810.         case SC_MAGNETICFIELD:
  9811.             val3 = tick / 1000;
  9812.             tick_time = 1000; // [GodLesZ] tick time
  9813.             break;
  9814.         case SC_INSPIRATION:
  9815.             val2 = (sd?sd->status.job_level:50);
  9816.             val3 = status_get_lv(bl) / 10 + val2 / 5; //All stat bonus
  9817.             val4 = tick / 5000;
  9818.             tick_time = 5000; // [GodLesZ] tick time
  9819.             status_change_clear_buffs(bl,3); // Remove buffs/debuffs
  9820.             break;
  9821.         case SC_CRESCENTELBOW:
  9822.             val2 = (sd?sd->status.job_level:50) / 2 + (50 + 5 * val1);
  9823.             break;
  9824.         case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
  9825.             val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
  9826.             break;
  9827.         case SC_RAISINGDRAGON:
  9828.             val3 = tick / 5000;
  9829.             tick_time = 5000; // [GodLesZ] tick time
  9830.             break;
  9831.         case SC_GT_ENERGYGAIN:
  9832.             val2 = 10 + 5 * val1; // Sphere gain chance.
  9833.             break;
  9834.         case SC_GT_CHANGE:
  9835.             { // Take note there is no def increase as skill desc says. [malufett]
  9836.                 struct status_data *sstatus = src ? status_get_status_data(src) : NULL;
  9837.                 val2 = ((sstatus?sstatus->dex:4) / 4 + (sstatus?sstatus->str:2) / 2) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
  9838.                 val3 = status->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
  9839.                 val4 = (200/(sstatus?sstatus->int_:1)) * val1; // MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
  9840.  
  9841.                 if (val4 < 0)
  9842.                     val4 = 0;
  9843.             }
  9844.             break;
  9845.         case SC_GT_REVITALIZE:
  9846.             { // Take note there is no vit,aspd,speed increase as skill desc says. [malufett]
  9847.                 struct status_data *sstatus = src ? status_get_status_data(src) : NULL;
  9848.                 val2 = 2 * val1; // MaxHP: [(Skill Level * 2)]%
  9849.                 val3 = val1 * 30 + 50; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
  9850.                 // The stat def is not shown in the status window and it is process differently
  9851.                 val4 = ((sstatus?sstatus->vit:4)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
  9852.             }
  9853.             break;
  9854.         case SC_PYROTECHNIC_OPTION:
  9855.             val2 = 60; // Eatk Renewal (Atk2)
  9856.             break;
  9857.         case SC_HEATER_OPTION:
  9858.             val2 = 120; // Eatk Renewal (Atk2)
  9859.             val3 = ELE_FIRE; // Change into fire element.
  9860.             break;
  9861.         case SC_TROPIC_OPTION:
  9862.             val2 = 180; // Eatk Renewal (Atk2)
  9863.             val3 = MG_FIREBOLT;
  9864.             break;
  9865.         case SC_AQUAPLAY_OPTION:
  9866.             val2 = 40;
  9867.             break;
  9868.         case SC_COOLER_OPTION:
  9869.             val2 = 80;
  9870.             val3 = ELE_WATER; // Change into water element.
  9871.             break;
  9872.         case SC_CHILLY_AIR_OPTION:
  9873.             val2 = 120; // Matk. Renewal (Matk1)
  9874.             val3 = MG_COLDBOLT;
  9875.             break;
  9876.         case SC_WIND_STEP_OPTION:
  9877.             val2 = 50; // % Increase speed and flee.
  9878.             break;
  9879.         case SC_BLAST_OPTION:
  9880.             val2 = 20;
  9881.             val3 = ELE_WIND; // Change into wind element.
  9882.             break;
  9883.         case SC_WILD_STORM_OPTION:
  9884.             val2 = MG_LIGHTNINGBOLT;
  9885.             break;
  9886.         case SC_PETROLOGY_OPTION:
  9887.             val2 = 5; //HP Rate bonus
  9888.             val3 = 50;
  9889.             break;
  9890.         case SC_SOLID_SKIN_OPTION:
  9891.             val2 = 33; //% Increase DEF
  9892.             break;
  9893.         case SC_CURSED_SOIL_OPTION:
  9894.             val2 = 10; //HP rate bonus
  9895.             val3 = ELE_EARTH; // Change into earth element.
  9896.             break;
  9897.         case SC_UPHEAVAL_OPTION:
  9898.             val2 = 15; //HP rate bonus
  9899.             val3 = WZ_EARTHSPIKE;
  9900.             break;
  9901.         case SC_CIRCLE_OF_FIRE_OPTION:
  9902.             val2 = 300;
  9903.             break;
  9904.         case SC_WATER_SCREEN_OPTION:
  9905.             tick_time = 10000;
  9906.             break;
  9907.         case SC_FIRE_CLOAK_OPTION:
  9908.         case SC_WATER_DROP_OPTION:
  9909.         case SC_WIND_CURTAIN_OPTION:
  9910.         case SC_STONE_SHIELD_OPTION:
  9911.             val2 = 100; // Elemental modifier.
  9912.             break;
  9913.         case SC_TROPIC:
  9914.         case SC_CHILLY_AIR:
  9915.         case SC_WILD_STORM:
  9916.         case SC_UPHEAVAL:
  9917.             val2 += 10;
  9918.         case SC_HEATER:
  9919.         case SC_COOLER:
  9920.         case SC_BLAST:
  9921.         case SC_CURSED_SOIL:
  9922.             val2 += 10;
  9923.         case SC_PYROTECHNIC:
  9924.         case SC_AQUAPLAY:
  9925.         case SC_GUST:
  9926.         case SC_PETROLOGY:
  9927.             val2 += 5;
  9928.             val3 += 9000;
  9929.         case SC_CIRCLE_OF_FIRE:
  9930.         case SC_FIRE_CLOAK:
  9931.         case SC_WATER_DROP:
  9932.         case SC_WATER_SCREEN:
  9933.         case SC_WIND_CURTAIN:
  9934.         case SC_WIND_STEP:
  9935.         case SC_STONE_SHIELD:
  9936.         case SC_SOLID_SKIN:
  9937.             val2 += 5;
  9938.             val3 += 1000;
  9939.             tick_time = val3; // [GodLesZ] tick time
  9940.             break;
  9941.         case SC_WATER_BARRIER:
  9942.             val2 = 30; // Reductions. Atk2 and Flee1
  9943.             break;
  9944.         case SC_ZEPHYR:
  9945.             val2 = 25; // Flee.
  9946.             break;
  9947.         case SC_TIDAL_WEAPON:
  9948.             val2 = 20; // Increase Elemental's attack.
  9949.             break;
  9950.         case SC_ROCK_CRUSHER:
  9951.         case SC_ROCK_CRUSHER_ATK:
  9952.         case SC_POWER_OF_GAIA:
  9953.             val2 = 33; //Def rate bonus/Speed rate reduction
  9954.             val3 = 20; //HP rate bonus
  9955.             break;
  9956.         case SC_TEARGAS:
  9957.             val2 = status_get_max_hp(bl) * 5 / 100; // Drain 5% HP
  9958.             val4 = tick / 2000;
  9959.             tick_time = 2000;
  9960.             break;
  9961.         case SC_TEARGAS_SOB:
  9962.             val4 = tick / 3000;
  9963.             tick_time = 3000;
  9964.             break;
  9965.         case SC_MELON_BOMB:
  9966.         case SC_BANANA_BOMB:
  9967.             val1 = 20;
  9968.             break;
  9969.         case SC_STOMACHACHE:
  9970.             val2 = 8; // SP consume.
  9971.             val4 = tick / 10000;
  9972.             tick_time = 10000; // [GodLesZ] tick time
  9973.             break;
  9974.         case SC_KYOUGAKU:
  9975.             val2 = 2*val1 + rnd()%val1;
  9976.             clif_status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
  9977.             break;
  9978.         case SC_KAGEMUSYA:
  9979.             val3 = val1 * 2;
  9980.         case SC_IZAYOI:
  9981.             val2 = tick/1000;
  9982.             if( type == SC_IZAYOI )
  9983.                 tick = -1; // Duration sent to the client should be infinite
  9984.             tick_time = 1000;
  9985.             break;
  9986.         case SC_ZANGETSU:
  9987.             if( status_get_hp(bl) % 2 == 0 )
  9988.                 val2 = (status_get_lv(bl) / 3) + (20 * val1); //+Watk
  9989.             else
  9990.                 val2 -= (status_get_lv(bl) / 3) + (30 * val1); //-Watk
  9991.  
  9992.             if( status_get_sp(bl) % 2 == 0 )
  9993.                 val3 = (status_get_lv(bl) / 3) + (20 * val1); //+Matk
  9994.             else
  9995.                 val3 -= (status_get_lv(bl) / 3) + (30 * val1); //-Matk
  9996.             break;
  9997.         case SC_GENSOU:
  9998.             {
  9999.                 int hp = status_get_hp(bl), lv = 5;
  10000.                 short per = 100 / (status_get_max_hp(bl) / hp);
  10001.  
  10002.                 if( per <= 15 )
  10003.                     lv = 1;
  10004.                 else if( per <= 30 )
  10005.                     lv = 2;
  10006.                 else if( per <= 50 )
  10007.                     lv = 3;
  10008.                 else if( per <= 75 )
  10009.                     lv = 4;
  10010.                 if( hp % 2 == 0)
  10011.                     status_heal(bl, hp * (6-lv) * 4 / 100, status_get_sp(bl) * (6-lv) * 3 / 100, 1);
  10012.                 else
  10013.                     status_zap(bl, hp * (lv*4) / 100, status_get_sp(bl) * (lv*3) / 100);
  10014.             }
  10015.             break;
  10016.         case SC_ANGRIFFS_MODUS:
  10017.             val2 = 50 + 20 * val1; // atk bonus
  10018.             val3 = 40 + 20 * val1; // Flee reduction.
  10019.             val4 = tick/1000; // hp/sp reduction timer
  10020.             tick_time = 1000;
  10021.             break;
  10022.         case SC_GOLDENE_FERSE:
  10023.             val2 = 10 + 10*val1; // flee bonus
  10024.             val3 = 6 + 4 * val1; // Aspd Bonus
  10025.             val4 = 2 + 2 * val1; // Chance of holy attack
  10026.             break;
  10027.         case SC_OVERED_BOOST:
  10028.             val2 = 300 + 40*val1; // flee bonus
  10029.             val3 = 179 + 2*val1; // aspd bonus
  10030.             val4 = 50; // def reduc %
  10031.             break;
  10032.         case SC_GRANITIC_ARMOR:
  10033.             val2 = 2*val1; // dmg reduction
  10034.             val3 = 6*val1; // dmg taken on status end (6%:12%:18%:24%:30%)
  10035.             val4 = 5*val1; // unknow formula
  10036.             break;
  10037.         case SC_MAGMA_FLOW:
  10038.             val2 = 3*val1; // Activation chance
  10039.             break;
  10040.         case SC_PYROCLASTIC:
  10041.             val2 += 10*val1; // atk bonus
  10042.             val3 = 2*val1; // Chance To AutoCast Hammer Fall %
  10043.             break;
  10044.         case SC_PARALYSIS: // [Lighta] need real info
  10045.             val2 = 2*val1; // def reduction
  10046.             val3 = 500*val1; // varcast augmentation
  10047.             break;
  10048.         case SC_LIGHT_OF_REGENE: // Yommy leak need confirm
  10049.             val2 = 20 * val1; // hp reco on death %
  10050.             break;
  10051.         case SC_PAIN_KILLER: // Yommy leak need confirm
  10052.             val2 = 10 * val1; // aspd reduction %
  10053.             val3 = min((( 200 * val1 ) * status_get_lv(src)) / 150, 1000); // dmg reduction linear. upto a maximum of 1000 [iRO Wiki]
  10054.             if(sc->data[SC_PARALYSIS])
  10055.                 sc_start(src,bl, SC_ENDURE, 100, val1, tick); // Start endure for same duration
  10056.             break;
  10057.         case SC_STYLE_CHANGE:
  10058.             tick = -1; // Infinite duration
  10059.             break;
  10060.         case SC_CBC:
  10061.             val3 = 10; // Drain sp % dmg
  10062.             val4 = tick/1000; // dmg each sec
  10063.             tick = 1000;
  10064.             break;
  10065.         case SC_EQC:
  10066.             val2 = 5 * val1; // def % reduc
  10067.             val3 = 5 * val1; // atk % reduc
  10068.             val4 = 2 * val1; // HP drain %
  10069.             sc_start2(src, bl,SC_STUN,100,val1,bl->id,(1000*status_get_lv(src))/50+500*val1);
  10070.             break;
  10071.         case SC_ASH:
  10072.             val2 = 50; // hit % reduc
  10073.             val3 = 0; // def % reduc
  10074.             val4 = 0; // atk flee & reduc
  10075.             if(status_get_race(bl) == RC_PLANT) // plant type
  10076.                 val3 = 50;
  10077.             if(status_get_element(bl) == ELE_WATER) // defense water type
  10078.                 val4 = 50;
  10079.             break;
  10080.         case SC_FULL_THROTTLE:
  10081.             val2 = ( val1 == 1 ? 6 : 6 - val1 );
  10082.             val3 = 20; //+% AllStats
  10083.             tick_time = 1000;
  10084.             val4 = tick / tick_time;
  10085.             tick = -1;
  10086.             break;
  10087.         case SC_REBOUND:
  10088.             tick_time = 2000;
  10089.             val4 = tick / tick_time;
  10090.             clif_emotion(bl, E_SWT);
  10091.             break;
  10092.         case SC_KINGS_GRACE:
  10093.             val2 = 3 + val1; //HP Recover rate
  10094.             tick_time = 1000;
  10095.             val4 = tick / tick_time;
  10096.             break;
  10097.         case SC_TELEKINESIS_INTENSE:
  10098.             val2 = val4 = 10 * val1; // sp consum / casttime reduc %
  10099.             val3 = 40 * val1; // magic dmg bonus
  10100.             break;
  10101.         case SC_OFFERTORIUM:
  10102.             val2 = 30 * val1; // heal power bonus
  10103.             val3 = 100 + 20 * val1; // sp cost inc
  10104.             break;
  10105.         case SC_FRIGG_SONG:
  10106.             val2 = 5 * val1; // maxhp bonus
  10107.             val3 = 80 + 20 * val1; // healing
  10108.             tick_time = 1000;
  10109.             val4 = tick / tick_time;
  10110.             break;
  10111.         case SC_FLASHCOMBO:
  10112.             val2 = 20 * val1 + 20; // atk bonus
  10113.             break;
  10114.         case SC_DARKCROW:
  10115.             val2 = 30 * val1;
  10116.             break;
  10117.         case SC_UNLIMIT:
  10118.             val2 = 50 * val1;
  10119.             status_change_start(bl, bl, SC_DEFSET, 10000, 1, 0, 0, 0, tick, SCSTART_NOTICKDEF);
  10120.             status_change_start(bl, bl, SC_MDEFSET, 10000, 1, 0, 0, 0, tick, SCSTART_NOTICKDEF);
  10121.             break;
  10122.         case SC_MONSTER_TRANSFORM:
  10123.             if( !mobdb_checkid(val1) )
  10124.                 val1 = MOBID_PORING; // Default poring
  10125.             break;
  10126.         case SC_APPLEIDUN:
  10127.             val2 = (5 + 2 * val1) + (status_get_vit(src) / 10); //HP Rate: (5 + 2 * skill_lv) + (vit/10) + (BA_MUSICALLESSON level)
  10128.             if (sd)
  10129.                 val2 += pc_checkskill(sd,BA_MUSICALLESSON);
  10130.             break;
  10131.         case SC_EPICLESIS:
  10132.             val2 = 5 * val1; //HP rate bonus
  10133.             break;
  10134.         case SC_ILLUSIONDOPING:
  10135.             val2 = 50; // -Hit
  10136.             break;
  10137.  
  10138.         case SC_STEALTHFIELD:
  10139.             val2 = 30; // Speed reduction
  10140.             break;
  10141.         case SC_STEALTHFIELD_MASTER:
  10142.             val3 = 3; // Reduces SP 3%
  10143.             tick_time = 3000;
  10144.             val4 = tick/tick_time;
  10145.             break;
  10146.         case SC_VACUUM_EXTREME:
  10147.             // Suck target at n second, only if the n second is lower than the duration
  10148.             // Doesn't apply to BL_PC
  10149.             if (bl->type != BL_PC && val4 < tick && !unit_blown_immune(bl,0x1) && status->mode&MD_CANMOVE) {
  10150.                 tick_time = val4;
  10151.                 val4 = tick - tick_time;
  10152.             }
  10153.             else
  10154.                 val4 = 0;
  10155.             break;
  10156.  
  10157.         /* Rebellion */
  10158.         case SC_B_TRAP:
  10159.             val2 = src->id;
  10160.             val3 = val1 * 25; // -movespeed (custom)
  10161.             break;
  10162.         case SC_C_MARKER:
  10163.             // val1 = skill_lv
  10164.             // val2 = src_id
  10165.             val3 = 10; // -10 flee
  10166.             //Start timer to send mark on mini map
  10167.             val4 = tick/1000;
  10168.             tick_time = 1000; // Sends every 1 seconds
  10169.             break;
  10170.         case SC_H_MINE:
  10171.             val2 = src->id;
  10172.             break;
  10173.         case SC_HEAT_BARREL:
  10174.             //kRO Update 2014-02-26
  10175.             {
  10176.                 uint8 n = 10;
  10177.                 if (sd)
  10178.                     n = (uint8)sd->spiritball_old;
  10179.                 val2 = val1 * 5; // -fixed casttime (custom)
  10180.                 val3 = val1 * n / 5; // +aspd (custom)
  10181.                 val4 = 75 - val1 * 5; // -flee
  10182.             }
  10183.             break;
  10184.         case SC_P_ALTER:
  10185.             {
  10186.                 uint8 n = 10;
  10187.                 if (sd)
  10188.                     n = (uint8)sd->spiritball_old;
  10189.                 val2 = val1 * n * 2; // +atk (custom)
  10190.                 val3 = val1 * 15; // +def (custom)
  10191.             }
  10192.             break;
  10193.         case SC_E_CHAIN:
  10194.             val2 = 10;
  10195.             if (sd)
  10196.                 val2 = sd->spiritball_old;
  10197.             break;
  10198.         case SC_ANTI_M_BLAST:
  10199.             val2 = val1 * 10;
  10200.             if (bl->type != BL_PC)
  10201.                 val2 /= 5; //(custom) //kRO update 2012-02-12, reduce the rate for Non-Player target [Cydh]
  10202.             break;
  10203.  
  10204.         default:
  10205.             if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == -1 && StatusIconChangeTable[type] == SI_BLANK ) {
  10206.                 // Status change with no calc, no icon, and no skill associated...?
  10207.                 ShowError("UnknownStatusChange [%d]\n", type);
  10208.                 return 0;
  10209.             }
  10210.     } else // Special considerations when loading SC data.
  10211.         switch( type ) {
  10212.             case SC_WEDDING:
  10213.             case SC_XMAS:
  10214.             case SC_SUMMER:
  10215.             case SC_HANBOK:
  10216.             case SC_OKTOBERFEST:
  10217.                 if( !vd )
  10218.                     break;
  10219.                 clif_changelook(bl,LOOK_BASE,vd->class_);
  10220.                 clif_changelook(bl,LOOK_WEAPON,0);
  10221.                 clif_changelook(bl,LOOK_SHIELD,0);
  10222.                 clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
  10223.                 break;
  10224.         }
  10225.  
  10226.     // Values that must be set regardless of flag&4 e.g. val_flag [Ind]
  10227.     switch(type) {
  10228.         // Start |1 val_flag setting
  10229.         case SC_ROLLINGCUTTER:
  10230.         case SC_BANDING:
  10231.         case SC_SPHERE_1:
  10232.         case SC_SPHERE_2:
  10233.         case SC_SPHERE_3:
  10234.         case SC_SPHERE_4:
  10235.         case SC_SPHERE_5:
  10236.         case SC_LIGHTNINGWALK:
  10237.         case SC_MONSTER_TRANSFORM:
  10238.         case SC_EXPBOOST:
  10239.         case SC_JEXPBOOST:
  10240.         case SC_ITEMBOOST:
  10241.         case SC_JP_EVENT04:
  10242.             val_flag |= 1;
  10243.             break;
  10244.         // Start |1|2 val_flag setting
  10245.         case SC_FIGHTINGSPIRIT:
  10246.         case SC_VENOMIMPRESS:
  10247.         case SC_WEAPONBLOCKING:
  10248.         case SC__INVISIBILITY:
  10249.         case SC__ENERVATION:
  10250.         case SC__WEAKNESS:
  10251.         case SC_PROPERTYWALK:
  10252.         case SC_PRESTIGE:
  10253.         case SC_SHIELDSPELL_DEF:
  10254.         case SC_SHIELDSPELL_MDEF:
  10255.         case SC_SHIELDSPELL_REF:
  10256.         case SC_CRESCENTELBOW:
  10257.         case SC_CHILLY_AIR_OPTION:
  10258.         case SC_GUST_OPTION:
  10259.         case SC_WILD_STORM_OPTION:
  10260.         case SC_UPHEAVAL_OPTION:
  10261.         case SC_CIRCLE_OF_FIRE_OPTION:
  10262.             val_flag |= 1|2;
  10263.             break;
  10264.         // Start |1|2|4 val_flag setting
  10265.         case SC_POISONINGWEAPON:
  10266.         case SC_CLOAKINGEXCEED:
  10267.         case SC_HALLUCINATIONWALK:
  10268.         case SC__SHADOWFORM:
  10269.         case SC__GROOMY:
  10270.         case SC__LAZINESS:
  10271.         case SC__UNLUCKY:
  10272.         case SC_FORCEOFVANGUARD:
  10273.         case SC_SPELLFIST:
  10274.         case SC_CURSEDCIRCLE_ATKER:
  10275.         case SC_PYROTECHNIC_OPTION:
  10276.         case SC_HEATER_OPTION:
  10277.         case SC_AQUAPLAY_OPTION:
  10278.         case SC_COOLER_OPTION:
  10279.         case SC_BLAST_OPTION:
  10280.         case SC_PETROLOGY_OPTION:
  10281.         case SC_CURSED_SOIL_OPTION:
  10282.         case SC_WATER_BARRIER:
  10283.             val_flag |= 1|2|4;
  10284.             break;
  10285.     }
  10286.  
  10287.     /* [Ind] */
  10288.     if (sd && StatusDisplayType[type]) {
  10289.         int dval1 = 0, dval2 = 0, dval3 = 0;
  10290.  
  10291.         switch (type) {
  10292.             case SC_ALL_RIDING:
  10293.                 dval1 = 1;
  10294.                 break;
  10295.             default: /* All others: just copy val1 */
  10296.                 dval1 = val1;
  10297.                 break;
  10298.         }
  10299.         status_display_add(sd,type,dval1,dval2,dval3);
  10300.     }
  10301.  
  10302.     // Those that make you stop attacking/walking....
  10303.     switch (type) {
  10304.         case SC_FREEZE:
  10305.         case SC_STUN:
  10306.         case SC_SLEEP:
  10307.         case SC_STONE:
  10308.         case SC_WHITEIMPRISON:
  10309.         case SC_DEEPSLEEP:
  10310.         case SC_CRYSTALIZE:
  10311.             if (sd && pc_issit(sd)) // Avoid sprite sync problems.
  10312.                 pc_setstand(sd, true);
  10313.         case SC_TRICKDEAD:
  10314.             status_change_end(bl, SC_DANCING, INVALID_TIMER);
  10315.             // Cancel cast when get status [LuzZza]
  10316.             if (battle_config.sc_castcancel&bl->type)
  10317.                 unit_skillcastcancel(bl, 0);
  10318.         // Fall through
  10319.         case SC_CURSEDCIRCLE_ATKER:
  10320.             unit_stop_attack(bl);
  10321.         // Fall through
  10322.         case SC_STOP:
  10323.         case SC_CONFUSION:
  10324.         case SC_CLOSECONFINE:
  10325.         case SC_CLOSECONFINE2:
  10326.         case SC_TINDER_BREAKER:
  10327.         case SC_TINDER_BREAKER2:
  10328.         case SC_BITE:
  10329.         case SC_THORNSTRAP:
  10330.         case SC_FEAR:
  10331.         case SC_MEIKYOUSISUI:
  10332.         case SC_KYOUGAKU:
  10333.         case SC_PARALYSIS:
  10334.         //case SC__CHAOS:
  10335.             unit_stop_walking(bl,1);
  10336.             break;
  10337.         case SC_CURSEDCIRCLE_TARGET:
  10338.             unit_stop_attack(bl);
  10339.         // Fall through
  10340.         case SC_ANKLE:
  10341.         case SC_SPIDERWEB:
  10342.         case SC_ELECTRICSHOCKER:
  10343.         case SC_MAGNETICFIELD:
  10344.         case SC_NETHERWORLD:
  10345.             if (!unit_blown_immune(bl,0x1))
  10346.                 unit_stop_walking(bl,1);
  10347.             break;
  10348.         case SC__MANHOLE:
  10349.             if (bl->type == BL_PC || !unit_blown_immune(bl,0x1))
  10350.                 unit_stop_walking(bl,1);
  10351.             break;
  10352.         case SC_VACUUM_EXTREME:
  10353.             if (bl->type != BL_PC && !unit_blown_immune(bl,0x1)) {
  10354.                 unit_stop_walking(bl,1);
  10355.                 unit_stop_attack(bl);
  10356.             }
  10357.             break;
  10358.         case SC_HIDING:
  10359.         case SC_CLOAKING:
  10360.         case SC_CLOAKINGEXCEED:
  10361.         case SC__FEINTBOMB:
  10362.         case SC_CHASEWALK:
  10363.         case SC_WEIGHT90:
  10364.         case SC_CAMOUFLAGE:
  10365.         case SC_VOICEOFSIREN:
  10366.         case SC_HEAT_BARREL_AFTER:
  10367.         case SC_WEDDING:
  10368.         case SC_XMAS:
  10369.         case SC_SUMMER:
  10370.         case SC_HANBOK:
  10371.         case SC_OKTOBERFEST:
  10372.             unit_stop_attack(bl);
  10373.             break;
  10374.         case SC_SILENCE:
  10375.             if (battle_config.sc_castcancel&bl->type)
  10376.                 unit_skillcastcancel(bl, 0);
  10377.             break;
  10378.         case SC_ITEMSCRIPT: // Shows Buff Icons
  10379.             if (sd && val2 != SI_BLANK)
  10380.                 clif_status_change(bl, (enum si_type)val2, 1, tick, 0, 0, 0);
  10381.             break;
  10382.     }
  10383.  
  10384.     // Set option as needed.
  10385.     opt_flag = 1;
  10386.     switch(type) {
  10387.         // OPT1
  10388.         case SC_STONE:      sc->opt1 = OPT1_STONEWAIT;  break;
  10389.         case SC_FREEZE:     sc->opt1 = OPT1_FREEZE;     break;
  10390.         case SC_STUN:       sc->opt1 = OPT1_STUN;       break;
  10391.         case SC_DEEPSLEEP:  opt_flag = 0;
  10392.         case SC_SLEEP:      sc->opt1 = OPT1_SLEEP;      break;
  10393.         case SC_BURNING:    sc->opt1 = OPT1_BURNING;    break; // Burning need this to be showed correctly. [pakpil]
  10394.         case SC_WHITEIMPRISON:  sc->opt1 = OPT1_IMPRISON;   break;
  10395.         case SC_CRYSTALIZE: sc->opt1 = OPT1_CRYSTALIZE; break;
  10396.         // OPT2
  10397.         case SC_POISON:       sc->opt2 |= OPT2_POISON;      break;
  10398.         case SC_CURSE:        sc->opt2 |= OPT2_CURSE;       break;
  10399.         case SC_SILENCE:      sc->opt2 |= OPT2_SILENCE;     break;
  10400.         case SC_SIGNUMCRUCIS: sc->opt2 |= OPT2_SIGNUMCRUCIS; break;
  10401.         case SC_BLIND:        sc->opt2 |= OPT2_BLIND;       break;
  10402.         case SC_ANGELUS:      sc->opt2 |= OPT2_ANGELUS;     break;
  10403.         case SC_BLEEDING:     sc->opt2 |= OPT2_BLEEDING;    break;
  10404.         case SC_DPOISON:      sc->opt2 |= OPT2_DPOISON;     break;
  10405.         // OPT3
  10406.         case SC_TWOHANDQUICKEN:
  10407.         case SC_ONEHAND:
  10408.         case SC_SPEARQUICKEN:
  10409.         case SC_CONCENTRATION:
  10410.         case SC_MERC_QUICKEN:
  10411.             sc->opt3 |= OPT3_QUICKEN;
  10412.             opt_flag = 0;
  10413.             break;
  10414.         case SC_MAXOVERTHRUST:
  10415.         case SC_OVERTHRUST:
  10416.         case SC_SWOO:   // Why does it shares the same opt as Overthrust? Perhaps we'll never know...
  10417.             sc->opt3 |= OPT3_OVERTHRUST;
  10418.             opt_flag = 0;
  10419.             break;
  10420.         case SC_ENERGYCOAT:
  10421.         case SC_SKE:
  10422.             sc->opt3 |= OPT3_ENERGYCOAT;
  10423.             opt_flag = 0;
  10424.             break;
  10425.         case SC_INCATKRATE:
  10426.             // Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
  10427.             if (bl->type != BL_MOB) {
  10428.                 opt_flag = 0;
  10429.                 break;
  10430.             }
  10431.         case SC_EXPLOSIONSPIRITS:
  10432.             sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
  10433.             opt_flag = 0;
  10434.             break;
  10435.         case SC_STEELBODY:
  10436.         case SC_SKA:
  10437.             sc->opt3 |= OPT3_STEELBODY;
  10438.             opt_flag = 0;
  10439.             break;
  10440.         case SC_BLADESTOP:
  10441.             sc->opt3 |= OPT3_BLADESTOP;
  10442.             opt_flag = 0;
  10443.             break;
  10444.         case SC_AURABLADE:
  10445.             sc->opt3 |= OPT3_AURABLADE;
  10446.             opt_flag = 0;
  10447.             break;
  10448.         case SC_BERSERK:
  10449.             opt_flag = 0;
  10450.             sc->opt3 |= OPT3_BERSERK;
  10451.             break;
  10452. //      case ???: // doesn't seem to do anything
  10453. //          sc->opt3 |= OPT3_LIGHTBLADE;
  10454. //          opt_flag = 0;
  10455. //          break;
  10456.         case SC_DANCING:
  10457.             if ((val1&0xFFFF) == CG_MOONLIT)
  10458.                 sc->opt3 |= OPT3_MOONLIT;
  10459.             opt_flag = 0;
  10460.             break;
  10461.         case SC_MARIONETTE:
  10462.         case SC_MARIONETTE2:
  10463.             sc->opt3 |= OPT3_MARIONETTE;
  10464.             opt_flag = 0;
  10465.             break;
  10466.         case SC_ASSUMPTIO:
  10467.             sc->opt3 |= OPT3_ASSUMPTIO;
  10468.             opt_flag = 0;
  10469.             break;
  10470.         case SC_WARM: // SG skills [Komurka]
  10471.             sc->opt3 |= OPT3_WARM;
  10472.             opt_flag = 0;
  10473.             break;
  10474.         case SC_KAITE:
  10475.             sc->opt3 |= OPT3_KAITE;
  10476.             opt_flag = 0;
  10477.             break;
  10478.         case SC_BUNSINJYUTSU:
  10479.             sc->opt3 |= OPT3_BUNSIN;
  10480.             opt_flag = 0;
  10481.             break;
  10482.         case SC_SPIRIT:
  10483.             sc->opt3 |= OPT3_SOULLINK;
  10484.             opt_flag = 0;
  10485.             break;
  10486.         case SC_CHANGEUNDEAD:
  10487.             sc->opt3 |= OPT3_UNDEAD;
  10488.             opt_flag = 0;
  10489.             break;
  10490. //      case ???: // from DA_CONTRACT (looks like biolab mobs aura)
  10491. //          sc->opt3 |= OPT3_CONTRACT;
  10492. //          opt_flag = 0;
  10493. //          break;
  10494.         // OPTION
  10495.         case SC_HIDING:
  10496.             sc->option |= OPTION_HIDE;
  10497.             opt_flag = 2;
  10498.             break;
  10499.         case SC_CLOAKING:
  10500.         case SC_CLOAKINGEXCEED:
  10501.         case SC__INVISIBILITY:
  10502.             sc->option |= OPTION_CLOAK;
  10503.         case SC_CAMOUFLAGE:
  10504.             opt_flag = 2;
  10505.             break;
  10506.         case SC_CHASEWALK:
  10507.             sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
  10508.             opt_flag = 2;
  10509.             break;
  10510.         case SC__FEINTBOMB:
  10511.             sc->option |= OPTION_INVISIBLE;
  10512.             opt_flag = 2;
  10513.             break;
  10514.         case SC_SIGHT:
  10515.             sc->option |= OPTION_SIGHT;
  10516.             break;
  10517.         case SC_RUWACH:
  10518.             sc->option |= OPTION_RUWACH;
  10519.             break;
  10520.         case SC_WEDDING:
  10521.             sc->option |= OPTION_WEDDING;
  10522.             opt_flag |= 0x4;
  10523.             break;
  10524.         case SC_XMAS:
  10525.             sc->option |= OPTION_XMAS;
  10526.             opt_flag |= 0x4;
  10527.             break;
  10528.         case SC_SUMMER:
  10529.             sc->option |= OPTION_SUMMER;
  10530.             opt_flag |= 0x4;
  10531.             break;
  10532.         case SC_HANBOK:
  10533.             sc->option |= OPTION_HANBOK;
  10534.             opt_flag |= 0x4;
  10535.             break;
  10536.         case SC_OKTOBERFEST:
  10537.             sc->option |= OPTION_OKTOBERFEST;
  10538.             opt_flag |= 0x4;
  10539.             break;
  10540.         case SC_ORCISH:
  10541.             sc->option |= OPTION_ORCISH;
  10542.             break;
  10543.         case SC_FUSION:
  10544.             sc->option |= OPTION_FLYING;
  10545.             break;
  10546.         default:
  10547.             opt_flag = 0;
  10548.     }
  10549.  
  10550.     // On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
  10551.     if(opt_flag) {
  10552.         clif_changeoption(bl);
  10553.         if(sd && (opt_flag&0x4)) {
  10554.             clif_changelook(bl,LOOK_BASE,vd->class_);
  10555.             clif_changelook(bl,LOOK_WEAPON,0);
  10556.             clif_changelook(bl,LOOK_SHIELD,0);
  10557.             clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
  10558.         }
  10559.     }
  10560.     if (calc_flag&SCB_DYE) { // Reset DYE color
  10561.         if (vd && vd->cloth_color) {
  10562.             val4 = vd->cloth_color;
  10563.             clif_changelook(bl,LOOK_CLOTHES_COLOR,0);
  10564.         }
  10565.         calc_flag&=~SCB_DYE;
  10566.     }
  10567.  
  10568.     if(!(flag&SCSTART_NOICON) && !(flag&SCSTART_LOADED && StatusDisplayType[type]))
  10569.         clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
  10570.  
  10571.     // Used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
  10572.     if( tick_time )
  10573.         tick = tick_time;
  10574.  
  10575.     // Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
  10576.     if((sce=sc->data[type])) { // reuse old sc
  10577.         if( sce->timer != INVALID_TIMER )
  10578.             delete_timer(sce->timer, status_change_timer);
  10579.         sc_isnew = false;
  10580.     } else { // New sc
  10581.         ++(sc->count);
  10582.         sce = sc->data[type] = ers_alloc(sc_data_ers, struct status_change_entry);
  10583.     }
  10584.     sce->val1 = val1;
  10585.     sce->val2 = val2;
  10586.     sce->val3 = val3;
  10587.     sce->val4 = val4;
  10588.     if (tick >= 0)
  10589.         sce->timer = add_timer(gettick() + tick, status_change_timer, bl->id, type);
  10590.     else
  10591.         sce->timer = INVALID_TIMER; // Infinite duration
  10592.  
  10593.     if (calc_flag)
  10594.         status_calc_bl(bl,calc_flag);
  10595.  
  10596.     if ( sc_isnew && StatusChangeStateTable[type] ) // Non-zero
  10597.         status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],true);
  10598.  
  10599.  
  10600.     if(sd) {
  10601.         if (sd->pd)
  10602.             pet_sc_check(sd, type); // Skotlex: Pet Status Effect Healing
  10603.         status_calc_pc(sd, SCO_NONE);
  10604.     }
  10605.  
  10606.     // 1st thing to execute when loading status
  10607.     switch (type) {
  10608.         case SC_FULL_THROTTLE:
  10609.             status_percent_heal(bl,100,0);
  10610.             break;
  10611.         case SC_BERSERK:
  10612.             if (!(sce->val2)) { // Don't heal if already set
  10613.                 status_heal(bl, status->max_hp, 0, 1); // Do not use percent_heal as this healing must override BERSERK's block.
  10614.                 status_set_sp(bl, 0, 0); // Damage all SP
  10615.             }
  10616.             sce->val2 = 5 * status->max_hp / 100;
  10617.             break;
  10618.         case SC_RUN:
  10619.             {
  10620.                 struct unit_data *ud = unit_bl2ud(bl);
  10621.  
  10622.                 if( ud )
  10623.                     ud->state.running = unit_run(bl, NULL, SC_RUN);
  10624.             }
  10625.             break;
  10626.         case SC_BOSSMAPINFO:
  10627.             clif_bossmapinfo(sd->fd, map_id2boss(sce->val1), 0); // First Message
  10628.             break;
  10629.         case SC_MERC_HPUP:
  10630.             status_percent_heal(bl, 100, 0); // Recover Full HP
  10631.             break;
  10632.         case SC_MERC_SPUP:
  10633.             status_percent_heal(bl, 0, 100); // Recover Full SP
  10634.             break;
  10635.         case SC_WUGDASH:
  10636.             {
  10637.                 struct unit_data *ud = unit_bl2ud(bl);
  10638.  
  10639.                 if( ud )
  10640.                     ud->state.running = unit_run(bl, sd, SC_WUGDASH);
  10641.             }
  10642.             break;
  10643.         case SC_COMBO:
  10644.             switch(sce->val1) {
  10645.             case TK_STORMKICK:
  10646.                 clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
  10647.                 break;
  10648.             case TK_DOWNKICK:
  10649.                 clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
  10650.                 break;
  10651.             case TK_TURNKICK:
  10652.                 clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
  10653.                 break;
  10654.             case TK_COUNTER:
  10655.                 clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
  10656.                 break;
  10657.             default: // Rest just toogle inf to enable autotarget
  10658.                 skill_combo_toogle_inf(bl,sce->val1,INF_SELF_SKILL);
  10659.                 break;
  10660.             }
  10661.             break;
  10662.         case SC_RAISINGDRAGON:
  10663.             sce->val2 = status->max_hp / 100; // Officially tested its 1%hp drain. [Jobbie]
  10664.             break;
  10665.         case SC_C_MARKER:
  10666.             //Send mini-map, don't wait for first timer triggered
  10667.             if (src->type == BL_PC && (sd = map_id2sd(src->id)))
  10668.                 clif_crimson_marker(sd, bl, false);
  10669.             break;
  10670.     }
  10671.  
  10672.     if( opt_flag&2 && sd && sd->touching_id )
  10673.         npc_touchnext_areanpc(sd,false); // Run OnTouch_ on next char in range
  10674.  
  10675.     return 1;
  10676. }
  10677.  
  10678. /**
  10679.  * End all statuses except those listed
  10680.  * TODO: May be useful for dispel instead resetting a list there
  10681.  * @param src: Source of the status change [PC|MOB|HOM|MER|ELEM|NPC]
  10682.  * @param type: Changes behaviour of the function
  10683.  *  0: PC killed -> Place here statuses that do not dispel on death.
  10684.  *  1: If for some reason status_change_end decides to still keep the status when quitting.
  10685.  *  2: Do clif_changeoption()
  10686.  *  3: Do not remove some permanent/time-independent effects
  10687.  * @return 1: Success 0: Fail
  10688.  */
  10689. int status_change_clear(struct block_list* bl, int type)
  10690. {
  10691.     struct status_change* sc;
  10692.     int i;
  10693.  
  10694.     sc = status_get_sc(bl);
  10695.  
  10696.     if (!sc || !sc->count)
  10697.         return 0;
  10698.  
  10699.     for(i = 0; i < SC_MAX; i++) {
  10700.         if(!sc->data[i])
  10701.             continue;
  10702.  
  10703.         if(type == 0) {
  10704.             switch (i) { // Type 0: PC killed -> Place here statuses that do not dispel on death.
  10705.             case SC_ELEMENTALCHANGE: // Only when its Holy or Dark that it doesn't dispell on death
  10706.                 if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK )
  10707.                     break;
  10708.             case SC_WEIGHT50:
  10709.             case SC_WEIGHT90:
  10710.             case SC_EDP:
  10711.             case SC_MELTDOWN:
  10712.             case SC_WEDDING:
  10713.             case SC_XMAS:
  10714.             case SC_SUMMER:
  10715.             case SC_HANBOK:
  10716.             case SC_OKTOBERFEST:
  10717.             case SC_NOCHAT:
  10718.             case SC_FUSION:
  10719.             case SC_EARTHSCROLL:
  10720.             case SC_READYSTORM:
  10721.             case SC_READYDOWN:
  10722.             case SC_READYCOUNTER:
  10723.             case SC_READYTURN:
  10724.             case SC_DODGE:
  10725.             case SC_JAILED:
  10726.             case SC_EXPBOOST:
  10727.             case SC_ITEMBOOST:
  10728.             case SC_HELLPOWER:
  10729.             case SC_JEXPBOOST:
  10730.             case SC_AUTOTRADE:
  10731.             case SC_WHISTLE:
  10732.             case SC_ASSNCROS:
  10733.             case SC_POEMBRAGI:
  10734.             case SC_APPLEIDUN:
  10735.             case SC_HUMMING:
  10736.             case SC_DONTFORGETME:
  10737.             case SC_FORTUNE:
  10738.             case SC_SERVICE4U:
  10739.             case SC_FOOD_STR_CASH:
  10740.             case SC_FOOD_AGI_CASH:
  10741.             case SC_FOOD_VIT_CASH:
  10742.             case SC_FOOD_DEX_CASH:
  10743.             case SC_FOOD_INT_CASH:
  10744.             case SC_FOOD_LUK_CASH:
  10745.             case SC_SAVAGE_STEAK:
  10746.             case SC_COCKTAIL_WARG_BLOOD:
  10747.             case SC_MINOR_BBQ:
  10748.             case SC_SIROMA_ICE_TEA:
  10749.             case SC_DROCERA_HERB_STEAMED:
  10750.             case SC_PUTTI_TAILS_NOODLES:
  10751.             case SC_DEF_RATE:
  10752.             case SC_MDEF_RATE:
  10753.             case SC_INCHEALRATE:
  10754.             case SC_INCFLEE2:
  10755.             case SC_INCHIT:
  10756.             case SC_ATKPOTION:
  10757.             case SC_MATKPOTION:
  10758.             case SC_S_LIFEPOTION:
  10759.             case SC_L_LIFEPOTION:
  10760.             case SC_PUSH_CART:
  10761.             case SC_ALL_RIDING:
  10762.             case SC_LIGHT_OF_REGENE:
  10763.             case SC_STYLE_CHANGE:
  10764.             case SC_MOONSTAR:
  10765.             case SC_SUPER_STAR:
  10766.             case SC_HEAT_BARREL_AFTER:
  10767.             case SC_STRANGELIGHTS:
  10768.             case SC_DECORATION_OF_MUSIC:
  10769.             case SC_QUEST_BUFF1:
  10770.             case SC_QUEST_BUFF2:
  10771.             case SC_QUEST_BUFF3:
  10772.             case SC_2011RWC_SCROLL:
  10773.             case SC_JP_EVENT04:
  10774.                 continue;
  10775.             }
  10776.         }
  10777.  
  10778.         if( type == 3 ) {
  10779.             switch (i) { // !TODO: This list may be incomplete
  10780.             case SC_WEIGHT50:
  10781.             case SC_WEIGHT90:
  10782.             case SC_NOCHAT:
  10783.             case SC_PUSH_CART:
  10784.             case SC_ALL_RIDING:
  10785.             case SC_STYLE_CHANGE:
  10786.             case SC_MOONSTAR:
  10787.             case SC_SUPER_STAR:
  10788.             case SC_STRANGELIGHTS:
  10789.             case SC_DECORATION_OF_MUSIC:
  10790.                 continue;
  10791.             }
  10792.         }
  10793.  
  10794.         status_change_end(bl, (sc_type)i, INVALID_TIMER);
  10795.  
  10796.         if( type == 1 && sc->data[i] ) { // If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
  10797.             (sc->count)--;
  10798.             if (sc->data[i]->timer != INVALID_TIMER)
  10799.                 delete_timer(sc->data[i]->timer, status_change_timer);
  10800.             ers_free(sc_data_ers, sc->data[i]);
  10801.             sc->data[i] = NULL;
  10802.         }
  10803.     }
  10804.  
  10805.     sc->opt1 = 0;
  10806.     sc->opt2 = 0;
  10807.     sc->opt3 = 0;
  10808.  
  10809.     // Cleaning all extras vars
  10810.     sc->comet_x = 0;
  10811.     sc->comet_y = 0;
  10812. #ifndef RENEWAL
  10813.     sc->sg_counter = 0;
  10814. #endif
  10815.     sc->bs_counter = 0;
  10816.  
  10817.     if( type == 0 || type == 2 )
  10818.         clif_changeoption(bl);
  10819.  
  10820.     return 1;
  10821. }
  10822.  
  10823. /**
  10824.  * End a specific status after checking
  10825.  * @param bl: Source of the status change [PC|MOB|HOM|MER|ELEM|NPC]
  10826.  * @param type: Status change (SC_*)
  10827.  * @param tid: Timer
  10828.  * @param file: Used for dancing save
  10829.  * @param line: Used for dancing save
  10830.  * @return 1: Success 0: Fail
  10831.  */
  10832. int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
  10833. {
  10834.     struct map_session_data *sd;
  10835.     struct status_change *sc;
  10836.     struct status_change_entry *sce;
  10837.     struct status_data *status;
  10838.     struct view_data *vd;
  10839.     int opt_flag = 0, calc_flag;
  10840.  
  10841.     nullpo_ret(bl);
  10842.  
  10843.     sc = status_get_sc(bl);
  10844.     status = status_get_status_data(bl);
  10845.  
  10846.     if(type < 0 || type >= SC_MAX || !sc || !(sce = sc->data[type]))
  10847.         return 0;
  10848.  
  10849.     sd = BL_CAST(BL_PC,bl);
  10850.  
  10851.     if (sce->timer != tid && tid != INVALID_TIMER)
  10852.         return 0;
  10853.  
  10854.     if (tid == INVALID_TIMER) {
  10855.         if (type == SC_ENDURE && sce->val4)
  10856.             // Do not end infinite endure.
  10857.             return 0;
  10858.         if (sce->timer != INVALID_TIMER) // Could be a SC with infinite duration
  10859.             delete_timer(sce->timer,status_change_timer);
  10860.         if (sc->opt1)
  10861.             switch (type) {
  10862.                 // "Ugly workaround"  [Skotlex]
  10863.                 // delays status change ending so that a skill that sets opt1 fails to
  10864.                 // trigger when it also removed one
  10865.                 case SC_STONE:
  10866.                     sce->val3 = 0; // Petrify time counter.
  10867.                 case SC_FREEZE:
  10868.                 case SC_STUN:
  10869.                 case SC_SLEEP:
  10870.                     if (sce->val1) {
  10871.                         // Removing the 'level' shouldn't affect anything in the code
  10872.                         // since these SC are not affected by it, and it lets us know
  10873.                         // if we have already delayed this attack or not.
  10874.                         sce->val1 = 0;
  10875.                         sce->timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
  10876.                         return 1;
  10877.                     }
  10878.             }
  10879.     }
  10880.  
  10881.     (sc->count)--;
  10882.  
  10883.     if ( StatusChangeStateTable[type] )
  10884.         status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
  10885.  
  10886.     sc->data[type] = NULL;
  10887.  
  10888.     if (sd && StatusDisplayType[type])
  10889.         status_display_remove(sd,type);
  10890.  
  10891.     vd = status_get_viewdata(bl);
  10892.     calc_flag = StatusChangeFlagTable[type];
  10893.     switch(type) {
  10894.         case SC_GRANITIC_ARMOR:
  10895.             {
  10896.                 int damage = status->max_hp*sce->val3/100;
  10897.                 if(status->hp < damage) // to not kill him
  10898.                     damage = status->hp-1;
  10899.                 status_damage(NULL,bl,damage,0,0,1);
  10900.             }
  10901.             break;
  10902.         case SC_PYROCLASTIC:
  10903.             if(bl->type == BL_PC)
  10904.                 skill_break_equip(bl,bl,EQP_WEAPON,10000,BCT_SELF);
  10905.             break;
  10906.         case SC_RUN:
  10907.         {
  10908.             struct unit_data *ud = unit_bl2ud(bl);
  10909.             bool begin_spurt = true;
  10910.             if (ud) {
  10911.                 if(!ud->state.running)
  10912.                     begin_spurt = false;
  10913.                 ud->state.running = 0;
  10914.                 if (ud->walktimer != INVALID_TIMER)
  10915.                     unit_stop_walking(bl,1);
  10916.             }
  10917.             if (begin_spurt && sce->val1 >= 7 &&
  10918.                 DIFF_TICK(gettick(), sce->val4) <= 1000 &&
  10919.                 (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
  10920.             )
  10921.                 sc_start(bl,bl,SC_SPURT,100,sce->val1,skill_get_time2(status_sc2skill(type), sce->val1));
  10922.         }
  10923.         break;
  10924.         case SC_AUTOBERSERK:
  10925.             if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
  10926.                 status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
  10927.             break;
  10928.  
  10929.         case SC_ENDURE:
  10930.         case SC_DEFENDER:
  10931.         case SC_REFLECTSHIELD:
  10932.         case SC_AUTOGUARD:
  10933.             {
  10934.                 struct map_session_data *tsd;
  10935.                 if( bl->type == BL_PC ) { // Clear Status from others
  10936.                     int i;
  10937.                     for( i = 0; i < MAX_DEVOTION; i++ ) {
  10938.                         if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type] )
  10939.                             status_change_end(&tsd->bl, type, INVALID_TIMER);
  10940.                     }
  10941.                 }
  10942.                 else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag ) { // Clear Status from Master
  10943.                     tsd = ((TBL_MER*)bl)->master;
  10944.                     if( tsd && tsd->sc.data[type] )
  10945.                         status_change_end(&tsd->bl, type, INVALID_TIMER);
  10946.                 }
  10947.             }
  10948.             break;
  10949.         case SC_DEVOTION:
  10950.             {
  10951.                 struct block_list *d_bl = map_id2bl(sce->val1);
  10952.                 if( d_bl ) {
  10953.                     if( d_bl->type == BL_PC )
  10954.                         ((TBL_PC*)d_bl)->devotion[sce->val2] = 0;
  10955.                     else if( d_bl->type == BL_MER )
  10956.                         ((TBL_MER*)d_bl)->devotion_flag = 0;
  10957.                     clif_devotion(d_bl, NULL);
  10958.                 }
  10959.  
  10960.                 status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
  10961.                 status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
  10962.                 status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
  10963.                 status_change_end(bl, SC_ENDURE, INVALID_TIMER);
  10964.             }
  10965.             break;
  10966.  
  10967.         case SC_BLADESTOP:
  10968.             if(sce->val4) {
  10969.                 int tid2 = sce->val4; //stop the status for the other guy of bladestop as well
  10970.                 struct block_list *tbl = map_id2bl(tid2);
  10971.                 struct status_change *tsc = status_get_sc(tbl);
  10972.                 sce->val4 = 0;
  10973.                 if(tbl && tsc && tsc->data[SC_BLADESTOP]) {
  10974.                     tsc->data[SC_BLADESTOP]->val4 = 0;
  10975.                     status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
  10976.                 }
  10977.                 clif_bladestop(bl, tid2, 0);
  10978.             }
  10979.             break;
  10980.         case SC_DANCING:
  10981.             {
  10982.                 const char* prevfile = "<unknown>";
  10983.                 int prevline = 0;
  10984.                 struct map_session_data *dsd;
  10985.                 struct status_change_entry *dsc;
  10986.  
  10987.                 if( sd ) {
  10988.                     if( sd->delunit_prevfile ) { // Initially this is NULL, when a character logs in
  10989.                         prevfile = sd->delunit_prevfile;
  10990.                         prevline = sd->delunit_prevline;
  10991.                     } else
  10992.                         prevfile = "<none>";
  10993.                     sd->delunit_prevfile = file;
  10994.                     sd->delunit_prevline = line;
  10995.                 }
  10996.  
  10997.                 if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4))) { // End status on partner as well
  10998.                     dsc = dsd->sc.data[SC_DANCING];
  10999.                     if(dsc) {
  11000.                         // This will prevent recursive loops.
  11001.                         dsc->val2 = dsc->val4 = 0;
  11002.                         status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
  11003.                     }
  11004.                 }
  11005.  
  11006.                 if(sce->val2) { // Erase associated land skill
  11007.                     struct skill_unit_group *group;
  11008.                     group = skill_id2group(sce->val2);
  11009.                     if( group == NULL ) {
  11010.                         ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
  11011.                             sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
  11012.                             sd ? sd->status.char_id : 0,
  11013.                             mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
  11014.                             prevfile, prevline,
  11015.                             file, line);
  11016.                     }
  11017.                     sce->val2 = 0;
  11018.                     skill_delunitgroup(group);
  11019.                 }
  11020.  
  11021.                 if((sce->val1&0xFFFF) == CG_MOONLIT)
  11022.                     clif_status_change(bl,SI_MOONLIT,0,0,0,0,0);
  11023.  
  11024.                 status_change_end(bl, SC_LONGING, INVALID_TIMER);
  11025.             }
  11026.             break;
  11027.         case SC_NOCHAT:
  11028.             if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
  11029.                 sd->status.manner = 0;
  11030.             if (sd && tid == INVALID_TIMER) {
  11031.                 clif_changestatus(sd,SP_MANNER,sd->status.manner);
  11032.                 clif_updatestatus(sd,SP_MANNER);
  11033.             }
  11034.             break;
  11035.         case SC_SPLASHER:
  11036.             {
  11037.                 struct block_list *src=map_id2bl(sce->val3);
  11038.                 if(src && tid != INVALID_TIMER)
  11039.                     skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL );
  11040.             }
  11041.             break;
  11042.         case SC_TINDER_BREAKER2:
  11043.         case SC_CLOSECONFINE2:{
  11044.             struct block_list *src = sce->val2?map_id2bl(sce->val2):NULL;
  11045.             struct status_change *sc2 = src?status_get_sc(src):NULL;
  11046.             enum sc_type type2 = ((type==SC_CLOSECONFINE2)?SC_CLOSECONFINE:SC_TINDER_BREAKER);
  11047.             if (src && sc2 && sc2->data[type2]) {
  11048.                 // If status was already ended, do nothing.
  11049.                 // Decrease count
  11050.                 if (type==SC_TINDER_BREAKER2 || (--(sc2->data[type2]->val1) <= 0)) // No more holds, free him up.
  11051.                     status_change_end(src, type2, INVALID_TIMER);
  11052.             }
  11053.         }
  11054.         case SC_TINDER_BREAKER:
  11055.         case SC_CLOSECONFINE:
  11056.             if (sce->val2 > 0) {
  11057.                 // Caster has been unlocked... nearby chars need to be unlocked.
  11058.                 int range = 1
  11059.                     +skill_get_range2(bl, status_sc2skill(type), sce->val1)
  11060.                     +skill_get_range2(bl, TF_BACKSLIDING, 1); // Since most people use this to escape the hold....
  11061.                 map_foreachinarea(status_change_timer_sub,
  11062.                     bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
  11063.             }
  11064.             break;
  11065.         case SC_COMBO:
  11066.             skill_combo_toogle_inf(bl,sce->val1,0);
  11067.             break;
  11068.         case SC_MARIONETTE:
  11069.         case SC_MARIONETTE2: // Marionette target
  11070.             if (sce->val1) { // Check for partner and end their marionette status as well
  11071.                 enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
  11072.                 struct block_list *pbl = map_id2bl(sce->val1);
  11073.                 struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
  11074.  
  11075.                 if (sc2 && sc2->data[type2]) {
  11076.                     sc2->data[type2]->val1 = 0;
  11077.                     status_change_end(pbl, type2, INVALID_TIMER);
  11078.                 }
  11079.             }
  11080.             break;
  11081.  
  11082.         case SC_CONCENTRATION:
  11083.             status_change_end(bl, SC_ENDURE, INVALID_TIMER);
  11084.             break;
  11085.         case SC_BERSERK:
  11086.             if(status->hp > 200 && sc && sc->data[SC__BLOODYLUST]) {
  11087.                 status_percent_heal(bl, 100, 0);
  11088.                 status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER);
  11089.             } else if (status->hp > 100 && sce->val2) // If val2 is removed, no HP penalty (dispelled?) [Skotlex]
  11090.                 status_set_hp(bl, 100, 0);
  11091.             if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) {
  11092.                 sc->data[SC_ENDURE]->val4 = 0;
  11093.                 status_change_end(bl, SC_ENDURE, INVALID_TIMER);
  11094.             }
  11095.             sc_start4(bl, bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
  11096.             break;
  11097.         case SC_GOSPEL:
  11098.             if (sce->val3) { // Clear the group.
  11099.                 struct skill_unit_group* group = skill_id2group(sce->val3);
  11100.                 sce->val3 = 0;
  11101.                 if (group)
  11102.                     skill_delunitgroup(group);
  11103.             }
  11104.             break;
  11105.         case SC_HERMODE:
  11106.             if(sce->val3 == BCT_SELF)
  11107.                 skill_clear_unitgroup(bl);
  11108.             break;
  11109.         case SC_BASILICA: // Clear the skill area. [Skotlex]
  11110.                 if (sce->val3 && sce->val4 == bl->id) {
  11111.                     struct skill_unit_group* group = skill_id2group(sce->val3);
  11112.                     sce->val3 = 0;
  11113.                     if (group)
  11114.                         skill_delunitgroup(group);
  11115.                 }
  11116.                 break;
  11117.         case SC_TRICKDEAD:
  11118.             if (vd) vd->dead_sit = 0;
  11119.             break;
  11120.         case SC_WARM:
  11121.         case SC__MANHOLE:
  11122.             if (sce->val4) { // Clear the group.
  11123.                 struct skill_unit_group* group = skill_id2group(sce->val4);
  11124.                 sce->val4 = 0;
  11125.                 if( group ) // Might have been cleared before status ended, e.g. land protector
  11126.                     skill_delunitgroup(group);
  11127.             }
  11128.             break;
  11129.         case SC_JAILED:
  11130.             if(tid == INVALID_TIMER)
  11131.                 break;
  11132.             // Natural expiration.
  11133.             if(sd && sd->mapindex == sce->val2)
  11134.                 pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
  11135.             break; // Guess hes not in jail :P
  11136.         case SC_CHANGE:
  11137.             if (tid == INVALID_TIMER)
  11138.                 break;
  11139.             // "lose almost all their HP and SP" on natural expiration.
  11140.             status_set_hp(bl, 10, 0);
  11141.             status_set_sp(bl, 10, 0);
  11142.             break;
  11143.         case SC_AUTOTRADE:
  11144.             if (tid == INVALID_TIMER)
  11145.                 break;
  11146.             // Vending is not automatically closed for autovenders
  11147.             vending_closevending(sd);
  11148.             map_quit(sd);
  11149.             // Because map_quit calls status_change_end with tid -1
  11150.             // from here it's not neccesary to continue
  11151.             return 1;
  11152.             break;
  11153.         case SC_STOP:
  11154.             if( sce->val2 ) {
  11155.                 struct block_list* tbl = map_id2bl(sce->val2);
  11156.                 sce->val2 = 0;
  11157.                 if( tbl && (sc = status_get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id )
  11158.                     status_change_end(tbl, SC_STOP, INVALID_TIMER);
  11159.             }
  11160.             break;
  11161.         case SC_MONSTER_TRANSFORM:
  11162.             if (sce->val2)
  11163.                 status_change_end(bl, (sc_type)sce->val2, INVALID_TIMER);
  11164.             break;
  11165.  
  11166.         /* 3rd Stuff */
  11167.         case SC_MILLENNIUMSHIELD:
  11168.             clif_millenniumshield(bl, 0);
  11169.             break;
  11170.         case SC_HALLUCINATIONWALK:
  11171.             sc_start(bl,bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill_get_time2(GC_HALLUCINATIONWALK,sce->val1));
  11172.             break;
  11173.         case SC_WHITEIMPRISON:
  11174.             {
  11175.                 struct block_list* src = map_id2bl(sce->val2);
  11176.                 if( tid == -1 || !src)
  11177.                     break; // Terminated by Damage
  11178.                 status_fix_damage(src,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,DMG_NORMAL,0));
  11179.             }
  11180.             break;
  11181.         case SC_WUGDASH:
  11182.             {
  11183.                 struct unit_data *ud = unit_bl2ud(bl);
  11184.                 if (ud) {
  11185.                     ud->state.running = 0;
  11186.                     if (ud->walktimer != INVALID_TIMER)
  11187.                         unit_stop_walking(bl,1);
  11188.                 }
  11189.             }
  11190.             break;
  11191.         case SC_ADORAMUS:
  11192.             status_change_end(bl, SC_BLIND, INVALID_TIMER);
  11193.             break;
  11194.         case SC__SHADOWFORM:
  11195.             {
  11196.                 struct map_session_data *s_sd = map_id2sd(sce->val2);
  11197.                 if(s_sd ) s_sd->shadowform_id = 0;
  11198.             }
  11199.             break;
  11200.         case SC__FEINTBOMB:
  11201.             if( sd && pc_ishiding(sd) ) {
  11202.                 status_change_end(bl, SC_HIDING, INVALID_TIMER);
  11203.                 status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  11204.                 status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
  11205.                 status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
  11206.             }
  11207.             break;
  11208.         case SC_SATURDAYNIGHTFEVER: // Sit down force of Saturday Night Fever has the duration of only 3 seconds.
  11209.             sc_start(bl, bl,SC_SITDOWN_FORCE,100,sce->val1,skill_get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
  11210.             break;
  11211.         case SC_SITDOWN_FORCE:
  11212.             if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
  11213.                 clif_standing(bl);
  11214.             }
  11215.             break;
  11216.         case SC_NEUTRALBARRIER_MASTER:
  11217.         case SC_STEALTHFIELD_MASTER:
  11218.             if( sce->val2 ) {
  11219.                 struct skill_unit_group* group = skill_id2group(sce->val2);
  11220.                 sce->val2 = 0;
  11221.                 if( group ) // Might have been cleared before status ended, e.g. land protector
  11222.                     skill_delunitgroup(group);
  11223.             }
  11224.             break;
  11225.         case SC_BANDING:
  11226.             if(sce->val4) {
  11227.                 struct skill_unit_group *group = skill_id2group(sce->val4);
  11228.                 sce->val4 = 0;
  11229.                 if( group ) // Might have been cleared before status ended, e.g. land protector
  11230.                     skill_delunitgroup(group);
  11231.             }
  11232.             break;
  11233.         case SC_CURSEDCIRCLE_ATKER:
  11234.             if( sce->val2 ) // Used the default area size cause there is a chance the caster could knock back and can't clear the target.
  11235.                 map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
  11236.             break;
  11237.         case SC_RAISINGDRAGON:
  11238.             if( sd && sce->val2 && !pc_isdead(sd) ) {
  11239.                 int i = min(sd->spiritball,5);
  11240.                 pc_delspiritball(sd, sd->spiritball, 0);
  11241.                 status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
  11242.                 while( i > 0 ) {
  11243.                     pc_addspiritball(sd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), 5);
  11244.                     --i;
  11245.                 }
  11246.             }
  11247.             break;
  11248.         case SC_CURSEDCIRCLE_TARGET:
  11249.             {
  11250.                 struct block_list *src = map_id2bl(sce->val2);
  11251.                 struct status_change *sc2 = status_get_sc(src);
  11252.                 if( sc2 && sc2->data[SC_CURSEDCIRCLE_ATKER] && --(sc2->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ) {
  11253.                     status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER);
  11254.                     clif_bladestop(bl, sce->val2, 0);
  11255.                 }
  11256.             }
  11257.             break;
  11258.         case SC_BLOODSUCKER:
  11259.             if( sce->val2 ) {
  11260.                 struct block_list *src = map_id2bl(sce->val2);
  11261.                 if(src) {
  11262.                     struct status_change *sc2 = status_get_sc(src);
  11263.                     sc2->bs_counter--;
  11264.                 }
  11265.             }
  11266.             break;
  11267.         case SC_TEARGAS:
  11268.             status_change_end(bl,SC_TEARGAS_SOB,INVALID_TIMER);
  11269.             break;
  11270.         case SC_BANANA_BOMB_SITDOWN:
  11271.             if( sd && pc_issit(sd) && pc_setstand(sd, false) ) {
  11272.                 skill_sit(sd,0);
  11273.                 clif_standing(bl);
  11274.             }
  11275.             break;
  11276.         case SC_KYOUGAKU:
  11277.             clif_status_load(bl, SI_KYOUGAKU, 0); // Avoid client crash
  11278.             clif_status_load(bl, SI_ACTIVE_MONSTER_TRANSFORM, 0);
  11279.             break;
  11280.         case SC_INTRAVISION:
  11281.             calc_flag = SCB_ALL; // Required for overlapping
  11282.             break;
  11283.         case SC_OVERED_BOOST:
  11284.             switch (bl->type) {
  11285.                 case BL_HOM: {
  11286.                         struct homun_data *hd = BL_CAST(BL_HOM,bl);
  11287.  
  11288.                         if( hd )
  11289.                             hd->homunculus.hunger = max(1,hd->homunculus.hunger - 50);
  11290.                     }
  11291.                     break;
  11292.                 case BL_PC:
  11293.                     status_zap(bl,0,status_get_max_sp(bl) / 2);
  11294.                     break;
  11295.             }
  11296.             break;
  11297.         case SC_FULL_THROTTLE: {
  11298.                 int sec = skill_get_time2(status_sc2skill(type), sce->val1);
  11299.  
  11300.                 clif_status_change(bl, SI_DECREASEAGI, 1, sec, 0, 0, 0);
  11301.                 sc_start(bl, bl, SC_REBOUND, 100, sce->val1, sec);
  11302.             }
  11303.             break;
  11304.         case SC_REBOUND:
  11305.             clif_status_load(bl, SI_DECREASEAGI, 0);
  11306.             break;
  11307.         case SC_ITEMSCRIPT: // Removes Buff Icons
  11308.             if (sd && sce->val2 != SI_BLANK)
  11309.                 clif_status_load(bl, (enum si_type)sce->val2, 0);
  11310.             break;
  11311.         case SC_HEAT_BARREL:
  11312.             if (sd)
  11313.                 sc_start(bl,bl,SC_HEAT_BARREL_AFTER,100,sce->val1,skill_get_time2(RL_HEAT_BARREL, sce->val1));
  11314.             break;
  11315.         case SC_C_MARKER:
  11316.             {
  11317.                 // Remove mark data from caster
  11318.                 struct map_session_data *caster = map_id2sd(sce->val2);
  11319.                 uint8 i = 0;
  11320.  
  11321.                 if (!caster)
  11322.                     break;
  11323.                 ARR_FIND(0,MAX_SKILL_CRIMSON_MARKER,i,caster->c_marker[i] == bl->id);
  11324.                 if (i < MAX_SKILL_CRIMSON_MARKER) {
  11325.                     caster->c_marker[i] = 0;
  11326.                     clif_crimson_marker(caster, bl, true);
  11327.                 }
  11328.             }
  11329.             break;
  11330.         case SC_H_MINE:
  11331.             {
  11332.                 // Drop the material from target if expired
  11333.                 struct item it;
  11334.                 struct map_session_data *caster = NULL;
  11335.  
  11336.                 if (sce->val3 || status_isdead(bl) || !(caster = map_id2sd(sce->val2)))
  11337.                     break;
  11338.                 if (!itemdb_exists(skill_get_itemid(RL_H_MINE,0)))
  11339.                     break;
  11340.                 memset(&it, 0, sizeof(it));
  11341.                 it.nameid = skill_get_itemid(RL_H_MINE,0);
  11342.                 it.amount = max(skill_get_itemqty(RL_H_MINE,0),1);
  11343.                 it.identify = 1;
  11344.                 map_addflooritem(&it, it.amount, bl->m,bl->x, bl->y, caster->status.char_id, 0, 0, 4);
  11345.             }
  11346.             break;
  11347.         case SC_VACUUM_EXTREME:
  11348.             ///< !CHECKME: Seems on official, there's delay before same target can be vacuumed in same area again [Cydh]
  11349.             sc_start2(bl, bl, SC_VACUUM_EXTREME_POSTDELAY, 100, sce->val1, sce->val2, skill_get_time2(SO_VACUUM_EXTREME,sce->val1));
  11350.             break;
  11351.     }
  11352.  
  11353.     opt_flag = 1;
  11354.     switch(type) {
  11355.     case SC_STONE:
  11356.     case SC_FREEZE:
  11357.     case SC_STUN:
  11358.     case SC_SLEEP:
  11359.     case SC_DEEPSLEEP:
  11360.     case SC_BURNING:
  11361.     case SC_WHITEIMPRISON:
  11362.     case SC_CRYSTALIZE:
  11363.         sc->opt1 = 0;
  11364.         break;
  11365.  
  11366.     case SC_POISON:
  11367.     case SC_CURSE:
  11368.     case SC_SILENCE:
  11369.     case SC_BLIND:
  11370.         sc->opt2 &= ~(1<<(type-SC_POISON));
  11371.         break;
  11372.     case SC_DPOISON:
  11373.         sc->opt2 &= ~OPT2_DPOISON;
  11374.         break;
  11375.     case SC_SIGNUMCRUCIS:
  11376.         sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
  11377.         break;
  11378.  
  11379.     case SC_HIDING:
  11380.         sc->option &= ~OPTION_HIDE;
  11381.         opt_flag |= 2|4; // Check for warp trigger + AoE trigger
  11382.         break;
  11383.     case SC_CLOAKING:
  11384.     case SC_CLOAKINGEXCEED:
  11385.     case SC__INVISIBILITY:
  11386.         sc->option &= ~OPTION_CLOAK;
  11387.     case SC_CAMOUFLAGE:
  11388.         opt_flag |= 2;
  11389.         break;
  11390.     case SC_CHASEWALK:
  11391.         sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
  11392.         opt_flag |= 2;
  11393.         break;
  11394.     case SC__FEINTBOMB:
  11395.         sc->option &= ~OPTION_INVISIBLE;
  11396.         opt_flag |= 2;
  11397.     case SC_SIGHT:
  11398.         sc->option &= ~OPTION_SIGHT;
  11399.         break;
  11400.     case SC_WEDDING:
  11401.         sc->option &= ~OPTION_WEDDING;
  11402.         opt_flag |= 0x4;
  11403.         break;
  11404.     case SC_XMAS:
  11405.         sc->option &= ~OPTION_XMAS;
  11406.         opt_flag |= 0x4;
  11407.         break;
  11408.     case SC_SUMMER:
  11409.         sc->option &= ~OPTION_SUMMER;
  11410.         opt_flag |= 0x4;
  11411.         break;
  11412.     case SC_HANBOK:
  11413.         sc->option &= ~OPTION_HANBOK;
  11414.         opt_flag |= 0x4;
  11415.         break;
  11416.     case SC_OKTOBERFEST:
  11417.         sc->option &= ~OPTION_OKTOBERFEST;
  11418.         opt_flag |= 0x4;
  11419.         break;
  11420.     case SC_ORCISH:
  11421.         sc->option &= ~OPTION_ORCISH;
  11422.         break;
  11423.     case SC_RUWACH:
  11424.         sc->option &= ~OPTION_RUWACH;
  11425.         break;
  11426.     case SC_FUSION:
  11427.         sc->option &= ~OPTION_FLYING;
  11428.         break;
  11429.     // opt3
  11430.     case SC_TWOHANDQUICKEN:
  11431.     case SC_ONEHAND:
  11432.     case SC_SPEARQUICKEN:
  11433.     case SC_CONCENTRATION:
  11434.     case SC_MERC_QUICKEN:
  11435.         sc->opt3 &= ~OPT3_QUICKEN;
  11436.         opt_flag = 0;
  11437.         break;
  11438.     case SC_OVERTHRUST:
  11439.     case SC_MAXOVERTHRUST:
  11440.     case SC_SWOO:
  11441.         sc->opt3 &= ~OPT3_OVERTHRUST;
  11442.         if( type == SC_SWOO )
  11443.             opt_flag = 8;
  11444.         else
  11445.             opt_flag = 0;
  11446.         break;
  11447.     case SC_ENERGYCOAT:
  11448.     case SC_SKE:
  11449.         sc->opt3 &= ~OPT3_ENERGYCOAT;
  11450.         opt_flag = 0;
  11451.         break;
  11452.     case SC_INCATKRATE: // Simulated Explosion spirits effect.
  11453.         if (bl->type != BL_MOB) {
  11454.             opt_flag = 0;
  11455.             break;
  11456.         }
  11457.     case SC_EXPLOSIONSPIRITS:
  11458.         sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
  11459.         opt_flag = 0;
  11460.         break;
  11461.     case SC_STEELBODY:
  11462.     case SC_SKA:
  11463.         sc->opt3 &= ~OPT3_STEELBODY;
  11464.         opt_flag = 0;
  11465.         break;
  11466.     case SC_BLADESTOP:
  11467.         sc->opt3 &= ~OPT3_BLADESTOP;
  11468.         opt_flag = 0;
  11469.         break;
  11470.     case SC_AURABLADE:
  11471.         sc->opt3 &= ~OPT3_AURABLADE;
  11472.         opt_flag = 0;
  11473.         break;
  11474.     case SC_BERSERK:
  11475.         opt_flag = 0;
  11476.         sc->opt3 &= ~OPT3_BERSERK;
  11477.         break;
  11478. //  case ???: // doesn't seem to do anything
  11479. //      sc->opt3 &= ~OPT3_LIGHTBLADE;
  11480. //      opt_flag = 0;
  11481. //      break;
  11482.     case SC_DANCING:
  11483.         if ((sce->val1&0xFFFF) == CG_MOONLIT)
  11484.             sc->opt3 &= ~OPT3_MOONLIT;
  11485.         opt_flag = 0;
  11486.         break;
  11487.     case SC_MARIONETTE:
  11488.     case SC_MARIONETTE2:
  11489.         sc->opt3 &= ~OPT3_MARIONETTE;
  11490.         opt_flag = 0;
  11491.         break;
  11492.     case SC_ASSUMPTIO:
  11493.         sc->opt3 &= ~OPT3_ASSUMPTIO;
  11494.         opt_flag = 0;
  11495.         break;
  11496.     case SC_WARM: // SG skills [Komurka]
  11497.         sc->opt3 &= ~OPT3_WARM;
  11498.         opt_flag = 0;
  11499.         break;
  11500.     case SC_KAITE:
  11501.         sc->opt3 &= ~OPT3_KAITE;
  11502.         opt_flag = 0;
  11503.         break;
  11504.     case SC_BUNSINJYUTSU:
  11505.         sc->opt3 &= ~OPT3_BUNSIN;
  11506.         opt_flag = 0;
  11507.         break;
  11508.     case SC_SPIRIT:
  11509.         sc->opt3 &= ~OPT3_SOULLINK;
  11510.         opt_flag = 0;
  11511.         break;
  11512.     case SC_CHANGEUNDEAD:
  11513.         sc->opt3 &= ~OPT3_UNDEAD;
  11514.         opt_flag = 0;
  11515.         break;
  11516. //  case ???: // from DA_CONTRACT (looks like biolab mobs aura)
  11517. //      sc->opt3 &= ~OPT3_CONTRACT;
  11518. //      opt_flag = 0;
  11519. //      break;
  11520.     default:
  11521.         opt_flag = 0;
  11522.     }
  11523.  
  11524.     if (calc_flag&SCB_DYE) { // Restore DYE color
  11525.         if (vd && !vd->cloth_color && sce->val4)
  11526.             clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
  11527.         calc_flag&=~SCB_DYE;
  11528.     }
  11529.  
  11530.     // On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
  11531.     clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
  11532.  
  11533.     if( opt_flag&8 ) // bugreport:681
  11534.         clif_changeoption2(bl);
  11535.     else if(opt_flag) {
  11536.         clif_changeoption(bl);
  11537.         if (sd && (opt_flag&0x4)) {
  11538.             clif_changelook(bl,LOOK_BASE,sd->vd.class_);
  11539.             clif_get_weapon_view(sd,&sd->vd.weapon,&sd->vd.shield);
  11540.             clif_changelook(bl,LOOK_WEAPON,sd->vd.weapon);
  11541.             clif_changelook(bl,LOOK_SHIELD,sd->vd.shield);
  11542.             clif_changelook(bl,LOOK_CLOTHES_COLOR,cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color));
  11543.         }
  11544.     }
  11545.     if (calc_flag)
  11546.         status_calc_bl(bl,calc_flag);
  11547.  
  11548.     if(opt_flag&4) // Out of hiding, invoke on place.
  11549.         skill_unit_move(bl,gettick(),1);
  11550.  
  11551.     if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
  11552.         npc_touch_areanpc(sd,bl->m,bl->x,bl->y); // Trigger on-touch event.
  11553.  
  11554.     ers_free(sc_data_ers, sce);
  11555.     return 1;
  11556. }
  11557.  
  11558. /**
  11559.  * Resets timers for statuses
  11560.  * Used with reoccurring status effects, such as dropping SP every 5 seconds
  11561.  * @param tid: Timer ID
  11562.  * @param tick: How long before next call
  11563.  * @param id: ID of character
  11564.  * @param data: Information passed through the timer call
  11565.  * @return 1: Success 0: Fail
  11566.  */
  11567. int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
  11568. {
  11569.     enum sc_type type = (sc_type)data;
  11570.     struct block_list *bl;
  11571.     struct map_session_data *sd;
  11572.     struct status_data *status;
  11573.     struct status_change *sc;
  11574.     struct status_change_entry *sce;
  11575.  
  11576.     bl = map_id2bl(id);
  11577.     if(!bl) {
  11578.         ShowDebug("status_change_timer: Null pointer id: %d data: %d\n", id, data);
  11579.         return 0;
  11580.     }
  11581.     sc = status_get_sc(bl);
  11582.     status = status_get_status_data(bl);
  11583.  
  11584.     if(!(sc && (sce = sc->data[type]))) {
  11585.         ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type);
  11586.         return 0;
  11587.     }
  11588.  
  11589.     if( sce->timer != tid ) {
  11590.         ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id);
  11591.         return 0;
  11592.     }
  11593.  
  11594.     sd = BL_CAST(BL_PC, bl);
  11595.  
  11596. // Set the next timer of the sce (don't assume the status still exists)
  11597. #define sc_timer_next(t,f,i,d) \
  11598.     if( (sce=sc->data[type]) ) \
  11599.         sce->timer = add_timer(t,f,i,d); \
  11600.     else \
  11601.         ShowError("status_change_timer: Unexpected NULL status change id: %d data: %d\n", id, data)
  11602.  
  11603.     switch(type) {
  11604.     case SC_MAXIMIZEPOWER:
  11605.     case SC_CLOAKING:
  11606.         if(!status_charge(bl, 0, 1))
  11607.             break; // Not enough SP to continue.
  11608.         sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
  11609.         return 0;
  11610.  
  11611.     case SC_CHASEWALK:
  11612.         if(!status_charge(bl, 0, sce->val4))
  11613.             break; // Not enough SP to continue.
  11614.  
  11615.         if (!sc->data[SC_CHASEWALK2]) {
  11616.             sc_start(bl,bl, SC_CHASEWALK2,100,1<<(sce->val1-1),
  11617.                 (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) // SL bonus -> x10 duration
  11618.                 *skill_get_time2(status_sc2skill(type),sce->val1));
  11619.         }
  11620.         sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
  11621.         return 0;
  11622.     break;
  11623.  
  11624.     case SC_SKA:
  11625.         if(--(sce->val2)>0) {
  11626.             sce->val3 = rnd()%100; // Random defense.
  11627.             sc_timer_next(1000+tick, status_change_timer,bl->id, data);
  11628.             return 0;
  11629.         }
  11630.         break;
  11631.  
  11632.     case SC_HIDING:
  11633.         if(--(sce->val2)>0) {
  11634.  
  11635.             if(sce->val2 % sce->val4 == 0 && !status_charge(bl, 0, 1))
  11636.                 break; // Fail if it's time to substract SP and there isn't.
  11637.  
  11638.             sc_timer_next(1000+tick, status_change_timer,bl->id, data);
  11639.             return 0;
  11640.         }
  11641.     break;
  11642.  
  11643.     case SC_SIGHT:
  11644.     case SC_RUWACH:
  11645.     case SC_SIGHTBLASTER:
  11646.         if(type == SC_SIGHTBLASTER) {
  11647.             //Restore trap immunity
  11648.             if(sce->val4%2)
  11649.                 sce->val4--;
  11650.             map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR|BL_SKILL, bl, sce, type, tick);
  11651.         } else
  11652.             map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
  11653.  
  11654.         if( --(sce->val2)>0 ) {
  11655.             sce->val4 += 20; // Use for Shadow Form 2 seconds checking.
  11656.             sc_timer_next(20+tick, status_change_timer, bl->id, data);
  11657.             return 0;
  11658.         }
  11659.         break;
  11660.  
  11661.     case SC_PROVOKE:
  11662.         if(sce->val2) { // Auto-provoke (it is ended in status_heal)
  11663.             sc_timer_next(1000*60+tick,status_change_timer, bl->id, data );
  11664.             return 0;
  11665.         }
  11666.         break;
  11667.  
  11668.     case SC_STONE:
  11669.         if(sc->opt1 == OPT1_STONEWAIT && sce->val3) {
  11670.             sce->val4 = 0;
  11671.             unit_stop_walking(bl,1);
  11672.             unit_stop_attack(bl);
  11673.             sc->opt1 = OPT1_STONE;
  11674.             clif_changeoption(bl);
  11675.             sc_timer_next(1000+tick,status_change_timer, bl->id, data );
  11676.             status_calc_bl(bl, StatusChangeFlagTable[type]);
  11677.             return 0;
  11678.         }
  11679.         if(--(sce->val3) > 0) {
  11680.             if(++(sce->val4)%5 == 0 && status->hp > status->max_hp/4)
  11681.                 status_percent_damage(NULL, bl, 1, 0, false);
  11682.             sc_timer_next(1000+tick,status_change_timer, bl->id, data );
  11683.             return 0;
  11684.         }
  11685.         break;
  11686.  
  11687.     case SC_POISON:
  11688.     case SC_DPOISON:
  11689.         if (--(sce->val3) > 0) {
  11690.             if (!sc->data[SC_SLOWPOISON]) {
  11691.                 if( sce->val2 && bl->type == BL_MOB ) {
  11692.                     struct block_list* src = map_id2bl(sce->val2);
  11693.                     if( src )
  11694.                         mob_log_damage((TBL_MOB*)bl,src,sce->val4);
  11695.                 }
  11696.                 map_freeblock_lock();
  11697.                 if(status->hp >= max(status->max_hp>>2, sce->val4)) // Stop damaging after 25% HP left.
  11698.                     status_zap(bl, sce->val4, 0);
  11699.                 if (sc->data[type]) { // Check if the status still last ( can be dead since then ).
  11700.                     sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
  11701.                 }
  11702.                 map_freeblock_unlock();
  11703.             }
  11704.             return 0;
  11705.         }
  11706.  
  11707.         break;
  11708.  
  11709.     case SC_TENSIONRELAX:
  11710.         if(status->max_hp > status->hp && --(sce->val3) >= 0) {
  11711.             sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  11712.             return 0;
  11713.         }
  11714.         break;
  11715.  
  11716.     case SC_KNOWLEDGE:
  11717.         if (!sd) break;
  11718.         if(bl->m == sd->feel_map[0].m ||
  11719.             bl->m == sd->feel_map[1].m ||
  11720.             bl->m == sd->feel_map[2].m)
  11721.         {   // Timeout will be handled by pc_setpos
  11722.             sce->timer = INVALID_TIMER;
  11723.             return 0;
  11724.         }
  11725.         break;
  11726.  
  11727.     case SC_BLEEDING:
  11728.         if (--(sce->val4) >= 0) {
  11729.             int hp =  rnd()%600 + 200;
  11730.             struct block_list* src = map_id2bl(sce->val2);
  11731.             if( src && bl && bl->type == BL_MOB )
  11732.                 mob_log_damage( (TBL_MOB*)bl, src, sd || hp < status->hp ? hp : status->hp - 1 );
  11733.             map_freeblock_lock();
  11734.             status_fix_damage(src, bl, sd||hp<status->hp?hp:status->hp-1, 1);
  11735.             if( sc->data[type] ) {
  11736.                 if( status->hp == 1 ) {
  11737.                     map_freeblock_unlock();
  11738.                     break;
  11739.                 }
  11740.                 sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  11741.             }
  11742.             map_freeblock_unlock();
  11743.             return 0;
  11744.         }
  11745.         break;
  11746.  
  11747.     case SC_S_LIFEPOTION:
  11748.     case SC_L_LIFEPOTION:
  11749.         if( sd && --(sce->val4) >= 0 ) {
  11750.             // val1 < 0 = per max% | val1 > 0 = exact amount
  11751.             int hp = 0;
  11752.             if( status->hp < status->max_hp )
  11753.                 hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
  11754.             status_heal(bl, hp, 0, 2);
  11755.             sc_timer_next((sce->val2 * 1000) + tick, status_change_timer, bl->id, data);
  11756.             return 0;
  11757.         }
  11758.         break;
  11759.  
  11760.     case SC_BOSSMAPINFO:
  11761.         if( sd && --(sce->val4) >= 0 ) {
  11762.             struct mob_data *boss_md = map_id2boss(sce->val1);
  11763.             if( boss_md && sd->bl.m == boss_md->bl.m ) {
  11764.                 clif_bossmapinfo(sd->fd, boss_md, 1); // Update X, Y on minimap
  11765.                 if (boss_md->bl.prev != NULL) {
  11766.                     sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  11767.                     return 0;
  11768.                 }
  11769.             }
  11770.         }
  11771.         break;
  11772.  
  11773.     case SC_DANCING: // SP consumption by time of dancing skills
  11774.         {
  11775.             int s = 0;
  11776.             int sp = 1;
  11777.             if (--sce->val3 <= 0)
  11778.                 break;
  11779.             switch(sce->val1&0xFFFF) {
  11780.                 case BD_RICHMANKIM:
  11781.                 case BD_DRUMBATTLEFIELD:
  11782.                 case BD_RINGNIBELUNGEN:
  11783.                 case BD_SIEGFRIED:
  11784.                 case BA_DISSONANCE:
  11785.                 case BA_ASSASSINCROSS:
  11786.                 case DC_UGLYDANCE:
  11787.                     s=3;
  11788.                     break;
  11789.                 case BD_LULLABY:
  11790.                 case BD_ETERNALCHAOS:
  11791.                 case BD_ROKISWEIL:
  11792.                 case DC_FORTUNEKISS:
  11793.                     s=4;
  11794.                     break;
  11795.                 case CG_HERMODE:
  11796.                 case BD_INTOABYSS:
  11797.                 case BA_WHISTLE:
  11798.                 case DC_HUMMING:
  11799.                 case BA_POEMBRAGI:
  11800.                 case DC_SERVICEFORYOU:
  11801.                     s=5;
  11802.                     break;
  11803.                 case BA_APPLEIDUN:
  11804.                     #ifdef RENEWAL
  11805.                         s=5;
  11806.                     #else
  11807.                         s=6;
  11808.                     #endif
  11809.                     break;
  11810.                 case CG_MOONLIT:
  11811.                     // Moonlit's cost is 4sp*skill_lv [Skotlex]
  11812.                     sp= 4*(sce->val1>>16);
  11813.                     // Upkeep is also every 10 secs.
  11814.                 case DC_DONTFORGETME:
  11815.                     s=10;
  11816.                     break;
  11817.             }
  11818.             if( s != 0 && sce->val3 % s == 0 ) {
  11819.                 if (sc->data[SC_LONGING])
  11820.                     sp*= 3;
  11821.                 if (!status_charge(bl, 0, sp))
  11822.                     break;
  11823.             }
  11824.             sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  11825.             return 0;
  11826.         }
  11827.         break;
  11828.     case SC_BERSERK:
  11829.         // 5% every 10 seconds [DracoRPG]
  11830.         if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 ) {
  11831.             sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
  11832.             return 0;
  11833.         }
  11834.         break;
  11835.  
  11836.     case SC_NOCHAT:
  11837.         if(sd) {
  11838.             sd->status.manner++;
  11839.             clif_changestatus(sd,SP_MANNER,sd->status.manner);
  11840.             clif_updatestatus(sd,SP_MANNER);
  11841.             if (sd->status.manner < 0) { // Every 60 seconds your manner goes up by 1 until it gets back to 0.
  11842.                 sc_timer_next(60000+tick, status_change_timer, bl->id, data);
  11843.                 return 0;
  11844.             }
  11845.         }
  11846.         break;
  11847.  
  11848.     case SC_SPLASHER:
  11849.         // Custom Venom Splasher countdown timer
  11850.         // if (sce->val4 % 1000 == 0) {
  11851.         //  char timer[10];
  11852.         //  snprintf (timer, 10, "%d", sce->val4/1000);
  11853.         //  clif_message(bl, timer);
  11854.         // }
  11855.         if((sce->val4 -= 500) > 0) {
  11856.             sc_timer_next(500 + tick, status_change_timer, bl->id, data);
  11857.             return 0;
  11858.         }
  11859.         break;
  11860.  
  11861.     case SC_MARIONETTE:
  11862.     case SC_MARIONETTE2:
  11863.         {
  11864.             struct block_list *pbl = map_id2bl(sce->val1);
  11865.             if( pbl && check_distance_bl(bl, pbl, 7) ) {
  11866.                 sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  11867.                 return 0;
  11868.             }
  11869.         }
  11870.         break;
  11871.  
  11872.     case SC_GOSPEL:
  11873.         if(sce->val4 == BCT_SELF && --(sce->val2) > 0) {
  11874.             int hp, sp;
  11875.             hp = (sce->val1 > 5) ? 45 : 30;
  11876.             sp = (sce->val1 > 5) ? 35 : 20;
  11877.             if(!status_charge(bl, hp, sp))
  11878.                 break;
  11879.             sc_timer_next(10000+tick, status_change_timer, bl->id, data);
  11880.             return 0;
  11881.         }
  11882.         break;
  11883.  
  11884.     case SC_JAILED:
  11885.         if(sce->val1 == INT_MAX || --(sce->val1) > 0) {
  11886.             sc_timer_next(60000+tick, status_change_timer, bl->id,data);
  11887.             return 0;
  11888.         }
  11889.         break;
  11890.  
  11891.     case SC_BLIND:
  11892.         if(sc->data[SC_FOGWALL]) { // Blind lasts forever while you are standing on the fog.
  11893.             sc_timer_next(5000+tick, status_change_timer, bl->id, data);
  11894.             return 0;
  11895.         }
  11896.         break;
  11897.     case SC_ABUNDANCE:
  11898.         if(--(sce->val4) > 0) {
  11899.             status_heal(bl,0,60,0);
  11900.             sc_timer_next(10000+tick, status_change_timer, bl->id, data);
  11901.         }
  11902.         break;
  11903.  
  11904.     case SC_PYREXIA:
  11905.         if( --(sce->val4) >= 0 ) {
  11906.             map_freeblock_lock();
  11907.             clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,DMG_NORMAL,0);
  11908.             status_fix_damage(NULL,bl,100,0);
  11909.             if( sc->data[type] ) {
  11910.                 sc_timer_next(3000+tick,status_change_timer,bl->id,data);
  11911.             }
  11912.             map_freeblock_unlock();
  11913.             return 0;
  11914.         }
  11915.         break;
  11916.  
  11917.     case SC_LEECHESEND:
  11918.         if( --(sce->val4) >= 0 ) {
  11919.             int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
  11920.             damage += status->vit * (sce->val1 - 3);
  11921.             unit_skillcastcancel(bl,2);
  11922.             map_freeblock_lock();
  11923.             status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,DMG_NORMAL,0), 1);
  11924.             if( sc->data[type] ) {
  11925.                 sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
  11926.             }
  11927.             map_freeblock_unlock();
  11928.             return 0;
  11929.         }
  11930.         break;
  11931.  
  11932.     case SC_MAGICMUSHROOM:
  11933.         if( --(sce->val4) >= 0 ) {
  11934.             bool flag = 0;
  11935.             int damage = status->max_hp * 3 / 100;
  11936.             if( status->hp <= damage )
  11937.                 damage = status->hp - 1; // Cannot Kill
  11938.  
  11939.             if( damage > 0 ) { // 3% Damage each 4 seconds
  11940.                 map_freeblock_lock();
  11941.                 status_zap(bl,damage,0);
  11942.                 flag = !sc->data[type]; // Killed? Should not
  11943.                 map_freeblock_unlock();
  11944.             }
  11945.  
  11946.             if( !flag ) { // Random Skill Cast
  11947.                 if (skill_magicmushroom_count && sd && !pc_issit(sd)) { // Can't cast if sit
  11948.                     int mushroom_skill_id = 0, checked = 0, checked_max = MAX_SKILL_MAGICMUSHROOM_DB * 3;
  11949.                     unit_stop_attack(bl);
  11950.                     unit_skillcastcancel(bl,1);
  11951.                     do {
  11952.                         int i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
  11953.                         mushroom_skill_id = skill_magicmushroom_db[i].skill_id;
  11954.                     }
  11955.                     while( checked++ < checked_max && mushroom_skill_id == 0 );
  11956.  
  11957.                     if (!skill_get_index(mushroom_skill_id))
  11958.                         break;
  11959.  
  11960.                     switch( skill_get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage
  11961.                         case CAST_GROUND:
  11962.                             skill_castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0);
  11963.                             break;
  11964.                         case CAST_NODAMAGE:
  11965.                             skill_castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0);
  11966.                             break;
  11967.                         case CAST_DAMAGE:
  11968.                             skill_castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0);
  11969.                             break;
  11970.                     }
  11971.                 }
  11972.  
  11973.                 clif_emotion(bl,E_HEH);
  11974.                 sc_timer_next(4000+tick,status_change_timer,bl->id,data);
  11975.             }
  11976.             return 0;
  11977.         }
  11978.         break;
  11979.  
  11980.     case SC_TOXIN:
  11981.         if( --(sce->val4) >= 0 ) { // Damage is every 10 seconds including 3%sp drain.
  11982.             map_freeblock_lock();
  11983.             clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,DMG_NORMAL,0);
  11984.             status_damage(NULL, bl, 1, status->max_sp * 3 / 100, 0, 0); // Cancel dmg only if cancelable
  11985.             if( sc->data[type] ) {
  11986.                 sc_timer_next(10000 + tick, status_change_timer, bl->id, data );
  11987.             }
  11988.             map_freeblock_unlock();
  11989.             return 0;
  11990.         }
  11991.         break;
  11992.  
  11993.     case SC_OBLIVIONCURSE:
  11994.         if( --(sce->val4) >= 0 ) {
  11995.             clif_emotion(bl,E_WHAT);
  11996.             sc_timer_next(3000 + tick, status_change_timer, bl->id, data );
  11997.             return 0;
  11998.         }
  11999.         break;
  12000.  
  12001.     case SC_WEAPONBLOCKING:
  12002.         if( --(sce->val4) >= 0 ) {
  12003.             if( !status_charge(bl,0,3) )
  12004.                 break;
  12005.             sc_timer_next(5000+tick,status_change_timer,bl->id,data);
  12006.             return 0;
  12007.         }
  12008.         break;
  12009.  
  12010.     case SC_CLOAKINGEXCEED:
  12011.         if(!status_charge(bl,0,10-sce->val1))
  12012.             break;
  12013.         sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12014.         return 0;
  12015.  
  12016.     case SC_RENOVATIO:
  12017.         if( --(sce->val4) >= 0 ) {
  12018.             int heal = status->max_hp * 3 / 100;
  12019.             if( sc && sc->data[SC_AKAITSUKI] && heal )
  12020.                 heal = ~heal + 1;
  12021.             status_heal(bl, heal, 0, 3);
  12022.             sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  12023.             return 0;
  12024.         }
  12025.         break;
  12026.  
  12027.     case SC_BURNING:
  12028.         if( --(sce->val4) >= 0 ) {
  12029.             struct block_list *src = map_id2bl(sce->val3);
  12030.             int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
  12031.  
  12032.             map_freeblock_lock();
  12033.             clif_damage(bl,bl,tick,0,0,damage,1,DMG_MULTI_HIT_ENDURE,0); // Damage is like endure effect with no walk delay
  12034.             status_damage(src, bl, damage, 0, 0, 1);
  12035.             if( sc->data[type]) { // Target still lives. [LimitLine]
  12036.                 sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  12037.             }
  12038.             map_freeblock_unlock();
  12039.             return 0;
  12040.         }
  12041.         break;
  12042.  
  12043.     case SC_FEAR:
  12044.         if( --(sce->val4) >= 0 ) {
  12045.             if( sce->val2 > 0 )
  12046.                 sce->val2--;
  12047.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12048.             return 0;
  12049.         }
  12050.         break;
  12051.  
  12052.     case SC_SPHERE_1:
  12053.     case SC_SPHERE_2:
  12054.     case SC_SPHERE_3:
  12055.     case SC_SPHERE_4:
  12056.     case SC_SPHERE_5:
  12057.         if( --(sce->val4) >= 0 ) {
  12058.             if( !status_charge(bl, 0, 1) )
  12059.                 break;
  12060.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12061.             return 0;
  12062.         }
  12063.         break;
  12064.  
  12065.     case SC_FREEZE_SP:
  12066.         if( !status_charge(bl, 0, sce->val2) ) {
  12067.             int i;
  12068.             for(i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) // Also remove stored spell as well.
  12069.                 status_change_end(bl, (sc_type)i, INVALID_TIMER);
  12070.             break;
  12071.         }
  12072.         sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  12073.         return 0;
  12074.  
  12075.     case SC_ELECTRICSHOCKER:
  12076.         if( --(sce->val4) >= 0 ) {
  12077.             status_charge(bl, 0, 5 * sce->val1 * status->max_sp / 100);
  12078.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12079.             return 0;
  12080.         }
  12081.         break;
  12082.  
  12083.     case SC_CAMOUFLAGE:
  12084.         if (!status_charge(bl, 0, 7 - sce->val1))
  12085.             break;
  12086.         if (--sce->val4 >= 0)
  12087.             sce->val3++;
  12088.         sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12089.         return 0;
  12090.  
  12091.     case SC__REPRODUCE:
  12092.         if(!status_charge(bl, 0, 1))
  12093.             break;
  12094.         sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  12095.         return 0;
  12096.  
  12097.     case SC__SHADOWFORM:
  12098.         if( --(sce->val4) >= 0 ) {
  12099.             if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
  12100.                 break;
  12101.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12102.             return 0;
  12103.         }
  12104.         break;
  12105.  
  12106.     case SC__INVISIBILITY:
  12107.         if( !status_charge(bl, 0, (12 - 2 * sce->val1) * status->max_sp / 100) ) // 6% - skill_lv.
  12108.             break;
  12109.         sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12110.         return 0;
  12111.  
  12112.     case SC__FEINTBOMB:
  12113.         if( --(sce->val4) >= 0) {
  12114.             if( !status_charge(bl, 0, sce->val2) )
  12115.                 break;
  12116.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12117.             return 0;
  12118.         }
  12119.         break;
  12120.  
  12121.     case SC_STRIKING:
  12122.         if( --(sce->val4) >= 0 ) {
  12123.             if( !status_charge(bl,0, sce->val3 ) )
  12124.                 break;
  12125.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12126.             return 0;
  12127.         }
  12128.         break;
  12129.     case SC_BLOODSUCKER:
  12130.         if( --(sce->val4) >= 0 ) {
  12131.             struct block_list *src = map_id2bl(sce->val2);
  12132.             int damage;
  12133.             if( !src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
  12134.                 break;
  12135.             map_freeblock_lock();
  12136.             damage =  200 + 100 * sce->val1 + status_get_int(src);
  12137.             status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,DMG_NORMAL,0), 0);
  12138.             unit_skillcastcancel(bl,1);
  12139.             if ( sc->data[type] ) {
  12140.                 sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12141.             }
  12142.             map_freeblock_unlock();
  12143.             status_heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
  12144.             return 0;
  12145.         }
  12146.         break;
  12147.  
  12148.     case SC_VOICEOFSIREN:
  12149.         if( --(sce->val4) >= 0 ) {
  12150.             clif_emotion(bl,E_LV);
  12151.             sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  12152.             return 0;
  12153.         }
  12154.         break;
  12155.  
  12156.     case SC_DEEPSLEEP:
  12157.         if( --(sce->val4) >= 0 ) { // Recovers 3% HP/SP every 2 seconds.
  12158.             status_heal(bl, status->max_hp * 3 / 100, status->max_sp * 3 / 100, 2);
  12159.             sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  12160.             return 0;
  12161.         }
  12162.         break;
  12163.  
  12164.     case SC_SIRCLEOFNATURE:
  12165.         if( --(sce->val4) >= 0 ) {
  12166.             if( !status_charge(bl,0,sce->val3) )
  12167.                 break;
  12168.             status_heal(bl, sce->val2, 0, 1);
  12169.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12170.             return 0;
  12171.         }
  12172.         break;
  12173.  
  12174.     case SC_SONGOFMANA:
  12175.         if( --(sce->val4) >= 0 ) {
  12176.             status_heal(bl,0,sce->val3,3);
  12177.             sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  12178.             return 0;
  12179.         }
  12180.         break;
  12181.  
  12182.  
  12183.     case SC_SATURDAYNIGHTFEVER:
  12184.         // 1% HP/SP drain every val4 seconds [Jobbie]
  12185.         if( --(sce->val3) >= 0 ) {
  12186.             if( !status_charge(bl, status->hp / 100, status->sp / 100) )
  12187.                 break;
  12188.             sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
  12189.             return 0;
  12190.         }
  12191.         break;
  12192.  
  12193.     case SC_MELODYOFSINK:
  12194.         if( --(sce->val4) >= 0 ) {
  12195.             status_charge(bl, 0, status->max_sp * ( 2 * sce->val1 + 2 * sce->val2 ) / 100);
  12196.             sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  12197.             return 0;
  12198.         }
  12199.         break;
  12200.  
  12201.     case SC_CRYSTALIZE:
  12202.         if( --(sce->val4) >= 0 ) { // Drains 2% of HP and 1% of SP every seconds.
  12203.             if( bl->type != BL_MOB) // Doesn't work on mobs
  12204.                 status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
  12205.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12206.             return 0;
  12207.         }
  12208.         break;
  12209.  
  12210.     case SC_FORCEOFVANGUARD:
  12211.         if( !status_charge(bl,0,24 - 4 * sce->val1) )
  12212.             break;
  12213.         sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  12214.         return 0;
  12215.  
  12216.     case SC_BANDING:
  12217.         if( status_charge(bl, 0, 7 - sce->val1) ) {
  12218.             if( sd ) pc_banding(sd, sce->val1);
  12219.             sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  12220.             return 0;
  12221.         }
  12222.         break;
  12223.  
  12224.     case SC_REFLECTDAMAGE:
  12225.         if( --(sce->val4) > 0 ) {
  12226.             if( !status_charge(bl,0,10) )
  12227.                 break;
  12228.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12229.             return 0;
  12230.         }
  12231.         break;
  12232.  
  12233.     case SC_OVERHEAT_LIMITPOINT:
  12234.         if( --(sce->val1) > 0 ) { // Cooling
  12235.             sc_timer_next(30000 + tick, status_change_timer, bl->id, data);
  12236.         }
  12237.         break;
  12238.  
  12239.     case SC_OVERHEAT:
  12240.         {
  12241.             int damage = status->max_hp / 100; // Suggestion 1% each second
  12242.             if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
  12243.             map_freeblock_lock();
  12244.             status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,DMG_NORMAL,0));
  12245.             if( sc->data[type] ) {
  12246.                 sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12247.             }
  12248.             map_freeblock_unlock();
  12249.         }
  12250.         break;
  12251.  
  12252.     case SC_MAGNETICFIELD:
  12253.         {
  12254.             if( --(sce->val3) <= 0 )
  12255.                 break; // Time out
  12256.             if( sce->val2 == bl->id ) {
  12257.                 if( !status_charge(bl,0,50) )
  12258.                     break; // No more SP status should end, and in the next second will end for the other affected players
  12259.             } else {
  12260.                 struct block_list *src = map_id2bl(sce->val2);
  12261.                 struct status_change *ssc;
  12262.                 if( !src || (ssc = status_get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD] )
  12263.                     break; // Source no more under Magnetic Field
  12264.             }
  12265.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12266.         }
  12267.         break;
  12268.  
  12269.     case SC_INSPIRATION:
  12270.         if(--(sce->val4) >= 0) {
  12271.             int hp = status->max_hp * (35 - 5 * sce->val1) / 1000;
  12272.             int sp = status->max_sp * (45 - 5 * sce->val1) / 1000;
  12273.  
  12274.             if( !status_charge(bl,hp,sp) ) break;
  12275.  
  12276.             sc_timer_next(5000+tick,status_change_timer,bl->id, data);
  12277.             return 0;
  12278.         }
  12279.         break;
  12280.  
  12281.     case SC_RAISINGDRAGON:
  12282.         // 1% every 5 seconds [Jobbie]
  12283.         if( --(sce->val3)>0 && status_charge(bl, sce->val2, 0) ) {
  12284.             if( !sc->data[type] ) return 0;
  12285.             sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
  12286.             return 0;
  12287.         }
  12288.         break;
  12289.  
  12290.     case SC_TROPIC:
  12291.     case SC_CHILLY_AIR:
  12292.     case SC_WILD_STORM:
  12293.     case SC_UPHEAVAL:
  12294.     case SC_HEATER:
  12295.     case SC_COOLER:
  12296.     case SC_BLAST:
  12297.     case SC_CURSED_SOIL:
  12298.     case SC_PYROTECHNIC:
  12299.     case SC_AQUAPLAY:
  12300.     case SC_GUST:
  12301.     case SC_PETROLOGY:
  12302.     case SC_CIRCLE_OF_FIRE:
  12303.     case SC_FIRE_CLOAK:
  12304.     case SC_WATER_DROP:
  12305.     case SC_WATER_SCREEN:
  12306.     case SC_WIND_CURTAIN:
  12307.     case SC_WIND_STEP:
  12308.     case SC_STONE_SHIELD:
  12309.     case SC_SOLID_SKIN:
  12310.         if( !status_charge(bl,0,sce->val2) ) {
  12311.             struct block_list *s_bl = battle_get_master(bl);
  12312.             if (bl->type == BL_ELEM)
  12313.                 elemental_change_mode(BL_CAST(BL_ELEM, bl), MAX_ELESKILLTREE);
  12314.             if( s_bl )
  12315.                 status_change_end(s_bl,type+1,INVALID_TIMER);
  12316.             status_change_end(bl,type,INVALID_TIMER);
  12317.             break;
  12318.         }
  12319.         sc_timer_next(sce->val3 + tick, status_change_timer, bl->id, data);
  12320.         return 0;
  12321.  
  12322.     case SC_WATER_SCREEN_OPTION:
  12323.         status_heal(bl,1000,0,2);
  12324.         sc_timer_next(10000 + tick,status_change_timer,bl->id,data);
  12325.         return 0;
  12326.  
  12327.     case SC_TEARGAS:
  12328.         if( --(sce->val4) >= 0 ) {
  12329.             struct block_list *src = map_id2bl(sce->val3);
  12330.             int damage = sce->val2;
  12331.  
  12332.             map_freeblock_lock();
  12333.             clif_damage(bl, bl, tick, 0, 0, damage, 1, DMG_MULTI_HIT_ENDURE, 0);
  12334.             status_damage(src, bl, damage,0, 0, 1);
  12335.             if( sc->data[type] ) {
  12336.                 sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  12337.             }
  12338.             map_freeblock_unlock();
  12339.             return 0;
  12340.         }
  12341.         break;
  12342.     case SC_TEARGAS_SOB:
  12343.         if( --(sce->val4) >= 0 ) {
  12344.             clif_emotion(bl, E_SOB);
  12345.             sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
  12346.             return 0;
  12347.         }
  12348.         break;
  12349.     case SC_STOMACHACHE:
  12350.         if( --(sce->val4) >= 0 ) {
  12351.             status_charge(bl,0,sce->val2);  // Reduce 8 every 10 seconds.
  12352.             if( sd && !pc_issit(sd) ) { // Force to sit every 10 seconds.
  12353.                 pc_setsit(sd);
  12354.                 skill_sit(sd, 1);
  12355.                 clif_sitting(bl);
  12356.             }
  12357.             sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
  12358.             return 0;
  12359.         }
  12360.         break;
  12361.     case SC_LEADERSHIP:
  12362.     case SC_GLORYWOUNDS:
  12363.     case SC_SOULCOLD:
  12364.     case SC_HAWKEYES:
  12365.         // They only end by status_change_end
  12366.         sc_timer_next(600000 + tick, status_change_timer, bl->id, data);
  12367.         return 0;
  12368.     case SC_MEIKYOUSISUI:
  12369.         if( --(sce->val4) >= 0 ) {
  12370.             status_heal(bl, status->max_hp * sce->val2 / 100, status->max_sp * sce->val3 / 100, 0);
  12371.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12372.             return 0;
  12373.         }
  12374.         break;
  12375.     case SC_IZAYOI:
  12376.     case SC_KAGEMUSYA:
  12377.         if( --(sce->val2) >= 0 ) {
  12378.             if(!status_charge(bl, 0, 1)) break;
  12379.             sc_timer_next(1000+tick, status_change_timer, bl->id, data);
  12380.             return 0;
  12381.         }
  12382.         break;
  12383.     case SC_ANGRIFFS_MODUS:
  12384.         if(--(sce->val4) >= 0) { // Drain hp/sp
  12385.             if( !status_charge(bl,100,20) ) break;
  12386.             sc_timer_next(1000+tick,status_change_timer,bl->id, data);
  12387.             return 0;
  12388.         }
  12389.         break;
  12390.     case SC_CBC:
  12391.         if(--(sce->val4) >= 0) { // Drain hp/sp
  12392.             int hp=0;
  12393.             int sp = (status->max_sp * sce->val3) / 100;
  12394.             if(bl->type == BL_MOB) hp = sp*10;
  12395.             if( !status_charge(bl,hp,sp) )break;
  12396.             sc_timer_next(1000+tick,status_change_timer,bl->id, data);
  12397.             return 0;
  12398.         }
  12399.         break;
  12400.     case SC_FULL_THROTTLE:
  12401.         if( --(sce->val4) >= 0 ) {
  12402.             status_percent_damage(bl, bl, 0, sce->val2, false);
  12403.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12404.             return 0;
  12405.         }
  12406.         break;
  12407.     case SC_REBOUND:
  12408.         if( --(sce->val4) >= 0 ) {
  12409.             clif_emotion(bl, E_SWT);
  12410.             sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
  12411.             return 0;
  12412.         }
  12413.         break;
  12414.     case SC_KINGS_GRACE:
  12415.         if( --(sce->val4) >= 0 ) {
  12416.             status_percent_heal(bl, sce->val2, 0);
  12417.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12418.             return 0;
  12419.         }
  12420.         break;
  12421.     case SC_FRIGG_SONG:
  12422.         if( --(sce->val4) >= 0 ) {
  12423.             status_heal(bl, sce->val3, 0, 0);
  12424.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12425.             return 0;
  12426.         }
  12427.         break;
  12428.     case SC_C_MARKER:
  12429.         if( --(sce->val4) >= 0 ) {
  12430.             TBL_PC *caster = map_id2sd(sce->val2);
  12431.             if (!caster || caster->bl.m != bl->m) //End the SC if caster isn't in same map
  12432.                 break;
  12433.             sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
  12434.             clif_crimson_marker(caster, bl, false);
  12435.             return 0;
  12436.         }
  12437.         break;
  12438.     case SC_STEALTHFIELD_MASTER:
  12439.         if (--(sce->val4) >= 0) {
  12440.             int sp = (status->max_sp * sce->val3) / 100;
  12441.             if (!status_charge(bl,0,sp))
  12442.                 break;
  12443.             sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
  12444.         }
  12445.         break;
  12446.     case SC_VACUUM_EXTREME:
  12447.         if (sce->val4) {
  12448.             if (unit_movepos(bl, sce->val3>>16, sce->val3&0xFFFF, 0, false)) {
  12449.                 clif_slide(bl, sce->val3>>16, sce->val3&0xFFFF);
  12450.                 clif_fixpos(bl);
  12451.             }
  12452.             sc_timer_next(tick+sce->val4, status_change_timer, bl->id, data);
  12453.             sce->val4 = 0;
  12454.         }
  12455.         break;
  12456.     }
  12457.  
  12458.     // Default for all non-handled control paths is to end the status
  12459.  
  12460.     return status_change_end( bl,type,tid );
  12461. #undef sc_timer_next
  12462. }
  12463.  
  12464. /**
  12465.  * For each iteration of repetitive status
  12466.  * @param bl: Object [PC|MOB|HOM|MER|ELEM]
  12467.  * @param ap: va_list arguments (src, sce, type, tick)
  12468.  */
  12469. int status_change_timer_sub(struct block_list* bl, va_list ap)
  12470. {
  12471.     struct status_change* tsc;
  12472.  
  12473.     struct block_list* src = va_arg(ap,struct block_list*);
  12474.     struct status_change_entry* sce = va_arg(ap,struct status_change_entry*);
  12475.     enum sc_type type = (sc_type)va_arg(ap,int); // gcc: enum args get promoted to int
  12476.     unsigned int tick = va_arg(ap,unsigned int);
  12477.  
  12478.     if (status_isdead(bl))
  12479.         return 0;
  12480.  
  12481.     tsc = status_get_sc(bl);
  12482.  
  12483.     switch( type ) {
  12484.     case SC_SIGHT: // Reveal hidden ennemy on 3*3 range
  12485.         if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // For every 2 seconds do the checking
  12486.             rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
  12487.                 status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
  12488.     case SC_CONCENTRATE:
  12489.         status_change_end(bl, SC_HIDING, INVALID_TIMER);
  12490.         status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  12491.         status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
  12492.         status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
  12493.         break;
  12494.     case SC_RUWACH: // Reveal hidden target and deal little dammages if enemy
  12495.         if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
  12496.                 tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED])) {
  12497.             status_change_end(bl, SC_HIDING, INVALID_TIMER);
  12498.             status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  12499.             status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
  12500.             status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
  12501.             if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
  12502.                 skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
  12503.         }
  12504.         if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // For every 2 seconds do the checking
  12505.             rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
  12506.                 status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
  12507.         break;
  12508.     case SC_SIGHTBLASTER:
  12509.         if (battle_check_target( src, bl, BCT_ENEMY ) > 0 &&
  12510.             status_check_skilluse(src, bl, WZ_SIGHTBLASTER, 2))
  12511.         {
  12512.             struct skill_unit *su = (struct skill_unit *)bl;
  12513.             if (sce) {
  12514.                 if (skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,sce->val1,tick,0x1000000)
  12515.                     && (!su || !su->group || !(skill_get_inf2(su->group->skill_id)&INF2_TRAP))) { // The hit is not counted if it's against a trap
  12516.                     sce->val2 = 0; // This signals it to end.
  12517.                 } else if((bl->type&BL_SKILL) && sce->val4%2 == 0) {
  12518.                     //Remove trap immunity temporarily so it triggers if you still stand on it
  12519.                     sce->val4++;
  12520.                 }
  12521.             }
  12522.         }
  12523.         break;
  12524.     case SC_TINDER_BREAKER:
  12525.     case SC_CLOSECONFINE:{
  12526.         int type2 = ((type==SC_CLOSECONFINE)?SC_CLOSECONFINE2:SC_TINDER_BREAKER2);
  12527.         // Lock char has released the hold on everyone...
  12528.         if (tsc && tsc->data[type2] && tsc->data[type2]->val2 == src->id) {
  12529.             tsc->data[type2]->val2 = 0;
  12530.             status_change_end(bl, type2, INVALID_TIMER);
  12531.         }
  12532.         break;
  12533.     }
  12534.     case SC_CURSEDCIRCLE_TARGET:
  12535.         if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) {
  12536.             clif_bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0);
  12537.             status_change_end(bl, type, INVALID_TIMER);
  12538.         }
  12539.         break;
  12540.     }
  12541.  
  12542.     return 0;
  12543. }
  12544.  
  12545. /**
  12546.  * Clears buffs/debuffs on an object
  12547.  * @param bl: Object to clear [PC|MOB|HOM|MER|ELEM]
  12548.  * @param type: Type to remove
  12549.  *  &1: Clear Buffs
  12550.  *  $2: Clear Debuffs
  12551.  *  &4: Specific debuffs with a refresh
  12552.  */
  12553. void status_change_clear_buffs (struct block_list* bl, int type)
  12554. {
  12555.     int i;
  12556.     struct status_change *sc= status_get_sc(bl);
  12557.  
  12558.     if (!sc || !sc->count)
  12559.         return;
  12560.  
  12561.     if (type&6) // Debuffs
  12562.         for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
  12563.             status_change_end(bl, (sc_type)i, INVALID_TIMER);
  12564.  
  12565.     for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ ) {
  12566.         if(!sc->data[i])
  12567.             continue;
  12568.  
  12569.         switch (i) {
  12570.             // Stuff that cannot be removed
  12571.             case SC_WEIGHT50:
  12572.             case SC_WEIGHT90:
  12573.             case SC_COMBO:
  12574.             case SC_SMA:
  12575.             case SC_DANCING:
  12576.             case SC_LEADERSHIP:
  12577.             case SC_GLORYWOUNDS:
  12578.             case SC_SOULCOLD:
  12579.             case SC_HAWKEYES:
  12580.             case SC_SAFETYWALL:
  12581.             case SC_PNEUMA:
  12582.             case SC_NOCHAT:
  12583.             case SC_JAILED:
  12584.             case SC_ANKLE:
  12585.             case SC_BLADESTOP:
  12586.             case SC_CP_WEAPON:
  12587.             case SC_CP_SHIELD:
  12588.             case SC_CP_ARMOR:
  12589.             case SC_CP_HELM:
  12590.             case SC_STRFOOD:
  12591.             case SC_AGIFOOD:
  12592.             case SC_VITFOOD:
  12593.             case SC_INTFOOD:
  12594.             case SC_DEXFOOD:
  12595.             case SC_LUKFOOD:
  12596.             case SC_FLEEFOOD:
  12597.             case SC_HITFOOD:
  12598.             case SC_CRIFOOD:
  12599.             case SC_BATKFOOD:
  12600.             case SC_WATKFOOD:
  12601.             case SC_MATKFOOD:
  12602.             case SC_FOOD_STR_CASH:
  12603.             case SC_FOOD_AGI_CASH:
  12604.             case SC_FOOD_VIT_CASH:
  12605.             case SC_FOOD_DEX_CASH:
  12606.             case SC_FOOD_INT_CASH:
  12607.             case SC_FOOD_LUK_CASH:
  12608.             case SC_EXPBOOST:
  12609.             case SC_JEXPBOOST:
  12610.             case SC_ITEMBOOST:
  12611.             case SC_ELECTRICSHOCKER:
  12612.             case SC__MANHOLE:
  12613.             case SC_GIANTGROWTH:
  12614.             case SC_MILLENNIUMSHIELD:
  12615.             case SC_REFRESH:
  12616.             case SC_STONEHARDSKIN:
  12617.             case SC_VITALITYACTIVATION:
  12618.             case SC_FIGHTINGSPIRIT:
  12619.             case SC_ABUNDANCE:
  12620.             case SC_SAVAGE_STEAK:
  12621.             case SC_COCKTAIL_WARG_BLOOD:
  12622.             case SC_MINOR_BBQ:
  12623.             case SC_SIROMA_ICE_TEA:
  12624.             case SC_DROCERA_HERB_STEAMED:
  12625.             case SC_PUTTI_TAILS_NOODLES:
  12626.             case SC_CURSEDCIRCLE_ATKER:
  12627.             case SC_CURSEDCIRCLE_TARGET:
  12628.             case SC_PUSH_CART:
  12629.             case SC_ALL_RIDING:
  12630.             case SC_STYLE_CHANGE:
  12631.             case SC_MONSTER_TRANSFORM:
  12632.             case SC_MOONSTAR:
  12633.             case SC_SUPER_STAR:
  12634.             case SC_MTF_ASPD:
  12635.             case SC_MTF_RANGEATK:
  12636.             case SC_MTF_MATK:
  12637.             case SC_MTF_MLEATKED:
  12638.             case SC_MTF_CRIDAMAGE:
  12639.             case SC_HEAT_BARREL_AFTER:
  12640.             case SC_STRANGELIGHTS:
  12641.             case SC_DECORATION_OF_MUSIC:
  12642.             case SC_QUEST_BUFF1:
  12643.             case SC_QUEST_BUFF2:
  12644.             case SC_QUEST_BUFF3:
  12645.             case SC_MTF_ASPD2:
  12646.             case SC_MTF_RANGEATK2:
  12647.             case SC_MTF_MATK2:
  12648.             case SC_2011RWC_SCROLL:
  12649.             case SC_JP_EVENT04:
  12650.             case SC_MTF_MHP:
  12651.             case SC_MTF_MSP:
  12652.             case SC_MTF_PUMPKIN:
  12653.             case SC_MTF_HITFLEE:
  12654.                 continue;
  12655.  
  12656.             // Debuffs that can be removed.
  12657.             case SC_DEEPSLEEP:
  12658.             case SC_BURNING:
  12659.             case SC_FREEZING:
  12660.             case SC_CRYSTALIZE:
  12661.             case SC_TOXIN:
  12662.             case SC_PARALYSE:
  12663.             case SC_VENOMBLEED:
  12664.             case SC_MAGICMUSHROOM:
  12665.             case SC_DEATHHURT:
  12666.             case SC_PYREXIA:
  12667.             case SC_OBLIVIONCURSE:
  12668.             case SC_LEECHESEND:
  12669.             case SC_MARSHOFABYSS:
  12670.             case SC_MANDRAGORA:
  12671.                 if(!(type&4))
  12672.                     continue;
  12673.                 break;
  12674.             case SC_HALLUCINATION:
  12675.             case SC_QUAGMIRE:
  12676.             case SC_SIGNUMCRUCIS:
  12677.             case SC_DECREASEAGI:
  12678.             case SC_SLOWDOWN:
  12679.             case SC_MINDBREAKER:
  12680.             case SC_WINKCHARM:
  12681.             case SC_STOP:
  12682.             case SC_ORCISH:
  12683.             case SC_STRIPWEAPON:
  12684.             case SC_STRIPSHIELD:
  12685.             case SC_STRIPARMOR:
  12686.             case SC_STRIPHELM:
  12687.             case SC_BITE:
  12688.             case SC_ADORAMUS:
  12689.             case SC_VACUUM_EXTREME:
  12690.             case SC_FEAR:
  12691.             case SC_MAGNETICFIELD:
  12692.             case SC_NETHERWORLD:
  12693.                 if (!(type&2))
  12694.                     continue;
  12695.                 break;
  12696.             // The rest are buffs that can be removed.
  12697.             case SC_BERSERK:
  12698.             case SC_SATURDAYNIGHTFEVER:
  12699.                 if (!(type&1))
  12700.                     continue;
  12701.                 sc->data[i]->val2 = 0;
  12702.                 break;
  12703.             default:
  12704.                 if (!(type&1))
  12705.                     continue;
  12706.                 break;
  12707.         }
  12708.         status_change_end(bl, (sc_type)i, INVALID_TIMER);
  12709.     }
  12710.  
  12711.     //Removes bonus_script
  12712.     if (bl->type == BL_PC) {
  12713.         i = 0;
  12714.         if (type&1) i |= BSF_REM_BUFF;
  12715.         if (type&2) i |= BSF_REM_DEBUFF;
  12716.         if (type&4) i |= BSF_REM_ON_REFRESH;
  12717.         if (type&8) i |= BSF_REM_ON_LUXANIMA;
  12718.         pc_bonus_script_clear(BL_CAST(BL_PC,bl),i);
  12719.     }
  12720.  
  12721.     // Cleaning all extras vars
  12722.     sc->comet_x = 0;
  12723.     sc->comet_y = 0;
  12724. #ifndef RENEWAL
  12725.     sc->sg_counter = 0;
  12726. #endif
  12727.     sc->bs_counter = 0;
  12728.  
  12729.     return;
  12730. }
  12731.  
  12732. /**
  12733.  * Infect a user with status effects (SC_DEADLYINFECT)
  12734.  * @param src: Object initiating change on bl [PC|MOB|HOM|MER|ELEM]
  12735.  * @param bl: Object to change
  12736.  * @param type: 0 - Shadow Chaser attacking, 1 - Shadow Chaser being attacked
  12737.  * @return 1: Success 0: Fail
  12738.  */
  12739. int status_change_spread(struct block_list *src, struct block_list *bl, bool type)
  12740. {
  12741.     int i, flag = 0;
  12742.     struct status_change *sc = status_get_sc(src);
  12743.     const struct TimerData *timer;
  12744.     unsigned int tick;
  12745.     struct status_change_data data;
  12746.  
  12747.     if( !sc || !sc->count )
  12748.         return 0;
  12749.  
  12750.     tick = gettick();
  12751.  
  12752.     //Boss monsters resistance
  12753.     if( (status_get_mode(src)&MD_BOSS) || (status_get_mode(bl)&MD_BOSS) )
  12754.         return 0;
  12755.  
  12756.     for( i = SC_COMMON_MIN; i < SC_MAX; i++ ) {
  12757.         if( !sc->data[i] || i == SC_COMMON_MAX )
  12758.             continue;
  12759.  
  12760.         switch( i ) {
  12761.             // Debuffs that can be spread.
  12762.             // NOTE: We'll add/delete SCs when we are able to confirm it.
  12763.             case SC_DEATHHURT:
  12764.             case SC_PARALYSE:
  12765.                 if (type)
  12766.                     continue;
  12767.             case SC_CURSE:
  12768.             case SC_SILENCE:
  12769.             case SC_CONFUSION:
  12770.             case SC_BLIND:
  12771.             case SC_HALLUCINATION:
  12772.             case SC_SIGNUMCRUCIS:
  12773.             case SC_DECREASEAGI:
  12774.             //case SC_SLOWDOWN:
  12775.             //case SC_MINDBREAKER:
  12776.             //case SC_WINKCHARM:
  12777.             //case SC_STOP:
  12778.             case SC_ORCISH:
  12779.             //case SC_STRIPWEAPON: // Omg I got infected and had the urge to strip myself physically.
  12780.             //case SC_STRIPSHIELD: // No this is stupid and shouldnt be spreadable at all.
  12781.             //case SC_STRIPARMOR: // Disabled until I can confirm if it does or not. [Rytech]
  12782.             //case SC_STRIPHELM:
  12783.             //case SC__STRIPACCESSORY:
  12784.             //case SC_BITE:
  12785.             case SC_FREEZING:
  12786.             case SC_VENOMBLEED:
  12787.                 if( sc->data[i]->timer != INVALID_TIMER ) {
  12788.                     timer = get_timer(sc->data[i]->timer);
  12789.                     if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
  12790.                         continue;
  12791.                     data.tick = DIFF_TICK(timer->tick,tick);
  12792.                 } else
  12793.                     data.tick = INVALID_TIMER;
  12794.                 break;
  12795.             // Special cases
  12796.             case SC_POISON:
  12797.             case SC_DPOISON:
  12798.                 data.tick = sc->data[i]->val3 * 1000;
  12799.                 break;
  12800.             case SC_LEECHESEND:
  12801.                 if (type)
  12802.                     continue;
  12803.             case SC_FEAR:
  12804.                 data.tick = sc->data[i]->val4 * 1000;
  12805.                 break;
  12806.             case SC_BURNING:
  12807.                 data.tick = sc->data[i]->val4 * 2000;
  12808.                 break;
  12809.             case SC_PYREXIA:
  12810.                 if (type)
  12811.                     continue;
  12812.             //case SC_OBLIVIONCURSE: // Players are not affected by Oblivion Curse.
  12813.                 data.tick = sc->data[i]->val4 * 3000;
  12814.                 break;
  12815.             case SC_MAGICMUSHROOM:
  12816.                 if (type)
  12817.                     continue;
  12818.                 data.tick = sc->data[i]->val4 * 4000;
  12819.                 break;
  12820.             case SC_TOXIN:
  12821.                 if (type)
  12822.                     continue;
  12823.             case SC_BLEEDING:
  12824.                 data.tick = sc->data[i]->val4 * 10000;
  12825.                 break;
  12826.             default:
  12827.                 continue;
  12828.         }
  12829.         if( i ) {
  12830.             data.val1 = sc->data[i]->val1;
  12831.             data.val2 = sc->data[i]->val2;
  12832.             data.val3 = sc->data[i]->val3;
  12833.             data.val4 = sc->data[i]->val4;
  12834.             status_change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
  12835.             flag = 1;
  12836.         }
  12837.     }
  12838.  
  12839.     return flag;
  12840. }
  12841.  
  12842. /**
  12843.  * Applying natural heal bonuses (sit, skill, homun, etc...)
  12844.  * TODO: the va_list doesn't seem to be used, safe to remove?
  12845.  * @param bl: Object applying bonuses to [PC|HOM|MER|ELEM]
  12846.  * @param args: va_list arguments
  12847.  * @return which regeneration bonuses have been applied (flag)
  12848.  */
  12849. static unsigned int natural_heal_prev_tick,natural_heal_diff_tick;
  12850. static int status_natural_heal(struct block_list* bl, va_list args)
  12851. {
  12852.     struct regen_data *regen;
  12853.     struct status_data *status;
  12854.     struct status_change *sc;
  12855.     struct unit_data *ud;
  12856.     struct view_data *vd = NULL;
  12857.     struct regen_data_sub *sregen;
  12858.     struct map_session_data *sd;
  12859.     int rate, multi = 1, flag;
  12860.  
  12861.     regen = status_get_regen_data(bl);
  12862.     if (!regen)
  12863.         return 0;
  12864.     status = status_get_status_data(bl);
  12865.     sc = status_get_sc(bl);
  12866.     if (sc && !sc->count)
  12867.         sc = NULL;
  12868.     sd = BL_CAST(BL_PC,bl);
  12869.  
  12870.     flag = regen->flag;
  12871.     if (flag&RGN_HP && (status->hp >= status->max_hp || regen->state.block&1))
  12872.         flag &= ~(RGN_HP|RGN_SHP);
  12873.     if (flag&RGN_SP && (status->sp >= status->max_sp || regen->state.block&2))
  12874.         flag &= ~(RGN_SP|RGN_SSP);
  12875.  
  12876.     if (flag && (
  12877.         status_isdead(bl) ||
  12878.         (sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || sc->data[SC__INVISIBILITY]))
  12879.     ))
  12880.         flag = RGN_NONE;
  12881.  
  12882.     if (sd) {
  12883.         if (sd->hp_loss.value || sd->sp_loss.value)
  12884.             pc_bleeding(sd, natural_heal_diff_tick);
  12885.         if (sd->hp_regen.value || sd->sp_regen.value)
  12886.             pc_regen(sd, natural_heal_diff_tick);
  12887.     }
  12888.  
  12889.     if(flag&(RGN_SHP|RGN_SSP) && regen->ssregen &&
  12890.         (vd = status_get_viewdata(bl)) && vd->dead_sit == 2)
  12891.     { // Apply sitting regen bonus.
  12892.         sregen = regen->ssregen;
  12893.         if(flag&(RGN_SHP)) { // Sitting HP regen
  12894.             rate = (int)(natural_heal_diff_tick * (sregen->rate.hp / 100.));
  12895.             if (regen->state.overweight)
  12896.                 rate >>= 1; // Half as fast when overweight.
  12897.             sregen->tick.hp += rate;
  12898.             while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
  12899.                 sregen->tick.hp -= battle_config.natural_heal_skill_interval;
  12900.                 if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp) { // Full
  12901.                     flag &= ~(RGN_HP|RGN_SHP);
  12902.                     break;
  12903.                 }
  12904.             }
  12905.         }
  12906.         if(flag&(RGN_SSP)) { // Sitting SP regen
  12907.             rate = (int)(natural_heal_diff_tick * (sregen->rate.sp / 100.));
  12908.             if (regen->state.overweight)
  12909.                 rate >>= 1; // Half as fast when overweight.
  12910.             sregen->tick.sp += rate;
  12911.             while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
  12912.                 sregen->tick.sp -= battle_config.natural_heal_skill_interval;
  12913.                 if(status_heal(bl, 0, sregen->sp, 3) < sregen->sp) { // Full
  12914.                     flag &= ~(RGN_SP|RGN_SSP);
  12915.                     break;
  12916.                 }
  12917.             }
  12918.         }
  12919.     }
  12920.  
  12921.     if (flag && regen->state.overweight)
  12922.         flag = RGN_NONE;
  12923.  
  12924.     ud = unit_bl2ud(bl);
  12925.  
  12926.     if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER) {
  12927.         flag &= ~(RGN_SHP|RGN_SSP);
  12928.         if(!regen->state.walk)
  12929.             flag &= ~RGN_HP;
  12930.     }
  12931.  
  12932.     if (!flag)
  12933.         return 0;
  12934.  
  12935.     if (flag&(RGN_HP|RGN_SP)) {
  12936.         if(!vd)
  12937.             vd = status_get_viewdata(bl);
  12938.         if(vd && vd->dead_sit == 2)
  12939.             multi += 1; //This causes the interval to be halved
  12940.         if(regen->state.gc)
  12941.             multi += 1; //This causes the interval to be halved
  12942.     }
  12943.  
  12944.     // Natural Hp regen
  12945.     if (flag&RGN_HP) {
  12946.         rate = (int)(natural_heal_diff_tick * (regen->rate.hp/100. * multi));
  12947.         if (ud && ud->walktimer != INVALID_TIMER)
  12948.             rate /= 2;
  12949.         // Homun HP regen fix (they should regen as if they were sitting (twice as fast)
  12950.         if(bl->type == BL_HOM)
  12951.             rate *= 2;
  12952.  
  12953.         regen->tick.hp += rate;
  12954.  
  12955.         if(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval) {
  12956.             int val = 0;
  12957.             do {
  12958.                 val += regen->hp;
  12959.                 regen->tick.hp -= battle_config.natural_healhp_interval;
  12960.             } while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
  12961.             if (status_heal(bl, val, 0, 1) < val)
  12962.                 flag &= ~RGN_SHP; // Full.
  12963.         }
  12964.     }
  12965.  
  12966.     // Natural SP regen
  12967.     if(flag&RGN_SP) {
  12968.         rate = (int)(natural_heal_diff_tick * (regen->rate.sp/100. * multi));
  12969.         // Homun SP regen fix (they should regen as if they were sitting (twice as fast)
  12970.         if(bl->type==BL_HOM)
  12971.             rate *= 2;
  12972. #ifdef RENEWAL
  12973.         if (bl->type == BL_PC && (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
  12974.             sc && sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK))
  12975.             rate /= 2; // Tick is doubled in Fury state
  12976. #endif
  12977.         regen->tick.sp += rate;
  12978.  
  12979.         if(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval) {
  12980.             int val = 0;
  12981.             do {
  12982.                 val += regen->sp;
  12983.                 regen->tick.sp -= battle_config.natural_healsp_interval;
  12984.             } while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
  12985.             if (status_heal(bl, 0, val, 1) < val)
  12986.                 flag &= ~RGN_SSP; // full.
  12987.         }
  12988.     }
  12989.  
  12990.     if (!regen->sregen)
  12991.         return flag;
  12992.  
  12993.     // Skill regen
  12994.     sregen = regen->sregen;
  12995.  
  12996.     if(flag&RGN_SHP) { // Skill HP regen
  12997.         sregen->tick.hp += (int)(natural_heal_diff_tick * (sregen->rate.hp / 100.));
  12998.  
  12999.         while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
  13000.             sregen->tick.hp -= battle_config.natural_heal_skill_interval;
  13001.             if(status_heal(bl, sregen->hp, 0, 3) < sregen->hp)
  13002.                 break; // Full
  13003.         }
  13004.     }
  13005.     if(flag&RGN_SSP) { // Skill SP regen
  13006.         sregen->tick.sp += (int)(natural_heal_diff_tick * (sregen->rate.sp /100.));
  13007.         while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
  13008.             int val = sregen->sp;
  13009.             if (sd && sd->state.doridori) {
  13010.                 val *= 2;
  13011.                 sd->state.doridori = 0;
  13012.                 if ((rate = pc_checkskill(sd,TK_SPTIME)))
  13013.                     sc_start(bl,bl,status_skill2sc(TK_SPTIME),
  13014.                         100,rate,skill_get_time(TK_SPTIME, rate));
  13015.                 if (
  13016.                     (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&
  13017.                     rnd()%10000 < battle_config.sg_angel_skill_ratio
  13018.                 ) { // Angel of the Sun/Moon/Star
  13019.                     clif_feel_hate_reset(sd);
  13020.                     pc_resethate(sd);
  13021.                     pc_resetfeel(sd);
  13022.                 }
  13023.             }
  13024.             sregen->tick.sp -= battle_config.natural_heal_skill_interval;
  13025.             if(status_heal(bl, 0, val, 3) < val)
  13026.                 break; // Full
  13027.         }
  13028.     }
  13029.     return flag;
  13030. }
  13031.  
  13032. /**
  13033.  * Natural heal main timer
  13034.  * @param tid: Timer ID
  13035.  * @param tick: Current tick (time)
  13036.  * @param id: Object ID to heal
  13037.  * @param data: data pushed through timer function
  13038.  * @return 0
  13039.  */
  13040. static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
  13041. {
  13042.     natural_heal_diff_tick = DIFF_TICK(tick,natural_heal_prev_tick);
  13043.     map_foreachregen(status_natural_heal);
  13044.     natural_heal_prev_tick = tick;
  13045.     return 0;
  13046. }
  13047.  
  13048. /**
  13049.  * Get the chance to upgrade a piece of equipment
  13050.  * @param wlv: The weapon type of the item to refine (see see enum refine_type)
  13051.  * @param refine: The target's refine level
  13052.  * @return The chance to refine the item, in percent (0~100)
  13053.  */
  13054. int status_get_refine_chance(enum refine_type wlv, int refine)
  13055. {
  13056.  
  13057.     if ( refine < 0 || refine >= MAX_REFINE)
  13058.         return 0;
  13059.  
  13060.     return refine_info[wlv].chance[refine];
  13061. }
  13062.  
  13063. /**
  13064.  * Read sizefix database for attack calculations
  13065.  * @param fields: Fields passed from sv_readdb
  13066.  * @param columns: Columns passed from sv_readdb function call
  13067.  * @param current: Current row being read into atkmods array
  13068.  * @return True
  13069.  */
  13070. static bool status_readdb_sizefix(char* fields[], int columns, int current)
  13071. {
  13072.     unsigned int i;
  13073.  
  13074.     for(i = 0; i < MAX_WEAPON_TYPE; i++)
  13075.         atkmods[current][i] = atoi(fields[i]);
  13076.  
  13077.     return true;
  13078. }
  13079.  
  13080. /**
  13081.  * Read refine database for refining calculations
  13082.  * @param fields: Fields passed from sv_readdb
  13083.  * @param columns: Columns passed from sv_readdb function call
  13084.  * @param current: Current row being read into refine_info array
  13085.  * @return True
  13086.  */
  13087. static bool status_readdb_refine(char* fields[], int columns, int current)
  13088. {
  13089.     int i, bonus_per_level, random_bonus, random_bonus_start_level;
  13090.  
  13091.     current = atoi(fields[0]);
  13092.  
  13093.     if (current < 0 || current >= REFINE_TYPE_MAX)
  13094.         return false;
  13095.  
  13096.     bonus_per_level = atoi(fields[1]);
  13097.     random_bonus_start_level = atoi(fields[2]);
  13098.     random_bonus = atoi(fields[3]);
  13099.  
  13100.     for(i = 0; i < MAX_REFINE; i++) {
  13101.         char* delim;
  13102.  
  13103.         if (!(delim = strchr(fields[4+i], ':')))
  13104.             return false;
  13105.  
  13106.         *delim = '\0';
  13107.  
  13108.         refine_info[current].chance[i] = atoi(fields[4+i]);
  13109.  
  13110.         if (i >= random_bonus_start_level - 1)
  13111.             refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
  13112.  
  13113.         refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
  13114.         if (i > 0)
  13115.             refine_info[current].bonus[i] += refine_info[current].bonus[i-1];
  13116.     }
  13117.     return true;
  13118. }
  13119.  
  13120. /**
  13121.  * Read attribute fix database for attack calculations
  13122.  * Function stores information in the attr_fix_table
  13123.  * @return True
  13124.  */
  13125. static bool status_readdb_attrfix(const char *basedir,bool silent)
  13126. {
  13127.     FILE *fp;
  13128.     char line[512], path[512];
  13129.     int entries = 0;
  13130.  
  13131.  
  13132.     sprintf(path, "%s/attr_fix.txt", basedir);
  13133.     fp = fopen(path,"r");
  13134.     if (fp == NULL) {
  13135.         if (silent==0)
  13136.             ShowError("Can't read %s\n", path);
  13137.         return 1;
  13138.     }
  13139.     while (fgets(line, sizeof(line), fp)) {
  13140.         int lv, i, j;
  13141.         if (line[0] == '/' && line[1] == '/')
  13142.             continue;
  13143.  
  13144.         lv = atoi(line);
  13145.         if (!CHK_ELEMENT_LEVEL(lv))
  13146.             continue;
  13147.  
  13148.         for (i = 0; i < ELE_ALL;) {
  13149.             char *p;
  13150.             if (!fgets(line, sizeof(line), fp))
  13151.                 break;
  13152.             if (line[0]=='/' && line[1]=='/')
  13153.                 continue;
  13154.  
  13155.             for (j = 0, p = line; j < ELE_ALL && p; j++) {
  13156.                 while (*p > 0 && *p == 32) //skipping newline and space (32=' ')
  13157.                     p++;
  13158.                 attr_fix_table[lv-1][i][j] = atoi(p);
  13159.                 if (battle_config.attr_recover == 0 && attr_fix_table[lv-1][i][j] < 0)
  13160.                     attr_fix_table[lv-1][i][j] = 0;
  13161.                 p = strchr(p,',');
  13162.                 if(p)
  13163.                     *p++=0;
  13164.             }
  13165.  
  13166.             i++;
  13167.         }
  13168.         entries++;
  13169.     }
  13170.     fclose(fp);
  13171.     ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entries, path);
  13172.     return true;
  13173. }
  13174.  
  13175. /**
  13176.  * Sets defaults in tables and starts read db functions
  13177.  * sv_readdb reads the file, outputting the information line-by-line to
  13178.  * previous functions above, separating information by delimiter
  13179.  * DBs being read:
  13180.  *  attr_fix.txt: Attribute adjustment table for attacks
  13181.  *  size_fix.txt: Size adjustment table for weapons
  13182.  *  refine_db.txt: Refining data table
  13183.  * @return 0
  13184.  */
  13185. int status_readdb(void)
  13186. {
  13187.     int i, j, k;
  13188.     const char* dbsubpath[] = {
  13189.         "",
  13190.         "/"DBIMPORT,
  13191.         //add other path here
  13192.     };
  13193.     // Initialize databases to default
  13194.     // size_fix.txt
  13195.     for(i=0;i<ARRAYLENGTH(atkmods);i++)
  13196.         for(j=0;j<MAX_WEAPON_TYPE;j++)
  13197.             atkmods[i][j]=100;
  13198.     // refine_db.txt
  13199.     for(i=0;i<ARRAYLENGTH(refine_info);i++)
  13200.     {
  13201.         for(j=0;j<MAX_REFINE; j++)
  13202.         {
  13203.             refine_info[i].chance[j] = 100;
  13204.             refine_info[i].bonus[j] = 0;
  13205.             refine_info[i].randombonus_max[j] = 0;
  13206.         }
  13207.     }
  13208.     // attr_fix.txt
  13209.     for(i=0;i<4;i++)
  13210.         for(j=0;j<ELE_ALL;j++)
  13211.             for(k=0;k<ELE_ALL;k++)
  13212.                 attr_fix_table[i][j][k]=100;
  13213.  
  13214.     // read databases
  13215.     // path,filename,separator,mincol,maxcol,maxrow,func_parsor
  13216.     for(i=0; i<ARRAYLENGTH(dbsubpath); i++){
  13217.         int n1 = strlen(db_path)+strlen(dbsubpath[i])+1;
  13218.         int n2 = strlen(db_path)+strlen(DBPATH)+strlen(dbsubpath[i])+1;
  13219.         char* dbsubpath1 = (char*)aMalloc(n1+1);
  13220.         char* dbsubpath2 = (char*)aMalloc(n2+1);
  13221.  
  13222.         if(i==0) {
  13223.             safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
  13224.             safesnprintf(dbsubpath2,n2,"%s/%s%s",db_path,DBPATH,dbsubpath[i]);
  13225.         }
  13226.         else {
  13227.             safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
  13228.             safesnprintf(dbsubpath2,n1,"%s%s",db_path,dbsubpath[i]);
  13229.         }
  13230.        
  13231.         status_readdb_attrfix(dbsubpath2,i); // !TODO use sv_readdb ?
  13232.         sv_readdb(dbsubpath1, "size_fix.txt",',',MAX_WEAPON_TYPE,MAX_WEAPON_TYPE,ARRAYLENGTH(atkmods),&status_readdb_sizefix, i);
  13233.         sv_readdb(dbsubpath2, "refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(refine_info), &status_readdb_refine, i);
  13234.         aFree(dbsubpath1);
  13235.         aFree(dbsubpath2);
  13236.     }
  13237.     return 0;
  13238. }
  13239.  
  13240. /**
  13241.  * Status db init and destroy.
  13242.  */
  13243. int do_init_status(void)
  13244. {
  13245.     add_timer_func_list(status_change_timer,"status_change_timer");
  13246.     add_timer_func_list(status_natural_heal_timer,"status_natural_heal_timer");
  13247.     initChangeTables();
  13248.     initDummyData();
  13249.     status_readdb();
  13250.     natural_heal_prev_tick = gettick();
  13251.     sc_data_ers = ers_new(sizeof(struct status_change_entry),"status.c::sc_data_ers",ERS_OPT_NONE);
  13252.     add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
  13253.     return 0;
  13254. }
  13255. void do_final_status(void)
  13256. {
  13257.     ers_destroy(sc_data_ers);
  13258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement