summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-11-22 23:52:58 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-11-22 23:52:58 +0000
commit2b2dbf43f11aecf778ff118dd1da1af9726f36e6 (patch)
tree890231641c122da8ef8664471be4a008041c6349 /src/map/status.c
parent78dcaf513236ab7736a84deff5820b71cf6a76fb (diff)
downloadhercules-2b2dbf43f11aecf778ff118dd1da1af9726f36e6.tar.gz
hercules-2b2dbf43f11aecf778ff118dd1da1af9726f36e6.tar.bz2
hercules-2b2dbf43f11aecf778ff118dd1da1af9726f36e6.tar.xz
hercules-2b2dbf43f11aecf778ff118dd1da1af9726f36e6.zip
- Changed the status_change structure to use dynamic rather than static memory to hold the individual status changes, this should have a noticeable impact on the server's memory consumption.
- Had to add a few 'ugly' flags to status_change since now you can't track SC related information while said SC is not active (happens only for Storm Gust, Joint Beat and Magic Power). - Since I am unable to fully test, watch out for any bugs~ git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11786 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c1785
1 files changed, 901 insertions, 884 deletions
diff --git a/src/map/status.c b/src/map/status.c
index b7221ea6e..a76c03a6c 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -7,6 +7,7 @@
#include "../common/showmsg.h"
#include "../common/malloc.h"
#include "../common/utils.h"
+#include "../common/ers.h"
#include "pc.h"
#include "map.h"
@@ -63,6 +64,8 @@ int current_equip_card_id; //To prevent card-stacking (from jA) [Skotlex]
//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
+static struct eri *sc_data_ers; //For sc_data entries
+
static void add_sc(int skill, int sc)
{
int sk = skill;
@@ -637,10 +640,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if (hp && !(flag&1)) {
if (sc) {
- if (sc->data[SC_DEVOTION].val1 && src && battle_getcurrentskill(src) != PA_PRESSURE)
+ struct status_change_entry *sce;
+ if ((sce=sc->data[SC_DEVOTION]) && src && battle_getcurrentskill(src) != PA_PRESSURE)
{ //Devotion prevents any of the other ailments from ending.
- struct map_session_data *sd2 = map_id2sd(sc->data[SC_DEVOTION].val1);
- if (sd2 && sd2->devotion[sc->data[SC_DEVOTION].val2] == target->id)
+ struct map_session_data *sd2 = map_id2sd(sce->val1);
+ if (sd2 && sd2->devotion[sce->val2] == target->id)
{
clif_damage(&sd2->bl, &sd2->bl, gettick(), 0, 0, hp, 0, 0, 0);
status_fix_damage(NULL, &sd2->bl, hp, 0);
@@ -648,41 +652,41 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
}
status_change_end(target, SC_DEVOTION, -1);
}
- if (sc->data[SC_FREEZE].timer != -1)
+ if (sc->data[SC_FREEZE])
status_change_end(target,SC_FREEZE,-1);
- if (sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE)
+ if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
status_change_end(target,SC_STONE,-1);
- if (sc->data[SC_SLEEP].timer != -1)
+ if (sc->data[SC_SLEEP])
status_change_end(target,SC_SLEEP,-1);
- if (sc->data[SC_WINKCHARM].timer != -1)
+ if (sc->data[SC_WINKCHARM])
status_change_end(target,SC_WINKCHARM,-1);
- if (sc->data[SC_CONFUSION].timer != -1)
+ if (sc->data[SC_CONFUSION])
status_change_end(target, SC_CONFUSION, -1);
- if (sc->data[SC_TRICKDEAD].timer != -1)
+ if (sc->data[SC_TRICKDEAD])
status_change_end(target, SC_TRICKDEAD, -1);
- if (sc->data[SC_HIDING].timer != -1)
+ if (sc->data[SC_HIDING])
status_change_end(target, SC_HIDING, -1);
- if (sc->data[SC_CLOAKING].timer != -1)
+ if (sc->data[SC_CLOAKING])
status_change_end(target, SC_CLOAKING, -1);
- if (sc->data[SC_CHASEWALK].timer != -1)
+ if (sc->data[SC_CHASEWALK])
status_change_end(target, SC_CHASEWALK, -1);
- if (sc->data[SC_ENDURE].timer != -1 && !sc->data[SC_ENDURE].val4) {
+ if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
//Endure count is only reduced by non-players on non-gvg maps.
//val4 signals infinite endure. [Skotlex]
if (src && src->type != BL_PC && !map_flag_gvg(target->m)
- && --(sc->data[SC_ENDURE].val2) < 0)
+ && --(sce->val2) < 0)
status_change_end(target, SC_ENDURE, -1);
}
- if (sc->data[SC_GRAVITATION].timer != -1 &&
- sc->data[SC_GRAVITATION].val3 == BCT_SELF) {
- struct skill_unit_group *sg = (struct skill_unit_group *)sc->data[SC_GRAVITATION].val4;
+ if ((sce=sc->data[SC_GRAVITATION]) &&
+ sce->val3 == BCT_SELF) {
+ struct skill_unit_group *sg = (struct skill_unit_group *)sce->val4;
if (sg) {
skill_delunitgroup(target,sg);
- sc->data[SC_GRAVITATION].val4 = 0;
+ sce->val4 = 0;
status_change_end(target, SC_GRAVITATION, -1);
}
}
- if(sc->data[SC_DANCING].timer != -1 && (unsigned int)hp > status->max_hp>>2)
+ if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
skill_stop_dancing(target);
}
unit_skillcastcancel(target, 2);
@@ -702,12 +706,11 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status->sp-= sp;
if (sc && hp && status->hp) {
- if (sc->data[SC_AUTOBERSERK].timer != -1 &&
- (sc->data[SC_PROVOKE].timer==-1 || !sc->data[SC_PROVOKE].val2) &&
+ if (sc->data[SC_AUTOBERSERK] &&
+ (!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) &&
status->hp < status->max_hp>>2)
sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
- if (sc->data[SC_BERSERK].timer != -1 &&
- status->hp <= 100)
+ if (sc->data[SC_BERSERK] && status->hp <= 100)
status_change_end(target, SC_BERSERK, -1);
}
@@ -801,7 +804,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
}
if(hp) {
- if (!(flag&1) && sc && sc->data[SC_BERSERK].timer!=-1)
+ if (!(flag&1) && sc && sc->data[SC_BERSERK])
hp = 0;
if((unsigned int)hp > status->max_hp - status->hp)
@@ -824,9 +827,9 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
status->sp+= sp;
if(hp && sc &&
- sc->data[SC_AUTOBERSERK].timer != -1 &&
- sc->data[SC_PROVOKE].timer!=-1 &&
- sc->data[SC_PROVOKE].val2==1 &&
+ sc->data[SC_AUTOBERSERK] &&
+ sc->data[SC_PROVOKE] &&
+ sc->data[SC_PROVOKE]->val2==1 &&
status->hp>=status->max_hp>>2
) //End auto berserk.
status_change_end(bl,SC_PROVOKE,-1);
@@ -1007,22 +1010,21 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
}
if (
- (sc->data[SC_TRICKDEAD].timer != -1 && skill_num != NV_TRICKDEAD)
- || (sc->data[SC_AUTOCOUNTER].timer != -1 && !flag)
- || (sc->data[SC_GOSPEL].timer != -1 && sc->data[SC_GOSPEL].val4 == BCT_SELF && skill_num != PA_GOSPEL)
- || (sc->data[SC_GRAVITATION].timer != -1 && sc->data[SC_GRAVITATION].val3 == BCT_SELF && flag != 2)
-// || (sc->data[SC_CLOAKING].timer != -1 && sc->data[SC_CLOAKING].val1 < 3 && skill_num != AS_CLOAKING) //Official sites say it blocks attack/skill usage, ingame proof says it does not.
+ (sc->data[SC_TRICKDEAD] && skill_num != NV_TRICKDEAD)
+ || (sc->data[SC_AUTOCOUNTER] && !flag)
+ || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_num != PA_GOSPEL)
+ || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF && flag != 2)
)
return 0;
- if (sc->data[SC_WINKCHARM].timer != -1 && target && !flag)
+ if (sc->data[SC_WINKCHARM] && target && !flag)
{ //Prevents skill usage
clif_emotion(src, 3);
return 0;
}
- if (sc->data[SC_BLADESTOP].timer != -1) {
- switch (sc->data[SC_BLADESTOP].val1)
+ if (sc->data[SC_BLADESTOP]) {
+ switch (sc->data[SC_BLADESTOP]->val1)
{
case 5: if (skill_num == MO_EXTREMITYFIST) break;
case 4: if (skill_num == MO_CHAINCOMBO) break;
@@ -1032,19 +1034,25 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
}
}
- if (sc->data[SC_DANCING].timer != -1 && flag!=2)
+ if (sc->data[SC_DANCING] && flag!=2)
{
- if(sc->data[SC_LONGING].timer != -1)
+ if(sc->data[SC_LONGING])
{ //Allow everything except dancing/re-dancing. [Skotlex]
if (skill_num == BD_ENCORE ||
skill_get_inf2(skill_num)&(INF2_SONG_DANCE|INF2_ENSEMBLE_SKILL)
)
return 0;
} else
- if (skill_num != BD_ADAPTATION && skill_num != CG_LONGINGFREEDOM
- && skill_num != BA_MUSICALSTRIKE && skill_num != DC_THROWARROW)
+ switch (skill_num) {
+ case BD_ADAPTATION:
+ case CG_LONGINGFREEDOM:
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ break;
+ default:
return 0;
- if ((sc->data[SC_DANCING].val1&0xFFFF) == CG_HERMODE && skill_num == BD_ADAPTATION)
+ }
+ if ((sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE && skill_num == BD_ADAPTATION)
return 0; //Can't amp out of Wand of Hermode :/ [Skotlex]
}
@@ -1052,20 +1060,20 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
(src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_num)
) { //Skills blocked through status changes...
if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through
- sc->data[SC_SILENCE].timer != -1 ||
- (sc->data[SC_MARIONETTE].timer != -1 && skill_num != CG_MARIONETTE) ||
- (sc->data[SC_MARIONETTE2].timer != -1 && skill_num == CG_MARIONETTE) ||
- sc->data[SC_STEELBODY].timer != -1 ||
- sc->data[SC_BERSERK].timer != -1
+ sc->data[SC_SILENCE] ||
+ (sc->data[SC_MARIONETTE] && skill_num != CG_MARIONETTE) ||
+ (sc->data[SC_MARIONETTE2] && skill_num == CG_MARIONETTE) ||
+ sc->data[SC_STEELBODY] ||
+ sc->data[SC_BERSERK]
))
return 0;
//Skill blocking.
if (
- (sc->data[SC_VOLCANO].timer != -1 && skill_num == WZ_ICEWALL) ||
- (sc->data[SC_ROKISWEIL].timer != -1 && skill_num != BD_ADAPTATION) ||
- (sc->data[SC_HERMODE].timer != -1 && skill_get_inf(skill_num) & INF_SUPPORT_SKILL) ||
- (sc->data[SC_NOCHAT].timer != -1 && sc->data[SC_NOCHAT].val1&MANNER_NOSKILL)
+ (sc->data[SC_VOLCANO] && skill_num == WZ_ICEWALL) ||
+ (sc->data[SC_ROKISWEIL] && skill_num != BD_ADAPTATION) ||
+ (sc->data[SC_HERMODE] && skill_get_inf(skill_num) & INF_SUPPORT_SKILL) ||
+ (sc->data[SC_NOCHAT] && sc->data[SC_NOCHAT]->val1&MANNER_NOSKILL)
)
return 0;
@@ -1098,12 +1106,12 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if(tsc && tsc->count)
{
- if(!skill_num && !(status->mode&MD_BOSS) && tsc->data[SC_TRICKDEAD].timer != -1)
+ if(!skill_num && !(status->mode&MD_BOSS) && tsc->data[SC_TRICKDEAD])
return 0;
if((skill_num == WZ_STORMGUST || skill_num == NJ_HYOUSYOURAKU)
- && tsc->data[SC_FREEZE].timer != -1)
+ && tsc->data[SC_FREEZE])
return 0;
- if(skill_num == PR_LEXAETERNA && (tsc->data[SC_FREEZE].timer != -1 || (tsc->data[SC_STONE].timer != -1 && tsc->opt1 == OPT1_STONE)))
+ if(skill_num == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
return 0;
}
@@ -2246,8 +2254,8 @@ int status_calc_pc(struct map_session_data* sd,int first)
sd->max_weight += 2000*skill;
if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
sd->max_weight += 10000;
- if(sd->sc.data[SC_KNOWLEDGE].timer != -1)
- sd->max_weight += sd->max_weight*sd->sc.data[SC_KNOWLEDGE].val1/10;
+ if(sd->sc.data[SC_KNOWLEDGE])
+ sd->max_weight += sd->max_weight*sd->sc.data[SC_KNOWLEDGE]->val1/10;
if((skill=pc_checkskill(sd,ALL_INCCARRY))>0)
sd->max_weight += 2000*skill;
@@ -2261,8 +2269,8 @@ int status_calc_pc(struct map_session_data* sd,int first)
sd->dsprate -= 4*skill;
if(sd->sc.count){
- if(sd->sc.data[SC_SERVICE4U].timer!=-1)
- sd->dsprate -= sd->sc.data[SC_SERVICE4U].val3;
+ if(sd->sc.data[SC_SERVICE4U])
+ sd->dsprate -= sd->sc.data[SC_SERVICE4U]->val3;
}
//Underflow protections.
@@ -2293,25 +2301,26 @@ int status_calc_pc(struct map_session_data* sd,int first)
}
if(sd->sc.count){
- if(sd->sc.data[SC_CONCENTRATE].timer!=-1)
+ if(sd->sc.data[SC_CONCENTRATE])
{ //Update the card-bonus data
- sd->sc.data[SC_CONCENTRATE].val3 = sd->param_bonus[1]; //Agi
- sd->sc.data[SC_CONCENTRATE].val4 = sd->param_bonus[4]; //Dex
+ sd->sc.data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; //Agi
+ sd->sc.data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; //Dex
}
- if(sd->sc.data[SC_SIEGFRIED].timer!=-1){
- sd->subele[1] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[2] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[3] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[4] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[5] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[6] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[7] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[8] += sd->sc.data[SC_SIEGFRIED].val2;
- sd->subele[9] += sd->sc.data[SC_SIEGFRIED].val2;
+ if(sd->sc.data[SC_SIEGFRIED]){
+ i = sd->sc.data[SC_SIEGFRIED]->val2;
+ sd->subele[ELE_WATER] += i;
+ sd->subele[ELE_EARTH] += i;
+ sd->subele[ELE_FIRE] += i;
+ sd->subele[ELE_WIND] += i;
+ sd->subele[ELE_POISON] += i;
+ sd->subele[ELE_HOLY] += i;
+ sd->subele[ELE_DARK] += i;
+ sd->subele[ELE_GHOST] += i;
+ sd->subele[ELE_UNDEAD] += i;
}
- if(sd->sc.data[SC_PROVIDENCE].timer!=-1){
- sd->subele[6] += sd->sc.data[SC_PROVIDENCE].val2;
- sd->subrace[RC_DEMON] += sd->sc.data[SC_PROVIDENCE].val2;
+ if(sd->sc.data[SC_PROVIDENCE]){
+ sd->subele[ELE_HOLY] += sd->sc.data[SC_PROVIDENCE]->val2;
+ sd->subrace[RC_DEMON] += sd->sc.data[SC_PROVIDENCE]->val2;
}
}
@@ -2616,42 +2625,43 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
return;
if (
- (sc->data[SC_POISON].timer != -1 && sc->data[SC_SLOWPOISON].timer == -1)
- || (sc->data[SC_DPOISON].timer != -1 && sc->data[SC_SLOWPOISON].timer == -1)
- || sc->data[SC_BERSERK].timer != -1
- || sc->data[SC_TRICKDEAD].timer != -1
- || sc->data[SC_BLEEDING].timer != -1
+ (sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
+ || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
+ || sc->data[SC_BERSERK]
+ || sc->data[SC_TRICKDEAD]
+ || sc->data[SC_BLEEDING]
) //No regen
regen->flag = 0;
if (
- sc->data[SC_EXTREMITYFIST].timer != -1
- || sc->data[SC_DANCING].timer != -1
- || (sc->data[SC_EXPLOSIONSPIRITS].timer != -1
- && (sc->data[SC_SPIRIT].timer==-1 || sc->data[SC_SPIRIT].val2 != SL_MONK))
+ sc->data[SC_EXTREMITYFIST]
+ || sc->data[SC_DANCING]
+ || (sc->data[SC_EXPLOSIONSPIRITS]
+ && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK))
) //No natural SP regen
regen->flag &=~RGN_SP;
if(
- sc->data[SC_TENSIONRELAX].timer!=-1
+ sc->data[SC_TENSIONRELAX]
) {
regen->rate.hp += 2;
if (regen->sregen)
regen->sregen->rate.hp += 3;
}
- if (sc->data[SC_MAGNIFICAT].timer != -1)
+ if (sc->data[SC_MAGNIFICAT])
{
regen->rate.hp += 1;
regen->rate.sp += 1;
}
- if (sc->data[SC_REGENERATION].timer != -1)
+ if (sc->data[SC_REGENERATION])
{
- if (!sc->data[SC_REGENERATION].val4)
+ const struct status_change_entry *sce = sc->data[SC_REGENERATION];
+ if (!sce->val4)
{
- regen->rate.hp += sc->data[SC_REGENERATION].val2;
- regen->rate.sp += sc->data[SC_REGENERATION].val3;
+ regen->rate.hp += sce->val2;
+ regen->rate.sp += sce->val3;
} else
- regen->flag&=~sc->data[SC_REGENERATION].val4; //Remove regen as specified by val4
+ regen->flag&=~sce->val4; //Remove regen as specified by val4
}
}
@@ -2715,9 +2725,9 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
status->matk_min = status_calc_matk(&sd->bl, &sd->sc, status->matk_min);
status->matk_max = status_calc_matk(&sd->bl, &sd->sc, status->matk_max);
- if(sd->sc.data[SC_MAGICPOWER].timer!=-1) { //Store current matk values
- sd->sc.data[SC_MAGICPOWER].val3 = status->matk_min;
- sd->sc.data[SC_MAGICPOWER].val4 = status->matk_max;
+ if(sd->sc.data[SC_MAGICPOWER]) { //Store current matk values
+ sd->sc.mp_matk_min = status->matk_min;
+ sd->sc.mp_matk_max = status->matk_max;
}
}
@@ -2834,7 +2844,6 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
{
struct status_data *status = &hd->battle_status, *b_status = &hd->base_status;
- struct status_change *sc = &hd->sc;
int skill = 0;
@@ -2862,23 +2871,23 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
if(flag&SCB_VIT)
{ //Since vit affects def, recalculate def.
flag|=SCB_DEF;
- status->def = status_calc_def(&hd->bl, sc, b_status->def);
+ status->def = status_calc_def(&hd->bl, &hd->sc, b_status->def);
status->def+= (status->vit/5 - b_status->vit/5);
}
if(flag&SCB_INT)
{
flag|=SCB_MDEF;
- status->mdef = status_calc_mdef(&hd->bl, sc, b_status->mdef);
+ status->mdef = status_calc_mdef(&hd->bl, &hd->sc, b_status->mdef);
status->mdef+= (status->int_/5 - b_status->int_/5);
}
if(flag&SCB_DEX) {
flag |=SCB_WATK;
- status->rhw.atk = status_calc_watk(&hd->bl, sc, b_status->rhw.atk);
+ status->rhw.atk = status_calc_watk(&hd->bl, &hd->sc, b_status->rhw.atk);
status->rhw.atk+= (status->dex - b_status->dex);
}
if(flag&SCB_STR) {
flag |=SCB_WATK;
- status->rhw.atk2 = status_calc_watk(&hd->bl, sc, b_status->rhw.atk2);
+ status->rhw.atk2 = status_calc_watk(&hd->bl, &hd->sc, b_status->rhw.atk2);
status->rhw.atk2+= (status->str - b_status->str);
}
if(flag|SCB_WATK && status->rhw.atk2 < status->rhw.atk)
@@ -2896,7 +2905,7 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
skill = (1000 -4*status->agi -status->dex)
*hd->homunculusDB->baseASPD/1000;
- status->aspd_rate = status_calc_aspd_rate(&hd->bl, sc , b_status->aspd_rate);
+ status->aspd_rate = status_calc_aspd_rate(&hd->bl, &hd->sc , b_status->aspd_rate);
if(status->aspd_rate != 1000)
skill = skill*status->aspd_rate/1000;
@@ -2907,14 +2916,14 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
if(flag&(SCB_AGI|SCB_DSPD)) {
skill = 800-status->agi*4;
status->dmotion = cap_value(skill, 400, 800);
- status->dmotion = status_calc_dmotion(&hd->bl, sc, b_status->dmotion);
+ status->dmotion = status_calc_dmotion(&hd->bl, &hd->sc, b_status->dmotion);
}
if(flag&(SCB_INT|SCB_MAXSP|SCB_VIT|SCB_MAXHP) && flag != SCB_ALL)
status_calc_regen(&hd->bl, status, &hd->regen);
if(flag&SCB_REGEN)
- status_calc_regen_rate(&hd->bl, &hd->regen, sc);
+ status_calc_regen_rate(&hd->bl, &hd->regen, &hd->sc);
if (flag == SCB_ALL)
return; //Refresh is done on invoking function (status_calc_hom)
@@ -3119,9 +3128,9 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
status->matk_max = status_base_matk_max(status);
status->matk_min = status_calc_matk(bl, sc, status->matk_min);
status->matk_max = status_calc_matk(bl, sc, status->matk_max);
- if(sc->data[SC_MAGICPOWER].timer!=-1) { //Store current matk values
- sc->data[SC_MAGICPOWER].val3 = status->matk_min;
- sc->data[SC_MAGICPOWER].val4 = status->matk_max;
+ if(sc->data[SC_MAGICPOWER]) { //Store current matk values
+ sc->mp_matk_min = status->matk_min;
+ sc->mp_matk_max = status->matk_max;
}
}
@@ -3158,35 +3167,35 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(str,0,USHRT_MAX);
- if(sc->data[SC_INCALLSTATUS].timer!=-1)
- str += sc->data[SC_INCALLSTATUS].val1;
- if(sc->data[SC_INCSTR].timer!=-1)
- str += sc->data[SC_INCSTR].val1;
- if(sc->data[SC_STRFOOD].timer!=-1)
- str += sc->data[SC_STRFOOD].val1;
- if(sc->data[SC_BATTLEORDERS].timer!=-1)
+ if(sc->data[SC_INCALLSTATUS])
+ str += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCSTR])
+ str += sc->data[SC_INCSTR]->val1;
+ if(sc->data[SC_STRFOOD])
+ str += sc->data[SC_STRFOOD]->val1;
+ if(sc->data[SC_BATTLEORDERS])
str += 5;
- if(sc->data[SC_GUILDAURA].timer != -1 && sc->data[SC_GUILDAURA].val3>>16)
- str += sc->data[SC_GUILDAURA].val3>>16;
- if(sc->data[SC_LOUD].timer!=-1)
+ if(sc->data[SC_GUILDAURA] && sc->data[SC_GUILDAURA]->val3>>16)
+ str += (sc->data[SC_GUILDAURA]->val3)>>16;
+ if(sc->data[SC_LOUD])
str += 4;
- if(sc->data[SC_TRUESIGHT].timer!=-1)
+ if(sc->data[SC_TRUESIGHT])
str += 5;
- if(sc->data[SC_SPURT].timer!=-1)
+ if(sc->data[SC_SPURT])
str += 10;
- if(sc->data[SC_NEN].timer!=-1)
- str += sc->data[SC_NEN].val1;
- if(sc->data[SC_BLESSING].timer != -1){
- if(sc->data[SC_BLESSING].val2)
- str += sc->data[SC_BLESSING].val2;
+ if(sc->data[SC_NEN])
+ str += sc->data[SC_NEN]->val1;
+ if(sc->data[SC_BLESSING]){
+ if(sc->data[SC_BLESSING]->val2)
+ str += sc->data[SC_BLESSING]->val2;
else
str >>= 1;
}
- if(sc->data[SC_MARIONETTE].timer!=-1)
- str -= (sc->data[SC_MARIONETTE].val3>>16)&0xFF;
- if(sc->data[SC_MARIONETTE2].timer!=-1)
- str += (sc->data[SC_MARIONETTE2].val3>>16)&0xFF;
- if(sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_HIGH && str < 50)
+ if(sc->data[SC_MARIONETTE])
+ str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && str < 50)
str = 50;
return (unsigned short)cap_value(str,0,USHRT_MAX);
@@ -3197,33 +3206,33 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(agi,0,USHRT_MAX);
- if(sc->data[SC_CONCENTRATE].timer!=-1 && sc->data[SC_QUAGMIRE].timer == -1)
- agi += (agi-sc->data[SC_CONCENTRATE].val3)*sc->data[SC_CONCENTRATE].val2/100;
- if(sc->data[SC_INCALLSTATUS].timer!=-1)
- agi += sc->data[SC_INCALLSTATUS].val1;
- if(sc->data[SC_INCAGI].timer!=-1)
- agi += sc->data[SC_INCAGI].val1;
- if(sc->data[SC_AGIFOOD].timer!=-1)
- agi += sc->data[SC_AGIFOOD].val1;
- if(sc->data[SC_GUILDAURA].timer != -1 && sc->data[SC_GUILDAURA].val4>>16)
- agi += sc->data[SC_GUILDAURA].val4>>16;
- if(sc->data[SC_TRUESIGHT].timer!=-1)
+ if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
+ agi += (agi-sc->data[SC_CONCENTRATE]->val3)*sc->data[SC_CONCENTRATE]->val2/100;
+ if(sc->data[SC_INCALLSTATUS])
+ agi += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCAGI])
+ agi += sc->data[SC_INCAGI]->val1;
+ if(sc->data[SC_AGIFOOD])
+ agi += sc->data[SC_AGIFOOD]->val1;
+ if(sc->data[SC_GUILDAURA] && (sc->data[SC_GUILDAURA]->val4)>>16)
+ agi += (sc->data[SC_GUILDAURA]->val4)>>16;
+ if(sc->data[SC_TRUESIGHT])
agi += 5;
- if(sc->data[SC_INCREASEAGI].timer!=-1)
- agi += sc->data[SC_INCREASEAGI].val2;
- if(sc->data[SC_INCREASING].timer!=-1)
+ if(sc->data[SC_INCREASEAGI])
+ agi += sc->data[SC_INCREASEAGI]->val2;
+ if(sc->data[SC_INCREASING])
agi += 4; // added based on skill updates [Reddozen]
- if(sc->data[SC_DECREASEAGI].timer!=-1)
- agi -= sc->data[SC_DECREASEAGI].val2;
- if(sc->data[SC_QUAGMIRE].timer!=-1)
- agi -= sc->data[SC_QUAGMIRE].val2;
- if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val3)
- agi -= sc->data[SC_SUITON].val2;
- if(sc->data[SC_MARIONETTE].timer!=-1)
- agi -= (sc->data[SC_MARIONETTE].val3>>8)&0xFF;
- if(sc->data[SC_MARIONETTE2].timer!=-1)
- agi += (sc->data[SC_MARIONETTE2].val3>>8)&0xFF;
- if(sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_HIGH && agi < 50)
+ if(sc->data[SC_DECREASEAGI])
+ agi -= sc->data[SC_DECREASEAGI]->val2;
+ if(sc->data[SC_QUAGMIRE])
+ agi -= sc->data[SC_QUAGMIRE]->val2;
+ if(sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
+ agi -= sc->data[SC_SUITON]->val2;
+ if(sc->data[SC_MARIONETTE])
+ agi -= ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50)
agi = 50;
return (unsigned short)cap_value(agi,0,USHRT_MAX);
@@ -3234,25 +3243,25 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(vit,0,USHRT_MAX);
- if(sc->data[SC_INCALLSTATUS].timer!=-1)
- vit += sc->data[SC_INCALLSTATUS].val1;
- if(sc->data[SC_INCVIT].timer!=-1)
- vit += sc->data[SC_INCVIT].val1;
- if(sc->data[SC_VITFOOD].timer!=-1)
- vit += sc->data[SC_VITFOOD].val1;
- if(sc->data[SC_CHANGE].timer!=-1)
- vit += sc->data[SC_CHANGE].val2;
- if(sc->data[SC_GUILDAURA].timer != -1 && sc->data[SC_GUILDAURA].val3&0xFFFF)
- vit += sc->data[SC_GUILDAURA].val3&0xFFFF;
- if(sc->data[SC_TRUESIGHT].timer!=-1)
+ if(sc->data[SC_INCALLSTATUS])
+ vit += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCVIT])
+ vit += sc->data[SC_INCVIT]->val1;
+ if(sc->data[SC_VITFOOD])
+ vit += sc->data[SC_VITFOOD]->val1;
+ if(sc->data[SC_CHANGE])
+ vit += sc->data[SC_CHANGE]->val2;
+ if(sc->data[SC_GUILDAURA] && sc->data[SC_GUILDAURA]->val3&0xFFFF)
+ vit += sc->data[SC_GUILDAURA]->val3&0xFFFF;
+ if(sc->data[SC_TRUESIGHT])
vit += 5;
- if(sc->data[SC_STRIPARMOR].timer!=-1)
- vit -= vit * sc->data[SC_STRIPARMOR].val2/100;
- if(sc->data[SC_MARIONETTE].timer!=-1)
- vit -= sc->data[SC_MARIONETTE].val3&0xFF;
- if(sc->data[SC_MARIONETTE2].timer!=-1)
- vit += sc->data[SC_MARIONETTE2].val3&0xFF;
- if(sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_HIGH && vit < 50)
+ if(sc->data[SC_STRIPARMOR])
+ vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
+ if(sc->data[SC_MARIONETTE])
+ vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50)
vit = 50;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
@@ -3263,33 +3272,33 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(int_,0,USHRT_MAX);
- if(sc->data[SC_INCALLSTATUS].timer!=-1)
- int_ += sc->data[SC_INCALLSTATUS].val1;
- if(sc->data[SC_INCINT].timer!=-1)
- int_ += sc->data[SC_INCINT].val1;
- if(sc->data[SC_INTFOOD].timer!=-1)
- int_ += sc->data[SC_INTFOOD].val1;
- if(sc->data[SC_CHANGE].timer!=-1)
- int_ += sc->data[SC_CHANGE].val3;
- if(sc->data[SC_BATTLEORDERS].timer!=-1)
+ if(sc->data[SC_INCALLSTATUS])
+ int_ += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCINT])
+ int_ += sc->data[SC_INCINT]->val1;
+ if(sc->data[SC_INTFOOD])
+ int_ += sc->data[SC_INTFOOD]->val1;
+ if(sc->data[SC_CHANGE])
+ int_ += sc->data[SC_CHANGE]->val3;
+ if(sc->data[SC_BATTLEORDERS])
int_ += 5;
- if(sc->data[SC_TRUESIGHT].timer!=-1)
+ if(sc->data[SC_TRUESIGHT])
int_ += 5;
- if(sc->data[SC_BLESSING].timer != -1){
- if (sc->data[SC_BLESSING].val2)
- int_ += sc->data[SC_BLESSING].val2;
+ if(sc->data[SC_BLESSING]){
+ if (sc->data[SC_BLESSING]->val2)
+ int_ += sc->data[SC_BLESSING]->val2;
else
int_ >>= 1;
}
- if(sc->data[SC_STRIPHELM].timer!=-1)
- int_ -= int_ * sc->data[SC_STRIPHELM].val2/100;
- if(sc->data[SC_NEN].timer!=-1)
- int_ += sc->data[SC_NEN].val1;
- if(sc->data[SC_MARIONETTE].timer!=-1)
- int_ -= (sc->data[SC_MARIONETTE].val4>>16)&0xFF;
- if(sc->data[SC_MARIONETTE2].timer!=-1)
- int_ += (sc->data[SC_MARIONETTE2].val4>>16)&0xFF;
- if(sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_HIGH && int_ < 50)
+ if(sc->data[SC_STRIPHELM])
+ int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
+ if(sc->data[SC_NEN])
+ int_ += sc->data[SC_NEN]->val1;
+ if(sc->data[SC_MARIONETTE])
+ int_ -= ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && int_ < 50)
int_ = 50;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
@@ -3300,36 +3309,36 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(dex,0,USHRT_MAX);
- if(sc->data[SC_CONCENTRATE].timer!=-1 && sc->data[SC_QUAGMIRE].timer == -1)
- dex += (dex-sc->data[SC_CONCENTRATE].val4)*sc->data[SC_CONCENTRATE].val2/100;
+ if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
+ dex += (dex-sc->data[SC_CONCENTRATE]->val4)*sc->data[SC_CONCENTRATE]->val2/100;
- if(sc->data[SC_INCALLSTATUS].timer!=-1)
- dex += sc->data[SC_INCALLSTATUS].val1;
- if(sc->data[SC_INCDEX].timer!=-1)
- dex += sc->data[SC_INCDEX].val1;
- if(sc->data[SC_DEXFOOD].timer!=-1)
- dex += sc->data[SC_DEXFOOD].val1;
- if(sc->data[SC_BATTLEORDERS].timer!=-1)
+ if(sc->data[SC_INCALLSTATUS])
+ dex += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCDEX])
+ dex += sc->data[SC_INCDEX]->val1;
+ if(sc->data[SC_DEXFOOD])
+ dex += sc->data[SC_DEXFOOD]->val1;
+ if(sc->data[SC_BATTLEORDERS])
dex += 5;
- if(sc->data[SC_GUILDAURA].timer != -1 && sc->data[SC_GUILDAURA].val4&0xFFFF)
- dex += sc->data[SC_GUILDAURA].val4&0xFFFF;
- if(sc->data[SC_TRUESIGHT].timer!=-1)
+ if(sc->data[SC_GUILDAURA] && sc->data[SC_GUILDAURA]->val4&0xFFFF)
+ dex += sc->data[SC_GUILDAURA]->val4&0xFFFF;
+ if(sc->data[SC_TRUESIGHT])
dex += 5;
- if(sc->data[SC_QUAGMIRE].timer!=-1)
- dex -= sc->data[SC_QUAGMIRE].val2;
- if(sc->data[SC_BLESSING].timer != -1){
- if (sc->data[SC_BLESSING].val2)
- dex += sc->data[SC_BLESSING].val2;
+ if(sc->data[SC_QUAGMIRE])
+ dex -= sc->data[SC_QUAGMIRE]->val2;
+ if(sc->data[SC_BLESSING]){
+ if (sc->data[SC_BLESSING]->val2)
+ dex += sc->data[SC_BLESSING]->val2;
else
dex >>= 1;
}
- if(sc->data[SC_INCREASING].timer!=-1)
+ if(sc->data[SC_INCREASING])
dex += 4; // added based on skill updates [Reddozen]
- if(sc->data[SC_MARIONETTE].timer!=-1)
- dex -= (sc->data[SC_MARIONETTE].val4>>8)&0xFF;
- if(sc->data[SC_MARIONETTE2].timer!=-1)
- dex += (sc->data[SC_MARIONETTE2].val4>>8)&0xFF;
- if(sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_HIGH && dex < 50)
+ if(sc->data[SC_MARIONETTE])
+ dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && dex < 50)
dex = 50;
return (unsigned short)cap_value(dex,0,USHRT_MAX);
@@ -3340,23 +3349,23 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(luk,0,USHRT_MAX);
- if(sc->data[SC_CURSE].timer!=-1)
+ if(sc->data[SC_CURSE])
return 0;
- if(sc->data[SC_INCALLSTATUS].timer!=-1)
- luk += sc->data[SC_INCALLSTATUS].val1;
- if(sc->data[SC_INCLUK].timer!=-1)
- luk += sc->data[SC_INCLUK].val1;
- if(sc->data[SC_LUKFOOD].timer!=-1)
- luk += sc->data[SC_LUKFOOD].val1;
- if(sc->data[SC_TRUESIGHT].timer!=-1)
+ if(sc->data[SC_INCALLSTATUS])
+ luk += sc->data[SC_INCALLSTATUS]->val1;
+ if(sc->data[SC_INCLUK])
+ luk += sc->data[SC_INCLUK]->val1;
+ if(sc->data[SC_LUKFOOD])
+ luk += sc->data[SC_LUKFOOD]->val1;
+ if(sc->data[SC_TRUESIGHT])
luk += 5;
- if(sc->data[SC_GLORIA].timer!=-1)
+ if(sc->data[SC_GLORIA])
luk += 30;
- if(sc->data[SC_MARIONETTE].timer!=-1)
- luk -= sc->data[SC_MARIONETTE].val4&0xFF;
- if(sc->data[SC_MARIONETTE2].timer!=-1)
- luk += sc->data[SC_MARIONETTE2].val4&0xFF;
- if(sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_HIGH && luk < 50)
+ if(sc->data[SC_MARIONETTE])
+ luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
+ if(sc->data[SC_MARIONETTE2])
+ luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
+ if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50)
luk = 50;
return (unsigned short)cap_value(luk,0,USHRT_MAX);
@@ -3367,34 +3376,34 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
if(!sc || !sc->count)
return cap_value(batk,0,USHRT_MAX);
- if(sc->data[SC_INCBASEATK].timer!=-1)
- batk += sc->data[SC_INCBASEATK].val1;
- if(sc->data[SC_ATKPOTION].timer!=-1)
- batk += sc->data[SC_ATKPOTION].val1;
- if(sc->data[SC_BATKFOOD].timer!=-1)
- batk += sc->data[SC_BATKFOOD].val1;
- if(sc->data[SC_INCATKRATE].timer!=-1)
- batk += batk * sc->data[SC_INCATKRATE].val1/100;
- if(sc->data[SC_PROVOKE].timer!=-1)
- batk += batk * sc->data[SC_PROVOKE].val3/100;
- if(sc->data[SC_CONCENTRATION].timer!=-1)
- batk += batk * sc->data[SC_CONCENTRATION].val2/100;
- if(sc->data[SC_SKE].timer!=-1)
+ if(sc->data[SC_INCBASEATK])
+ batk += sc->data[SC_INCBASEATK]->val1;
+ if(sc->data[SC_ATKPOTION])
+ batk += sc->data[SC_ATKPOTION]->val1;
+ if(sc->data[SC_BATKFOOD])
+ batk += sc->data[SC_BATKFOOD]->val1;
+ if(sc->data[SC_INCATKRATE])
+ batk += batk * sc->data[SC_INCATKRATE]->val1/100;
+ if(sc->data[SC_PROVOKE])
+ batk += batk * sc->data[SC_PROVOKE]->val3/100;
+ if(sc->data[SC_CONCENTRATION])
+ batk += batk * sc->data[SC_CONCENTRATION]->val2/100;
+ if(sc->data[SC_SKE])
batk += batk * 3;
- if(sc->data[SC_BLOODLUST].timer!=-1)
- batk += batk * sc->data[SC_BLOODLUST].val2/100;
- if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2&BREAK_WAIST)
+ if(sc->data[SC_BLOODLUST])
+ batk += batk * sc->data[SC_BLOODLUST]->val2/100;
+ if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST)
batk -= batk * 25/100;
- if(sc->data[SC_CURSE].timer!=-1)
+ if(sc->data[SC_CURSE])
batk -= batk * 25/100;
//Curse shouldn't effect on this? <- Curse OR Bleeding??
-// if(sc->data[SC_BLEEDING].timer != -1)
+// if(sc->data[SC_BLEEDING]->)
// batk -= batk * 25/100;
- if(sc->data[SC_FLEET].timer!=-1)
- batk += batk * sc->data[SC_FLEET].val3/100;
- if(sc->data[SC_GATLINGFEVER].timer!=-1)
- batk += sc->data[SC_GATLINGFEVER].val3;
- if(sc->data[SC_MADNESSCANCEL].timer!=-1)
+ if(sc->data[SC_FLEET])
+ batk += batk * sc->data[SC_FLEET]->val3/100;
+ if(sc->data[SC_GATLINGFEVER])
+ batk += sc->data[SC_GATLINGFEVER]->val3;
+ if(sc->data[SC_MADNESSCANCEL])
batk += 100;
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
@@ -3404,40 +3413,40 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
if(!sc || !sc->count)
return cap_value(watk,0,USHRT_MAX);
- if(sc->data[SC_IMPOSITIO].timer!=-1)
- watk += sc->data[SC_IMPOSITIO].val2;
- if(sc->data[SC_WATKFOOD].timer!=-1)
- watk += sc->data[SC_WATKFOOD].val1;
- if(sc->data[SC_DRUMBATTLE].timer!=-1)
- watk += sc->data[SC_DRUMBATTLE].val2;
- if(sc->data[SC_VOLCANO].timer!=-1)
- watk += sc->data[SC_VOLCANO].val2;
- if(sc->data[SC_INCATKRATE].timer!=-1)
- watk += watk * sc->data[SC_INCATKRATE].val1/100;
- if(sc->data[SC_PROVOKE].timer!=-1)
- watk += watk * sc->data[SC_PROVOKE].val3/100;
- if(sc->data[SC_CONCENTRATION].timer!=-1)
- watk += watk * sc->data[SC_CONCENTRATION].val2/100;
- if(sc->data[SC_SKE].timer!=-1)
+ if(sc->data[SC_IMPOSITIO])
+ watk += sc->data[SC_IMPOSITIO]->val2;
+ if(sc->data[SC_WATKFOOD])
+ watk += sc->data[SC_WATKFOOD]->val1;
+ if(sc->data[SC_DRUMBATTLE])
+ watk += sc->data[SC_DRUMBATTLE]->val2;
+ if(sc->data[SC_VOLCANO])
+ watk += sc->data[SC_VOLCANO]->val2;
+ if(sc->data[SC_INCATKRATE])
+ watk += watk * sc->data[SC_INCATKRATE]->val1/100;
+ if(sc->data[SC_PROVOKE])
+ watk += watk * sc->data[SC_PROVOKE]->val3/100;
+ if(sc->data[SC_CONCENTRATION])
+ watk += watk * sc->data[SC_CONCENTRATION]->val2/100;
+ if(sc->data[SC_SKE])
watk += watk * 3;
- if(sc->data[SC_NIBELUNGEN].timer!=-1) {
+ if(sc->data[SC_NIBELUNGEN]) {
if (bl->type != BL_PC)
- watk += sc->data[SC_NIBELUNGEN].val2;
+ watk += sc->data[SC_NIBELUNGEN]->val2;
else {
TBL_PC *sd = (TBL_PC*)bl;
- int index = sd->equip_index[sd->state.lr_flag?8:9];
+ int index = sd->equip_index[sd->state.lr_flag?EQI_HAND_L:EQI_HAND_R];
if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
- watk += sc->data[SC_NIBELUNGEN].val2;
+ watk += sc->data[SC_NIBELUNGEN]->val2;
}
}
- if(sc->data[SC_BLOODLUST].timer!=-1)
- watk += watk * sc->data[SC_BLOODLUST].val2/100;
- if(sc->data[SC_FLEET].timer!=-1)
- watk += watk * sc->data[SC_FLEET].val3/100;
- if(sc->data[SC_CURSE].timer!=-1)
+ if(sc->data[SC_BLOODLUST])
+ watk += watk * sc->data[SC_BLOODLUST]->val2/100;
+ if(sc->data[SC_FLEET])
+ watk += watk * sc->data[SC_FLEET]->val3/100;
+ if(sc->data[SC_CURSE])
watk -= watk * 25/100;
- if(sc->data[SC_STRIPWEAPON].timer!=-1)
- watk -= watk * sc->data[SC_STRIPWEAPON].val2/100;
+ if(sc->data[SC_STRIPWEAPON])
+ watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
return (unsigned short)cap_value(watk,0,USHRT_MAX);
}
@@ -3447,16 +3456,16 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
if(!sc || !sc->count)
return cap_value(matk,0,USHRT_MAX);
- if(sc->data[SC_MATKPOTION].timer!=-1)
- matk += sc->data[SC_MATKPOTION].val1;
- if(sc->data[SC_MATKFOOD].timer!=-1)
- matk += sc->data[SC_MATKFOOD].val1;
- if(sc->data[SC_MAGICPOWER].timer!=-1)
- matk += matk * 5*sc->data[SC_MAGICPOWER].val1/100;
- if(sc->data[SC_MINDBREAKER].timer!=-1)
- matk += matk * sc->data[SC_MINDBREAKER].val2/100;
- if(sc->data[SC_INCMATKRATE].timer!=-1)
- matk += matk * sc->data[SC_INCMATKRATE].val1/100;
+ if(sc->data[SC_MATKPOTION])
+ matk += sc->data[SC_MATKPOTION]->val1;
+ if(sc->data[SC_MATKFOOD])
+ matk += sc->data[SC_MATKFOOD]->val1;
+ if(sc->data[SC_MAGICPOWER])
+ matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
+ if(sc->data[SC_MINDBREAKER])
+ matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
+ if(sc->data[SC_INCMATKRATE])
+ matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
return (unsigned short)cap_value(matk,0,USHRT_MAX);
}
@@ -3466,15 +3475,15 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
if(!sc || !sc->count)
return cap_value(critical,10,SHRT_MAX);
- if (sc->data[SC_INCCRI].timer!=-1)
- critical += sc->data[SC_INCCRI].val2;
- if (sc->data[SC_EXPLOSIONSPIRITS].timer!=-1)
- critical += sc->data[SC_EXPLOSIONSPIRITS].val2;
- if (sc->data[SC_FORTUNE].timer!=-1)
- critical += sc->data[SC_FORTUNE].val2;
- if (sc->data[SC_TRUESIGHT].timer!=-1)
- critical += sc->data[SC_TRUESIGHT].val2;
- if(sc->data[SC_CLOAKING].timer!=-1)
+ if (sc->data[SC_INCCRI])
+ critical += sc->data[SC_INCCRI]->val2;
+ if (sc->data[SC_EXPLOSIONSPIRITS])
+ critical += sc->data[SC_EXPLOSIONSPIRITS]->val2;
+ if (sc->data[SC_FORTUNE])
+ critical += sc->data[SC_FORTUNE]->val2;
+ if (sc->data[SC_TRUESIGHT])
+ critical += sc->data[SC_TRUESIGHT]->val2;
+ if(sc->data[SC_CLOAKING])
critical += critical;
return (short)cap_value(critical,10,SHRT_MAX);
@@ -3486,23 +3495,23 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
if(!sc || !sc->count)
return cap_value(hit,1,SHRT_MAX);
- if(sc->data[SC_INCHIT].timer != -1)
- hit += sc->data[SC_INCHIT].val1;
- if(sc->data[SC_HITFOOD].timer!=-1)
- hit += sc->data[SC_HITFOOD].val1;
- if(sc->data[SC_TRUESIGHT].timer != -1)
- hit += sc->data[SC_TRUESIGHT].val3;
- if(sc->data[SC_HUMMING].timer!=-1)
- hit += sc->data[SC_HUMMING].val2;
- if(sc->data[SC_CONCENTRATION].timer != -1)
- hit += sc->data[SC_CONCENTRATION].val3;
- if(sc->data[SC_INCHITRATE].timer != -1)
- hit += hit * sc->data[SC_INCHITRATE].val1/100;
- if(sc->data[SC_BLIND].timer != -1)
+ if(sc->data[SC_INCHIT])
+ hit += sc->data[SC_INCHIT]->val1;
+ if(sc->data[SC_HITFOOD])
+ hit += sc->data[SC_HITFOOD]->val1;
+ if(sc->data[SC_TRUESIGHT])
+ hit += sc->data[SC_TRUESIGHT]->val3;
+ if(sc->data[SC_HUMMING])
+ hit += sc->data[SC_HUMMING]->val2;
+ if(sc->data[SC_CONCENTRATION])
+ hit += sc->data[SC_CONCENTRATION]->val3;
+ if(sc->data[SC_INCHITRATE])
+ hit += hit * sc->data[SC_INCHITRATE]->val1/100;
+ if(sc->data[SC_BLIND])
hit -= hit * 25/100;
- if(sc->data[SC_ADJUSTMENT].timer!=-1)
+ if(sc->data[SC_ADJUSTMENT])
hit -= 30;
- if(sc->data[SC_INCREASING].timer!=-1)
+ if(sc->data[SC_INCREASING])
hit += 20; // RockmanEXE; changed based on updated [Reddozen]
return (short)cap_value(hit,1,SHRT_MAX);
@@ -3516,34 +3525,34 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
if(!sc || !sc->count)
return cap_value(flee,1,SHRT_MAX);
- if(sc->data[SC_INCFLEE].timer!=-1)
- flee += sc->data[SC_INCFLEE].val1;
- if(sc->data[SC_FLEEFOOD].timer!=-1)
- flee += sc->data[SC_FLEEFOOD].val1;
- if(sc->data[SC_WHISTLE].timer!=-1)
- flee += sc->data[SC_WHISTLE].val2;
- if(sc->data[SC_WINDWALK].timer!=-1)
- flee += sc->data[SC_WINDWALK].val2;
- if(sc->data[SC_INCFLEERATE].timer!=-1)
- flee += flee * sc->data[SC_INCFLEERATE].val1/100;
- if(sc->data[SC_VIOLENTGALE].timer!=-1)
- flee += sc->data[SC_VIOLENTGALE].val2;
- if(sc->data[SC_MOON_COMFORT].timer!=-1) //SG skill [Komurka]
- flee += sc->data[SC_MOON_COMFORT].val2;
- if(sc->data[SC_CLOSECONFINE].timer!=-1)
+ if(sc->data[SC_INCFLEE])
+ flee += sc->data[SC_INCFLEE]->val1;
+ if(sc->data[SC_FLEEFOOD])
+ flee += sc->data[SC_FLEEFOOD]->val1;
+ if(sc->data[SC_WHISTLE])
+ flee += sc->data[SC_WHISTLE]->val2;
+ if(sc->data[SC_WINDWALK])
+ flee += sc->data[SC_WINDWALK]->val2;
+ if(sc->data[SC_INCFLEERATE])
+ flee += flee * sc->data[SC_INCFLEERATE]->val1/100;
+ if(sc->data[SC_VIOLENTGALE])
+ flee += sc->data[SC_VIOLENTGALE]->val2;
+ if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
+ flee += sc->data[SC_MOON_COMFORT]->val2;
+ if(sc->data[SC_CLOSECONFINE])
flee += 10;
- if(sc->data[SC_SPIDERWEB].timer!=-1)
+ if(sc->data[SC_SPIDERWEB])
flee -= flee * 50/100;
- if(sc->data[SC_BERSERK].timer!=-1)
+ if(sc->data[SC_BERSERK])
flee -= flee * 50/100;
- if(sc->data[SC_BLIND].timer!=-1)
+ if(sc->data[SC_BLIND])
flee -= flee * 25/100;
- if(sc->data[SC_ADJUSTMENT].timer!=-1)
+ if(sc->data[SC_ADJUSTMENT])
flee += 30;
- if(sc->data[SC_GATLINGFEVER].timer!=-1)
- flee -= sc->data[SC_GATLINGFEVER].val4;
- if(sc->data[SC_SPEED].timer!=-1)
- flee += 10 + sc->data[SC_SPEED].val1 * 10 ;
+ if(sc->data[SC_GATLINGFEVER])
+ flee -= sc->data[SC_GATLINGFEVER]->val4;
+ if(sc->data[SC_SPEED])
+ flee += 10 + sc->data[SC_SPEED]->val1 * 10 ;
return (short)cap_value(flee,1,SHRT_MAX);
}
@@ -3553,10 +3562,10 @@ static signed short status_calc_flee2(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(flee2,10,SHRT_MAX);
- if(sc->data[SC_INCFLEE2].timer!=-1)
- flee2 += sc->data[SC_INCFLEE2].val2;
- if(sc->data[SC_WHISTLE].timer!=-1)
- flee2 += sc->data[SC_WHISTLE].val3*10;
+ if(sc->data[SC_INCFLEE2])
+ flee2 += sc->data[SC_INCFLEE2]->val2;
+ if(sc->data[SC_WHISTLE])
+ flee2 += sc->data[SC_WHISTLE]->val3*10;
return (short)cap_value(flee2,10,SHRT_MAX);
}
@@ -3566,42 +3575,42 @@ static signed char status_calc_def(struct block_list *bl, struct status_change *
if(!sc || !sc->count)
return cap_value(def,0,CHAR_MAX);
- if(sc->data[SC_BERSERK].timer!=-1)
+ if(sc->data[SC_BERSERK])
return 0;
- if(sc->data[SC_SKA].timer != -1)
- return sc->data[SC_SKA].val3;
- if(sc->data[SC_BARRIER].timer!=-1)
+ if(sc->data[SC_SKA])
+ return sc->data[SC_SKA]->val3;
+ if(sc->data[SC_BARRIER])
return 100;
- if(sc->data[SC_KEEPING].timer!=-1)
+ if(sc->data[SC_KEEPING])
return 90;
- if(sc->data[SC_STEELBODY].timer!=-1)
+ if(sc->data[SC_STEELBODY])
return 90;
- if(sc->data[SC_INCDEF].timer!=-1)
- def += sc->data[SC_INCDEF].val1;
- if(sc->data[SC_ARMORCHANGE].timer!=-1)
- def += sc->data[SC_ARMORCHANGE].val2;
- if(sc->data[SC_DRUMBATTLE].timer!=-1)
- def += sc->data[SC_DRUMBATTLE].val3;
- if(sc->data[SC_DEFENCE].timer != -1) //[orn]
- def += sc->data[SC_DEFENCE].val2 ;
- if(sc->data[SC_INCDEFRATE].timer!=-1)
- def += def * sc->data[SC_INCDEFRATE].val1/100;
- if(sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE)
+ if(sc->data[SC_INCDEF])
+ def += sc->data[SC_INCDEF]->val1;
+ if(sc->data[SC_ARMORCHANGE])
+ def += sc->data[SC_ARMORCHANGE]->val2;
+ if(sc->data[SC_DRUMBATTLE])
+ def += sc->data[SC_DRUMBATTLE]->val3;
+ if(sc->data[SC_DEFENCE]) //[orn]
+ def += sc->data[SC_DEFENCE]->val2 ;
+ if(sc->data[SC_INCDEFRATE])
+ def += def * sc->data[SC_INCDEFRATE]->val1/100;
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
def >>=1;
- if(sc->data[SC_FREEZE].timer!=-1)
+ if(sc->data[SC_FREEZE])
def >>=1;
- if(sc->data[SC_SIGNUMCRUCIS].timer!=-1)
- def -= def * sc->data[SC_SIGNUMCRUCIS].val2/100;
- if(sc->data[SC_CONCENTRATION].timer!=-1)
- def -= def * sc->data[SC_CONCENTRATION].val4/100;
- if(sc->data[SC_SKE].timer!=-1)
+ if(sc->data[SC_SIGNUMCRUCIS])
+ def -= def * sc->data[SC_SIGNUMCRUCIS]->val2/100;
+ if(sc->data[SC_CONCENTRATION])
+ def -= def * sc->data[SC_CONCENTRATION]->val4/100;
+ if(sc->data[SC_SKE])
def >>=1;
- if(sc->data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC) // Provoke doesn't alter player defense.
- def -= def * sc->data[SC_PROVOKE].val4/100;
- if(sc->data[SC_STRIPSHIELD].timer!=-1)
- def -= def * sc->data[SC_STRIPSHIELD].val2/100;
- if (sc->data[SC_FLING].timer!=-1)
- def -= def * (sc->data[SC_FLING].val2)/100;
+ if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
+ def -= def * sc->data[SC_PROVOKE]->val4/100;
+ if(sc->data[SC_STRIPSHIELD])
+ def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
+ if (sc->data[SC_FLING])
+ def -= def * (sc->data[SC_FLING]->val2)/100;
return (char)cap_value(def,0,CHAR_MAX);
}
@@ -3611,31 +3620,31 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
if(!sc || !sc->count)
return cap_value(def2,1,SHRT_MAX);
- if(sc->data[SC_BERSERK].timer!=-1)
+ if(sc->data[SC_BERSERK])
return 0;
- if(sc->data[SC_ETERNALCHAOS].timer!=-1)
+ if(sc->data[SC_ETERNALCHAOS])
return 0;
- if(sc->data[SC_SUN_COMFORT].timer!=-1)
- def2 += sc->data[SC_SUN_COMFORT].val2;
- if(sc->data[SC_ANGELUS].timer!=-1)
- def2 += def2 * sc->data[SC_ANGELUS].val2/100;
- if(sc->data[SC_CONCENTRATION].timer!=-1)
- def2 -= def2 * sc->data[SC_CONCENTRATION].val4/100;
- if(sc->data[SC_POISON].timer!=-1)
+ if(sc->data[SC_SUN_COMFORT])
+ def2 += sc->data[SC_SUN_COMFORT]->val2;
+ if(sc->data[SC_ANGELUS])
+ def2 += def2 * sc->data[SC_ANGELUS]->val2/100;
+ if(sc->data[SC_CONCENTRATION])
+ def2 -= def2 * sc->data[SC_CONCENTRATION]->val4/100;
+ if(sc->data[SC_POISON])
def2 -= def2 * 25/100;
- if(sc->data[SC_DPOISON].timer!=-1)
+ if(sc->data[SC_DPOISON])
def2 -= def2 * 25/100;
- if(sc->data[SC_SKE].timer!=-1)
+ if(sc->data[SC_SKE])
def2 -= def2 * 50/100;
- if(sc->data[SC_PROVOKE].timer!=-1)
- def2 -= def2 * sc->data[SC_PROVOKE].val4/100;
- if(sc->data[SC_JOINTBEAT].timer!=-1){
+ if(sc->data[SC_PROVOKE])
+ def2 -= def2 * sc->data[SC_PROVOKE]->val4/100;
+ if(sc->data[SC_JOINTBEAT]){
def2 -= def2 *
- ( ( sc->data[SC_JOINTBEAT].val2&BREAK_SHOULDER ? 50 : 0 )
- + ( sc->data[SC_JOINTBEAT].val2&BREAK_WAIST ? 25 : 0 ) );
+ ( ( sc->data[SC_JOINTBEAT]->val2&BREAK_SHOULDER ? 50 : 0 )
+ + ( sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST ? 25 : 0 ) );
}
- if(sc->data[SC_FLING].timer!=-1)
- def2 -= def2 * (sc->data[SC_FLING].val3)/100;
+ if(sc->data[SC_FLING])
+ def2 -= def2 * (sc->data[SC_FLING]->val3)/100;
return (short)cap_value(def2,1,SHRT_MAX);
}
@@ -3645,24 +3654,24 @@ static signed char status_calc_mdef(struct block_list *bl, struct status_change
if(!sc || !sc->count)
return cap_value(mdef,0,CHAR_MAX);
- if(sc->data[SC_BERSERK].timer!=-1)
+ if(sc->data[SC_BERSERK])
return 0;
- if(sc->data[SC_BARRIER].timer!=-1)
+ if(sc->data[SC_BARRIER])
return 100;
- if(sc->data[SC_STEELBODY].timer!=-1)
+ if(sc->data[SC_STEELBODY])
return 90;
- if(sc->data[SC_SKA].timer != -1) // [marquis007]
+ if(sc->data[SC_SKA])
return 90;
- if(sc->data[SC_ARMORCHANGE].timer!=-1)
- mdef += sc->data[SC_ARMORCHANGE].val3;
- if(sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE)
+ if(sc->data[SC_ARMORCHANGE])
+ mdef += sc->data[SC_ARMORCHANGE]->val3;
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
mdef += 25*mdef/100;
- if(sc->data[SC_FREEZE].timer!=-1)
+ if(sc->data[SC_FREEZE])
mdef += 25*mdef/100;
- if(sc->data[SC_ENDURE].timer!=-1 && sc->data[SC_ENDURE].val4 == 0)
- mdef += sc->data[SC_ENDURE].val1;
- if(sc->data[SC_INCMDEFRATE].timer!=-1)
- mdef += mdef * sc->data[SC_INCMDEFRATE].val1/100;
+ if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 0)
+ mdef += sc->data[SC_ENDURE]->val1;
+ if(sc->data[SC_INCMDEFRATE])
+ mdef += mdef * sc->data[SC_INCMDEFRATE]->val1/100;
return (char)cap_value(mdef,0,CHAR_MAX);
}
@@ -3672,10 +3681,10 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(mdef2,1,SHRT_MAX);
- if(sc->data[SC_BERSERK].timer!=-1)
+ if(sc->data[SC_BERSERK])
return 0;
- if(sc->data[SC_MINDBREAKER].timer!=-1)
- mdef2 -= mdef2 * sc->data[SC_MINDBREAKER].val3/100;
+ if(sc->data[SC_MINDBREAKER])
+ mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
return (short)cap_value(mdef2,1,SHRT_MAX);
}
@@ -3686,71 +3695,71 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
return cap_value(speed,10,USHRT_MAX);
// Fixed reductions
- if(sc->data[SC_CURSE].timer!=-1)
+ if(sc->data[SC_CURSE])
speed += 450;
- if(sc->data[SC_SWOO].timer != -1) // [marquis007]
+ if(sc->data[SC_SWOO])
speed += 450; //Let's use Curse's slow down momentarily (exact value unknown)
- if(sc->data[SC_WEDDING].timer!=-1)
+ if(sc->data[SC_WEDDING])
speed += 300;
- if(sc->data[SC_GATLINGFEVER].timer==-1)
+ if(!sc->data[SC_GATLINGFEVER])
{ //% increases (they don't stack, with a few exceptions)
- if(sc->data[SC_SPEEDUP1].timer!=-1)
+ if(sc->data[SC_SPEEDUP1])
speed -= speed * 50/100;
- else if(sc->data[SC_AVOID].timer!=-1)
- speed -= speed * sc->data[SC_AVOID].val2/100;
+ else if(sc->data[SC_AVOID])
+ speed -= speed * sc->data[SC_AVOID]->val2/100;
- if(sc->data[SC_RUN].timer!=-1)
+ if(sc->data[SC_RUN])
speed -= speed * 50/100;
- else if(sc->data[SC_SPEEDUP0].timer!=-1)
+ else if(sc->data[SC_SPEEDUP0])
speed -= speed * 25/100;
- else if(sc->data[SC_INCREASEAGI].timer!=-1)
+ else if(sc->data[SC_INCREASEAGI])
speed -= speed * 25/100;
- else if(sc->data[SC_FUSION].timer != -1)
+ else if(sc->data[SC_FUSION])
speed -= speed * 25/100;
- else if(sc->data[SC_CARTBOOST].timer!=-1)
+ else if(sc->data[SC_CARTBOOST])
speed -= speed * 20/100;
- else if(sc->data[SC_BERSERK].timer!=-1)
+ else if(sc->data[SC_BERSERK])
speed -= speed * 20/100;
- else if(sc->data[SC_WINDWALK].timer!=-1)
- speed -= speed * sc->data[SC_WINDWALK].val3/100;
+ else if(sc->data[SC_WINDWALK])
+ speed -= speed * sc->data[SC_WINDWALK]->val3/100;
}
//% reductions (they stack)
- if(sc->data[SC_DANCING].timer!=-1 && sc->data[SC_DANCING].val3&0xFFFF)
- speed += speed*(sc->data[SC_DANCING].val3&0xFFFF)/100;
- if(sc->data[SC_DECREASEAGI].timer!=-1)
+ if(sc->data[SC_DANCING] && sc->data[SC_DANCING]->val3&0xFFFF)
+ speed += speed*(sc->data[SC_DANCING]->val3&0xFFFF)/100;
+ if(sc->data[SC_DECREASEAGI])
speed = speed * 100/75;
- if(sc->data[SC_STEELBODY].timer!=-1)
+ if(sc->data[SC_STEELBODY])
speed = speed * 100/75;
- if(sc->data[SC_QUAGMIRE].timer!=-1)
+ if(sc->data[SC_QUAGMIRE])
speed = speed * 100/50;
- if(sc->data[SC_SUITON].timer!=-1 && sc->data[SC_SUITON].val3)
- speed = speed * 100/sc->data[SC_SUITON].val3;
- if(sc->data[SC_DONTFORGETME].timer!=-1)
- speed = speed * 100/sc->data[SC_DONTFORGETME].val3;
- if(sc->data[SC_DEFENDER].timer!=-1)
- speed = speed * 100/sc->data[SC_DEFENDER].val3;
- if(sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_ENEMY)
+ if(sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
+ speed = speed * 100/sc->data[SC_SUITON]->val3;
+ if(sc->data[SC_DONTFORGETME])
+ speed = speed * 100/sc->data[SC_DONTFORGETME]->val3;
+ if(sc->data[SC_DEFENDER])
+ speed = speed * 100/sc->data[SC_DEFENDER]->val3;
+ if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
speed = speed * 100/75;
- if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2&(BREAK_ANKLE|BREAK_KNEE)) {
+ if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&(BREAK_ANKLE|BREAK_KNEE)) {
speed = speed * 100/(100
- - ( sc->data[SC_JOINTBEAT].val2&BREAK_ANKLE ? 50 : 0 )
- - ( sc->data[SC_JOINTBEAT].val2&BREAK_KNEE ? 30 : 0 ));
+ - ( sc->data[SC_JOINTBEAT]->val2&BREAK_ANKLE ? 50 : 0 )
+ - ( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE ? 30 : 0 ));
}
- if(sc->data[SC_CLOAKING].timer!=-1)
+ if(sc->data[SC_CLOAKING])
speed = speed * 100 /(
- (sc->data[SC_CLOAKING].val4&1?25:0) //Wall speed bonus
- +sc->data[SC_CLOAKING].val3); //Normal adjustment bonus.
+ (sc->data[SC_CLOAKING]->val4&1?25:0) //Wall speed bonus
+ +sc->data[SC_CLOAKING]->val3); //Normal adjustment bonus->
- if(sc->data[SC_LONGING].timer!=-1)
- speed = speed * 100/sc->data[SC_LONGING].val3;
- if(sc->data[SC_HIDING].timer!=-1 && sc->data[SC_HIDING].val3)
- speed = speed * 100/sc->data[SC_HIDING].val3;
- if(sc->data[SC_CHASEWALK].timer!=-1)
- speed = speed * 100/sc->data[SC_CHASEWALK].val3;
- if(sc->data[SC_GATLINGFEVER].timer!=-1)
+ if(sc->data[SC_LONGING])
+ speed = speed * 100/sc->data[SC_LONGING]->val3;
+ if(sc->data[SC_HIDING] && sc->data[SC_HIDING]->val3)
+ speed = speed * 100/sc->data[SC_HIDING]->val3;
+ if(sc->data[SC_CHASEWALK])
+ speed = speed * 100/sc->data[SC_CHASEWALK]->val3;
+ if(sc->data[SC_GATLINGFEVER])
speed = speed * 100/75;
- if(sc->data[SC_SLOWDOWN].timer!=-1)
+ if(sc->data[SC_SLOWDOWN])
speed = speed * 100/75;
return (short)cap_value(speed,10,USHRT_MAX);
@@ -3762,45 +3771,45 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
if(!sc || !sc->count)
return cap_value(aspd_rate,0,SHRT_MAX);
- if(sc->data[SC_QUAGMIRE].timer==-1 && sc->data[SC_DONTFORGETME].timer==-1)
+ if(!sc->data[SC_QUAGMIRE] && !sc->data[SC_DONTFORGETME])
{
int max = 0;
- if(sc->data[SC_STAR_COMFORT].timer!=-1)
- max = sc->data[SC_STAR_COMFORT].val2;
+ if(sc->data[SC_STAR_COMFORT])
+ max = sc->data[SC_STAR_COMFORT]->val2;
- if(sc->data[SC_TWOHANDQUICKEN].timer!=-1 &&
- max < sc->data[SC_TWOHANDQUICKEN].val2)
- max = sc->data[SC_TWOHANDQUICKEN].val2;
+ if(sc->data[SC_TWOHANDQUICKEN] &&
+ max < sc->data[SC_TWOHANDQUICKEN]->val2)
+ max = sc->data[SC_TWOHANDQUICKEN]->val2;
- if(sc->data[SC_ONEHAND].timer!=-1 &&
- max < sc->data[SC_ONEHAND].val2)
- max = sc->data[SC_ONEHAND].val2;
+ if(sc->data[SC_ONEHAND] &&
+ max < sc->data[SC_ONEHAND]->val2)
+ max = sc->data[SC_ONEHAND]->val2;
- if(sc->data[SC_ADRENALINE2].timer!=-1 &&
- max < sc->data[SC_ADRENALINE2].val3)
- max = sc->data[SC_ADRENALINE2].val3;
+ if(sc->data[SC_ADRENALINE2] &&
+ max < sc->data[SC_ADRENALINE2]->val3)
+ max = sc->data[SC_ADRENALINE2]->val3;
- if(sc->data[SC_ADRENALINE].timer!=-1 &&
- max < sc->data[SC_ADRENALINE].val3)
- max = sc->data[SC_ADRENALINE].val3;
+ if(sc->data[SC_ADRENALINE] &&
+ max < sc->data[SC_ADRENALINE]->val3)
+ max = sc->data[SC_ADRENALINE]->val3;
- if(sc->data[SC_SPEARQUICKEN].timer!=-1 &&
- max < sc->data[SC_SPEARQUICKEN].val2)
- max = sc->data[SC_SPEARQUICKEN].val2;
+ if(sc->data[SC_SPEARQUICKEN] &&
+ max < sc->data[SC_SPEARQUICKEN]->val2)
+ max = sc->data[SC_SPEARQUICKEN]->val2;
- if(sc->data[SC_GATLINGFEVER].timer!=-1 &&
- max < sc->data[SC_GATLINGFEVER].val2)
- max = sc->data[SC_GATLINGFEVER].val2;
+ if(sc->data[SC_GATLINGFEVER] &&
+ max < sc->data[SC_GATLINGFEVER]->val2)
+ max = sc->data[SC_GATLINGFEVER]->val2;
- if(sc->data[SC_FLEET].timer!=-1 &&
- max < sc->data[SC_FLEET].val2)
- max = sc->data[SC_FLEET].val2;
+ if(sc->data[SC_FLEET] &&
+ max < sc->data[SC_FLEET]->val2)
+ max = sc->data[SC_FLEET]->val2;
- if(sc->data[SC_ASSNCROS].timer!=-1 &&
- max < sc->data[SC_ASSNCROS].val2)
+ if(sc->data[SC_ASSNCROS] &&
+ max < sc->data[SC_ASSNCROS]->val2)
{
if (bl->type!=BL_PC)
- max = sc->data[SC_ASSNCROS].val2;
+ max = sc->data[SC_ASSNCROS]->val2;
else
switch(((TBL_PC*)bl)->status.weapon)
{
@@ -3812,46 +3821,43 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
case W_GRENADE:
break;
default:
- max = sc->data[SC_ASSNCROS].val2;
+ max = sc->data[SC_ASSNCROS]->val2;
}
}
aspd_rate -= max;
- //These stack with the rest of bonuses.
- if(sc->data[SC_BERSERK].timer!=-1)
+ //These stack with the rest of bonuses->
+ if(sc->data[SC_BERSERK])
aspd_rate -= 300;
- else if(sc->data[SC_MADNESSCANCEL].timer!=-1)
+ else if(sc->data[SC_MADNESSCANCEL])
aspd_rate -= 200;
}
- if(sc->data[SC_INCASPDRATE].timer!=-1)
- aspd_rate -= sc->data[SC_INCASPDRATE].val2;
- if(sc->data[i=SC_ASPDPOTION3].timer!=-1 ||
- sc->data[i=SC_ASPDPOTION2].timer!=-1 ||
- sc->data[i=SC_ASPDPOTION1].timer!=-1 ||
- sc->data[i=SC_ASPDPOTION0].timer!=-1)
- aspd_rate -= sc->data[i].val2;
- if(sc->data[SC_DONTFORGETME].timer!=-1)
- aspd_rate += sc->data[SC_DONTFORGETME].val2;
- if(sc->data[SC_LONGING].timer!=-1)
- aspd_rate += sc->data[SC_LONGING].val2;
- if(sc->data[SC_STEELBODY].timer!=-1)
+ if(sc->data[SC_INCASPDRATE])
+ aspd_rate -= sc->data[SC_INCASPDRATE]->val2;
+ if(sc->data[i=SC_ASPDPOTION3] ||
+ sc->data[i=SC_ASPDPOTION2] ||
+ sc->data[i=SC_ASPDPOTION1] ||
+ sc->data[i=SC_ASPDPOTION0])
+ aspd_rate -= sc->data[i]->val2;
+ if(sc->data[SC_DONTFORGETME])
+ aspd_rate += sc->data[SC_DONTFORGETME]->val2;
+ if(sc->data[SC_LONGING])
+ aspd_rate += sc->data[SC_LONGING]->val2;
+ if(sc->data[SC_STEELBODY])
aspd_rate += 250;
- if(sc->data[SC_SKA].timer!=-1)
+ if(sc->data[SC_SKA])
aspd_rate += 250;
- if(sc->data[SC_DEFENDER].timer != -1)
- aspd_rate += sc->data[SC_DEFENDER].val4;
- if(sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_ENEMY)
+ if(sc->data[SC_DEFENDER])
+ aspd_rate += sc->data[SC_DEFENDER]->val4;
+ if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY)
aspd_rate += 250;
- if(sc->data[SC_GRAVITATION].timer!=-1)
- aspd_rate += sc->data[SC_GRAVITATION].val2;
-//Curse shouldn't effect on this?
-// if(sc->data[SC_BLEEDING].timer != -1)
-// aspd_rate += 250;
- if(sc->data[SC_JOINTBEAT].timer!=-1) {
- if( sc->data[SC_JOINTBEAT].val2&BREAK_WRIST )
+ if(sc->data[SC_GRAVITATION])
+ aspd_rate += sc->data[SC_GRAVITATION]->val2;
+ if(sc->data[SC_JOINTBEAT]) {
+ if( sc->data[SC_JOINTBEAT]->val2&BREAK_WRIST )
aspd_rate += 250;
- if( sc->data[SC_JOINTBEAT].val2&BREAK_KNEE )
+ if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
aspd_rate += 100;
}
@@ -3863,11 +3869,11 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c
if(!sc || !sc->count || map_flag_gvg(bl->m))
return cap_value(dmotion,0,USHRT_MAX);
- if (sc->data[SC_ENDURE].timer!=-1)
+ if (sc->data[SC_ENDURE])
return 0;
- if (sc->data[SC_CONCENTRATION].timer!=-1)
+ if (sc->data[SC_CONCENTRATION])
return 0;
- if(sc->data[SC_RUN].timer!=-1)
+ if(sc->data[SC_RUN])
return 0;
return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
@@ -3878,13 +3884,13 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(maxhp,1,UINT_MAX);
- if(sc->data[SC_INCMHPRATE].timer!=-1)
- maxhp += maxhp * sc->data[SC_INCMHPRATE].val1/100;
- if(sc->data[SC_APPLEIDUN].timer!=-1)
- maxhp += maxhp * sc->data[SC_APPLEIDUN].val2/100;
- if(sc->data[SC_DELUGE].timer!=-1)
- maxhp += maxhp * sc->data[SC_DELUGE].val2/100;
- if(sc->data[SC_BERSERK].timer!=-1)
+ if(sc->data[SC_INCMHPRATE])
+ maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1/100;
+ if(sc->data[SC_APPLEIDUN])
+ maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100;
+ if(sc->data[SC_DELUGE])
+ maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
+ if(sc->data[SC_BERSERK])
maxhp += maxhp * 2;
return cap_value(maxhp,1,UINT_MAX);
@@ -3895,10 +3901,10 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(maxsp,1,UINT_MAX);
- if(sc->data[SC_INCMSPRATE].timer!=-1)
- maxsp += maxsp * sc->data[SC_INCMSPRATE].val1/100;
- if(sc->data[SC_SERVICE4U].timer!=-1)
- maxsp += maxsp * sc->data[SC_SERVICE4U].val2/100;
+ if(sc->data[SC_INCMSPRATE])
+ maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100;
+ if(sc->data[SC_SERVICE4U])
+ maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
return cap_value(maxsp,1,UINT_MAX);
}
@@ -3907,16 +3913,17 @@ static unsigned char status_calc_element(struct block_list *bl, struct status_ch
{
if(!sc || !sc->count)
return element;
- if( sc->data[SC_FREEZE].timer!=-1 )
+
+ if(sc->data[SC_FREEZE])
return ELE_WATER;
- if( sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE)
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
return ELE_EARTH;
- if( sc->data[SC_BENEDICTIO].timer!=-1 )
+ if(sc->data[SC_BENEDICTIO])
return ELE_HOLY;
- if( sc->data[SC_CHANGEUNDEAD].timer!=-1)
+ if(sc->data[SC_CHANGEUNDEAD])
return ELE_UNDEAD;
- if( sc->data[SC_ELEMENTALCHANGE].timer!=-1)
- return sc->data[SC_ELEMENTALCHANGE].val2;
+ if(sc->data[SC_ELEMENTALCHANGE])
+ return sc->data[SC_ELEMENTALCHANGE]->val2;
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
@@ -3924,16 +3931,18 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status
{
if(!sc || !sc->count)
return lv;
- if( sc->data[SC_FREEZE].timer!=-1 )
+
+ if(sc->data[SC_FREEZE])
return 1;
- if( sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE)
+ if(sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
return 1;
- if( sc->data[SC_BENEDICTIO].timer!=-1 )
+ if(sc->data[SC_BENEDICTIO])
return 1;
- if( sc->data[SC_CHANGEUNDEAD].timer!=-1)
+ if(sc->data[SC_CHANGEUNDEAD])
return 1;
- if(sc->data[SC_ELEMENTALCHANGE].timer!=-1)
- return sc->data[SC_ELEMENTALCHANGE].val1;
+ if(sc->data[SC_ELEMENTALCHANGE])
+ return sc->data[SC_ELEMENTALCHANGE]->val1;
+
return (unsigned char)cap_value(lv,1,4);
}
@@ -3942,23 +3951,23 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
{
if(!sc || !sc->count)
return element;
- if( sc->data[SC_ENCHANTARMS].timer!=-1)
- return sc->data[SC_ENCHANTARMS].val2;
- if( sc->data[SC_WATERWEAPON].timer!=-1)
+ if(sc->data[SC_ENCHANTARMS])
+ return sc->data[SC_ENCHANTARMS]->val2;
+ if(sc->data[SC_WATERWEAPON])
return ELE_WATER;
- if( sc->data[SC_EARTHWEAPON].timer!=-1)
+ if(sc->data[SC_EARTHWEAPON])
return ELE_EARTH;
- if( sc->data[SC_FIREWEAPON].timer!=-1)
+ if(sc->data[SC_FIREWEAPON])
return ELE_FIRE;
- if( sc->data[SC_WINDWEAPON].timer!=-1)
+ if(sc->data[SC_WINDWEAPON])
return ELE_WIND;
- if( sc->data[SC_ENCPOISON].timer!=-1)
+ if(sc->data[SC_ENCPOISON])
return ELE_POISON;
- if( sc->data[SC_ASPERSIO].timer!=-1)
+ if(sc->data[SC_ASPERSIO])
return ELE_HOLY;
- if( sc->data[SC_SHADOWWEAPON].timer!=-1)
+ if(sc->data[SC_SHADOWWEAPON])
return ELE_DARK;
- if( sc->data[SC_GHOSTWEAPON].timer!=-1)
+ if(sc->data[SC_GHOSTWEAPON])
return ELE_GHOST;
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
@@ -3967,13 +3976,13 @@ static unsigned short status_calc_mode(struct block_list *bl, struct status_chan
{
if(!sc || !sc->count)
return mode;
- if(sc->data[SC_MODECHANGE].timer!=-1) {
- if (sc->data[SC_MODECHANGE].val2)
- mode = sc->data[SC_MODECHANGE].val2; //Set mode
- if (sc->data[SC_MODECHANGE].val3)
- mode|= sc->data[SC_MODECHANGE].val3; //Add mode
- if (sc->data[SC_MODECHANGE].val4)
- mode&=~sc->data[SC_MODECHANGE].val4; //Del mode
+ if(sc->data[SC_MODECHANGE]) {
+ if (sc->data[SC_MODECHANGE]->val2)
+ mode = sc->data[SC_MODECHANGE]->val2; //Set mode
+ if (sc->data[SC_MODECHANGE]->val3)
+ mode|= sc->data[SC_MODECHANGE]->val3; //Add mode
+ if (sc->data[SC_MODECHANGE]->val4)
+ mode&=~sc->data[SC_MODECHANGE]->val4; //Del mode
}
return cap_value(mode,0,USHRT_MAX);
}
@@ -4252,7 +4261,7 @@ int status_isdead(struct block_list *bl)
int status_isimmune(struct block_list *bl)
{
struct status_change *sc =status_get_sc(bl);
- if (sc && sc->count && sc->data[SC_HERMODE].timer != -1)
+ if (sc && sc->data[SC_HERMODE])
return 100;
if (bl->type == BL_PC &&
@@ -4407,11 +4416,8 @@ struct status_change *status_get_sc(struct block_list *bl)
void status_change_init(struct block_list *bl)
{
struct status_change *sc = status_get_sc(bl);
- int i;
nullpo_retv(sc);
memset(sc, 0, sizeof (struct status_change));
- for (i=0; i< SC_MAX; i++)
- sc->data[i].timer = -1;
}
//Applies SC defense to a given status change.
@@ -4542,10 +4548,10 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc = status_get_sc(bl);
if (sc && sc->count)
{
- if (sc->data[SC_SCRESIST].timer != -1)
- sc_def += sc->data[SC_SCRESIST].val1; //Status resist
- else if (sc->data[SC_SIEGFRIED].timer != -1)
- sc_def += sc->data[SC_SIEGFRIED].val3; //Status resistance.
+ if (sc->data[SC_SCRESIST])
+ sc_def += sc->data[SC_SCRESIST]->val1; //Status resist
+ else if (sc->data[SC_SIEGFRIED])
+ sc_def += sc->data[SC_SIEGFRIED]->val3; //Status resistance.
}
//When no tick def, reduction is the same for both.
@@ -4594,6 +4600,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
{
struct map_session_data *sd = NULL;
struct status_change* sc;
+ struct status_change_entry* sce;
struct status_data *status;
struct view_data *vd;
int opt_flag, calc_flag, undead_flag;
@@ -4630,7 +4637,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
undead_flag = battle_check_undead(status->race,status->def_ele);
-
//Check for inmunities / sc fails
switch (type)
{
@@ -4650,7 +4656,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0;
break;
case SC_AETERNA:
- if (sc->data[SC_STONE].timer != -1 || sc->data[SC_FREEZE].timer != -1)
+ if (sc->data[SC_STONE] || sc->data[SC_FREEZE])
return 0;
break;
case SC_KYRIE:
@@ -4658,30 +4664,30 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0;
break;
case SC_OVERTHRUST:
- if (sc->data[SC_MAXOVERTHRUST].timer != -1)
+ if (sc->data[SC_MAXOVERTHRUST])
return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
break;
case SC_ADRENALINE:
if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE)))
return 0;
- if (sc->data[SC_QUAGMIRE].timer!=-1 ||
- sc->data[SC_DONTFORGETME].timer!=-1 ||
- sc->data[SC_DECREASEAGI].timer!=-1
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DONTFORGETME] ||
+ sc->data[SC_DECREASEAGI]
)
return 0;
break;
case SC_ADRENALINE2:
if(sd && !pc_check_weapontype(sd,skill_get_weapontype(BS_ADRENALINE2)))
return 0;
- if (sc->data[SC_QUAGMIRE].timer!=-1 ||
- sc->data[SC_DONTFORGETME].timer!=-1 ||
- sc->data[SC_DECREASEAGI].timer!=-1
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DONTFORGETME] ||
+ sc->data[SC_DECREASEAGI]
)
return 0;
break;
case SC_ONEHAND:
case SC_TWOHANDQUICKEN:
- if(sc->data[SC_DECREASEAGI].timer!=-1)
+ if(sc->data[SC_DECREASEAGI])
return 0;
case SC_CONCENTRATE:
case SC_INCREASEAGI:
@@ -4690,15 +4696,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_WINDWALK:
case SC_CARTBOOST:
case SC_ASSNCROS:
- if (sc->data[SC_QUAGMIRE].timer!=-1 || sc->data[SC_DONTFORGETME].timer!=-1)
+ if (sc->data[SC_QUAGMIRE] || sc->data[SC_DONTFORGETME])
return 0;
break;
case SC_CLOAKING:
//Avoid cloaking with no wall and low skill level. [Skotlex]
//Due to the cloaking card, we have to check the wall versus to known
//skill level rather than the used one. [Skotlex]
- //if (sd && val1 < 3 && skill_check_cloaking(bl))
- if (sd && pc_checkskill(sd, AS_CLOAKING)< 3 && skill_check_cloaking(bl,sc))
+ //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
+ if (sd && pc_checkskill(sd, AS_CLOAKING)< 3 && skill_check_cloaking(bl,NULL))
return 0;
break;
case SC_MODECHANGE:
@@ -4706,17 +4712,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
int mode;
struct status_data *bstatus = status_get_base_status(bl);
if (!bstatus) return 0;
- if (sc->data[type].timer != -1)
+ if (sc->data[type])
{ //Pile up with previous values.
- if(!val2) val2 = sc->data[type].val2;
- val3 |= sc->data[type].val3;
- val4 |= sc->data[type].val4;
+ if(!val2) val2 = sc->data[type]->val2;
+ val3 |= sc->data[type]->val3;
+ val4 |= sc->data[type]->val4;
}
mode = val2?val2:bstatus->mode; //Base mode
if (val4) mode&=~val4; //Del mode
if (val3) mode|= val3; //Add mode
if (mode == bstatus->mode) { //No change.
- if (sc->data[type].timer != -1) //Abort previous status
+ if (sc->data[type]) //Abort previous status
return status_change_end(bl, type, -1);
return 0;
}
@@ -4816,126 +4822,125 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
{
case SC_BLESSING:
if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) {
- if (sc->data[SC_CURSE].timer!=-1)
+ if (sc->data[SC_CURSE])
status_change_end(bl,SC_CURSE,-1);
- if (sc->data[SC_STONE].timer!=-1 && sc->opt1 == OPT1_STONE)
+ if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
status_change_end(bl,SC_STONE,-1);
}
break;
case SC_INCREASEAGI:
- if(sc->data[SC_DECREASEAGI].timer!=-1 )
+ if(sc->data[SC_DECREASEAGI])
status_change_end(bl,SC_DECREASEAGI,-1);
break;
case SC_QUAGMIRE:
- if(sc->data[SC_CONCENTRATE].timer!=-1 )
+ if(sc->data[SC_CONCENTRATE])
status_change_end(bl,SC_CONCENTRATE,-1);
- if(sc->data[SC_TRUESIGHT].timer!=-1 )
+ if(sc->data[SC_TRUESIGHT])
status_change_end(bl,SC_TRUESIGHT,-1);
- if(sc->data[SC_WINDWALK].timer!=-1 )
+ if(sc->data[SC_WINDWALK])
status_change_end(bl,SC_WINDWALK,-1);
//Also blocks the ones below...
case SC_DECREASEAGI:
- if(sc->data[SC_CARTBOOST].timer!=-1 )
+ if(sc->data[SC_CARTBOOST])
status_change_end(bl,SC_CARTBOOST,-1);
//Also blocks the ones below...
case SC_DONTFORGETME:
- if(sc->data[SC_INCREASEAGI].timer!=-1 )
+ if(sc->data[SC_INCREASEAGI])
status_change_end(bl,SC_INCREASEAGI,-1);
- if(sc->data[SC_ADRENALINE].timer!=-1 )
+ if(sc->data[SC_ADRENALINE])
status_change_end(bl,SC_ADRENALINE,-1);
- if(sc->data[SC_ADRENALINE2].timer!=-1 )
+ if(sc->data[SC_ADRENALINE2])
status_change_end(bl,SC_ADRENALINE2,-1);
- if(sc->data[SC_SPEARQUICKEN].timer!=-1 )
+ if(sc->data[SC_SPEARQUICKEN])
status_change_end(bl,SC_SPEARQUICKEN,-1);
- if(sc->data[SC_TWOHANDQUICKEN].timer!=-1 )
+ if(sc->data[SC_TWOHANDQUICKEN])
status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- if(sc->data[SC_ONEHAND].timer!=-1 )
+ if(sc->data[SC_ONEHAND])
status_change_end(bl,SC_ONEHAND,-1);
break;
case SC_ONEHAND:
//Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- if(sc->data[SC_ASPDPOTION0].timer!=-1)
+ if(sc->data[SC_ASPDPOTION0])
status_change_end(bl,SC_ASPDPOTION0,-1);
- if(sc->data[SC_ASPDPOTION1].timer!=-1)
+ if(sc->data[SC_ASPDPOTION1])
status_change_end(bl,SC_ASPDPOTION1,-1);
- if(sc->data[SC_ASPDPOTION2].timer!=-1)
+ if(sc->data[SC_ASPDPOTION2])
status_change_end(bl,SC_ASPDPOTION2,-1);
- if(sc->data[SC_ASPDPOTION3].timer!=-1)
+ if(sc->data[SC_ASPDPOTION3])
status_change_end(bl,SC_ASPDPOTION3,-1);
break;
case SC_MAXOVERTHRUST:
//Cancels Normal Overthrust. [Skotlex]
- if (sc->data[SC_OVERTHRUST].timer != -1)
+ if (sc->data[SC_OVERTHRUST])
status_change_end(bl, SC_OVERTHRUST, -1);
break;
case SC_KYRIE:
// -- moonsoul (added to undo assumptio status if target has it)
- if(sc->data[SC_ASSUMPTIO].timer!=-1 )
+ if(sc->data[SC_ASSUMPTIO])
status_change_end(bl,SC_ASSUMPTIO,-1);
break;
case SC_DELUGE:
- if (sc->data[SC_FOGWALL].timer != -1 && sc->data[SC_BLIND].timer != -1)
+ if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
status_change_end(bl,SC_BLIND,-1);
break;
case SC_SILENCE:
- if (sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_SELF)
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
status_change_end(bl,SC_GOSPEL,-1);
break;
case SC_HIDING:
- if(sc->data[SC_CLOSECONFINE].timer != -1)
+ if(sc->data[SC_CLOSECONFINE])
status_change_end(bl, SC_CLOSECONFINE, -1);
- if(sc->data[SC_CLOSECONFINE2].timer != -1)
+ if(sc->data[SC_CLOSECONFINE2])
status_change_end(bl, SC_CLOSECONFINE2, -1);
break;
case SC_BERSERK:
if(battle_config.berserk_cancels_buffs)
{
- if (sc->data[SC_ONEHAND].timer != -1)
+ if (sc->data[SC_ONEHAND])
status_change_end(bl,SC_ONEHAND,-1);
- if (sc->data[SC_TWOHANDQUICKEN].timer != -1)
+ if (sc->data[SC_TWOHANDQUICKEN])
status_change_end(bl,SC_TWOHANDQUICKEN,-1);
- if (sc->data[SC_CONCENTRATION].timer != -1)
+ if (sc->data[SC_CONCENTRATION])
status_change_end(bl,SC_CONCENTRATION,-1);
- if (sc->data[SC_PARRYING].timer != -1)
+ if (sc->data[SC_PARRYING])
status_change_end(bl,SC_PARRYING,-1);
- if (sc->data[SC_AURABLADE].timer != -1)
+ if (sc->data[SC_AURABLADE])
status_change_end(bl,SC_AURABLADE,-1);
}
break;
case SC_ASSUMPTIO:
- if(sc->data[SC_KYRIE].timer!=-1)
+ if(sc->data[SC_KYRIE])
status_change_end(bl,SC_KYRIE,-1);
- if(sc->data[SC_KAITE].timer!=-1)
+ if(sc->data[SC_KAITE])
status_change_end(bl,SC_KAITE,-1);
break;
case SC_KAITE:
- if(sc->data[SC_ASSUMPTIO].timer!=-1 )
+ if(sc->data[SC_ASSUMPTIO])
status_change_end(bl,SC_ASSUMPTIO,-1);
break;
-
case SC_CARTBOOST:
- if(sc->data[SC_DECREASEAGI].timer!=-1 )
+ if(sc->data[SC_DECREASEAGI])
{ //Cancel Decrease Agi, but take no further effect [Skotlex]
status_change_end(bl,SC_DECREASEAGI,-1);
return 0;
}
break;
case SC_FUSION:
- if(sc->data[SC_SPIRIT].timer!=-1 )
+ if(sc->data[SC_SPIRIT])
status_change_end(bl,SC_SPIRIT,-1);
break;
case SC_ADJUSTMENT:
- if(sc->data[SC_MADNESSCANCEL].timer != -1)
+ if(sc->data[SC_MADNESSCANCEL])
status_change_end(bl,SC_MADNESSCANCEL,-1);
break;
case SC_MADNESSCANCEL:
- if(sc->data[SC_ADJUSTMENT].timer!=-1)
+ if(sc->data[SC_ADJUSTMENT])
status_change_end(bl,SC_ADJUSTMENT,-1);
break;
}
//Check for overlapping fails
- if(sc->data[type].timer != -1)
+ if((sce=sc->data[type]))
{
switch (type)
{
@@ -4943,7 +4948,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_ADRENALINE2:
case SC_WEAPONPERFECTION:
case SC_OVERTHRUST:
- if (sc->data[type].val2 > val2)
+ if (sce->val2 > val2)
return 0;
break;
case SC_HPREGEN:
@@ -4976,44 +4981,50 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_GOSPEL:
//Must not override a casting gospel char.
- if(sc->data[type].val4 == BCT_SELF)
+ if(sce->val4 == BCT_SELF)
return 0;
- if(sc->data[type].val1 > val1)
+ if(sce->val1 > val1)
return 1;
break;
case SC_ENDURE:
- if(sc->data[type].val4 && !val4)
+ if(sce->val4 && !val4)
return 1; //Don't let you override infinite endure.
- if(sc->data[type].val1 > val1)
+ if(sce->val1 > val1)
return 1;
break;
case SC_KAAHI:
- if(sc->data[type].val1 > val1)
+ if(sce->val1 > val1)
return 1;
//Delete timer if it exists.
- if (sc->data[type].val4 != -1) {
- delete_timer(sc->data[type].val4,kaahi_heal_timer);
- sc->data[type].val4=-1;
+ if (sce->val4 != -1) {
+ delete_timer(sce->val4,kaahi_heal_timer);
+ sce->val4=-1;
}
break;
case SC_JAILED:
//When a player is already jailed, do not edit the jail data.
- val2 = sc->data[type].val2;
- val3 = sc->data[type].val3;
- val4 = sc->data[type].val4;
+ val2 = sce->val2;
+ val3 = sce->val3;
+ val4 = sce->val4;
break;
+ case SC_JOINTBEAT:
+ val2 |= sce->val2; // stackable ailments
default:
- if(sc->data[type].val1 > val1)
+ if(sce->val1 > val1)
return 1; //Return true to not mess up skill animations. [Skotlex
}
(sc->count)--;
- delete_timer(sc->data[type].timer, status_change_timer);
- sc->data[type].timer = -1;
+ if (sce->timer != -1)
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = -1;
}
+ //NOTE: avoiding returning after this point, or if you must return a failure, use this to properly cleanup any existing data.
+#define sc_start_abort(ret) { \
+ if (sce) { ers_free(sc_data_ers, sce); sc->data[type] = NULL; } \
+ return ret; }
vd = status_get_viewdata(bl);
calc_flag = StatusChangeFlagTable[type];
-
if(!(flag&4)) //&4 - Do not parse val settings when loading SCs
switch(type)
{
@@ -5034,15 +5045,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
}
//val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
+ if(val4)
+ tick = -1;
break;
case SC_AUTOBERSERK:
if (status->hp < status->max_hp>>2 &&
- (sc->data[SC_PROVOKE].timer==-1 || sc->data[SC_PROVOKE].val2==0))
+ (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
+ tick = -1;
break;
-
case SC_SIGNUMCRUCIS:
val2 = 10 + 4*val1; //Def reduction
+ tick = -1;
clif_emotion(bl,4);
break;
case SC_MAXIMIZEPOWER:
@@ -5066,11 +5080,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_MAGICPOWER:
//val1: Skill lv
val2 = 1; //Lasts 1 invocation
- //val3 will store matk_min (needed in case you use ground-spells)
- //val4 will store matk_max
+ val3 = 5*val1; //Matk% increase
+ tick = -1;
break;
case SC_SACRIFICE:
val2 = 5; //Lasts 5 hits
+ tick = -1;
break;
case SC_ENCPOISON:
val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
@@ -5180,7 +5195,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = 0; //Tick duration/Speed penalty.
if (sd) { //Store walk speed change in lower part of val3
val3 = 500-40*pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON));
- if (sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_BARDDANCER)
+ if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)
val3 -= 40; //TODO: Figure out real bonus rate.
}
val3|= ((tick/1000)<<16)&0xFFFF0000; //Store tick in upper part of val3
@@ -5203,7 +5218,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_WEDDING:
case SC_XMAS:
case SC_SUMMER:
- if (!vd) return 0;
+ if (!vd) sc_start_abort(0);
//Store previous values as they could be removed.
val1 = vd->class_;
val2 = vd->weapon;
@@ -5279,7 +5294,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CHASEWALK:
val2 = tick>0?tick:10000; //Interval at which SP is drained.
val3 = 65+val1*5; //Speed adjustment.
- if (sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_ROGUE)
+ if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE)
val3 += 60;
val4 = 10+val1*2; //SP cost.
if (map_flag_gvg(bl->m)) val4 *= 5;
@@ -5311,17 +5326,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
//Permanent effects.
+ case SC_AETERNA:
case SC_MODECHANGE:
case SC_WEIGHT50:
case SC_WEIGHT90:
case SC_BROKENWEAPON:
case SC_BROKENARMOR:
- case SC_READYSTORM: // Taekwon stances SCs [Dralnu]
+ case SC_READYSTORM:
case SC_READYDOWN:
case SC_READYCOUNTER:
case SC_READYTURN:
case SC_DODGE:
- tick = 600*1000;
+ tick = -1;
break;
case SC_AUTOGUARD:
@@ -5382,11 +5398,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_JOINTBEAT:
if( val2&BREAK_NECK )
sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(StatusSkillChangeTable[type],val1));
- val2 |= sc->data[SC_JOINTBEAT].val2; // stackable ailments
break;
case SC_BERSERK:
- if (sc->data[SC_ENDURE].timer == -1 || !sc->data[SC_ENDURE].val4)
+ if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)
sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
//HP healing is performing after the calc_status call.
//Val2 holds HP penalty
@@ -5434,7 +5449,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
} else {
struct status_data *b_status = status_get_base_status(bl);
if (!b_status)
- return 0;
+ sc_start_abort(0);
val3 = 0;
val2 = b_status->str>>1;
@@ -5469,74 +5484,75 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
{
struct block_list *pbl = map_id2bl(val1);
struct status_change *psc = pbl?status_get_sc(pbl):NULL;
+ struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL;
int stat,max;
- if (!psc || psc->data[SC_MARIONETTE].timer == -1)
- return 0;
+ if (!psce)
+ sc_start_abort(0);
val2 = tick /1000;
val3 = val4 = 0;
if (sd) {
max = pc_maxparameter(sd); //Cap to max parameter. [Skotlex]
//Str
- stat = (psc->data[SC_MARIONETTE].val3>>16)&0xFF;
+ stat = (psce->val3>>16)&0xFF;
if (sd->status.str+stat > max)
stat =max-sd->status.str;
val3 |= stat<<16;
//Agi
- stat = (psc->data[SC_MARIONETTE].val3>>8)&0xFF;
+ stat = (psce->val3>>8)&0xFF;
if (sd->status.agi+stat > max)
stat =max-sd->status.agi;
val3 |= stat<<8;
//Vit
- stat = psc->data[SC_MARIONETTE].val3&0xFF;
+ stat = psce->val3&0xFF;
if (sd->status.vit+stat > max)
stat =max-sd->status.vit;
val3 |= stat;
//Int
- stat = (psc->data[SC_MARIONETTE].val4>>16)&0xFF;
+ stat = (psce->val4>>16)&0xFF;
if (sd->status.int_+stat > max)
stat =max-sd->status.int_;
val4 |= stat<<16;
//Dex
- stat = (psc->data[SC_MARIONETTE].val4>>8)&0xFF;
+ stat = (psce->val4>>8)&0xFF;
if (sd->status.dex+stat > max)
stat =max-sd->status.dex;
val4 |= stat<<8;
//Luk
- stat = psc->data[SC_MARIONETTE].val4&0xFF;
+ stat = psce->val4&0xFF;
if (sd->status.luk+stat > max)
stat =max-sd->status.luk;
val4 |= stat;
} else {
struct status_data *b_status = status_get_base_status(bl);
- if (!b_status) return 0;
+ if (!b_status) sc_start_abort(0);
max = 0xFF; //Assume a 256 max parameter
//Str
- stat = (psc->data[SC_MARIONETTE].val3>>16)&0xFF;
+ stat = (psce->val3>>16)&0xFF;
if (b_status->str+stat > max)
stat = max - b_status->str;
val3 |= stat<<16;
//Agi
- stat = (psc->data[SC_MARIONETTE].val3>>8)&0xFF;
+ stat = (psce->val3>>8)&0xFF;
if (b_status->agi+stat > max)
stat = max - b_status->agi;
val3 |= stat<<8;
//Vit
- stat = psc->data[SC_MARIONETTE].val3&0xFF;
+ stat = psce->val3&0xFF;
if (b_status->vit+stat > max)
stat = max - b_status->vit;
val3 |= stat;
//Int
- stat = (psc->data[SC_MARIONETTE].val4>>16)&0xFF;
+ stat = (psce->val4>>16)&0xFF;
if (b_status->int_+stat > max)
stat = max - b_status->int_;
val4 |= stat<<16;
//Dex
- stat = (psc->data[SC_MARIONETTE].val4>>8)&0xFF;
+ stat = (psce->val4>>8)&0xFF;
if (b_status->dex+stat > max)
stat = max - b_status->dex;
val4 |= stat<<8;
//Luk
- stat = psc->data[SC_MARIONETTE].val4&0xFF;
+ stat = psce->val4&0xFF;
if (b_status->luk+stat > max)
stat = max - b_status->luk;
val4 |= stat;
@@ -5547,10 +5563,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_REJECTSWORD:
val2 = 15*val1; //Reflect chance
val3 = 3; //Reflections
+ tick = -1;
break;
case SC_MEMORIZE:
val2 = 5; //Memorized casts.
+ tick = -1;
break;
case SC_GRAVITATION:
@@ -5582,9 +5600,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
int i = map_flag_gvg(bl->m)?2:3;
while (i >= 0) {
type2 = types[i];
- if (src->sc.data[type2].timer != -1)
- sc_start(bl,type2,100,src->sc.data[type2].val1,
- skill_get_time(StatusSkillChangeTable[type2],src->sc.data[type2].val1));
+ if (src->sc.data[type2])
+ sc_start(bl,type2,100,src->sc.data[type2]->val1,
+ skill_get_time(StatusSkillChangeTable[type2],src->sc.data[type2]->val1));
i--;
}
}
@@ -5593,22 +5611,23 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
status_zap(bl, status->hp-1, val2?0:status->sp);
- return 1;
-
+ sc_start_abort(1);
+ break;
case SC_CLOSECONFINE2:
{
struct block_list *src = val2?map_id2bl(val2):NULL;
struct status_change *sc2 = src?status_get_sc(src):NULL;
+ struct status_change_entry *sce2 = sc2?sc2->data[SC_CLOSECONFINE]:NULL;
if (src && sc2) {
- if (sc2->data[SC_CLOSECONFINE].timer == -1) //Start lock on caster.
- sc_start4(src,SC_CLOSECONFINE,100,sc->data[type].val1,1,0,0,tick+1000);
+ if (!sce2) //Start lock on caster.
+ sc_start4(src,SC_CLOSECONFINE,100,val1,1,0,0,tick+1000);
else { //Increase count of locked enemies and refresh time.
- sc2->data[SC_CLOSECONFINE].val2++;
- delete_timer(sc2->data[SC_CLOSECONFINE].timer, status_change_timer);
- sc2->data[SC_CLOSECONFINE].timer = add_timer(gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
+ (sce2->val2)++;
+ delete_timer(sce2->timer, status_change_timer);
+ sce2->timer = add_timer(gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
}
} else //Status failed.
- return 0;
+ sc_start_abort(0);
}
break;
case SC_KAITE:
@@ -5664,6 +5683,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_RUN:
val4 = gettick(); //Store time at which you started running.
+ tick = -1;
break;
case SC_KAAHI:
val2 = 200*val1; //HP heal
@@ -5678,6 +5698,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_TRICKDEAD:
if (vd) vd->dead_sit = 1;
+ tick = -1;
break;
case SC_CONCENTRATE:
val2 = 2 + val1;
@@ -5688,11 +5709,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = val4 = 0;
}
break;
+ case SC_MAXOVERTHRUST:
+ val2 = 20*val1; //Power increase
+ break;
+ case SC_OVERTHRUST:
+ val2 = 5*val1; //Power increase
+ if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ break;
case SC_ADRENALINE2:
case SC_ADRENALINE:
val3 = (val2) ? 300 : 200; // aspd increase
case SC_WEAPONPERFECTION:
- case SC_OVERTHRUST:
if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
tick += tick / 10;
break;
@@ -5859,20 +5887,29 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SUFFRAGIUM:
val2 = 15 * val1; //Speed cast decrease
break;
+ case SC_INCHEALRATE:
+ if (val1 < 1)
+ val1 = 1;
+ break;
+ case SC_HALLUCINATION:
+ val2 = 5+val1; //Factor by which displayed damage is increased by
+ break;
+ case SC_DOUBLECAST:
+ val2 = 40+10*val1; //Trigger rate
+ break;
+ case SC_KAIZEL:
+ val2 = 10*val1; //% of life to be revived with
+ break;
case SC_ARMOR_ELEMENT:
case SC_FASTCAST:
//Place here SCs that have no SCB_* data, no skill associated, no ICON
//associated, and yet are not wrong/unknown. [Skotlex]
break;
- case SC_INCHEALRATE:
- if (val1 < 1)
- val1 = 1;
- break;
default:
if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
{ //Status change with no calc, no icon, and no skill associated...?
ShowError("UnknownStatusChange [%d]\n", type);
- return 0;
+ sc_start_abort(0);
}
}
else //Special considerations when loading SC data.
@@ -5896,8 +5933,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_HIDING:
case SC_CHASEWALK:
case SC_DEFENDER:
- if (!val3)
- return 0;
+ if (!val3) val3 = 100;
break;
}
@@ -6078,12 +6114,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
(sc->count)++;
- sc->data[type].val1 = val1;
- sc->data[type].val2 = val2;
- sc->data[type].val3 = val3;
- sc->data[type].val4 = val4;
-
- sc->data[type].timer = add_timer(gettick() + tick, status_change_timer, bl->id, type);
+ if (!sce) //Not null when overwriting existing sc.
+ sce = sc->data[type] = ers_alloc(sc_data_ers, struct status_change_entry);
+ sce->val1 = val1;
+ sce->val2 = val2;
+ sce->val3 = val3;
+ sce->val4 = val4;
+ if (tick >= 0)
+ sce->timer = add_timer(gettick() + tick, status_change_timer, bl->id, type);
+ else
+ sce->timer = -1; //Infinite duration
if (calc_flag)
status_calc_bl(bl,calc_flag);
@@ -6092,19 +6132,19 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
if (type==SC_BERSERK) {
- sc->data[type].val2 = 5*status->max_hp/100;
+ sce->val2 = 5*status->max_hp/100;
status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
status_set_sp(bl, 0, 0); //Damage all SP
} else if (type==SC_CHANGE) //Heal all HP/SP
status_percent_heal(bl, 100, 100);
-
if (type==SC_RUN) {
struct unit_data *ud = unit_bl2ud(bl);
if (ud)
ud->state.running = unit_run(bl);
}
return 1;
+#undef sc_start_abort
}
/*==========================================
* ステータス異常全解除
@@ -6123,12 +6163,12 @@ int status_change_clear(struct block_list* bl, int type)
if (!sc || !sc->count)
return 0;
- if(sc->data[SC_DANCING].timer != -1)
+ if(sc->data[SC_DANCING])
skill_stop_dancing(bl);
for(i = 0; i < SC_MAX; i++)
{
- if(sc->data[i].timer == -1)
+ if(!sc->data[i])
continue;
if(type == 0)
@@ -6152,11 +6192,13 @@ int status_change_clear(struct block_list* bl, int type)
status_change_end(bl, i, INVALID_TIMER);
- if( type == 1 && sc->data[i].timer != INVALID_TIMER )
+ if( type == 1 && sc->data[i] )
{ //If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
(sc->count)--;
- delete_timer(sc->data[i].timer, status_change_timer);
- sc->data[i].timer = -1;
+ if (sc->data[i]->timer != INVALID_TIMER)
+ delete_timer(sc->data[i]->timer, status_change_timer);
+ ers_free(sc_data_ers, sc->data[i]);
+ sc->data[i] = NULL;
}
}
@@ -6178,6 +6220,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
{
struct map_session_data *sd;
struct status_change *sc;
+ struct status_change_entry *sce;
struct status_data *status;
struct view_data *vd;
int opt_flag=0, calc_flag;
@@ -6189,39 +6232,42 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
nullpo_retr(0,sc);
nullpo_retr(0,status);
- if(type < 0 || type >= SC_MAX)
+ if(type < 0 || type >= SC_MAX || !(sce = sc->data[type]))
return 0;
BL_CAST(BL_PC,bl,sd);
- if (sc->data[type].timer == -1 ||
- (sc->data[type].timer != tid && tid != -1))
+ if (sce->timer != tid && tid != -1)
return 0;
-
+
if (tid == -1) {
- delete_timer(sc->data[type].timer,status_change_timer);
+ if (type == SC_ENDURE && sce->val4)
+ //Do not end infinite endure.
+ return 0;
+ if (sce->timer != -1) //Could be a SC with infinite duration
+ delete_timer(sce->timer,status_change_timer);
if (sc->opt1)
switch (type) {
//"Ugly workaround" [Skotlex]
//delays status change ending so that a skill that sets opt1 fails to
//trigger when it also removed one
case SC_STONE:
- sc->data[type].val3 = 0; //Petrify time counter.
+ sce->val3 = 0; //Petrify time counter.
case SC_FREEZE:
case SC_STUN:
case SC_SLEEP:
- if (sc->data[type].val1) {
+ if (sce->val1) {
//Removing the 'level' shouldn't affect anything in the code
//since these SC are not affected by it, and it lets us know
//if we have already delayed this attack or not.
- sc->data[type].val1 = 0;
- sc->data[type].timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
+ sce->val1 = 0;
+ sce->timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
return 1;
}
}
}
- sc->data[type].timer=-1;
+ sc->data[type] = NULL;
(sc->count)--;
vd = status_get_viewdata(bl);
@@ -6230,7 +6276,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
case SC_WEDDING:
case SC_XMAS:
case SC_SUMMER:
- if (!vd) return 0;
+ if (!vd) break;
if (sd)
{ //Load data from sd->status.* as the stored values could have changed.
//Must remove OPTION to prevent class being rechanged.
@@ -6238,10 +6284,10 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
clif_changeoption(&sd->bl);
status_set_viewdata(bl, sd->status.class_);
} else {
- vd->class_ = sc->data[type].val1;
- vd->weapon = sc->data[type].val2;
- vd->shield = sc->data[type].val3;
- vd->cloth_color = sc->data[type].val4;
+ vd->class_ = sce->val1;
+ vd->weapon = sce->val2;
+ vd->shield = sce->val3;
+ vd->cloth_color = sce->val4;
}
clif_changelook(bl,LOOK_BASE,vd->class_);
clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
@@ -6256,21 +6302,19 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if (ud->walktimer != -1)
unit_stop_walking(bl,1);
}
- if (sc->data[type].val1 >= 7 &&
- DIFF_TICK(gettick(), sc->data[type].val4) <= 1000 &&
+ if (sce->val1 >= 7 &&
+ DIFF_TICK(gettick(), sce->val4) <= 1000 &&
(!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
)
- sc_start(bl,SC_SPURT,100,sc->data[type].val1,skill_get_time2(StatusSkillChangeTable[type], sc->data[type].val1));
+ sc_start(bl,SC_SPURT,100,sce->val1,skill_get_time2(StatusSkillChangeTable[type], sce->val1));
}
break;
case SC_AUTOBERSERK:
- if (sc->data[SC_PROVOKE].timer != -1 && sc->data[SC_PROVOKE].val2 == 1)
+ if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
status_change_end(bl,SC_PROVOKE,-1);
break;
case SC_ENDURE:
- if (sc->data[SC_ENDURE].val4)
- return 0; //Do not end infinite endure.
case SC_DEFENDER:
case SC_REFLECTSHIELD:
case SC_AUTOGUARD:
@@ -6279,40 +6323,40 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
int i;
for (i = 0; i < 5; i++)
{ //Clear the status from the others too [Skotlex]
- if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type].timer != -1)
+ if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type])
status_change_end(&tsd->bl,type,-1);
}
}
break;
case SC_DEVOTION:
{
- struct map_session_data *md = map_id2sd(sc->data[type].val1);
+ struct map_session_data *md = map_id2sd(sce->val1);
//The status could have changed because the Crusader left the game. [Skotlex]
if (md)
{
- md->devotion[sc->data[type].val2] = 0;
+ md->devotion[sce->val2] = 0;
clif_devotion(md);
}
//Remove inherited status [Skotlex]
- if (sc->data[SC_AUTOGUARD].timer != -1)
+ if (sc->data[SC_AUTOGUARD])
status_change_end(bl,SC_AUTOGUARD,-1);
- if (sc->data[SC_DEFENDER].timer != -1)
+ if (sc->data[SC_DEFENDER])
status_change_end(bl,SC_DEFENDER,-1);
- if (sc->data[SC_REFLECTSHIELD].timer != -1)
+ if (sc->data[SC_REFLECTSHIELD])
status_change_end(bl,SC_REFLECTSHIELD,-1);
- if (sc->data[SC_ENDURE].timer != -1)
+ if (sc->data[SC_ENDURE])
status_change_end(bl,SC_ENDURE,-1);
break;
}
case SC_BLADESTOP:
- if(sc->data[type].val4)
+ if(sce->val4)
{
- struct block_list *tbl = (struct block_list *)sc->data[type].val4;
+ struct block_list *tbl = (struct block_list *)sce->val4;
struct status_change *tsc = status_get_sc(tbl);
- sc->data[type].val4 = 0;
- if(tsc && tsc->data[SC_BLADESTOP].timer!=-1)
+ sce->val4 = 0;
+ if(tsc && tsc->data[SC_BLADESTOP])
{
- tsc->data[SC_BLADESTOP].val4 = 0;
+ tsc->data[SC_BLADESTOP]->val4 = 0;
status_change_end(tbl,SC_BLADESTOP,-1);
}
clif_bladestop(bl,tbl,0);
@@ -6321,27 +6365,27 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
case SC_DANCING:
{
struct map_session_data *dsd;
- struct status_change *dsc;
+ struct status_change_entry *dsc;
struct skill_unit_group *group;
- if(sc->data[type].val2)
+ if(sce->val2)
{
- group = (struct skill_unit_group *)sc->data[type].val2;
- sc->data[type].val2 = 0;
+ group = (struct skill_unit_group *)sce->val2;
+ sce->val2 = 0;
skill_delunitgroup(bl, group);
}
- if(sc->data[type].val4 && sc->data[type].val4 != BCT_SELF && (dsd=map_id2sd(sc->data[type].val4))){
- dsc = &dsd->sc;
- if(dsc && dsc->data[type].timer!=-1)
+ if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4))){
+ dsc = dsd->sc.data[type];
+ if(dsc)
{ //This will prevent recursive loops.
- dsc->data[type].val2 = dsc->data[type].val4 = 0;
+ dsc->val2 = dsc->val4 = 0;
status_change_end(&dsd->bl, type, -1);
}
}
}
- if ((sc->data[type].val1&0xFFFF) == CG_MOONLIT)
+ if ((sce->val1&0xFFFF) == CG_MOONLIT)
clif_status_change(bl,SI_MOONLIT,0);
- if (sc->data[SC_LONGING].timer!=-1)
+ if (sc->data[SC_LONGING])
status_change_end(bl,SC_LONGING,-1);
break;
case SC_NOCHAT:
@@ -6350,54 +6394,48 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
break;
case SC_SPLASHER:
{
- struct block_list *src=map_id2bl(sc->data[type].val3);
+ struct block_list *src=map_id2bl(sce->val3);
if(src && tid!=-1)
- skill_castend_damage_id(src, bl, sc->data[type].val2, sc->data[type].val1, gettick(), SD_LEVEL );
+ skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL );
}
break;
case SC_CLOSECONFINE2:
{
- struct block_list *src = sc->data[type].val2?map_id2bl(sc->data[type].val2):NULL;
+ struct block_list *src = sce->val2?map_id2bl(sce->val2):NULL;
struct status_change *sc2 = src?status_get_sc(src):NULL;
- if (src && sc2 && sc2->count) {
+ if (src && sc2 && sc2->data[SC_CLOSECONFINE]) {
//If status was already ended, do nothing.
- if (sc2->data[SC_CLOSECONFINE].timer != -1)
- { //Decrease count
- if (--sc2->data[SC_CLOSECONFINE].val1 <= 0) //No more holds, free him up.
- status_change_end(src, SC_CLOSECONFINE, -1);
- }
+ //Decrease count
+ if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
+ status_change_end(src, SC_CLOSECONFINE, -1);
}
}
case SC_CLOSECONFINE:
- if (sc->data[type].val2 > 0) {
+ if (sce->val2 > 0) {
//Caster has been unlocked... nearby chars need to be unlocked.
int range = 1
- +skill_get_range2(bl, StatusSkillChangeTable[type], sc->data[type].val1)
+ +skill_get_range2(bl, StatusSkillChangeTable[type], sce->val1)
+skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold....
map_foreachinarea(status_change_timer_sub,
- bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sc,type,gettick());
+ bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
}
break;
case SC_COMBO: //Clear last used skill when it is part of a combo.
- if (sd && sd->skillid_old == sc->data[type].val1)
+ if (sd && sd->skillid_old == sce->val1)
sd->skillid_old = sd->skilllv_old = 0;
break;
- case SC_FREEZE:
- sc->data[type].val3 = 0; //Clear Storm Gust hit count
- break;
-
case SC_MARIONETTE:
case SC_MARIONETTE2: /// Marionette target
- if (sc->data[type].val1)
+ if (sce->val1)
{ // check for partner and end their marionette status as well
int type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
- struct block_list *pbl = map_id2bl(sc->data[type].val1);
+ struct block_list *pbl = map_id2bl(sce->val1);
struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
- if (sc2 && sc2->count && sc2->data[type2].timer != -1)
+ if (sc2 && sc2->data[type2])
{
- sc2->data[type2].val1 = 0;
+ sc2->data[type2]->val1 = 0;
status_change_end(pbl, type2, -1);
}
}
@@ -6407,25 +6445,25 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
case SC_BERSERK:
//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
- if(status->hp > 100 && sc->data[type].val2)
+ if(status->hp > 100 && sce->val2)
status_set_hp(bl, 100, 0);
- if(sc->data[SC_ENDURE].timer != -1 && sc->data[SC_ENDURE].val4 == 2)
+ if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
{
- sc->data[SC_ENDURE].val4 = 0;
+ sc->data[SC_ENDURE]->val4 = 0;
status_change_end(bl, SC_ENDURE, -1);
}
sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP),
- skill_get_time(LK_BERSERK, sc->data[type].val1));
+ skill_get_time(LK_BERSERK, sce->val1));
break;
case SC_GOSPEL:
- if (sc->data[type].val3) { //Clear the group.
- struct skill_unit_group *group = (struct skill_unit_group *)sc->data[type].val3;
- sc->data[type].val3 = 0;
+ if (sce->val3) { //Clear the group.
+ struct skill_unit_group *group = (struct skill_unit_group *)sce->val3;
+ sce->val3 = 0;
skill_delunitgroup(bl, group);
}
break;
case SC_HERMODE:
- if(sc->data[type].val3 == BCT_SELF)
+ if(sce->val3 == BCT_SELF)
skill_clear_unitgroup(bl);
break;
case SC_BASILICA: //Clear the skill area. [Skotlex]
@@ -6435,25 +6473,23 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if (vd) vd->dead_sit = 0;
break;
case SC_WARM:
- if (sc->data[type].val4) { //Clear the group.
- struct skill_unit_group *group = (struct skill_unit_group *)sc->data[type].val4;
- sc->data[type].val4 = 0;
+ if (sce->val4) { //Clear the group.
+ struct skill_unit_group *group = (struct skill_unit_group *)sce->val4;
+ sce->val4 = 0;
skill_delunitgroup(bl, group);
}
break;
case SC_KAAHI:
//Delete timer if it exists.
- if (sc->data[type].val4 != -1) {
- delete_timer(sc->data[type].val4,kaahi_heal_timer);
- sc->data[type].val4=-1;
- }
+ if (sce->val4 != -1)
+ delete_timer(sce->val4,kaahi_heal_timer);
break;
case SC_JAILED:
if(tid == -1)
break;
//natural expiration.
- if(sd && sd->mapindex == sc->data[type].val2)
- pc_setpos(sd,(unsigned short)sc->data[type].val3,sc->data[type].val4&0xFFFF, sc->data[type].val4>>16, 3);
+ if(sd && sd->mapindex == sce->val2)
+ pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, 3);
break; //guess hes not in jail :P
case SC_CHANGE:
if (tid == -1)
@@ -6462,9 +6498,6 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
status_set_hp(bl, 10, 0);
status_set_sp(bl, 10, 0);
break;
- case SC_JOINTBEAT:
- sc->data[type].val2 = 0; // Clear stackable ailments
- break;
}
opt_flag = 1;
@@ -6584,8 +6617,8 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if (calc_flag&SCB_DYE)
{ //Restore DYE color
- if (vd && !vd->cloth_color && sc->data[type].val4)
- clif_changelook(bl,LOOK_CLOTHES_COLOR,sc->data[type].val4);
+ if (vd && !vd->cloth_color && sce->val4)
+ clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
calc_flag&=~SCB_DYE;
}
@@ -6607,6 +6640,7 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid)
if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
+ ers_free(sc_data_ers, sce);
return 1;
}
@@ -6614,6 +6648,7 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, int data)
{
struct block_list *bl;
struct status_change *sc;
+ struct status_change_entry *sce;
struct status_data *status;
int hp;
@@ -6621,25 +6656,26 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, int data)
sc=status_get_sc(bl);
status=status_get_status_data(bl);
- if (!sc || !status || data != SC_KAAHI || sc->data[data].timer==-1)
+ if (!(sc && status && data == SC_KAAHI && sc->data[data]))
return 0;
- if(sc->data[data].val4 != tid) {
- ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sc->data[data].val4);
- sc->data[data].val4=-1;
+ sce = sc->data[data];
+ if(sce->val4 != tid) {
+ ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sce->val4);
+ sce->val4=-1;
return 0;
}
- if(!status_charge(bl, 0, sc->data[data].val3)) {
- sc->data[data].val4=-1;
+ if(!status_charge(bl, 0, sce->val3)) {
+ sce->val4=-1;
return 0;
}
hp = status->max_hp - status->hp;
- if (hp > sc->data[data].val2)
- hp = sc->data[data].val2;
+ if (hp > sce->val2)
+ hp = sce->val2;
if (hp)
status_heal(bl, hp, 0, 2);
- sc->data[data].val4=-1;
+ sce->val4=-1;
return 1;
}
@@ -6653,20 +6689,21 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
struct map_session_data *sd;
struct status_data *status;
struct status_change *sc;
+ struct status_change_entry *sce;
bl = map_id2bl(id);
sc = status_get_sc(bl);
status = status_get_status_data(bl);
- if( !bl || !sc || !status )
+ if(!(bl && sc && (sce = sc->data[type])))
{
ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl?bl->type:-1);
return 0;
}
- if( sc->data[type].timer != tid )
+ if( sce->timer != tid )
{
- ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sc->data[type].timer, bl->id);
+ ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id);
return 0;
}
@@ -6678,37 +6715,37 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_CLOAKING:
if(!status_charge(bl, 0, 1))
break; //Not enough SP to continue.
- sc->data[type].timer = add_timer(sc->data[type].val2+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(sce->val2+tick, status_change_timer, bl->id, data);
return 0;
case SC_CHASEWALK:
- if(!status_charge(bl, 0, sc->data[type].val4))
+ if(!status_charge(bl, 0, sce->val4))
break; //Not enough SP to continue.
- if (sc->data[SC_INCSTR].timer == -1) {
- sc_start(bl, SC_INCSTR,100,1<<(sc->data[type].val1-1),
- (sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
- *skill_get_time2(StatusSkillChangeTable[type],sc->data[type].val1));
+ if (!sc->data[SC_INCSTR]) {
+ sc_start(bl, SC_INCSTR,100,1<<(sce->val1-1),
+ (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
+ *skill_get_time2(StatusSkillChangeTable[type],sce->val1));
}
- sc->data[type].timer = add_timer(sc->data[type].val2+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(sce->val2+tick, status_change_timer, bl->id, data);
return 0;
break;
case SC_SKA:
- if((--sc->data[type].val2)>0){
- sc->data[type].val3 = rand()%100; //Random defense.
- sc->data[type].timer = add_timer(1000+tick, status_change_timer,bl->id, data);
+ if(--(sce->val2)>0){
+ sce->val3 = rand()%100; //Random defense.
+ sce->timer = add_timer(1000+tick, status_change_timer,bl->id, data);
return 0;
}
break;
case SC_HIDING:
- if((--sc->data[type].val2)>0){
+ if(--(sce->val2)>0){
- if(sc->data[type].val2 % sc->data[type].val4 == 0 &&!status_charge(bl, 0, 1))
+ if(sce->val2 % sce->val4 == 0 &&!status_charge(bl, 0, 1))
break; //Fail if it's time to substract SP and there isn't.
- sc->data[type].timer = add_timer(1000+tick, status_change_timer,bl->id, data);
+ sce->timer = add_timer(1000+tick, status_change_timer,bl->id, data);
return 0;
}
break;
@@ -6716,42 +6753,35 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_SIGHT:
case SC_RUWACH:
case SC_SIGHTBLASTER:
- map_foreachinrange( status_change_timer_sub, bl, sc->data[type].val3, BL_CHAR, bl,sc,type,tick);
+ map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
- if( (--sc->data[type].val2)>0 ){
- sc->data[type].timer = add_timer(250+tick, status_change_timer, bl->id, data);
+ if( --(sce->val2)>0 ){
+ sce->timer = add_timer(250+tick, status_change_timer, bl->id, data);
return 0;
}
break;
case SC_PROVOKE:
- if(sc->data[type].val2) { //Auto-provoke (it is ended in status_heal)
- sc->data[type].timer = add_timer(1000*60+tick,status_change_timer, bl->id, data );
- return 0;
- }
- break;
-
- case SC_ENDURE:
- if(sc->data[type].val4) { //Infinite Endure.
- sc->data[type].timer = add_timer(1000*60+tick,status_change_timer, bl->id, data);
+ if(sce->val2) { //Auto-provoke (it is ended in status_heal)
+ sce->timer = add_timer(1000*60+tick,status_change_timer, bl->id, data );
return 0;
}
break;
case SC_STONE:
- if(sc->opt1 == OPT1_STONEWAIT && sc->data[type].val3) {
- sc->data[type].val4 = 0;
+ if(sc->opt1 == OPT1_STONEWAIT && sce->val3) {
+ sce->val4 = 0;
unit_stop_walking(bl,1);
sc->opt1 = OPT1_STONE;
clif_changeoption(bl);
- sc->data[type].timer = add_timer(1000+tick,status_change_timer, bl->id, data );
+ sce->timer = add_timer(1000+tick,status_change_timer, bl->id, data );
status_calc_bl(bl, StatusChangeFlagTable[type]);
return 0;
}
- if((--sc->data[type].val3) > 0) {
- if((++sc->data[type].val4)%5 == 0 && status->hp > status->max_hp/4)
- status_zap(bl, sc->data[type].val2, 0);
- sc->data[type].timer = add_timer(1000+tick,status_change_timer, bl->id, data );
+ if(--(sce->val3) > 0) {
+ if(++(sce->val4)%5 == 0 && status->hp > status->max_hp/4)
+ status_zap(bl, sce->val2, 0);
+ sce->timer = add_timer(1000+tick,status_change_timer, bl->id, data );
return 0;
}
break;
@@ -6760,84 +6790,66 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
if(status->hp <= status->max_hp>>2) //Stop damaging after 25% HP left.
break;
case SC_DPOISON:
- if ((--sc->data[type].val3) > 0) {
- if (sc->data[SC_SLOWPOISON].timer == -1) {
- status_zap(bl, sc->data[type].val4, 0);
+ if (--(sce->val3) > 0) {
+ if (!sc->data[SC_SLOWPOISON]) {
+ status_zap(bl, sce->val4, 0);
if (status_isdead(bl))
break;
}
- sc->data[type].timer = add_timer(1000 + tick, status_change_timer, bl->id, data );
+ sce->timer = add_timer(1000 + tick, status_change_timer, bl->id, data );
return 0;
}
break;
case SC_TENSIONRELAX:
- if(status->max_hp > status->hp && (--sc->data[type].val3) > 0){
- sc->data[type].timer = add_timer(sc->data[type].val4+tick, status_change_timer, bl->id, data);
+ if(status->max_hp > status->hp && --(sce->val3) > 0){
+ sce->timer = add_timer(sce->val4+tick, status_change_timer, bl->id, data);
return 0;
}
break;
case SC_BLEEDING:
- if ((--sc->data[type].val4) >= 0) {
+ if (--(sce->val4) >= 0) {
status_fix_damage(NULL, bl, rand()%600 + 200, 0);
if (status_isdead(bl))
break;
- sc->data[type].timer = add_timer(10000 + tick, status_change_timer, bl->id, data );
+ sce->timer = add_timer(10000 + tick, status_change_timer, bl->id, data );
return 0;
}
break;
case SC_HPREGEN:
- if( sd && (--sc->data[type].val4) >= 0 )
+ if( sd && --(sce->val4) >= 0 )
{
if( status->hp < status->max_hp ) {
- int hp = (int)(sd->status.max_hp * sc->data[type].val1 / 100.);
+ int hp = (int)(sd->status.max_hp * sce->val1 / 100.);
status_heal(bl, hp, 0, 2);
}
- sc->data[type].timer = add_timer((sc->data[type].val2 * 1000) + tick, status_change_timer, bl->id, data );
+ sce->timer = add_timer((sce->val2 * 1000) + tick, status_change_timer, bl->id, data );
return 0;
}
break;
case SC_KNOWLEDGE:
- if (sd) {
- if(bl->m != sd->feel_map[0].m && bl->m != sd->feel_map[1].m && bl->m != sd->feel_map[2].m)
- break; //End it
- } //Otherwise continue.
- // Status changes that don't have a time limit
- case SC_AETERNA:
- case SC_TRICKDEAD:
- case SC_MODECHANGE:
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_MAGICPOWER:
- case SC_REJECTSWORD:
- case SC_MEMORIZE:
- case SC_BROKENWEAPON:
- case SC_BROKENARMOR:
- case SC_SACRIFICE:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYTURN:
- case SC_READYCOUNTER:
- case SC_RUN:
- case SC_DODGE:
- case SC_AUTOBERSERK:
- case SC_SIGNUMCRUCIS:
- sc->data[type].timer = add_timer( 1000*600+tick,status_change_timer, bl->id, data );
- return 0;
-
+ if (!sd) break;
+ if(bl->m == sd->feel_map[0].m ||
+ bl->m == sd->feel_map[1].m ||
+ bl->m == sd->feel_map[2].m)
+ { //Timeout will be handled by pc_setpos
+ sce->timer = -1;
+ return 0;
+ }
+ break;
case SC_DANCING: //ダンススキルの時間SP消費
{
int s = 0;
int sp = 1;
- int counter = sc->data[type].val3>>16;
+ int counter = (sce->val3)>>16;
if (--counter <= 0)
break;
- sc->data[type].val3&= 0xFFFF; //Remove counter
- sc->data[type].val3|=(counter<<16);//Reset it.
- switch(sc->data[type].val1&0xFFFF){
+ sce->val3&= 0xFFFF; //Remove counter
+ sce->val3|=(counter<<16);//Reset it.
+ switch(sce->val1&0xFFFF){
case BD_RICHMANKIM:
case BD_DRUMBATTLEFIELD:
case BD_RINGNIBELUNGEN:
@@ -6866,7 +6878,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
break;
case CG_MOONLIT:
//Moonlit's cost is 4sp*skill_lv [Skotlex]
- sp= 4*(sc->data[type].val1>>16);
+ sp= 4*(sce->val1>>16);
//Upkeep is also every 10 secs.
case DC_DONTFORGETME:
s=10;
@@ -6874,12 +6886,12 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
}
if (s && (counter%s == 0))
{
- if (sc->data[SC_LONGING].timer != -1)
+ if (sc->data[SC_LONGING])
sp*= 3;
if (!status_charge(bl, 0, sp))
break;
}
- sc->data[type].timer = add_timer(1000+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(1000+tick, status_change_timer, bl->id, data);
return 0;
}
break;
@@ -6887,10 +6899,10 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_DEVOTION:
{ //Check range and timeleft to preserve status [Skotlex]
//This implementation won't work for mobs because of map_id2sd, but it's a small cost in exchange of the speed of map_id2sd over map_id2bl
- struct map_session_data *md = map_id2sd(sc->data[type].val1);
- if (md && check_distance_bl(bl, &md->bl, sc->data[type].val3) && (sc->data[type].val4-=1000)>0)
+ struct map_session_data *md = map_id2sd(sce->val1);
+ if (md && check_distance_bl(bl, &md->bl, sce->val3) && (sce->val4-=1000)>0)
{
- sc->data[type].timer = add_timer(1000+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(1000+tick, status_change_timer, bl->id, data);
return 0;
}
}
@@ -6898,9 +6910,9 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_BERSERK:
// 5% every 10 seconds [DracoRPG]
- if((--sc->data[type].val3)>0 && status_charge(bl, sc->data[type].val2, 0))
+ if(--(sce->val3)>0 && status_charge(bl, sce->val2, 0))
{
- sc->data[type].timer = add_timer(sc->data[type].val4+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(sce->val4+tick, status_change_timer, bl->id, data);
return 0;
}
break;
@@ -6911,7 +6923,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
clif_updatestatus(sd,SP_MANNER);
if (sd->status.manner < 0)
{ //Every 60 seconds your manner goes up by 1 until it gets back to 0.
- sc->data[type].timer = add_timer(60000+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(60000+tick, status_change_timer, bl->id, data);
return 0;
}
}
@@ -6919,13 +6931,13 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_SPLASHER:
// custom Venom Splasher countdown timer
- //if (sc->data[type].val4 % 1000 == 0) {
+ //if (sce->val4 % 1000 == 0) {
// char timer[10];
- // snprintf (timer, 10, "%d", sc->data[type].val4/1000);
+ // snprintf (timer, 10, "%d", sce->val4/1000);
// clif_message(bl, timer);
//}
- if((sc->data[type].val4 -= 500) > 0) {
- sc->data[type].timer = add_timer(500 + tick, status_change_timer, bl->id, data);
+ if((sce->val4 -= 500) > 0) {
+ sce->timer = add_timer(500 + tick, status_change_timer, bl->id, data);
return 0;
}
break;
@@ -6933,51 +6945,51 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
case SC_MARIONETTE:
case SC_MARIONETTE2:
{
- struct block_list *pbl = map_id2bl(sc->data[type].val1);
- if (pbl && check_distance_bl(bl, pbl, 7) && (sc->data[type].val2--)>0)
+ struct block_list *pbl = map_id2bl(sce->val1);
+ if (pbl && check_distance_bl(bl, pbl, 7) && (sce->val2)-->0)
{
- sc->data[type].timer = add_timer(1000 + tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(1000 + tick, status_change_timer, bl->id, data);
return 0;
}
}
break;
case SC_GOSPEL:
- if(sc->data[type].val4 == BCT_SELF && (--sc->data[type].val2) > 0)
+ if(sce->val4 == BCT_SELF && --(sce->val2) > 0)
{
int hp, sp;
- hp = (sc->data[type].val1 > 5) ? 45 : 30;
- sp = (sc->data[type].val1 > 5) ? 35 : 20;
+ hp = (sce->val1 > 5) ? 45 : 30;
+ sp = (sce->val1 > 5) ? 35 : 20;
if(!status_charge(bl, hp, sp))
break;
- sc->data[type].timer = add_timer(10000+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(10000+tick, status_change_timer, bl->id, data);
return 0;
}
break;
case SC_GUILDAURA:
{
- struct block_list *tbl = map_id2bl(sc->data[type].val2);
+ struct block_list *tbl = map_id2bl(sce->val2);
if (tbl && battle_check_range(bl, tbl, 2)){
- sc->data[type].timer = add_timer(1000 + tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(1000 + tick, status_change_timer, bl->id, data);
return 0;
}
}
break;
case SC_JAILED:
- if(sc->data[type].val1 == INT_MAX || --sc->data[type].val1 > 0)
+ if(sce->val1 == INT_MAX || --(sce->val1) > 0)
{
- sc->data[type].timer = add_timer(60000+tick, status_change_timer, bl->id,data);
+ sce->timer = add_timer(60000+tick, status_change_timer, bl->id,data);
return 0;
}
break;
case SC_BLIND:
- if(sc->data[SC_FOGWALL].timer!= -1)
+ if(sc->data[SC_FOGWALL])
{ //Blind lasts forever while you are standing on the fog.
- sc->data[type].timer = add_timer(5000+tick, status_change_timer, bl->id, data);
+ sce->timer = add_timer(5000+tick, status_change_timer, bl->id, data);
return 0;
}
break;
@@ -6996,8 +7008,8 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
struct status_change* tsc;
struct block_list* src = va_arg(ap,struct block_list*);
- struct status_change* sc = va_arg(ap,struct status_change*);
- enum sc_type type = va_arg(ap,enum sc_type);
+ struct status_change_entry* sce = va_arg(ap,struct status_change_entry*);
+ enum sc_type type = va_arg(ap,enum sc_type);
unsigned int tick = va_arg(ap,unsigned int);
if (status_isdead(bl))
@@ -7013,14 +7025,14 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
case SC_SIGHT: /* サイト */
case SC_CONCENTRATE:
if (tsc) {
- if (tsc->data[SC_HIDING].timer != -1)
+ if (tsc->data[SC_HIDING])
status_change_end( bl, SC_HIDING, -1);
- if (tsc->data[SC_CLOAKING].timer != -1)
+ if (tsc->data[SC_CLOAKING])
status_change_end( bl, SC_CLOAKING, -1);
}
break;
case SC_RUWACH: /* ルアフ */
- if (tsc && (tsc->data[SC_HIDING].timer != -1 || tsc->data[SC_CLOAKING].timer != -1)) {
+ if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING])) {
status_change_end( bl, SC_HIDING, -1);
status_change_end( bl, SC_CLOAKING, -1);
if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
@@ -7032,13 +7044,13 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
status_check_skilluse(src, bl, WZ_SIGHTBLASTER, 2))
{
skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0);
- if (sc) sc->data[type].val2 = 0; //This signals it to end.
+ if (sce) sce->val2 = 0; //This signals it to end.
}
break;
case SC_CLOSECONFINE:
//Lock char has released the hold on everyone...
- if (tsc && tsc->data[SC_CLOSECONFINE2].timer != -1 && tsc->data[SC_CLOSECONFINE2].val2 == src->id) {
- tsc->data[SC_CLOSECONFINE2].val2 = 0;
+ if (tsc && tsc->data[SC_CLOSECONFINE2] && tsc->data[SC_CLOSECONFINE2]->val2 == src->id) {
+ tsc->data[SC_CLOSECONFINE2]->val2 = 0;
status_change_end(bl, SC_CLOSECONFINE2, -1);
}
break;
@@ -7061,13 +7073,13 @@ int status_change_clear_buffs (struct block_list* bl, int type)
if (type&2) //Debuffs
for( i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++ )
{
- if(sc->data[i].timer != -1)
+ if(sc->data[i])
status_change_end(bl,i,-1);
}
for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ )
{
- if(sc->data[i].timer == -1)
+ if(!sc->data[i])
continue;
switch (i) {
@@ -7121,7 +7133,7 @@ int status_change_clear_buffs (struct block_list* bl, int type)
case SC_BERSERK:
if (!(type&1))
continue;
- sc->data[i].val2 = 0;
+ sc->data[i]->val2 = 0;
break;
default:
if (!(type&1))
@@ -7490,6 +7502,11 @@ int do_init_status(void)
status_readdb();
status_calc_sigma();
natural_heal_prev_tick = gettick();
+ sc_data_ers = ers_new(sizeof(struct status_change_entry));
add_timer_interval(natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status_natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL);
return 0;
}
+void do_final_status(void)
+{
+ ers_destroy(sc_data_ers);
+}