summaryrefslogtreecommitdiff
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
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
-rw-r--r--Changelog-Trunk.txt6
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/map/atcommand.c42
-rw-r--r--src/map/battle.c262
-rw-r--r--src/map/charcommand.c8
-rw-r--r--src/map/chrif.c28
-rw-r--r--src/map/clif.c69
-rw-r--r--src/map/map.c25
-rw-r--r--src/map/map.h13
-rw-r--r--src/map/mob.c35
-rw-r--r--src/map/party.c2
-rw-r--r--src/map/pc.c97
-rw-r--r--src/map/pet.c2
-rw-r--r--src/map/skill.c692
-rw-r--r--src/map/skill.h2
-rw-r--r--src/map/status.c1785
-rw-r--r--src/map/status.h9
-rw-r--r--src/map/unit.c148
18 files changed, 1618 insertions, 1609 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 750659746..2ecab7ca6 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -3,6 +3,12 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
+2007/11/23
+ * 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. However, since this is a pretty
+ large update (and I am unable to fully test all possible situations
+ relating to status changes), watch out for any bugs. [Skotlex]
2007/11/22
* Moved the reset of references to after the empty script checks in
parse_script. (fixes bugreport:222 and bugreport:449)
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 1db623982..56e4eb9ce 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -436,7 +436,7 @@ enum {
GD_SKILLBASE=10000,
GD_APPROVAL=10000,
GD_KAFRACONTRACT=10001,
- GD_GUARDIANRESEARCH=10002,
+ GD_GUARDRESEARCH=10002,
GD_GUARDUP=10003,
GD_EXTENSION=10004,
GD_GLORYGUILD=10005,
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 3cbe1f885..81761a453 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -4950,7 +4950,7 @@ int atcommand_jail(const int fd, struct map_session_data* sd, const char* comman
return -1;
}
- if (pl_sd->sc.data[SC_JAILED].timer != -1)
+ if (pl_sd->sc.data[SC_JAILED])
{
clif_displaymessage(fd, msg_txt(118)); // Player warped in jails.
return -1;
@@ -5002,7 +5002,7 @@ int atcommand_unjail(const int fd, struct map_session_data* sd, const char* comm
return -1;
}
- if (pl_sd->sc.data[SC_JAILED].timer == -1)
+ if (!pl_sd->sc.data[SC_JAILED])
{
clif_displaymessage(fd, msg_txt(119)); // This player is not in jails.
return -1;
@@ -5086,10 +5086,10 @@ int atcommand_jailfor(const int fd, struct map_session_data* sd, const char* com
}
//Added by Coltaro
- if (pl_sd->sc.count && pl_sd->sc.data[SC_JAILED].timer != -1 &&
- pl_sd->sc.data[SC_JAILED].val1 != INT_MAX)
+ if(pl_sd->sc.data[SC_JAILED] &&
+ pl_sd->sc.data[SC_JAILED]->val1 != INT_MAX)
{ //Update the player's jail time
- jailtime += pl_sd->sc.data[SC_JAILED].val1;
+ jailtime += pl_sd->sc.data[SC_JAILED]->val1;
if (jailtime <= 0) {
jailtime = 0;
clif_displaymessage(pl_sd->fd, msg_txt(120)); // GM has discharge you.
@@ -5131,23 +5131,23 @@ int atcommand_jailtime(const int fd, struct map_session_data* sd, const char* co
nullpo_retr(-1, sd);
- if (!sd->sc.count || sd->sc.data[SC_JAILED].timer == -1) {
+ if (!sd->sc.data[SC_JAILED]) {
clif_displaymessage(fd, "You are not in jail."); // You are not in jail.
return -1;
}
- if (sd->sc.data[SC_JAILED].val1 == INT_MAX) {
+ if (sd->sc.data[SC_JAILED]->val1 == INT_MAX) {
clif_displaymessage(fd, "You have been jailed indefinitely.");
return 0;
}
- if (sd->sc.data[SC_JAILED].val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
+ if (sd->sc.data[SC_JAILED]->val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
clif_displaymessage(fd, "You have been jailed for an unknown amount of time.");
return -1;
}
//Get remaining jail time
- get_jail_time(sd->sc.data[SC_JAILED].val1,&year,&month,&day,&hour,&minute);
+ get_jail_time(sd->sc.data[SC_JAILED]->val1,&year,&month,&day,&hour,&minute);
sprintf(atcmd_output,msg_txt(402),"You will remain",year,month,day,hour,minute); // You will remain in jail for %d years, %d months, %d days, %d hours and %d minutes
clif_displaymessage(fd, atcmd_output);
@@ -6366,8 +6366,8 @@ int atcommand_npctalk(const int fd, struct map_session_data* sd, const char* com
struct npc_data *nd;
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK].timer!=-1 ||
- (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT)))
+ (sd->sc.data[SC_BERSERK] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return -1;
if (!message || !*message || sscanf(message, "%23[^,], %99[^\n]", name, mes) < 2) {
@@ -6407,8 +6407,8 @@ int atcommand_pettalk(const int fd, struct map_session_data* sd, const char* com
}
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK].timer!=-1 ||
- (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT)))
+ (sd->sc.data[SC_BERSERK] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return -1;
if (!message || !*message || sscanf(message, "%99[^\n]", mes) < 1) {
@@ -6670,7 +6670,7 @@ int atcommand_unmute(const int fd, struct map_session_data* sd, const char* comm
return -1;
}
- if(pl_sd->sc.data[SC_NOCHAT].timer == -1) {
+ if(!pl_sd->sc.data[SC_NOCHAT]) {
clif_displaymessage(sd->fd,"Player is not muted");
return -1;
}
@@ -7175,8 +7175,8 @@ int atcommand_homtalk(const int fd, struct map_session_data* sd, const char* com
nullpo_retr(-1, sd);
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK].timer!=-1 ||
- (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT)))
+ (sd->sc.data[SC_BERSERK] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return -1;
if ( !merc_is_hom_active(sd->hd) ) {
@@ -7564,7 +7564,7 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
pl_sd->status.manner -= time;
if (pl_sd->status.manner < 0)
sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
- else if (pl_sd->sc.count && pl_sd->sc.data[SC_NOCHAT].timer != -1)
+ else if (pl_sd->sc.data[SC_NOCHAT])
status_change_end(&pl_sd->bl, SC_NOCHAT, -1);
}
return 0;
@@ -7617,8 +7617,8 @@ int atcommand_me(const int fd, struct map_session_data* sd, const char* command,
memset(atcmd_output, '\0', sizeof(atcmd_output));
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK].timer!=-1 ||
- (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT)))
+ (sd->sc.data[SC_BERSERK] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return -1;
if (!message || !*message || sscanf(message, "%199[^\n]", tempmes) < 0) {
@@ -8025,7 +8025,7 @@ int atcommand_main(const int fd, struct map_session_data* sd, const char* comman
sd->state.mainchat = 1;
clif_displaymessage(fd, msg_txt(380)); // Main chat has been activated.
}
- if (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) {
+ if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) {
clif_displaymessage(fd, msg_txt(387));
return -1;
}
@@ -8474,7 +8474,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
if( !message || !*message )
return false; // shouldn't happen
- if( sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCOMMAND )
+ if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND )
return true; // so that it won't display as normal message
if( battle_config.atc_gmonly != 0 && gmlvl == 0 )
diff --git a/src/map/battle.c b/src/map/battle.c
index f686410f4..13740edb7 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -223,24 +223,24 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
ratio = attr_fix_table[def_lv-1][atk_elem][def_type];
if (sc && sc->count)
{
- if(sc->data[SC_VOLCANO].timer!=-1 && atk_elem == ELE_FIRE)
- ratio += enchant_eff[sc->data[SC_VOLCANO].val1-1];
- if(sc->data[SC_VIOLENTGALE].timer!=-1 && atk_elem == ELE_WIND)
- ratio += enchant_eff[sc->data[SC_VIOLENTGALE].val1-1];
- if(sc->data[SC_DELUGE].timer!=-1 && atk_elem == ELE_WATER)
- ratio += enchant_eff[sc->data[SC_DELUGE].val1-1];
+ if(sc->data[SC_VOLCANO] && atk_elem == ELE_FIRE)
+ ratio += enchant_eff[sc->data[SC_VOLCANO]->val1-1];
+ if(sc->data[SC_VIOLENTGALE] && atk_elem == ELE_WIND)
+ ratio += enchant_eff[sc->data[SC_VIOLENTGALE]->val1-1];
+ if(sc->data[SC_DELUGE] && atk_elem == ELE_WATER)
+ ratio += enchant_eff[sc->data[SC_DELUGE]->val1-1];
}
if (tsc && tsc->count)
{
- if(tsc->data[SC_ARMOR_ELEMENT].timer!=-1)
+ if(tsc->data[SC_ARMOR_ELEMENT])
{
- if (tsc->data[SC_ARMOR_ELEMENT].val1 == atk_elem)
- ratio -= tsc->data[SC_ARMOR_ELEMENT].val2;
+ if (tsc->data[SC_ARMOR_ELEMENT]->val1 == atk_elem)
+ ratio -= tsc->data[SC_ARMOR_ELEMENT]->val2;
else
- if (tsc->data[SC_ARMOR_ELEMENT].val3 == atk_elem)
- ratio -= tsc->data[SC_ARMOR_ELEMENT].val4;
+ if (tsc->data[SC_ARMOR_ELEMENT]->val3 == atk_elem)
+ ratio -= tsc->data[SC_ARMOR_ELEMENT]->val4;
}
- if(tsc->data[SC_SPIDERWEB].timer!=-1 && atk_elem == ELE_FIRE)
+ if(tsc->data[SC_SPIDERWEB] && atk_elem == ELE_FIRE)
{ // [Celest]
damage <<= 1;
status_change_end(target, SC_SPIDERWEB, -1);
@@ -256,7 +256,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
{
struct map_session_data *sd = NULL;
struct status_change *sc;
- struct status_change_entry *sci;
+ struct status_change_entry *sce;
nullpo_retr(0, bl);
@@ -290,9 +290,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
if (sc && sc->count) {
//First, sc_*'s that reduce damage to 0.
- if (sc->data[SC_SAFETYWALL].timer!=-1 && flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK
+ if (sc->data[SC_SAFETYWALL] && flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK
) {
- struct skill_unit_group *group = (struct skill_unit_group *)sc->data[SC_SAFETYWALL].val3;
+ struct skill_unit_group *group = (struct skill_unit_group *)sc->data[SC_SAFETYWALL]->val3;
if (group) {
if (--group->val2<=0)
skill_delunitgroup(NULL,group);
@@ -301,82 +301,80 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
status_change_end(bl,SC_SAFETYWALL,-1);
}
- if(sc->data[SC_AUTOGUARD].timer != -1 && flag&BF_WEAPON &&
+ if((sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON &&
!(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK) &&
- rand()%100 < sc->data[SC_AUTOGUARD].val2)
+ rand()%100 < sce->val2)
{
int delay;
- clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sc->data[SC_AUTOGUARD].val1,1);
+ clif_skill_nodamage(bl,bl,CR_AUTOGUARD,sce->val1,1);
// different delay depending on skill level [celest]
- if (sc->data[SC_AUTOGUARD].val1 <= 5)
+ if (sce->val1 <= 5)
delay = 300;
- else if (sc->data[SC_AUTOGUARD].val1 > 5 && sc->data[SC_AUTOGUARD].val1 <= 9)
+ else if (sce->val1 > 5 && sce->val1 <= 9)
delay = 200;
else
delay = 100;
unit_set_walkdelay(bl, gettick(), delay, 1);
- if(sc->data[SC_SHRINK].timer != -1 && rand()%100<5*sc->data[SC_AUTOGUARD].val1)
+ if(sc->data[SC_SHRINK] && rand()%100<5*sce->val1)
skill_blown(bl,src,skill_get_blewcount(CR_SHRINK,1),-1,0);
return 0;
}
// -- moonsoul (chance to block attacks with new Lord Knight skill parrying)
//
- if(sc->data[SC_PARRYING].timer != -1 && flag&BF_WEAPON &&
- rand()%100 < sc->data[SC_PARRYING].val2) {
- clif_skill_nodamage(bl,bl,LK_PARRYING,sc->data[SC_PARRYING].val1,1);
+ if((sce=sc->data[SC_PARRYING]) && flag&BF_WEAPON &&
+ rand()%100 < sce->val2) {
+ clif_skill_nodamage(bl,bl,LK_PARRYING,sce->val1,1);
return 0;
}
- if(sc->data[SC_DODGE].timer != -1 && !sc->opt1 &&
- (flag&BF_LONG || sc->data[SC_SPURT].timer != -1)
+ if(sc->data[SC_DODGE] && !sc->opt1 &&
+ (flag&BF_LONG || sc->data[SC_SPURT])
&& rand()%100 < 20) {
if (sd && pc_issit(sd)) pc_setstand(sd); //Stand it to dodge.
clif_skill_nodamage(bl,bl,TK_DODGE,1,1);
- if (sc->data[SC_COMBO].timer == -1)
+ if (!sc->data[SC_COMBO])
sc_start4(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
return 0;
}
- if(sc->data[SC_HERMODE].timer != -1 && flag&BF_MAGIC)
+ if(sc->data[SC_HERMODE] && flag&BF_MAGIC)
return 0;
- if(sc->data[SC_TATAMIGAESHI].timer != -1 && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
+ if(sc->data[SC_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
return 0;
- if(sc->data[SC_KAUPE].timer != -1 &&
- rand()%100 < sc->data[SC_KAUPE].val2 &&
+ if((sce=sc->data[SC_KAUPE]) &&
+ rand()%100 < sce->val2 &&
(src->type == BL_PC || !skill_num))
{ //Kaupe only blocks all skills of players.
clif_specialeffect(bl, 462, AREA);
//Shouldn't end until Breaker's non-weapon part connects.
if (skill_num != ASC_BREAKER || !(flag&BF_WEAPON))
- if (--sc->data[SC_KAUPE].val3 <= 0) //We make it work like Safety Wall, even though it only blocks 1 time.
+ if (--(sce->val3) <= 0) //We make it work like Safety Wall, even though it only blocks 1 time.
status_change_end(bl, SC_KAUPE, -1);
return 0;
}
- if ((sc->data[SC_UTSUSEMI].timer != -1 || sc->data[SC_BUNSINJYUTSU].timer != -1)
+ if (((sce=sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU])
&&
flag&BF_WEAPON && !(skill_get_nk(skill_num)&NK_NO_CARDFIX_ATK))
{
- if (sc->data[SC_UTSUSEMI].timer != -1) {
+ if (sce) {
clif_specialeffect(bl, 462, AREA);
- skill_blown(src,bl,sc->data[SC_UTSUSEMI].val3,-1,0);
+ skill_blown(src,bl,sce->val3,-1,0);
}
//Both need to be consumed if they are active.
- if (sc->data[SC_UTSUSEMI].timer != -1 &&
- --sc->data[SC_UTSUSEMI].val2 <= 0)
+ if (sce && --(sce->val2) <= 0)
status_change_end(bl, SC_UTSUSEMI, -1);
- if (sc->data[SC_BUNSINJYUTSU].timer != -1 &&
- --sc->data[SC_BUNSINJYUTSU].val2 <= 0)
+ if ((sce=sc->data[SC_BUNSINJYUTSU]) && --(sce->val2) <= 0)
status_change_end(bl, SC_BUNSINJYUTSU, -1);
return 0;
}
//Now damage increasing effects
- if(sc->data[SC_AETERNA].timer!=-1 && skill_num != PF_SOULBURN){
+ if(sc->data[SC_AETERNA] && skill_num != PF_SOULBURN){
damage<<=1;
//Shouldn't end until Breaker's non-weapon part connects.
if (skill_num != ASC_BREAKER || !(flag&BF_WEAPON))
@@ -384,35 +382,33 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
}
//Finally damage reductions....
- if(sc->data[SC_ASSUMPTIO].timer != -1){
+ if(sc->data[SC_ASSUMPTIO]){
if(map_flag_vs(bl->m))
damage=damage*2/3; //Receive 66% damage
else
damage>>=1; //Receive 50% damage
}
- if(sc->data[SC_DEFENDER].timer != -1 &&
+ if(sc->data[SC_DEFENDER] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
- damage=damage*(100-sc->data[SC_DEFENDER].val2)/100;
+ damage=damage*(100-sc->data[SC_DEFENDER]->val2)/100;
- if(sc->data[SC_ADJUSTMENT].timer != -1 &&
+ if(sc->data[SC_ADJUSTMENT] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage -= 20*damage/100;
- if(sc->data[SC_FOGWALL].timer != -1) {
+ if(sc->data[SC_FOGWALL]) {
if(flag&BF_SKILL) //25% reduction
damage -= 25*damage/100;
else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage >>= 2; //75% reduction
}
- if(sc->data[SC_ARMOR].timer != -1 &&
- sc->data[SC_ARMOR].val3&flag &&
- sc->data[SC_ARMOR].val4&flag)
- //NPC_DEFENDER
- damage -= damage*sc->data[SC_ARMOR].val2/100;
+ if((sce=sc->data[SC_ARMOR]) && //NPC_DEFENDER
+ sce->val3&flag && sce->val4&flag)
+ damage -= damage*sc->data[SC_ARMOR]->val2/100;
- if(sc->data[SC_ENERGYCOAT].timer!=-1 && flag&BF_WEAPON){
+ if(sc->data[SC_ENERGYCOAT] && flag&BF_WEAPON){
struct status_data *status = status_get_status_data(bl);
int per = 100*status->sp / status->max_sp -1; //100% should be counted as the 80~99% interval
per /=20; //Uses 20% SP intervals.
@@ -423,34 +419,32 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
damage -= damage * 6 * (1+per) / 100;
}
- if(sc->data[SC_REJECTSWORD].timer!=-1 && flag&BF_WEAPON &&
+ if((sce=sc->data[SC_REJECTSWORD]) && flag&BF_WEAPON &&
// Fixed the condition check [Aalye]
(src->type!=BL_PC || (
((TBL_PC *)src)->status.weapon == W_DAGGER ||
((TBL_PC *)src)->status.weapon == W_1HSWORD ||
((TBL_PC *)src)->status.weapon == W_2HSWORD
- ))
+ )) &&
+ rand()%100 < sce->val2
){
- if(rand()%100 < sc->data[SC_REJECTSWORD].val2){
- damage = damage*50/100;
- status_fix_damage(bl,src,damage,clif_damage(bl,src,gettick(),0,0,damage,0,0,0));
- clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sc->data[SC_REJECTSWORD].val1,1);
- if((--sc->data[SC_REJECTSWORD].val3)<=0)
- status_change_end(bl, SC_REJECTSWORD, -1);
- }
+ damage = damage*50/100;
+ status_fix_damage(bl,src,damage,clif_damage(bl,src,gettick(),0,0,damage,0,0,0));
+ clif_skill_nodamage(bl,bl,ST_REJECTSWORD,sce->val1,1);
+ if(--(sce->val3)<=0)
+ status_change_end(bl, SC_REJECTSWORD, -1);
}
//Finally Kyrie because it may, or not, reduce damage to 0.
- if(sc->data[SC_KYRIE].timer!=-1 && damage > 0){
- sci=&sc->data[SC_KYRIE];
- sci->val2-=damage;
+ if((sce = sc->data[SC_KYRIE]) && damage > 0){
+ sce->val2-=damage;
if(flag&BF_WEAPON || skill_num == TF_THROWSTONE){
- if(sci->val2>=0)
+ if(sce->val2>=0)
damage=0;
else
- damage=-sci->val2;
+ damage=-sce->val2;
}
- if((--sci->val3)<=0 || (sci->val2<=0) || skill_num == AL_HOLYLIGHT)
+ if((--sce->val3)<=0 || (sce->val2<=0) || skill_num == AL_HOLYLIGHT)
status_change_end(bl, SC_KYRIE, -1);
}
@@ -458,9 +452,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
//Probably not the most correct place, but it'll do here
//(since battle_drain is strictly for players currently)
- if (sc->data[SC_BLOODLUST].timer != -1 && flag&BF_WEAPON && damage > 0 &&
- rand()%100 < sc->data[SC_BLOODLUST].val3)
- status_heal(src, damage*sc->data[SC_BLOODLUST].val4/100, 0, 3);
+ if ((sce=sc->data[SC_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
+ rand()%100 < sce->val3)
+ status_heal(src, damage*sce->val4/100, 0, 3);
}
//SC effects from caster side. Currently none.
@@ -611,7 +605,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
if((skill = pc_checkskill(sd,HT_BEASTBANE)) > 0 && (status->race==RC_BRUTE || status->race==RC_INSECT) ) {
damage += (skill * 4);
- if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_HUNTER)
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_HUNTER)
damage += sd->status.str;
}
@@ -729,7 +723,7 @@ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk
}
}
- if (sc && sc->data[SC_MAXIMIZEPOWER].timer!=-1)
+ if (sc && sc->data[SC_MAXIMIZEPOWER])
atkmin = atkmax;
//Weapon Damage calculation
@@ -1009,7 +1003,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
if(tsc)
{
- if (tsc->data[SC_SLEEP].timer!=-1 )
+ if (tsc->data[SC_SLEEP])
cri <<=1;
}
switch (skill_num)
@@ -1040,7 +1034,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
} else { //Check for Perfect Hit
if(sd && sd->perfect_hit > 0 && rand()%100 < sd->perfect_hit)
flag.hit = 1;
- if (sc && sc->data[SC_FUSION].timer != -1) {
+ if (sc && sc->data[SC_FUSION]) {
flag.hit = 1; //SG_FUSION always hit [Komurka]
flag.idef = flag.idef2 = 1; //def ignore [Komurka]
}
@@ -1053,7 +1047,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
flag.hit = 1;
break;
case CR_SHIELDBOOMERANG:
- if (sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_CRUSADER)
+ if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
flag.hit = 1;
break;
case 0:
@@ -1090,7 +1084,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
hitrate+= sstatus->hit - flee;
if(wd.flag&BF_LONG && !skill_num && //Fogwall's hit penalty is only for normal ranged attacks.
- tsc && tsc->data[SC_FOGWALL].timer!=-1)
+ tsc && tsc->data[SC_FOGWALL])
hitrate -= 50;
if(sd && flag.arrow)
@@ -1166,9 +1160,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
status_zap(src, wd.damage, 0);//Damage to self is always 9%
wd.damage2 = 0;
- if (sc && sc->data[SC_SACRIFICE].timer != -1)
+ if (sc && sc->data[SC_SACRIFICE])
{
- if (--sc->data[SC_SACRIFICE].val2 <= 0)
+ if (--sc->data[SC_SACRIFICE]->val2 <= 0)
status_change_end(src, SC_SACRIFICE,-1);
}
break;
@@ -1221,9 +1215,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
i = (flag.cri?1:0)|
(flag.arrow?2:0)|
(skill_num == HW_MAGICCRASHER?4:0)|
- (!skill_num && sc && sc->data[SC_CHANGE].timer!=-1?4:0)|
+ (!skill_num && sc && sc->data[SC_CHANGE]?4:0)|
(skill_num == MO_EXTREMITYFIST?8:0)|
- (sc && sc->data[SC_WEAPONPERFECTION].timer!=-1?8:0);
+ (sc && sc->data[SC_WEAPONPERFECTION]?8:0);
if (flag.arrow && sd)
switch(sd->status.weapon) {
case W_BOW:
@@ -1267,11 +1261,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//Skill damage modifiers that stack linearly
if(sc && skill_num != PA_SACRIFICE)
{
- if(sc->data[SC_OVERTHRUST].timer != -1)
- skillratio += 5*sc->data[SC_OVERTHRUST].val1;
- if(sc->data[SC_MAXOVERTHRUST].timer != -1)
- skillratio += 20*sc->data[SC_MAXOVERTHRUST].val1;
- if(sc->data[SC_BERSERK].timer != -1)
+ if(sc->data[SC_OVERTHRUST])
+ skillratio += sc->data[SC_OVERTHRUST]->val2;
+ if(sc->data[SC_MAXOVERTHRUST])
+ skillratio += sc->data[SC_MAXOVERTHRUST]->val2;
+ if(sc->data[SC_BERSERK])
skillratio += 100;
}
if (!skill_num)
@@ -1498,7 +1492,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
break;
case TK_JUMPKICK:
skillratio += -70 + 10*skill_lv;
- if (sc && sc->data[SC_COMBO].timer != -1 && sc->data[SC_COMBO].val1 == skill_num)
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
skillratio += 10*status_get_lv(src)/3;
break;
case GS_TRIPLEACTION:
@@ -1597,29 +1591,29 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//The following are applied on top of current damage and are stackable.
if (sc) {
- if(sc->data[SC_TRUESIGHT].timer != -1)
- ATK_ADDRATE(2*sc->data[SC_TRUESIGHT].val1);
+ if(sc->data[SC_TRUESIGHT])
+ ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1);
- if(sc->data[SC_EDP].timer != -1 &&
+ if(sc->data[SC_EDP] &&
skill_num != ASC_BREAKER &&
skill_num != ASC_METEORASSAULT &&
skill_num != AS_SPLASHER &&
skill_num != AS_VENOMKNIFE)
- ATK_ADDRATE(sc->data[SC_EDP].val3);
+ ATK_ADDRATE(sc->data[SC_EDP]->val3);
}
switch (skill_num) {
case AS_SONICBLOW:
- if (sc && sc->data[SC_SPIRIT].timer != -1 &&
- sc->data[SC_SPIRIT].val2 == SL_ASSASIN)
+ if (sc && sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
ATK_ADDRATE(map_flag_gvg(src->m)?25:100); //+25% dmg on woe/+100% dmg on nonwoe
if(sd && pc_checkskill(sd,AS_SONICACCEL)>0)
ATK_ADDRATE(10);
break;
case CR_SHIELDBOOMERANG:
- if(sc && sc->data[SC_SPIRIT].timer != -1 &&
- sc->data[SC_SPIRIT].val2 == SL_CRUSADER)
+ if(sc && sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
ATK_ADDRATE(100);
break;
}
@@ -1732,8 +1726,8 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
//Post skill/vit reduction damage increases
if (sc && skill_num != LK_SPIRALPIERCE)
{ //SC skill damages
- if(sc->data[SC_AURABLADE].timer!=-1)
- ATK_ADD(20*sc->data[SC_AURABLADE].val1);
+ if(sc->data[SC_AURABLADE])
+ ATK_ADD(20*sc->data[SC_AURABLADE]->val1);
}
//Refine bonus
@@ -1767,7 +1761,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
wd.damage2 = battle_addmastery(sd,target,wd.damage2,1);
if((skill=pc_checkskill(sd,SG_STAR_ANGER)) >0 && (t_class == sd->hate_mob[2] ||
- (sc && sc->data[SC_MIRACLE].timer!=-1)))
+ (sc && sc->data[SC_MIRACLE])))
{
skillratio = sd->status.base_level + sstatus->str + sstatus->dex + sstatus->luk;
if (skill<4)
@@ -1814,11 +1808,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
if (flag.lh && wd.damage2 > 0)
wd.damage2 = battle_attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- if(sc && sc->data[SC_WATK_ELEMENT].timer != -1)
+ if(sc && sc->data[SC_WATK_ELEMENT])
{ //Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
int damage= battle_calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, (flag.arrow?2:0));
- damage = damage*sc->data[SC_WATK_ELEMENT].val2/100;
- damage = battle_attr_fix(src,target,damage,sc->data[SC_WATK_ELEMENT].val1,tstatus->def_ele, tstatus->ele_lv);
+ damage = damage*sc->data[SC_WATK_ELEMENT]->val2/100;
+ damage = battle_attr_fix(src,target,damage,sc->data[SC_WATK_ELEMENT]->val1,tstatus->def_ele, tstatus->ele_lv);
ATK_ADD(damage);
}
}
@@ -2047,9 +2041,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
{ // Self weapon breaking
int breakrate = battle_config.equip_natural_break_rate;
if (sc) {
- if(sc->data[SC_OVERTHRUST].timer!=-1)
+ if(sc->data[SC_OVERTHRUST])
breakrate += 10;
- if(sc->data[SC_MAXOVERTHRUST].timer!=-1)
+ if(sc->data[SC_MAXOVERTHRUST])
breakrate += 10;
}
if (breakrate)
@@ -2064,9 +2058,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
breakrate[1] += sd->break_armor_rate;
}
if (sc) {
- if (sc->data[SC_MELTDOWN].timer!=-1) {
- breakrate[0] += sc->data[SC_MELTDOWN].val2;
- breakrate[1] += sc->data[SC_MELTDOWN].val3;
+ if (sc->data[SC_MELTDOWN]) {
+ breakrate[0] += sc->data[SC_MELTDOWN]->val2;
+ breakrate[1] += sc->data[SC_MELTDOWN]->val3;
}
}
if (breakrate[0])
@@ -2077,7 +2071,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
//SG_FUSION hp penalty [Komurka]
- if (sc && sc->data[SC_FUSION].timer!=-1)
+ if (sc && sc->data[SC_FUSION])
{
int hp= sstatus->max_hp;
if (sd && tsd) {
@@ -2243,7 +2237,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
case AL_HOLYLIGHT:
skillratio += 25;
- if (sd && sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_PRIEST)
+ if (sd && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_PRIEST)
skillratio *= 5; //Does 5x damage include bonuses from other skills?
break;
case AL_RUWACH:
@@ -2678,27 +2672,25 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl
int battle_calc_return_damage(struct block_list* bl, int damage, int flag)
{
struct map_session_data* sd = NULL;
- struct status_change* sc;
int rdamage = 0;
BL_CAST(BL_PC, bl, sd);
- sc = status_get_sc(bl);
- if(sc && !sc->count)
- sc = NULL;
//Bounces back part of the damage.
if (flag & BF_SHORT) {
+ struct status_change* sc;
if (sd && sd->short_weapon_damage_return)
{
rdamage += damage * sd->short_weapon_damage_return / 100;
if(rdamage < 1) rdamage = 1;
}
- if (sc && sc->data[SC_REFLECTSHIELD].timer != -1)
+ sc = status_get_sc(bl);
+ if (sc && sc->data[SC_REFLECTSHIELD])
{
- rdamage += damage * sc->data[SC_REFLECTSHIELD].val2 / 100;
+ rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
if (rdamage < 1) rdamage = 1;
}
- } else if (flag & BF_LONG) {
+ } else {
if (sd && sd->long_weapon_damage_return)
{
rdamage += damage * sd->long_weapon_damage_return / 100;
@@ -2823,14 +2815,13 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
}
- if (sc && sc->data[SC_CLOAKING].timer != -1 && !(sc->data[SC_CLOAKING].val4&2))
+ if (sc && sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&2))
status_change_end(src,SC_CLOAKING,-1);
//Check for counter attacks that block your attack. [Skotlex]
if(tsc)
{
- if(tsc->data[SC_AUTOCOUNTER].timer != -1 &&
- (!sc || sc->data[SC_AUTOCOUNTER].timer == -1) &&
+ if(tsc->data[SC_AUTOCOUNTER] &&
status_check_skilluse(target, src, KN_AUTOCOUNTER, 1)
) {
int dir = map_calc_dir(target,src->x,src->y);
@@ -2838,7 +2829,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
int dist = distance_bl(src, target);
if(dist <= 0 || (!map_check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1))
{
- int skilllv = tsc->data[SC_AUTOCOUNTER].val1;
+ int skilllv = tsc->data[SC_AUTOCOUNTER]->val1;
clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
status_change_end(target,SC_AUTOCOUNTER,-1);
@@ -2846,8 +2837,8 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
return 0;
}
}
- if (tsc->data[SC_BLADESTOP_WAIT].timer != -1 && !is_boss(src)) {
- int skilllv = tsc->data[SC_BLADESTOP_WAIT].val1;
+ if (tsc->data[SC_BLADESTOP_WAIT] && !is_boss(src)) {
+ int skilllv = tsc->data[SC_BLADESTOP_WAIT]->val1;
int duration = skill_get_time2(MO_BLADESTOP,skilllv);
status_change_end(target, SC_BLADESTOP_WAIT, -1);
if(sc_start4(src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, (int)target, duration))
@@ -2863,9 +2854,9 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if(sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0)
{
int triple_rate= 30 - skillv; //Base Rate
- if (sc && sc->data[SC_SKILLRATE_UP].timer!=-1 && sc->data[SC_SKILLRATE_UP].val1 == MO_TRIPLEATTACK)
+ if (sc && sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == MO_TRIPLEATTACK)
{
- triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP].val2)/100;
+ triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP]->val2)/100;
status_change_end(src,SC_SKILLRATE_UP,-1);
}
if (rand()%100 < triple_rate)
@@ -2874,10 +2865,10 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
if (sc)
{
- if (sc->data[SC_SACRIFICE].timer != -1)
- return skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,sc->data[SC_SACRIFICE].val1,tick,0);
- if (sc->data[SC_MAGICALATTACK].timer != -1)
- return skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK].val1,tick,0);
+ if (sc->data[SC_SACRIFICE])
+ return skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,sc->data[SC_SACRIFICE]->val1,tick,0);
+ if (sc->data[SC_MAGICALATTACK])
+ return skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0);
}
wd = battle_calc_weapon_attack(src, target, 0, 0, flag);
@@ -2908,12 +2899,12 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
battle_delay_damage(tick+wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
- if (sc && sc->data[SC_AUTOSPELL].timer != -1 && rand()%100 < sc->data[SC_AUTOSPELL].val4) {
+ if (sc && sc->data[SC_AUTOSPELL] && rand()%100 < sc->data[SC_AUTOSPELL]->val4) {
int sp = 0;
- int skillid = sc->data[SC_AUTOSPELL].val2;
- int skilllv = sc->data[SC_AUTOSPELL].val3;
+ int skillid = sc->data[SC_AUTOSPELL]->val2;
+ int skilllv = sc->data[SC_AUTOSPELL]->val3;
int i = rand()%100;
- if (sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_SAGE)
+ if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_SAGE)
i = 0; //Max chance, no skilllv reduction. [Skotlex]
if (i >= 50) skilllv -= 2;
else if (i >= 15) skilllv--;
@@ -2949,20 +2940,21 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if (tsc) {
- if (tsc->data[SC_POISONREACT].timer != -1 &&
- (rand()%100 < tsc->data[SC_POISONREACT].val3
+ if (tsc->data[SC_POISONREACT] &&
+ (rand()%100 < tsc->data[SC_POISONREACT]->val3
|| sstatus->def_ele == ELE_POISON) &&
// check_distance_bl(src, target, tstatus->rhw.range+1) && Doesn't checks range! o.O;
status_check_skilluse(target, src, TF_POISON, 0)
) { //Poison React
+ struct status_change_entry *sce = tsc->data[SC_POISONREACT];
if (sstatus->def_ele == ELE_POISON) {
- tsc->data[SC_POISONREACT].val2 = 0;
- skill_attack(BF_WEAPON,target,target,src,AS_POISONREACT,tsc->data[SC_POISONREACT].val1,tick,0);
+ sce->val2 = 0;
+ skill_attack(BF_WEAPON,target,target,src,AS_POISONREACT,sce->val1,tick,0);
} else {
skill_attack(BF_WEAPON,target,target,src,TF_POISON, 5, tick, 0);
- --tsc->data[SC_POISONREACT].val2;
+ --sce->val2;
}
- if (tsc->data[SC_POISONREACT].val2 <= 0)
+ if (sce->val2 <= 0)
status_change_end(target, SC_POISONREACT, -1);
}
}
diff --git a/src/map/charcommand.c b/src/map/charcommand.c
index 08aa5ead2..e44954a4c 100644
--- a/src/map/charcommand.c
+++ b/src/map/charcommand.c
@@ -2830,17 +2830,17 @@ int charcommand_jailtime(const int fd, struct map_session_data* sd, const char*
return -1;
}
- if (pl_sd->sc.data[SC_JAILED].val1 == INT_MAX) {
+ if (pl_sd->sc.data[SC_JAILED]->val1 == INT_MAX) {
clif_displaymessage(fd, "You have been jailed indefinitely.");
return 0;
}
- if (pl_sd->sc.data[SC_JAILED].val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
+ if (pl_sd->sc.data[SC_JAILED]->val1 <= 0) { // Was not jailed with @jailfor (maybe @jail? or warped there? or got recalled?)
clif_displaymessage(fd, "This player has been jailed for an unknown amount of time.");
return -1;
}
//Get remaining jail time
- get_jail_time(pl_sd->sc.data[SC_JAILED].val1,&year,&month,&day,&hour,&minute);
+ get_jail_time(pl_sd->sc.data[SC_JAILED]->val1,&year,&month,&day,&hour,&minute);
sprintf(output,msg_txt(402),"This player will remain",year,month,day,hour,minute);
clif_displaymessage(fd, output);
@@ -3861,7 +3861,7 @@ bool is_charcommand(const int fd, struct map_session_data* sd, const char* messa
if( !message || !*message )
return false;
- if( sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCOMMAND )
+ if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCOMMAND )
return true; // so that it won't display as normal message
if( battle_config.atc_gmonly != 0 && gmlvl == 0 )
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 0f4df2544..03bed41b1 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -1022,6 +1022,7 @@ int chrif_save_scdata(struct map_session_data *sd)
int i, count=0;
unsigned int tick;
struct status_change_data data;
+ struct status_change *sc = &sd->sc;
const struct TimerData *timer;
if (sd->state.finalsave) //Character was already saved?
@@ -1036,17 +1037,21 @@ int chrif_save_scdata(struct map_session_data *sd)
WFIFOL(char_fd,8) = sd->status.char_id;
for (i = 0; i < SC_MAX; i++)
{
- if (sd->sc.data[i].timer == -1)
+ if (!sc->data[i])
continue;
- timer = get_timer(sd->sc.data[i].timer);
- if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
- continue;
- data.tick = DIFF_TICK(timer->tick,tick); //Duration that is left before ending.
+ if (sc->data[i]->timer != -1)
+ {
+ timer = get_timer(sc->data[i]->timer);
+ if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
+ continue;
+ data.tick = DIFF_TICK(timer->tick,tick); //Duration that is left before ending.
+ } else
+ data.tick = -1; //Infinite duration
data.type = i;
- data.val1 = sd->sc.data[i].val1;
- data.val2 = sd->sc.data[i].val2;
- data.val3 = sd->sc.data[i].val3;
- data.val4 = sd->sc.data[i].val4;
+ data.val1 = sc->data[i]->val1;
+ data.val2 = sc->data[i]->val2;
+ data.val3 = sc->data[i]->val3;
+ data.val4 = sc->data[i]->val4;
memcpy(WFIFOP(char_fd,14 +count*sizeof(struct status_change_data)),
&data, sizeof(struct status_change_data));
count++;
@@ -1086,11 +1091,6 @@ int chrif_load_scdata(int fd)
for (i = 0; i < count; i++)
{
data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
- if (data->tick < 1)
- { //Protection against invalid tick values. [Skotlex]
- ShowWarning("chrif_load_scdata: Received invalid duration (%d ms) for status change %d (character %s)\n", data->tick, data->type, sd->status.name);
- continue;
- }
status_change_start(&sd->bl, data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
}
#endif
diff --git a/src/map/clif.c b/src/map/clif.c
index 0e1d11e35..ff78a8f3f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -3675,11 +3675,11 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
sc = status_get_sc(dst);
if(sc && sc->count) {
- if(type != 4 && dst->type == BL_PC && sc->data[SC_ENDURE].timer != -1 && !map_flag_gvg(dst->m))
+ if(type != 4 && dst->type == BL_PC && sc->data[SC_ENDURE] && !map_flag_gvg(dst->m))
type = 9;
- if(sc->data[SC_HALLUCINATION].timer != -1) {
- if(damage > 0) damage = damage*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
- if(damage2 > 0) damage2 = damage2*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
+ if(sc->data[SC_HALLUCINATION]) {
+ if(damage) damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rand()%100;
+ if(damage2) damage2 = damage2*(sc->data[SC_HALLUCINATION]->val2) + rand()%100;
}
}
@@ -4246,10 +4246,10 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
sc = status_get_sc(dst);
if(sc && sc->count) {
- if(type != 4 && dst->type == BL_PC && sc->data[SC_ENDURE].timer != -1 && !map_flag_gvg(dst->m))
+ if(type != 4 && dst->type == BL_PC && sc->data[SC_ENDURE] && !map_flag_gvg(dst->m))
type = 9;
- if(sc->data[SC_HALLUCINATION].timer != -1 && damage > 0)
- damage = damage*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
+ if(sc->data[SC_HALLUCINATION] && damage)
+ damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rand()%100;
}
#if PACKETVER < 3
@@ -4337,8 +4337,8 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in
sc = status_get_sc(dst);
if(sc && sc->count) {
- if(sc->data[SC_HALLUCINATION].timer != -1 && damage > 0)
- damage = damage*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
+ if(sc->data[SC_HALLUCINATION] && damage)
+ damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rand()%100;
}
WBUFW(buf,0)=0x115;
@@ -8084,7 +8084,7 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
else if (pc_cant_act(sd))
return;
- if(sd->sc.count && sd->sc.data[SC_RUN].timer != -1)
+ if(sd->sc.data[SC_RUN])
return;
pc_delinvincibletimer(sd);
@@ -8109,7 +8109,7 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
WFIFOW(fd,0) = 0x18b;
/* Rovert's prevent logout option fixed [Valaris] */
- if (sd->sc.data[SC_CLOAKING].timer==-1 && sd->sc.data[SC_HIDING].timer==-1 &&
+ if (!sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] &&
(!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
) {
clif_setwaitclose(fd);
@@ -8176,7 +8176,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
if( is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
- if( sd->sc.data[SC_BERSERK].timer != -1 || (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
@@ -8355,9 +8355,9 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
}
if (sd->sc.count &&
- (sd->sc.data[SC_TRICKDEAD].timer != -1 ||
- sd->sc.data[SC_AUTOCOUNTER].timer != -1 ||
- sd->sc.data[SC_BLADESTOP].timer != -1))
+ (sd->sc.data[SC_TRICKDEAD] ||
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_BLADESTOP]))
return;
pc_stop_walking(sd, 1);
@@ -8404,8 +8404,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
break;
if (sd->sc.count && (
- sd->sc.data[SC_DANCING].timer != -1 ||
- (sd->sc.data[SC_GRAVITATION].timer != -1 && sd->sc.data[SC_GRAVITATION].val3 == BCT_SELF)
+ sd->sc.data[SC_DANCING] ||
+ (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF)
)) //No sitting during these states either.
break;
@@ -8487,7 +8487,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
if (is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
- if (sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT))
+ if (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
return;
if (battle_config.min_chat_delay)
@@ -8665,9 +8665,9 @@ void clif_parse_TakeItem(int fd, struct map_session_data *sd)
break;
if(sd->sc.count && (
- sd->sc.data[SC_TRICKDEAD].timer != -1 ||
- sd->sc.data[SC_BLADESTOP].timer != -1 ||
- (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOITEM))
+ sd->sc.data[SC_TRICKDEAD] ||
+ sd->sc.data[SC_BLADESTOP] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM))
)
break;
@@ -8696,9 +8696,9 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd)
return;
if (sd->sc.count && (
- sd->sc.data[SC_AUTOCOUNTER].timer != -1 ||
- sd->sc.data[SC_BLADESTOP].timer != -1 ||
- (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOITEM)
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_BLADESTOP] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
))
return;
@@ -8768,7 +8768,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
else if (pc_cant_act(sd))
return;
- if(sd->sc.data[SC_BLADESTOP].timer!=-1 || sd->sc.data[SC_BERSERK].timer!=-1 )
+ if(sd->sc.data[SC_BLADESTOP] || sd->sc.data[SC_BERSERK])
return;
if(!sd->status.inventory[index].identify) {
@@ -8916,7 +8916,7 @@ void clif_parse_CreateChatRoom(int fd, struct map_session_data* sd)
char s_title[CHATROOM_TITLE_SIZE];
char s_password[CHATROOM_PASS_SIZE];
- if (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOROOM)
+ if (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM)
return;
if(battle_config.basic_skill_check && pc_checkskill(sd,NV_BASIC) < 4) {
clif_skill_fail(sd,1,0,3);
@@ -9241,10 +9241,10 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
sd->skillitem = sd->skillitemlv = 0;
if (skillnum == MO_EXTREMITYFIST) {
- if ((sd->sc.data[SC_COMBO].timer == -1 ||
- (sd->sc.data[SC_COMBO].val1 != MO_COMBOFINISH &&
- sd->sc.data[SC_COMBO].val1 != CH_TIGERFIST &&
- sd->sc.data[SC_COMBO].val1 != CH_CHAINCRUSH))) {
+ if ((!sd->sc.data[SC_COMBO] ||
+ (sd->sc.data[SC_COMBO]->val1 != MO_COMBOFINISH &&
+ sd->sc.data[SC_COMBO]->val1 != CH_TIGERFIST &&
+ sd->sc.data[SC_COMBO]->val1 != CH_CHAINCRUSH))) {
if (!sd->state.skill_flag ) {
sd->state.skill_flag = 1;
clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1);
@@ -9256,8 +9256,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
}
}
if (skillnum == TK_JUMPKICK) {
- if (sd->sc.data[SC_COMBO].timer == -1 ||
- sd->sc.data[SC_COMBO].val1 != TK_JUMPKICK) {
+ if (!sd->sc.data[SC_COMBO] || sd->sc.data[SC_COMBO]->val1 != TK_JUMPKICK) {
if (!sd->state.skill_flag ) {
sd->state.skill_flag = 1;
clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1);
@@ -9893,7 +9892,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
if( is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
- if( sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
@@ -9950,7 +9949,7 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd)
bool flag = (bool)RFIFOB(fd,84);
const uint8* data = (uint8*)RFIFOP(fd,85);
- if( sd->sc.data[SC_NOCHAT].timer != -1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOROOM )
+ if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM )
return;
if( map[sd->bl.m].flag.novending || map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOVENDING) ) {
clif_displaymessage (sd->fd, msg_txt(276)); // "You can't open shop on this map"
@@ -10165,7 +10164,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
if( is_atcommand(fd, sd, message) || is_charcommand(fd, sd, message) )
return;
- if( sd->sc.data[SC_BERSERK].timer!=-1 || (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
diff --git a/src/map/map.c b/src/map/map.c
index 5cff144b9..d113e8a6d 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -454,17 +454,17 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
skill_unit_move(bl,tick,2);
sc = status_get_sc(bl);
if (sc && sc->count) {
- 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);
-// if (sc->data[SC_BLADESTOP].timer != -1) //Won't stop when you are knocked away, go figure...
+// if (sc->data[SC_BLADESTOP]) //Won't stop when you are knocked away, go figure...
// status_change_end(bl, SC_BLADESTOP, -1);
- if (sc->data[SC_BASILICA].timer != -1)
+ if (sc->data[SC_BASILICA])
status_change_end(bl, SC_BASILICA, -1);
- if (sc->data[SC_TATAMIGAESHI].timer != -1)
+ if (sc->data[SC_TATAMIGAESHI])
status_change_end(bl, SC_TATAMIGAESHI, -1);
- if (sc->data[SC_MAGICROD].timer != -1)
+ if (sc->data[SC_MAGICROD])
status_change_end(bl, SC_MAGICROD, -1);
}
} else
@@ -484,12 +484,12 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
skill_unit_move(bl,tick,3);
if (sc) {
if (sc->count) {
- if (sc->data[SC_CLOAKING].timer != -1)
- skill_check_cloaking(bl, sc);
- if (sc->data[SC_DANCING].timer != -1)
- skill_unit_move_unit_group((struct skill_unit_group *)sc->data[SC_DANCING].val2, bl->m, x1-x0, y1-y0);
- if (sc->data[SC_WARM].timer != -1)
- skill_unit_move_unit_group((struct skill_unit_group *)sc->data[SC_WARM].val4, bl->m, x1-x0, y1-y0);
+ if (sc->data[SC_CLOAKING])
+ skill_check_cloaking(bl, sc->data[SC_CLOAKING]);
+ if (sc->data[SC_DANCING])
+ skill_unit_move_unit_group((struct skill_unit_group *)sc->data[SC_DANCING]->val2, bl->m, x1-x0, y1-y0);
+ if (sc->data[SC_WARM])
+ skill_unit_move_unit_group((struct skill_unit_group *)sc->data[SC_WARM]->val4, bl->m, x1-x0, y1-y0);
}
}
} else
@@ -3073,6 +3073,7 @@ void do_final(void)
do_final_guild();
do_final_party();
do_final_pc();
+ do_final_status();
do_final_pet();
do_final_mob();
do_final_msg();
diff --git a/src/map/map.h b/src/map/map.h
index 6f3b27c2b..dcc2412d1 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -374,12 +374,17 @@ struct status_change_entry {
};
struct status_change {
- struct status_change_entry data[SC_MAX];
- short count;
+ unsigned int option;// effect state
+ unsigned int opt3;// skill state
unsigned short opt1;// body state
unsigned short opt2;// health state
- unsigned int opt3;
- unsigned int option;// effect state
+ unsigned char count;
+ //TODO: See if it is possible to implement the following SC's without requiring extra parameters while the SC is inactive.
+ unsigned char jb_flag; //Joint Beat type flag
+ unsigned short mp_matk_min, mp_matk_max; //Previous matk min/max for ground spells (Amplify magic power)
+ int sg_id; //ID of the previous Storm gust that hit you
+ unsigned char sg_counter; //Storm gust counter (previous hits from storm gust)
+ struct status_change_entry *data[SC_MAX];
};
struct s_vending {
diff --git a/src/map/mob.c b/src/map/mob.c
index 00ef6f794..d38e4b098 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1141,13 +1141,13 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
return 0;
// Abnormalities
- if((md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT) || md->sc.data[SC_BLADESTOP].timer != -1)
+ if((md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT) || md->sc.data[SC_BLADESTOP])
{ //Should reset targets.
md->target_id = md->attacked_id = 0;
return 0;
}
- if (md->sc.count && md->sc.data[SC_BLIND].timer != -1)
+ if (md->sc.count && md->sc.data[SC_BLIND])
view_range = 3;
else
view_range = md->db->range2;
@@ -1181,7 +1181,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
if (!battle_check_range(&md->bl, tbl, md->status.rhw.range) &&
( //Can't attack back and can't reach back.
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 &&
- (battle_config.mob_ai&0x2 || md->sc.data[SC_SPIDERWEB].timer != -1)) ||
+ (battle_config.mob_ai&0x2 || md->sc.data[SC_SPIDERWEB])) ||
(!mob_can_reach(md, tbl, md->min_chase, MSS_RUSH))
) &&
md->state.attacked_count++ >= RUDE_ATTACKED_COUNT &&
@@ -1200,7 +1200,7 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
(!battle_check_range(&md->bl, abl, md->status.rhw.range) &&
( //Reach check
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 &&
- (battle_config.mob_ai&0x2 || md->sc.data[SC_SPIDERWEB].timer != -1)) ||
+ (battle_config.mob_ai&0x2 || md->sc.data[SC_SPIDERWEB])) ||
!mob_can_reach(md, abl, dist+md->db->range3, MSS_RUSH)
)
)
@@ -1787,9 +1787,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
md->state.skillstate = MSS_DEAD;
mobskill_use(md,tick,-1); //On Dead skill.
- if (md->sc.data[SC_KAIZEL].timer != -1)
+ if (md->sc.data[SC_KAIZEL])
{ //Revive in a bit.
- add_timer(gettick()+3000, mob_respawn, md->bl.id, 10*md->sc.data[SC_KAIZEL].val1); //% of life to rebirth with
+ add_timer(gettick()+3000, mob_respawn, md->bl.id, md->sc.data[SC_KAIZEL]->val2); //% of life to rebirth with
map_delblock(&md->bl);
return 1; //Return 1 to only clear the object.
}
@@ -1900,8 +1900,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
bonus = 100;
- if (md->sc.data[SC_RICHMANKIM].timer != -1)
- bonus += md->sc.data[SC_RICHMANKIM].val2;
+ if (md->sc.data[SC_RICHMANKIM])
+ bonus += md->sc.data[SC_RICHMANKIM]->val2;
if(battle_config.mobs_level_up && md->level > md->db->lv) // [Valaris]
bonus += (md->level-md->db->lv)*battle_config.mobs_level_up_exp_rate;
@@ -2017,13 +2017,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
// attempt to drop the item
if (rand() % 10000 >= drop_rate)
- {
- if (sd && sd->sc.data[SC_ITEMBOOST].timer != -1)
- {
- if (rand() % 10000 >= drop_rate)
- continue; // Double try by Bubble Gum
- }
- else
+ { // Double try by Bubble Gum
+ if (!(sd && sd->sc.data[SC_ITEMBOOST] && rand() % 10000 < drop_rate))
continue;
}
@@ -2667,11 +2662,11 @@ int mob_getfriendstatus_sub(struct block_list *bl,va_list ap)
if( cond2==-1 ){
int j;
for(j=SC_COMMON_MIN;j<=SC_COMMON_MAX && !flag;j++){
- if ((flag=(md->sc.data[j].timer!=-1))) //Once an effect was found, break out. [Skotlex]
+ if ((flag=(md->sc.data[j] != NULL))) //Once an effect was found, break out. [Skotlex]
break;
}
}else
- flag=( md->sc.data[cond2].timer!=-1 );
+ flag=( md->sc.data[cond2] != NULL );
if( flag^( cond1==MSC_FRIENDSTATUSOFF ) )
(*fr)=md;
@@ -2755,10 +2750,10 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
flag = 0;
} else if (ms[i].cond2 == -1) {
for (j = SC_COMMON_MIN; j <= SC_COMMON_MAX; j++)
- if ((flag = (md->sc.data[j].timer != -1)) != 0)
+ if ((flag = (md->sc.data[j]!=NULL)) != 0)
break;
} else {
- flag = (md->sc.data[ms[i].cond2].timer != -1);
+ flag = (md->sc.data[ms[i].cond2]!=NULL);
}
flag ^= (ms[i].cond1 == MSC_MYSTATUSOFF); break;
case MSC_FRIENDHPLTMAXRATE: // friend HP < maxhp%
@@ -3236,7 +3231,7 @@ static bool mob_parse_dbrow(char** str)
}
if (mob_db_data[class_] == NULL)
- mob_db_data[class_] = aCalloc(1, sizeof (struct mob_data));
+ mob_db_data[class_] = aCalloc(1, sizeof (struct mob_db));
db = mob_db_data[class_];
status = &db->status;
diff --git a/src/map/party.c b/src/map/party.c
index 70fdafe97..772fd9ab6 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -663,7 +663,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, int skillid, in
break;
case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
- && sd->sc.data[SC_READYCOUNTER].timer != -1
+ && sd->sc.data[SC_READYCOUNTER]
&& pc_checkskill(p_sd,SG_FRIEND)) {
sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
50+50*pc_checkskill(p_sd,SG_FRIEND), //+100/150/200% rate
diff --git a/src/map/pc.c b/src/map/pc.c
index 913f108d0..1dcf97fda 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -339,7 +339,7 @@ int pc_makesavestatus(struct map_session_data *sd)
//status change load/saving. [Skotlex]
sd->status.option = sd->sc.option&(OPTION_CART|OPTION_FALCON|OPTION_RIDING);
- if (sd->sc.count && sd->sc.data[SC_JAILED].timer != -1)
+ if (sd->sc.data[SC_JAILED])
{ //When Jailed, do not move last point.
if(pc_isdead(sd)){
pc_setrestartvalue(sd,0);
@@ -563,16 +563,16 @@ int pc_isequip(struct map_session_data *sd,int n)
return 0;
if (sd->sc.count) {
- if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON].timer != -1) // Also works with left-hand weapons [DracoRPG]
+ if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
return 0;
- if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD].timer != -1)
+ if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD])
return 0;
- if(item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR].timer != -1)
+ if(item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR])
return 0;
- if(item->equip & EQP_HELM && sd->sc.data[SC_STRIPHELM].timer != -1)
+ if(item->equip & EQP_HELM && sd->sc.data[SC_STRIPHELM])
return 0;
- if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_SUPERNOVICE) {
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SUPERNOVICE) {
//Spirit of Super Novice equip bonuses. [Skotlex]
if (sd->status.base_level > 90 && item->equip & EQP_HELM)
return 1; //Can equip all helms
@@ -964,7 +964,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[i].lv=(sd->status.skill[i].flag==1)?0:sd->status.skill[i].flag-2;
sd->status.skill[i].flag=0;
}
- if(sd->sc.count && sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU)
+ if(sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU)
{ //Enable Bard/Dancer spirit linked skills.
if (sd->status.sex) { //Link dancer skills to bard.
sd->status.skill[i].id=i;
@@ -1024,7 +1024,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
if(!sd->status.skill[id].lv && (
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
inf2&INF2_WEDDING_SKILL ||
- (inf2&INF2_SPIRIT_SKILL && !(sd->sc.count && sd->sc.data[SC_SPIRIT].timer != -1))
+ (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
))
continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
@@ -1106,7 +1106,7 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill)
if(!sd->status.skill[id].lv && (
(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
j&INF2_WEDDING_SKILL ||
- (j&INF2_SPIRIT_SKILL && !(sd->sc.count && sd->sc.data[SC_SPIRIT].timer != -1))
+ (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
))
continue; //Cannot be learned via normal means.
@@ -1177,7 +1177,7 @@ int pc_updateweightstatus(struct map_session_data *sd)
nullpo_retr(1, sd);
- old_overweight = (sd->sc.data[SC_WEIGHT90].timer != -1) ? 2 : (sd->sc.data[SC_WEIGHT50].timer != -1) ? 1 : 0;
+ old_overweight = (sd->sc.data[SC_WEIGHT90]) ? 2 : (sd->sc.data[SC_WEIGHT50]) ? 1 : 0;
new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is50overweight(sd)) ? 1 : 0;
if( old_overweight == new_overweight )
@@ -3092,12 +3092,12 @@ int pc_useitem(struct map_session_data *sd,int n)
return 0;
if (sd->sc.count && (
- sd->sc.data[SC_BERSERK].timer!=-1 ||
- sd->sc.data[SC_MARIONETTE].timer!=-1 ||
- (sd->sc.data[SC_GRAVITATION].timer!=-1 && sd->sc.data[SC_GRAVITATION].val3 == BCT_SELF) ||
- sd->sc.data[SC_TRICKDEAD].timer != -1 ||
- sd->sc.data[SC_BLADESTOP].timer != -1 ||
- (sd->sc.data[SC_NOCHAT].timer!=-1 && sd->sc.data[SC_NOCHAT].val1&MANNER_NOITEM)
+ sd->sc.data[SC_BERSERK] ||
+ sd->sc.data[SC_MARIONETTE] ||
+ (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) ||
+ sd->sc.data[SC_TRICKDEAD] ||
+ sd->sc.data[SC_BLADESTOP] ||
+ (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
))
return 0;
@@ -3123,7 +3123,7 @@ int pc_useitem(struct map_session_data *sd,int n)
pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST))
{
potion_flag = 2; // Famous player's potions have 50% more efficiency
- if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_ROGUE)
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE)
potion_flag = 3; //Even more effective potions.
}
@@ -3399,7 +3399,7 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
return 0;
md = (TBL_MOB*)target;
- if(md->state.steal_coin_flag || md->sc.data[SC_STONE].timer != -1 || md->sc.data[SC_FREEZE].timer != -1)
+ if(md->state.steal_coin_flag || md->sc.data[SC_STONE] || md->sc.data[SC_FREEZE])
return 0;
if (md->class_>=1324 && md->class_<1364)
@@ -3439,19 +3439,21 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
{ //Misc map-changing settings
if (sd->sc.count)
{ //Cancel some map related stuff.
- if (sd->sc.data[SC_JAILED].timer != -1)
+ if (sd->sc.data[SC_JAILED])
return 1; //You may not get out!
- if (sd->sc.data[SC_WARM].timer != -1)
+ if (sd->sc.data[SC_WARM])
status_change_end(&sd->bl,SC_WARM,-1);
- if (sd->sc.data[SC_SUN_COMFORT].timer != -1)
+ if (sd->sc.data[SC_SUN_COMFORT])
status_change_end(&sd->bl,SC_SUN_COMFORT,-1);
- if (sd->sc.data[SC_MOON_COMFORT].timer != -1)
+ if (sd->sc.data[SC_MOON_COMFORT])
status_change_end(&sd->bl,SC_MOON_COMFORT,-1);
- if (sd->sc.data[SC_STAR_COMFORT].timer != -1)
+ if (sd->sc.data[SC_STAR_COMFORT])
status_change_end(&sd->bl,SC_STAR_COMFORT,-1);
- if (sd->sc.data[SC_KNOWLEDGE].timer != -1) {
- delete_timer(sd->sc.data[SC_KNOWLEDGE].timer, status_change_timer);
- sd->sc.data[SC_KNOWLEDGE].timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sd->sc.data[SC_KNOWLEDGE].val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE);
+ if (sd->sc.data[SC_KNOWLEDGE]) {
+ struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE];
+ if (sce->timer != -1)
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(gettick() + skill_get_time(SG_KNOWLEDGE, sce->val1), status_change_timer, sd->bl.id, SC_KNOWLEDGE);
}
}
if (battle_config.clear_unit_onwarp&BL_PC)
@@ -3677,18 +3679,18 @@ int pc_checkallowskill(struct map_session_data *sd)
for (i = 0; i < ARRAYLENGTH(scw_list); i++)
{ // Skills requiring specific weapon types
- if(sd->sc.data[scw_list[i]].timer!=-1 &&
+ if(sd->sc.data[scw_list[i]] &&
!pc_check_weapontype(sd,skill_get_weapontype(StatusSkillChangeTable[scw_list[i]])))
status_change_end(&sd->bl,scw_list[i],-1);
}
- if(sd->sc.data[SC_SPURT].timer!=-1 && sd->status.weapon)
+ if(sd->sc.data[SC_SPURT] && sd->status.weapon)
// Spurt requires bare hands (feet, in fact xD)
status_change_end(&sd->bl,SC_SPURT,-1);
if(sd->status.shield <= 0) { // Skills requiring a shield
for (i = 0; i < ARRAYLENGTH(scs_list); i++)
- if(sd->sc.data[scs_list[i]].timer!=-1)
+ if(sd->sc.data[scs_list[i]])
status_change_end(&sd->bl,scs_list[i],-1);
}
return 0;
@@ -4199,7 +4201,7 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
//SG additional exp from Blessings [Komurka] - probably can be optimalized ^^;;
temp = status_get_class(src);
if(temp == sd->hate_mob[2] &&
- (battle_config.allow_skill_without_day || is_day_of_star() || sd->sc.data[SC_MIRACLE].timer!=-1))
+ (battle_config.allow_skill_without_day || is_day_of_star() || sd->sc.data[SC_MIRACLE]))
bonus += 20*pc_checkskill(sd,SG_STAR_BLESS);
else
if(temp == sd->hate_mob[1] &&
@@ -4214,8 +4216,8 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
(int)(status_get_lv(src) - sd->status.base_level) >= 20)
bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
- if (sd->sc.data[SC_EXPBOOST].timer != -1)
- bonus += sd->sc.data[SC_EXPBOOST].val1;
+ if (sd->sc.data[SC_EXPBOOST])
+ bonus += sd->sc.data[SC_EXPBOOST]->val1;
if (!bonus)
return;
@@ -5104,7 +5106,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
if(battle_config.death_penalty_type && sd->state.snovice_dead_flag != 1
&& (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
&& !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
- && sd->sc.data[SC_BABY].timer == -1 && sd->sc.data[SC_LIFEINSURANCE].timer == -1)
+ && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
{
unsigned int base_penalty =0;
if (battle_config.death_penalty_base > 0) {
@@ -5228,16 +5230,17 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
return 1;
}
- if (sd->sc.count && sd->sc.data[SC_KAIZEL].timer != -1)
+ if (sd->sc.data[SC_KAIZEL])
{
- j = sd->sc.data[SC_KAIZEL].val1; //Kaizel Lv.
+ j = sd->sc.data[SC_KAIZEL]->val1; //Kaizel Lv.
+ i = sd->sc.data[SC_KAIZEL]->val2; //Revive %
pc_setstand(sd);
status_change_clear(&sd->bl,0);
clif_skill_nodamage(&sd->bl,&sd->bl,ALL_RESURRECTION,1,1);
if(sd->special_state.restart_full_recover)
status_percent_heal(&sd->bl, 100, 100);
else
- status_percent_heal(&sd->bl, 10*j, 0);
+ status_percent_heal(&sd->bl, i, 0);
clif_resurrection(&sd->bl, 1);
if(battle_config.pc_invincible_time)
pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
@@ -5489,8 +5492,8 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
hp = hp * bonus / 100;
// Recovery Potion
- if( sd->sc.count && sd->sc.data[SC_INCHEALRATE].timer!=-1 )
- hp += (int)(hp * sd->sc.data[SC_INCHEALRATE].val1/100.);
+ if( sd->sc.data[SC_INCHEALRATE] )
+ hp += (int)(hp * sd->sc.data[SC_INCHEALRATE]->val1/100.);
}
if(sp) {
bonus = 100 + (sd->battle_status.int_<<1)
@@ -5502,10 +5505,10 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
sp = sp * bonus / 100;
}
- if (sd->sc.count && sd->sc.data[SC_CRITICALWOUND].timer!=-1)
+ if (sd->sc.data[SC_CRITICALWOUND])
{
- hp -= hp * sd->sc.data[SC_CRITICALWOUND].val2 / 100;
- sp -= sp * sd->sc.data[SC_CRITICALWOUND].val2 / 100;
+ hp -= hp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
+ sp -= sp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
}
return status_heal(&sd->bl, hp, sp, 1);
@@ -5606,7 +5609,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
for(i = 0; i < MAX_SKILL_TREE && (id = skill_tree[class_][i].id) > 0; i++) {
//Remove status specific to your current tree skills.
id = SkillStatusChangeTable(id);
- if (id > SC_COMMON_MAX && sd->sc.data[id].timer != -1)
+ if (id > SC_COMMON_MAX && sd->sc.data[id])
status_change_end(&sd->bl, id, -1);
}
}
@@ -6372,7 +6375,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
// -- moonsoul (if player is berserk then cannot equip)
//
- if(sd->sc.count && sd->sc.data[SC_BERSERK].timer!=-1){
+ if(sd->sc.data[SC_BERSERK]){
clif_equipitemack(sd,n,0,0); // fail
return 0;
}
@@ -6513,7 +6516,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
// -- moonsoul (if player is berserk then cannot unequip)
//
- if(!(flag&2) && sd->sc.count && (sd->sc.data[SC_BLADESTOP].timer!=-1 || sd->sc.data[SC_BERSERK].timer!=-1)){
+ if(!(flag&2) && sd->sc.count && (sd->sc.data[SC_BLADESTOP] || sd->sc.data[SC_BERSERK])){
clif_unequipitemack(sd,n,0,0);
return 0;
}
@@ -6535,7 +6538,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
sd->status.weapon = sd->weapontype2;
pc_calcweapontype(sd);
clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
- if(sd->sc.data[SC_DANCING].timer!=-1) //When unequipping, stop dancing. [Skotlex]
+ if(sd->sc.data[SC_DANCING]) //When unequipping, stop dancing. [Skotlex]
skill_stop_dancing(&sd->bl);
}
if(sd->status.inventory[n].equip & EQP_HAND_L) {
@@ -6571,7 +6574,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
status_calc_pc(sd,0);
}
- if(sd->sc.count && sd->sc.data[SC_SIGNUMCRUCIS].timer != -1 && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
+ if(sd->sc.data[SC_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
status_change_end(&sd->bl,SC_SIGNUMCRUCIS,-1);
//OnUnEquip script [Skotlex]
@@ -7091,7 +7094,7 @@ int map_night_timer(int tid, unsigned int tick, int id, int data)
void pc_setstand(struct map_session_data *sd){
nullpo_retv(sd);
- if(sd->sc.count && sd->sc.data[SC_TENSIONRELAX].timer!=-1)
+ if(sd->sc.data[SC_TENSIONRELAX])
status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
//Reset sitting tick.
diff --git a/src/map/pet.c b/src/map/pet.c
index fc4dd3875..e52753085 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -1127,7 +1127,7 @@ int pet_recovery_timer(int tid,unsigned int tick,int id,int data)
return 0;
}
- if(sd->sc.count && sd->sc.data[pd->recovery->type].timer != -1)
+ if(sd->sc.data[pd->recovery->type])
{ //Display a heal animation?
//Detoxify is chosen for now.
clif_skill_nodamage(&pd->bl,&sd->bl,TF_DETOXIFY,1,1);
diff --git a/src/map/skill.c b/src/map/skill.c
index 46913de66..4bc847560 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -256,10 +256,10 @@ int skill_calc_heal (struct block_list *src, struct block_list *target, int skil
sc = status_get_sc(target);
if (sc && sc->count)
{
- if( sc->data[SC_CRITICALWOUND].timer!=-1 )
- heal -= heal * sc->data[SC_CRITICALWOUND].val2/100;
- if( sc->data[SC_INCHEALRATE].timer!=-1 )
- heal += heal * sc->data[SC_INCHEALRATE].val1/100;
+ if( sc->data[SC_CRITICALWOUND] )
+ heal -= heal * sc->data[SC_CRITICALWOUND]->val2/100;
+ if( sc->data[SC_INCHEALRATE] )
+ heal += heal * sc->data[SC_INCHEALRATE]->val1/100;
}
return heal;
}
@@ -451,24 +451,24 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
clif_skill_fail(sd,RG_SNATCHER,0,0);
}
// Chance to trigger Taekwon kicks [Dralnu]
- if(sc && sc->data[SC_COMBO].timer == -1) {
- if(sc->data[SC_READYSTORM].timer != -1 &&
+ if(sc && !sc->data[SC_COMBO]) {
+ if(sc->data[SC_READYSTORM] &&
sc_start(src,SC_COMBO, 15, TK_STORMKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
- else if(sc->data[SC_READYDOWN].timer != -1 &&
+ else if(sc->data[SC_READYDOWN] &&
sc_start(src,SC_COMBO, 15, TK_DOWNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
- else if(sc->data[SC_READYTURN].timer != -1 &&
+ else if(sc->data[SC_READYTURN] &&
sc_start(src,SC_COMBO, 15, TK_TURNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
- else if(sc->data[SC_READYCOUNTER].timer != -1)
+ else if(sc->data[SC_READYCOUNTER])
{ //additional chance from SG_FRIEND [Komurka]
rate = 20;
- if (sc->data[SC_SKILLRATE_UP].timer != -1 && sc->data[SC_SKILLRATE_UP].val1 == TK_COUNTER) {
- rate += rate*sc->data[SC_SKILLRATE_UP].val2/100;
+ if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
+ rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
status_change_end(src,SC_SKILLRATE_UP,-1);
}
sc_start4(src,SC_COMBO, rate, TK_COUNTER, bl->id,0,0,
@@ -486,15 +486,15 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
}
if (sc) {
- // Enchant Poison gives a chance to poison attacked enemies
- if(sc->data[SC_ENCPOISON].timer != -1) //Don't use sc_start since chance comes in 1/10000 rate.
- status_change_start(bl,SC_POISON,sc->data[SC_ENCPOISON].val2,
- sc->data[SC_ENCPOISON].val1,0,0,0,
- skill_get_time2(AS_ENCHANTPOISON,sc->data[SC_ENCPOISON].val1),0);
+ struct status_change_entry *sce;
+ // Enchant Poison gives a chance to poison attacked enemies
+ if((sce=sc->data[SC_ENCPOISON])) //Don't use sc_start since chance comes in 1/10000 rate.
+ status_change_start(bl,SC_POISON,sce->val2, sce->val1,0,0,0,
+ skill_get_time2(AS_ENCHANTPOISON,sce->val1),0);
// Enchant Deadly Poison gives a chance to deadly poison attacked enemies
- if(sc->data[SC_EDP].timer != -1)
- sc_start4(bl,SC_DPOISON,sc->data[SC_EDP].val2,
- sc->data[SC_EDP].val1,0,0,0,skill_get_time2(ASC_EDP,sc->data[SC_EDP].val1));
+ if((sce=sc->data[SC_EDP]))
+ sc_start4(bl,SC_DPOISON,sce->val2, sce->val1,0,0,0,
+ skill_get_time2(ASC_EDP,sce->val1));
}
}
break;
@@ -524,7 +524,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case AS_GRIMTOOTH:
skill = dstsd?SC_SLOWDOWN:SC_STOP;
- if (tsc->data[skill].timer == -1)
+ if (!tsc->data[skill])
sc_start(bl,skill,100,skilllv,skill_get_time2(skillid, skilllv));
break;
case MG_FROSTDIVER:
@@ -533,9 +533,10 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
break;
case WZ_STORMGUST:
- //Use two since the counter is increased AFTER the attack.
- if(tsc->data[SC_FREEZE].val3 >= 2) //Tharis pointed out that this is normal freeze chance with a base of 300%
- sc_start(bl,SC_FREEZE,300,skilllv,skill_get_time2(skillid,skilllv));
+ //Tharis pointed out that this is normal freeze chance with a base of 300%
+ if(tsc->sg_counter >= 3 &&
+ sc_start(bl,SC_FREEZE,300,skilllv,skill_get_time2(skillid,skilllv)))
+ tsc->sg_counter = 0;
break;
case WZ_METEOR:
@@ -689,7 +690,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
break;
case PF_FOGWALL:
- if (src != bl && tsc->data[SC_DELUGE].timer == -1)
+ if (src != bl && !tsc->data[SC_DELUGE])
status_change_start(bl,SC_BLIND,10000,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8);
break;
@@ -700,9 +701,9 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
case LK_JOINTBEAT:
skill = SkillStatusChangeTable(skillid);
- if (tsc->data[skill].val4) {
- sc_start2(bl,skill,(5*skilllv+5),skilllv,tsc->data[skill].val4&BREAK_FLAGS,skill_get_time2(skillid,skilllv));
- tsc->data[skill].val4 = 0;
+ if (tsc->jb_flag) {
+ sc_start2(bl,skill,(5*skilllv+5),skilllv,tsc->jb_flag&BREAK_FLAGS,skill_get_time2(skillid,skilllv));
+ tsc->jb_flag = 0;
}
break;
case ASC_METEORASSAULT:
@@ -739,23 +740,23 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
//Cancel out Soul Linker status of the target. [Skotlex]
if (tsc->count) {
//Remove NORMAL potions effect.
- if (tsc->data[SC_ASPDPOTION0].timer != -1 && !tsc->data[SC_ASPDPOTION0].val4)
+ if (tsc->data[SC_ASPDPOTION0] && !tsc->data[SC_ASPDPOTION0]->val4)
status_change_end(bl, SC_ASPDPOTION0, -1);
- if (tsc->data[SC_ASPDPOTION1].timer != -1 && !tsc->data[SC_ASPDPOTION1].val4)
+ if (tsc->data[SC_ASPDPOTION1] && !tsc->data[SC_ASPDPOTION1]->val4)
status_change_end(bl, SC_ASPDPOTION1, -1);
- if (tsc->data[SC_ASPDPOTION2].timer != -1 && !tsc->data[SC_ASPDPOTION2].val4)
+ if (tsc->data[SC_ASPDPOTION2] && !tsc->data[SC_ASPDPOTION2]->val4)
status_change_end(bl, SC_ASPDPOTION2, -1);
- if (tsc->data[SC_ASPDPOTION3].timer != -1 && !tsc->data[SC_ASPDPOTION3].val4)
+ if (tsc->data[SC_ASPDPOTION3] && !tsc->data[SC_ASPDPOTION3]->val4)
status_change_end(bl, SC_ASPDPOTION3, -1);
- if (tsc->data[SC_SPEEDUP0].timer != -1 && !tsc->data[SC_SPEEDUP0].val4)
+ if (tsc->data[SC_SPEEDUP0] && !tsc->data[SC_SPEEDUP0]->val4)
status_change_end(bl, SC_SPEEDUP0, -1);
- if (tsc->data[SC_SPEEDUP1].timer != -1 && !tsc->data[SC_SPEEDUP1].val4)
+ if (tsc->data[SC_SPEEDUP1] && !tsc->data[SC_SPEEDUP1]->val4)
status_change_end(bl, SC_SPEEDUP1, -1);
- if (tsc->data[SC_SPIRIT].timer != -1)
+ if (tsc->data[SC_SPIRIT])
status_change_end(bl, SC_SPIRIT, -1);
- if (tsc->data[SC_ONEHAND].timer != -1)
+ if (tsc->data[SC_ONEHAND])
status_change_end(bl, SC_ONEHAND, -1);
- if (tsc->data[SC_ADRENALINE2].timer != -1)
+ if (tsc->data[SC_ADRENALINE2])
status_change_end(bl, SC_ADRENALINE2, -1);
}
break;
@@ -954,9 +955,9 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
switch(skillid){
case 0: //Normal Attack
- if(tsc && tsc->data[SC_KAAHI].timer != -1 && tsc->data[SC_KAAHI].val4 == -1)
- tsc->data[SC_KAAHI].val4 = add_timer(
- tick+skill_get_time2(SL_KAAHI,tsc->data[SC_KAAHI].val1),
+ if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == -1)
+ tsc->data[SC_KAAHI]->val4 = add_timer(
+ tick+skill_get_time2(SL_KAAHI,tsc->data[SC_KAAHI]->val1),
kaahi_heal_timer, bl->id, SC_KAAHI); //Activate heal.
break;
case MO_EXTREMITYFIST:
@@ -1135,7 +1136,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
for (i = 0; i < 4; i++) {
if (where&where_list[i]) {
- if (sc && sc->count && sc->data[scdef[i]].timer != -1)
+ if (sc && sc->count && sc->data[scdef[i]])
where&=~where_list[i];
else if (rand()%10000 >= rate)
where&=~where_list[i];
@@ -1194,7 +1195,7 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int
return 0;
for (i = 0; i < ARRAYLENGTH(pos); i++) {
- if (where&pos[i] && sc->data[sc_def[i]].timer != -1)
+ if (where&pos[i] && sc->data[sc_def[i]])
where&=~pos[i];
}
if (!where) return 0;
@@ -1297,13 +1298,13 @@ static int skill_magic_reflect(struct block_list *bl, int type)
if(sc && sc->count)
{
- if(sc->data[SC_MAGICMIRROR].timer != -1 && rand()%100 < sc->data[SC_MAGICMIRROR].val2)
+ if(sc->data[SC_MAGICMIRROR] && rand()%100 < sc->data[SC_MAGICMIRROR]->val2)
return 1;
- if(sc->data[SC_KAITE].timer != -1 && (sd || status_get_lv(bl) <= 80))
+ if(sc->data[SC_KAITE] && (sd || status_get_lv(bl) <= 80))
{ //Works on players or mobs with level under 80.
clif_specialeffect(bl, 438, AREA);
- if (--sc->data[SC_KAITE].val2 <= 0)
+ if (--sc->data[SC_KAITE]->val2 <= 0)
status_change_end(bl, SC_KAITE, -1);
return 1;
}
@@ -1362,7 +1363,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if(skillid == WZ_FROSTNOVA && dsrc->x == bl->x && dsrc->y == bl->y)
return 0;
//Trick Dead protects you from damage, but not from buffs and the like, hence it's placed here.
- if (sc && sc->data[SC_TRICKDEAD].timer != -1 && !(sstatus->mode&MD_BOSS))
+ if (sc && sc->data[SC_TRICKDEAD] && !(sstatus->mode&MD_BOSS))
return 0;
dmg=battle_calc_attack(attack_type,src,bl,skillid,skilllv,flag&0xFFF);
@@ -1399,16 +1400,16 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if (sc && !sc->count)
sc = NULL; //Don't need it.
//Spirit of Wizard blocks bounced back spells.
- if (sc && sc->data[SC_SPIRIT].timer != -1 &&
- sc->data[SC_SPIRIT].val2 == SL_WIZARD)
+ if (sc && sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_WIZARD)
{
//It should only consume once per skill casted. Val3 is the skill
//id and val4 is the ID of the damage src, this should account for
//ground spells (and single target spells will be completed on
//castend_id) [Skotlex]
if (tsd && !(
- sc->data[SC_SPIRIT].val3 == skillid &&
- sc->data[SC_SPIRIT].val4 == dsrc->id)
+ sc->data[SC_SPIRIT]->val3 == skillid &&
+ sc->data[SC_SPIRIT]->val4 == dsrc->id)
) { //Check if you have stone to consume.
type = pc_search_inventory (tsd, 7321);
if (type >= 0)
@@ -1418,21 +1419,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if (type >= 0) {
dmg.damage = dmg.damage2 = 0;
dmg.dmg_lv = ATK_FLEE;
- sc->data[SC_SPIRIT].val3 = skillid;
- sc->data[SC_SPIRIT].val4 = dsrc->id;
+ sc->data[SC_SPIRIT]->val3 = skillid;
+ sc->data[SC_SPIRIT]->val4 = dsrc->id;
}
}
}
- if(sc && sc->data[SC_MAGICROD].timer != -1 && src == dsrc) {
+ if(sc && sc->data[SC_MAGICROD] && src == dsrc) {
int sp = skill_get_sp(skillid,skilllv);
dmg.damage = dmg.damage2 = 0;
dmg.dmg_lv = ATK_FLEE; //This will prevent skill additional effect from taking effect. [Skotlex]
- sp = sp * sc->data[SC_MAGICROD].val2 / 100;
+ sp = sp * sc->data[SC_MAGICROD]->val2 / 100;
if(skillid == WZ_WATERBALL && skilllv > 1)
sp = sp/((skilllv|1)*(skilllv|1)); //Estimate SP cost of a single water-ball
status_heal(bl, 0, sp, 2);
- clif_skill_nodamage(bl,bl,SA_MAGICROD,sc->data[SC_MAGICROD].val1,1);
+ clif_skill_nodamage(bl,bl,SA_MAGICROD,sc->data[SC_MAGICROD]->val1,1);
}
}
@@ -1462,7 +1463,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if(sd) {
int flag = 0; //Used to signal if this skill can be combo'ed later on.
- if (sd->sc.data[SC_COMBO].timer!=-1)
+ if (sd->sc.data[SC_COMBO])
{ //End combo state after skill is invoked. [Skotlex]
switch (skillid) {
case TK_TURNKICK:
@@ -1473,10 +1474,10 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
{ //Extend combo time.
sd->skillid_old = skillid; //Set as previous so you can't repeat
sd->skilllv_old = skilllv;
- sd->sc.data[SC_COMBO].val1 = skillid; //Update combo-skill
- delete_timer(sd->sc.data[SC_COMBO].timer, status_change_timer);
- sd->sc.data[SC_COMBO].timer = add_timer(
- tick+sd->sc.data[SC_COMBO].val4,
+ sd->sc.data[SC_COMBO]->val1 = skillid; //Update combo-skill
+ delete_timer(sd->sc.data[SC_COMBO]->timer, status_change_timer);
+ sd->sc.data[SC_COMBO]->timer = add_timer(
+ tick+sd->sc.data[SC_COMBO]->val4,
status_change_timer, src->id, SC_COMBO);
break;
}
@@ -1503,7 +1504,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if (!flag && pc_checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)
flag=1;
case CH_CHAINCRUSH:
- if (!flag && pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS].timer != -1)
+ if (!flag && pc_checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS])
flag=1;
break;
case AC_DOUBLE:
@@ -1524,7 +1525,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
case SL_STIN:
case SL_STUN:
- if (skilllv >= 7 && sd->sc.data[SC_SMA].timer == -1)
+ if (skilllv >= 7 && !sd->sc.data[SC_SMA])
sc_start(src,SC_SMA,100,skilllv,skill_get_time(SL_SMA, skilllv));
break;
case GS_FULLBUSTER:
@@ -1583,7 +1584,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if(damage > 0 && dmg.flag&BF_SKILL && tsd
&& pc_checkskill(tsd,RG_PLAGIARISM)
- && (!sc || sc->data[SC_PRESERVE].timer == -1)
+ && (!sc || !sc->data[SC_PRESERVE])
&& damage < tsd->status.hp)
{ //Updated to not be able to copy skills if the blow will kill you. [Skotlex]
if ((!tsd->status.skill[skillid].id || tsd->status.skill[skillid].flag >= 13) &&
@@ -1677,8 +1678,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
skillid == MG_COLDBOLT || skillid == MG_FIREBOLT || skillid == MG_LIGHTNINGBOLT
) &&
(sc = status_get_sc(src)) &&
- sc->count && sc->data[SC_DOUBLECAST].timer != -1 &&
- rand() % 100 < 40+10*sc->data[SC_DOUBLECAST].val1)
+ sc->data[SC_DOUBLECAST] &&
+ rand() % 100 < sc->data[SC_DOUBLECAST]->val2)
{
// skill_addtimerskill(src, tick + dmg.div_*dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|2);
skill_addtimerskill(src, tick + dmg.amotion, bl->id, 0, 0, skillid, skilllv, BF_MAGIC, flag|2);
@@ -1853,11 +1854,11 @@ int skill_guildaura_sub (struct block_list *bl, va_list ap)
strvit = va_arg(ap,int);
agidex = va_arg(ap,int);
- if (sd->sc.count && sd->sc.data[SC_GUILDAURA].timer != -1) {
- if (sd->sc.data[SC_GUILDAURA].val3 != strvit ||
- sd->sc.data[SC_GUILDAURA].val4 != agidex) {
- sd->sc.data[SC_GUILDAURA].val3 = strvit;
- sd->sc.data[SC_GUILDAURA].val4 = agidex;
+ if (sd->sc.data[SC_GUILDAURA]) {
+ struct status_change_entry *sce = sd->sc.data[SC_GUILDAURA];
+ if (sce->val3 != strvit || sce->val4 != agidex) {
+ sce->val3 = strvit;
+ sce->val4 = agidex;
status_calc_bl(&sd->bl, StatusChangeFlagTable[SC_GUILDAURA]);
}
return 0;
@@ -1876,7 +1877,6 @@ int skill_guildaura_sub (struct block_list *bl, va_list ap)
static int skill_check_condition_hom (struct homun_data *hd, int skill, int lv, int type)
{
struct status_data *status;
- struct status_change *sc;
TBL_PC * sd;
int i,j,hp,sp,hp_rate,sp_rate,state,mhp ;
int itemid[10],amount[10];
@@ -1888,10 +1888,7 @@ static int skill_check_condition_hom (struct homun_data *hd, int skill, int lv,
if (lv <= 0) return 0;
status = &hd->battle_status;
- sc = &hd->sc;
- if (!sc->count)
- sc = NULL;
-
+
//Code speedup, rather than using skill_get_* over and over again.
j = skill_get_index(skill);
if( j == 0 )
@@ -2081,12 +2078,12 @@ static int skill_timerskill (int tid, unsigned int tick, int id, int data)
} else {
struct status_change *sc = status_get_sc(src);
if(sc) {
- if(sc->data[SC_MAGICPOWER].timer != -1)
+ if(sc->data[SC_MAGICPOWER])
status_change_end(src,SC_MAGICPOWER,-1);
- if(sc->data[SC_SPIRIT].timer != -1 &&
- sc->data[SC_SPIRIT].val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT].val3 == skl->skill_id)
- sc->data[SC_SPIRIT].val3 = 0; //Clear bounced spell check.
+ if(sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
+ sc->data[SC_SPIRIT]->val3 == skl->skill_id)
+ sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
}
}
break;
@@ -2311,15 +2308,14 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case 4: flag |= BREAK_WAIST; break;
case 5: flag |= BREAK_NECK; break;
}
- //Seems a little ugly, but we have done this or worse with other skills like Storm Gust. [Skotlex]
- //val3 holds the status that it should start when it connects.
+ //TODO: is there really no cleaner way to do this?
sc = status_get_sc(bl);
- if (sc) sc->data[SkillStatusChangeTable(skillid)].val4 = flag;
+ if (sc) sc->jb_flag = flag;
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
case MO_COMBOFINISH:
- if (!(flag&1) && sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_MONK)
+ if (!(flag&1) && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
{ //Becomes a splash attack when Soul Linked.
map_foreachinrange(skill_area_sub, bl,
skill_get_splash(skillid, skilllv),splash_target(src),
@@ -2389,7 +2385,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case MO_INVESTIGATE:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if (sc && sc->data[SC_BLADESTOP].timer != -1)
+ if (sc && sc->data[SC_BLADESTOP])
status_change_end(src,SC_BLADESTOP,-1);
break;
@@ -2397,7 +2393,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
{
int dir = map_calc_dir(src, bl->x, bl->y), t_dir = unit_getdir(bl);
if ((!check_distance_bl(src, bl, 0) && !map_check_dir(dir, t_dir)) || bl->type == BL_SKILL) {
- if (sc && sc->data[SC_HIDING].timer != -1)
+ if (sc && sc->data[SC_HIDING])
status_change_end(src, SC_HIDING, -1);
skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
@@ -2415,29 +2411,29 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
for (i = 1; i < sd->spiritball_old; i++)
skill_addtimerskill(src, tick + i * 200, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag);
}
- if (sc && sc->data[SC_BLADESTOP].timer != -1)
+ if (sc && sc->data[SC_BLADESTOP])
status_change_end(src,SC_BLADESTOP,-1);
break;
case MO_CHAINCOMBO:
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
- if (sc && sc->data[SC_BLADESTOP].timer != -1)
+ if (sc && sc->data[SC_BLADESTOP])
status_change_end(src,SC_BLADESTOP,-1);
break;
case NJ_ISSEN:
if (sc) {
- if (sc->data[SC_NEN].timer != -1)
+ if (sc->data[SC_NEN])
status_change_end(src,SC_NEN,-1);
- if (sc->data[SC_HIDING].timer != -1)
+ if (sc->data[SC_HIDING])
status_change_end(src,SC_HIDING,-1);
}
case MO_EXTREMITYFIST:
if (sc && skillid == MO_EXTREMITYFIST)
{
- if (sc->data[SC_EXPLOSIONSPIRITS].timer != -1)
+ if (sc->data[SC_EXPLOSIONSPIRITS])
status_change_end(src, SC_EXPLOSIONSPIRITS, -1);
- if (sc->data[SC_BLADESTOP].timer != -1)
+ if (sc->data[SC_BLADESTOP])
status_change_end(src,SC_BLADESTOP,-1);
}
//Client expects you to move to target regardless of distance
@@ -2690,7 +2686,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
break;
case SL_SMA:
- if (sc && sc->data[SC_SMA].timer != -1)
+ if (sc && sc->data[SC_SMA])
status_change_end(src,SC_SMA,-1);
case SL_STIN:
case SL_STUN:
@@ -2764,7 +2760,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
if (unit_movepos(src, x, y, 0, 0))
clif_slide(src,src->x,src->y);
}
- if (sc && sc->data[SC_HIDING].timer != -1)
+ if (sc && sc->data[SC_HIDING])
status_change_end(src, SC_HIDING, -1);
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
break;
@@ -2810,6 +2806,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
struct map_session_data *dstsd;
struct status_data *sstatus, *tstatus;
struct status_change *tsc;
+ struct status_change_entry *tsce;
struct mob_data *md;
struct mob_data *dstmd;
int i,type;
@@ -2870,6 +2867,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
type = SkillStatusChangeTable(skillid);
tsc = status_get_sc(bl);
+ tsce = (tsc && type != -1)?tsc->data[type]:NULL;
if (src!=bl && type > -1 &&
(i = skill_get_ele(skillid, skilllv)) > ELE_NEUTRAL &&
@@ -2898,9 +2896,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if (tsc && tsc->count)
{
- if (tsc->data[SC_KAITE].timer != -1 && !(sstatus->mode&MD_BOSS)
+ if (tsc->data[SC_KAITE] && !(sstatus->mode&MD_BOSS)
) { //Bounce back heal
- if (--tsc->data[SC_KAITE].val2 <= 0)
+ if (--tsc->data[SC_KAITE]->val2 <= 0)
status_change_end(bl, SC_KAITE, -1);
if (src == bl)
heal=0; //When you try to heal yourself under Kaite, the heal is voided.
@@ -2909,7 +2907,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
dstsd = sd;
}
} else
- if (tsc->data[SC_BERSERK].timer != -1)
+ if (tsc->data[SC_BERSERK])
heal = 0; //Needed so that it actually displays 0 when healing.
}
heal_get_jobexp = status_heal(bl,heal,0,0);
@@ -3016,7 +3014,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case PR_LEXDIVINA:
- if (tsc && tsc->count && tsc->data[type].timer != -1) {
+ if (tsce) {
status_change_end(bl,type, -1);
clif_skill_nodamage (src, bl, skillid, skilllv, 1);
} else
@@ -3160,14 +3158,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
int type2 = SC_MARIONETTE2;
if(sc && tsc){
- if (sc->data[type].timer == -1 && tsc->data[type2].timer == -1) {
+ if (!sc->data[type] && !tsc->data[type2]) {
sc_start(src,type,100,bl->id,skill_get_time(skillid,skilllv));
sc_start(bl,type2,100,src->id,skill_get_time(skillid,skilllv));
clif_marionette(src, bl);
clif_skill_nodamage(src,bl,skillid,skilllv,1);
}
- else if (sc->data[type].timer != -1 && tsc->data[type2].timer != -1 &&
- sc->data[type].val1 == bl->id && tsc->data[type2].val1 == src->id) {
+ else if (sc->data[type] && tsc->data[type2] &&
+ sc->data[type]->val1 == bl->id && tsc->data[type2]->val1 == src->id) {
status_change_end(src, type, -1);
status_change_end(bl, type2, -1);
}
@@ -3190,15 +3188,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SA_SEISMICWEAPON:
if (dstsd) {
if(dstsd->status.weapon == W_FIST ||
- (dstsd->sc.count && dstsd->sc.data[type].timer == -1 &&
+ (dstsd->sc.count && !dstsd->sc.data[type] &&
( //Allow re-enchanting to lenghten time. [Skotlex]
- dstsd->sc.data[SC_FIREWEAPON].timer != -1 ||
- dstsd->sc.data[SC_WATERWEAPON].timer != -1 ||
- dstsd->sc.data[SC_WINDWEAPON].timer != -1 ||
- dstsd->sc.data[SC_EARTHWEAPON].timer != -1 ||
- dstsd->sc.data[SC_SHADOWWEAPON].timer != -1 ||
- dstsd->sc.data[SC_GHOSTWEAPON].timer != -1 ||
- dstsd->sc.data[SC_ENCPOISON].timer != -1
+ dstsd->sc.data[SC_FIREWEAPON] ||
+ dstsd->sc.data[SC_WATERWEAPON] ||
+ dstsd->sc.data[SC_WINDWEAPON] ||
+ dstsd->sc.data[SC_EARTHWEAPON] ||
+ dstsd->sc.data[SC_SHADOWWEAPON] ||
+ dstsd->sc.data[SC_GHOSTWEAPON] ||
+ dstsd->sc.data[SC_ENCPOISON]
))
) {
if (sd) clif_skill_fail(sd,skillid,0,0);
@@ -3334,7 +3332,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case NJ_BUNSINJYUTSU:
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
- if (tsc && tsc->data[SC_NEN].timer != -1)
+ if (tsc && tsc->data[SC_NEN])
status_change_end(bl,SC_NEN,-1);
break;
/* Was modified to only affect targetted char. [Skotlex]
@@ -3360,13 +3358,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
if (sd && dstsd && dstsd->sc.count) {
- if (dstsd->sc.data[SC_FIREWEAPON].timer != -1 ||
- dstsd->sc.data[SC_WATERWEAPON].timer != -1 ||
- dstsd->sc.data[SC_WINDWEAPON].timer != -1 ||
- dstsd->sc.data[SC_EARTHWEAPON].timer != -1 ||
- dstsd->sc.data[SC_SHADOWWEAPON].timer != -1 ||
- dstsd->sc.data[SC_GHOSTWEAPON].timer != -1
- // dstsd->sc.data[SC_ENCPOISON].timer != -1 //People say you should be able to recast to lengthen the timer. [Skotlex]
+ if (dstsd->sc.data[SC_FIREWEAPON] ||
+ dstsd->sc.data[SC_WATERWEAPON] ||
+ dstsd->sc.data[SC_WINDWEAPON] ||
+ dstsd->sc.data[SC_EARTHWEAPON] ||
+ dstsd->sc.data[SC_SHADOWWEAPON] ||
+ dstsd->sc.data[SC_GHOSTWEAPON]
+ // dstsd->sc.data[SC_ENCPOISON] //People say you should be able to recast to lengthen the timer. [Skotlex]
) {
clif_skill_nodamage(src,bl,skillid,skilllv,0);
clif_skill_fail(sd,skillid,0,0);
@@ -3414,7 +3412,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
map_foreachinrange( status_change_timer_sub, src,
skill_get_splash(skillid, skilllv), BL_CHAR,
- src,status_get_sc(src),type,tick);
+ src,NULL,type,tick);
}
break;
@@ -3438,11 +3436,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
unit_skillcastcancel(bl, 2);
if(tsc && tsc->count){
- if(tsc->data[SC_FREEZE].timer!=-1)
+ if(tsc->data[SC_FREEZE])
status_change_end(bl,SC_FREEZE,-1);
- if(tsc->data[SC_STONE].timer!=-1 && tsc->data[SC_STONE].val2==0)
+ if(tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)
status_change_end(bl,SC_STONE,-1);
- if(tsc->data[SC_SLEEP].timer!=-1)
+ if(tsc->data[SC_SLEEP])
status_change_end(bl,SC_SLEEP,-1);
}
@@ -3458,7 +3456,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
int lv = sd->status.base_level - dstsd->status.base_level;
if (lv < 0) lv = -lv;
if (lv > battle_config.devotion_level_difference ||
- (dstsd->sc.data[type].timer != -1 && dstsd->sc.data[type].val1 != src->id) || //Avoid overriding [Skotlex]
+ (dstsd->sc.data[type] && dstsd->sc.data[type]->val1 != src->id) || //Avoid overriding [Skotlex]
(dstsd->class_&MAPID_UPPERMASK) == MAPID_CRUSADER) {
clif_skill_fail(sd,skillid,0,0);
map_freeblock_unlock();
@@ -3697,7 +3695,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case ST_PRESERVE:
case SG_FUSION:
case GS_GATLINGFEVER:
- if (tsc && tsc->data[type].timer != -1)
+ if (tsce)
i = status_change_end(bl, type, -1);
else
i = sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
@@ -3709,7 +3707,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SL_KAUPE:
if (sd) {
if (!dstsd || !(
- (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_SOULLINKER) ||
+ (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SOULLINKER) ||
(dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER ||
dstsd->status.char_id == sd->status.char_id ||
dstsd->status.char_id == sd->status.partner_id ||
@@ -3724,7 +3722,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
sc_start(bl,type,100,skilllv,skill_get_time(skillid, skilllv)));
break;
case SM_AUTOBERSERK: // Celest
- if (tsc && tsc->data[type].timer != -1)
+ if (tsce)
i = status_change_end(bl, type, -1);
else
i = sc_start(bl,type,100,skilllv,60000);
@@ -3732,14 +3730,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case TF_HIDING:
case ST_CHASEWALK:
- if (tsc && tsc->data[type].timer != -1)
+ if (tsce)
i = status_change_end(bl, type, -1);
else
i = sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
clif_skill_nodamage(src,bl,skillid,-1,i); //Hide skill-scream animation.
break;
case TK_RUN:
- if (tsc && tsc->data[type].timer != -1)
+ if (tsce)
clif_skill_nodamage(src,bl,skillid,skilllv,
status_change_end(bl, type, -1));
else {
@@ -3752,7 +3750,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
}
break;
case AS_CLOAKING:
- if(tsc && tsc->data[type].timer!=-1 )
+ if(tsce)
i = status_change_end(bl, type, -1);
else
i = sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv));
@@ -3762,7 +3760,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case BD_ADAPTATION:
- if(tsc && tsc->data[SC_DANCING].timer!=-1){
+ if(tsc && tsc->data[SC_DANCING]){
clif_skill_nodamage(src,bl,skillid,skilllv,1);
skill_stop_dancing(bl);
}
@@ -3833,7 +3831,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if (dstmd)
mob_target(dstmd,src,skill_get_range2(src,skillid,skilllv));
- if (tsc->data[SC_STONE].timer != -1) {
+ if (tsc->data[SC_STONE]) {
status_change_end(bl,SC_STONE,-1);
if (sd) clif_skill_fail(sd,skillid,0,0);
break;
@@ -3848,7 +3846,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if (skilllv > 5) break;
}
if (sd) {
- if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_WIZARD)
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_WIZARD)
break; //Do not delete the gemstone.
if ((i=pc_search_inventory(sd, skill_db[skillid].itemid[0])) >= 0 )
pc_delitem(sd, i, skill_db[skillid].amount[0], 0);
@@ -4073,7 +4071,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
run_script(sd->inventory_data[i]->script,0,sd->bl.id,0);
pc_delitem(sd,i,skill_db[skillid].amount[x],0);
potion_flag = potion_target = 0;
- if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_ALCHEMIST)
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ALCHEMIST)
bonus += sd->status.base_level;
if(potion_per_hp > 0 || potion_per_sp > 0) {
hp = tstatus->max_hp * potion_per_hp / 100;
@@ -4109,10 +4107,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if(dstsd)
hp = hp * (100 + pc_checkskill(dstsd,SM_RECOVERY)*10) / 100;
}
- if (tsc && tsc->count && tsc->data[SC_CRITICALWOUND].timer!=-1)
+ if (tsc && tsc->data[SC_CRITICALWOUND])
{
- hp -= hp * tsc->data[SC_CRITICALWOUND].val2 / 100;
- sp -= sp * tsc->data[SC_CRITICALWOUND].val2 / 100;
+ hp -= hp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+ sp -= sp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
}
clif_skill_nodamage(src,bl,skillid,skilllv,1);
if(hp > 0 || (skillid == AM_POTIONPITCHER && sp <= 0))
@@ -4128,7 +4126,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case AM_CP_HELM:
{
int scid = SC_STRIPWEAPON + (skillid - AM_CP_WEAPON);
- if(tsc && tsc->data[scid].timer != -1)
+ if(tsc && tsc->data[scid])
status_change_end(bl, scid, -1 );
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
@@ -4173,7 +4171,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
i = tstatus->mdef;
if (i >= 100 ||
(dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) ||
- tsc == NULL || (tsc->data[SC_SPIRIT].timer != -1 && tsc->data[SC_SPIRIT].val2 == SL_ROGUE) || //Rogue's spirit defends againt dispel.
+ tsc == NULL || (tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_ROGUE) || //Rogue's spirit defends againt dispel.
//Fixed & changed to use a proportionnal reduction (no info, but seems far more logical) [DracoRPG]
rand()%100 >= (100-i)*(50+10*skilllv)/100)
{
@@ -4184,7 +4182,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if(status_isimmune(bl) || !tsc->count)
break;
for(i=0;i<SC_MAX;i++){
- if (tsc->data[i].timer == -1)
+ if (!tsc->data[i])
continue;
switch (i) {
case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
@@ -4203,7 +4201,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SC_BOSSMAPINFO:
continue;
}
- if(i==SC_BERSERK) tsc->data[i].val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
+ if(i==SC_BERSERK) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
status_change_end(bl,i,-1);
}
break;
@@ -4255,12 +4253,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case SA_SPELLBREAKER:
{
int sp;
- if(tsc && tsc->data[SC_MAGICROD].timer != -1) {
+ if(tsc && tsc->data[SC_MAGICROD]) {
sp = skill_get_sp(skillid,skilllv);
- sp = sp * tsc->data[SC_MAGICROD].val2 / 100;
+ sp = sp * tsc->data[SC_MAGICROD]->val2 / 100;
if(sp < 1) sp = 1;
status_heal(bl,0,sp,2);
- clif_skill_nodamage(bl,bl,SA_MAGICROD,tsc->data[SC_MAGICROD].val1,1);
+ clif_skill_nodamage(bl,bl,SA_MAGICROD,tsc->data[SC_MAGICROD]->val1,1);
status_percent_damage(bl, src, 0, -20); //20% max SP damage.
} else {
struct unit_data *ud = unit_bl2ud(bl);
@@ -4309,7 +4307,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
if(skilllv >= 10) {
spellid = MG_FROSTDIVER;
-// if (tsc && tsc->data[SC_SPIRIT].timer != -1 && tsc->data[SC_SPIRIT].val2 == SA_SAGE)
+// if (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SA_SAGE)
// maxlv = 10;
// else
maxlv = skilllv - 9;
@@ -4481,7 +4479,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if(md && md->skillidx >= 0 && tsc)
{
clif_emotion(bl, md->db->skill[md->skillidx].val[0]);
- if(md->db->skill[md->skillidx].val[4] && tsc->data[type].timer != -1)
+ if(md->db->skill[md->skillidx].val[4] && tsce)
status_change_end(bl, type, -1);
if(md->db->skill[md->skillidx].val[1] || md->db->skill[md->skillidx].val[2])
@@ -4661,7 +4659,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
return 1;
}
- if (tsc && tsc->data[type].timer != -1)
+ if (tsce)
{ //HelloKitty2 (?) explained that this silently fails when target is
//already inflicted. [Skotlex]
map_freeblock_unlock();
@@ -4680,11 +4678,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
unit_skillcastcancel(bl,0);
if(tsc && tsc->count){
- if(tsc->data[SC_FREEZE].timer!=-1)
+ if(tsc->data[SC_FREEZE])
status_change_end(bl,SC_FREEZE,-1);
- if(tsc->data[SC_STONE].timer!=-1 && tsc->data[SC_STONE].val2==0)
+ if(tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)
status_change_end(bl,SC_STONE,-1);
- if(tsc->data[SC_SLEEP].timer!=-1)
+ if(tsc->data[SC_SLEEP])
status_change_end(bl,SC_SLEEP,-1);
}
@@ -4728,10 +4726,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
if (sp)
sp = sp * (100 + pc_checkskill(dstsd,MG_SRECOVERY)*10)/100;
}
- if (tsc && tsc->count && tsc->data[SC_CRITICALWOUND].timer!=-1)
+ if (tsc && tsc->data[SC_CRITICALWOUND]->timer!=-1)
{
- hp -= hp * tsc->data[SC_CRITICALWOUND].val2 / 100;
- sp -= sp * tsc->data[SC_CRITICALWOUND].val2 / 100;
+ hp -= hp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
+ sp -= sp * tsc->data[SC_CRITICALWOUND]->val2 / 100;
}
if(hp > 0)
clif_skill_nodamage(NULL,bl,AL_HEAL,hp,1);
@@ -4750,7 +4748,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
}
for (i=0; i<4; i++) {
- if(tsc->data[SC_STRIPWEAPON + i].timer != -1)
+ if(tsc->data[SC_STRIPWEAPON + i])
status_change_end(bl, SC_STRIPWEAPON + i, -1 );
sc_start(bl,SC_CP_WEAPON + i,100,skilllv,skilltime);
}
@@ -4764,8 +4762,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case CG_LONGINGFREEDOM:
{
- if (tsc && tsc->data[SC_LONGING].timer == -1 && tsc->data[SC_DANCING].timer != -1 && tsc->data[SC_DANCING].val4
- && (tsc->data[SC_DANCING].val1&0xFFFF) != CG_MOONLIT) //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex]
+ if (tsc && !tsce && (tsce=tsc->data[SC_DANCING]) && tsce->val4
+ && (tsce->val1&0xFFFF) != CG_MOONLIT) //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex]
{
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
@@ -4900,7 +4898,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case SL_SWOO:
- if (tsc && tsc->data[type].timer != -1) {
+ if (tsce) {
sc_start(src,SC_STUN,100,skilllv,10000);
break;
}
@@ -5234,7 +5232,7 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
{
sc = status_get_sc(target);
if (battle_check_target(src,target, BCT_ENEMY)<=0 &&
- (!sc || sc->data[SC_SILENCE].timer == -1))
+ (!sc || !sc->data[SC_SILENCE]))
{ //If it's not an enemy, and not silenced, you can't use the skill on them. [Skotlex]
clif_skill_nodamage (src, target, ud->skillid, ud->skilllv, 0);
break;
@@ -5265,7 +5263,7 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
break;
if(inf&BCT_ENEMY && (sc = status_get_sc(target)) &&
- sc->count && sc->data[SC_FOGWALL].timer != -1 &&
+ sc->data[SC_FOGWALL] &&
rand()%100 < 75)
{ //Fogwall makes all offensive-type targetted skills fail at 75%
if (sd) clif_skill_fail(sd,ud->skillid,0,0);
@@ -5320,14 +5318,14 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
sc = status_get_sc(src);
if(sc && sc->count) {
- if(sc->data[SC_MAGICPOWER].timer != -1 &&
+ if(sc->data[SC_MAGICPOWER] &&
ud->skillid != HW_MAGICPOWER && ud->skillid != WZ_WATERBALL)
status_change_end(src,SC_MAGICPOWER,-1);
- if(sc->data[SC_SPIRIT].timer != -1 &&
- sc->data[SC_SPIRIT].val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT].val3 == ud->skillid &&
+ if(sc->data[SC_SPIRIT] &&
+ sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
+ sc->data[SC_SPIRIT]->val3 == ud->skillid &&
ud->skillid != WZ_WATERBALL)
- sc->data[SC_SPIRIT].val3 = 0; //Clear bounced spell check.
+ sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
}
if (ud->skilltimer == -1) {
@@ -5340,7 +5338,7 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
} while(0);
//Skill failed.
- if (ud->skillid == MO_EXTREMITYFIST && sd && !(sc && sc->count && sc->data[SC_FOGWALL].timer != -1))
+ if (ud->skillid == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL]))
{ //When Asura fails... (except when it fails from Fog of Wall)
//Consume SP/spheres
skill_check_condition(sd,ud->skillid, ud->skilllv,1);
@@ -5348,9 +5346,9 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
sc = &sd->sc;
if (sc->count)
{ //End states
- if (sc->data[SC_EXPLOSIONSPIRITS].timer != -1)
+ if (sc->data[SC_EXPLOSIONSPIRITS])
status_change_end(src, SC_EXPLOSIONSPIRITS, -1);
- if (sc->data[SC_BLADESTOP].timer != -1)
+ if (sc->data[SC_BLADESTOP])
status_change_end(src,SC_BLADESTOP,-1);
}
if (target && target->m == src->m)
@@ -5504,6 +5502,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
{
struct map_session_data* sd;
struct status_change* sc;
+ struct status_change_entry *sce;
struct skill_unit_group* sg;
int i,type;
@@ -5519,6 +5518,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
sc = status_get_sc(src);
type = SkillStatusChangeTable(skillid);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
switch (skillid) { //Skill effect.
case WZ_METEOR:
@@ -5560,7 +5560,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
i = skill_get_splash(skillid, skilllv);
map_foreachinarea( status_change_timer_sub,
src->m, x-i, y-i, x+i,y+i,BL_CHAR,
- src,status_get_sc(src),SC_SIGHT,tick);
+ src,NULL,SC_SIGHT,tick);
if(battle_config.traps_setting&1)
map_foreachinarea( skill_reveal_trap,
src->m, x-i, y-i, x+i,y+i,BL_SKILL);
@@ -5660,7 +5660,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
{
int flag=0, area = skill_get_splash(skillid, skilllv);
short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
- if (sc && sc->data[SC_MAGICPOWER].timer != -1)
+ if (sc && sc->data[SC_MAGICPOWER])
flag = flag|2; //Store the magic power flag for future use. [Skotlex]
for(i=0;i<2+(skilllv>>1);i++) {
tmpx = x;
@@ -5705,7 +5705,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
unit_movepos(src, x, y, 1, 0);
clif_slide(src,x,y);
}
- if (sc && sc->data[SC_HIDING].timer != -1)
+ if (sc && sc->data[SC_HIDING])
status_change_end(src, SC_HIDING, -1);
}
break;
@@ -5831,13 +5831,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
break;
case PA_GOSPEL:
- if (sc && sc->data[type].timer != -1 && sc->data[type].val4 == BCT_SELF)
+ if (sce && sce->val4 == BCT_SELF)
status_change_end(src,SC_GOSPEL,-1);
else
{
sg = skill_unitsetting(src,skillid,skilllv,src->x,src->y,0);
if (!sg) break;
- if (sc && sc->data[type].timer != -1)
+ if (sce)
status_change_end(src,type,-1); //Was under someone else's Gospel. [Skotlex]
sc_start4(src,type,100,skilllv,0,(int)sg,BCT_SELF,skill_get_time(skillid,skilllv));
clif_skill_poseffect(src, skillid, skilllv, 0, 0, tick); // PA_GOSPEL music packet
@@ -5864,7 +5864,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
return 1;
}
- if (sc && sc->data[SC_MAGICPOWER].timer != -1)
+ if (sc && sc->data[SC_MAGICPOWER])
status_change_end(src,SC_MAGICPOWER,-1);
if (sd && !(flag&1) && sd->state.arrow_atk) //Consume arrow if a ground skill was not invoked. [Skotlex]
@@ -5895,13 +5895,13 @@ int skill_castend_map (struct map_session_data *sd, short skill_num, const char
return 0;
}
if(sd->sc.count && (
- sd->sc.data[SC_SILENCE].timer!=-1 ||
- sd->sc.data[SC_ROKISWEIL].timer!=-1 ||
- sd->sc.data[SC_AUTOCOUNTER].timer != -1 ||
- sd->sc.data[SC_STEELBODY].timer != -1 ||
- sd->sc.data[SC_DANCING].timer!=-1 ||
- sd->sc.data[SC_BERSERK].timer != -1 ||
- sd->sc.data[SC_MARIONETTE].timer != -1
+ sd->sc.data[SC_SILENCE] ||
+ sd->sc.data[SC_ROKISWEIL] ||
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_STEELBODY] ||
+ sd->sc.data[SC_DANCING] ||
+ sd->sc.data[SC_BERSERK] ||
+ sd->sc.data[SC_MARIONETTE]
)) {
skill_failed(sd);
return 0;
@@ -6135,7 +6135,7 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli
val2=skilllv+1;
break;
case MG_FIREWALL:
- if(sc && sc->data[SC_VIOLENTGALE].timer!=-1)
+ if(sc && sc->data[SC_VIOLENTGALE])
limit = limit*3/2;
val2=4+skilllv;
break;
@@ -6347,7 +6347,7 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli
group->val3=val3;
group->target_flag=target;
group->bl_flag= skill_get_unit_bl_target(skillid);
- group->state.magic_power = (flag&2 || (sc && sc->data[SC_MAGICPOWER].timer != -1)); //Store the magic power flag. [Skotlex]
+ group->state.magic_power = (flag&2 || (sc && sc->data[SC_MAGICPOWER])); //Store the magic power flag. [Skotlex]
group->state.ammo_consume = (sd && sd->state.arrow_atk && skillid != GS_GROUNDDRIFT); //Store if this skill needs to consume ammo.
group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)?1:0)|(unit_flag&UF_ENSEMBLE?2:0); //Signals if this is a song/dance/duet
@@ -6475,6 +6475,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
struct skill_unit_group *sg;
struct block_list *ss;
struct status_change *sc;
+ struct status_change_entry *sce;
int type,skillid;
nullpo_retr(0, src);
@@ -6495,11 +6496,12 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
return 0; //Hidden characters are immune to AoE skills except Heaven's Drive. [Skotlex]
type = SkillStatusChangeTable(sg->skill_id);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
skillid = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still.
switch (sg->unit_id) {
case UNT_SAFETYWALL:
//TODO: Find a more reliable way to handle the link to sg, this could cause dangling pointers. [Skotlex]
- if (sc && sc->data[type].timer == -1)
+ if (!sce)
sc_start4(bl,type,100,sg->skill_lv,sg->group_id,(int)sg,0,sg->limit);
break;
@@ -6523,19 +6525,19 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
break;
case UNT_QUAGMIRE:
- if(sc && sc->data[type].timer==-1)
+ if(!sce)
sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
break;
case UNT_VOLCANO:
case UNT_DELUGE:
case UNT_VIOLENTGALE:
- if(sc && sc->data[type].timer==-1)
+ if(!sce)
sc_start(bl,type,100,sg->skill_lv,sg->limit);
break;
case UNT_SUITON:
- if(sc && sc->data[type].timer==-1)
+ if(!sce)
sc_start4(bl,type,100,sg->skill_lv,
map_flag_vs(bl->m) || battle_check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi.
0,0,sg->limit);
@@ -6550,9 +6552,9 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_SIEGFRIED:
case UNT_HERMODE:
//Needed to check when a dancer/bard leaves their ensemble area.
- if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_BARDDANCER))
+ if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
return skillid;
- if (sc && sc->data[type].timer==-1)
+ if (!sce)
sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
break;
case UNT_WHISTLE:
@@ -6563,21 +6565,21 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_DONTFORGETME:
case UNT_FORTUNEKISS:
case UNT_SERVICEFORYOU:
- if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_BARDDANCER))
+ if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
return 0;
if (!sc) return 0;
- if (sc->data[type].timer==-1)
+ if (!sce)
sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
- else if (sc->data[type].val4 == 1) {
+ else if (sce->val4 == 1) {
//Readjust timers since the effect will not last long.
- sc->data[type].val4 = 0;
- delete_timer(sc->data[type].timer, status_change_timer);
- sc->data[type].timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type);
+ sce->val4 = 0;
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(tick+sg->limit, status_change_timer, bl->id, type);
}
break;
case UNT_FOGWALL:
- if (sc && sc->data[type].timer==-1)
+ if (!sce)
{
sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit);
if (battle_check_target(&src->bl,bl,BCT_ENEMY)>0)
@@ -6586,7 +6588,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
break;
case UNT_GRAVITATION:
- if (sc && sc->data[type].timer==-1)
+ if (!sce)
sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
break;
@@ -6599,7 +6601,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_MOONLIT:
//Knockback out of area if affected char isn't in Moonlit effect
- if (sc && sc->data[SC_DANCING].timer != -1 && (sc->data[SC_DANCING].val1&0xFFFF) == CG_MOONLIT)
+ if (sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT)
break;
if (ss == bl) //Also needed to prevent infinite loop crash.
break;
@@ -6621,7 +6623,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
struct status_data *tstatus, *sstatus;
struct status_change *tsc, *sc;
struct skill_unit_group_tickset *ts;
- int matk_min = 0, matk_max = 0; //For Magic power...
int type, skillid;
int diff=0;
@@ -6671,13 +6672,11 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y,BL_CHAR)-1);
}
//Temporarily set magic power to have it take effect. [Skotlex]
- if (sg->state.magic_power && sc && sc->data[SC_MAGICPOWER].timer == -1)
+ if (sg->state.magic_power && sc && !sc->data[SC_MAGICPOWER])
{ //Store previous values.
- matk_min = sstatus->matk_min;
- matk_max = sstatus->matk_max;
+ swap(sstatus->matk_min, sc->mp_matk_min);
+ swap(sstatus->matk_max, sc->mp_matk_max);
//Note to NOT return from the function until this is unset!
- sstatus->matk_min = sc->data[SC_MAGICPOWER].val3;
- sstatus->matk_max = sc->data[SC_MAGICPOWER].val4;
}
switch (sg->unit_id)
@@ -6712,10 +6711,10 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
break;
if (tsc)
{
- if( tsc->data[SC_INCHEALRATE].timer!=-1 )
- heal += heal * tsc->data[SC_INCHEALRATE].val1 / 100;
- if( tsc->data[SC_CRITICALWOUND].timer!=-1 )
- heal -= heal * tsc->data[SC_CRITICALWOUND].val2 / 100;
+ if( tsc->data[SC_INCHEALRATE] )
+ heal += heal * tsc->data[SC_INCHEALRATE]->val1 / 100;
+ if( tsc->data[SC_CRITICALWOUND] )
+ heal -= heal * tsc->data[SC_CRITICALWOUND]->val2 / 100;
}
if (status_isimmune(bl))
heal = 0; /* 鮟驥題浚繧ォ繝シ繝会シ医ヲ繝シ繝ォ驥擾シ撰シ */
@@ -6737,8 +6736,8 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
int heal = sg->val2;
if (tstatus->hp >= tstatus->max_hp)
break;
- if (tsc && tsc->count && tsc->data[SC_CRITICALWOUND].timer!=-1)
- heal -= heal * tsc->data[SC_CRITICALWOUND].val2 / 100;
+ if (tsc && tsc->data[SC_CRITICALWOUND])
+ heal -= heal * tsc->data[SC_CRITICALWOUND]->val2 / 100;
if (status_isimmune(bl))
heal = 0;
clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
@@ -6779,14 +6778,16 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
}
break;
case WZ_STORMGUST:
- if (tsc && tsc->data[SC_FREEZE].val4 != sg->group_id)
+ if (tsc)
{ //Reset hit counter when under new storm gust.
- tsc->data[SC_FREEZE].val4 = sg->group_id;
- tsc->data[SC_FREEZE].val3 = 0;
+ if (tsc->sg_id != sg->group_id) {
+ tsc->sg_id = sg->group_id;
+ tsc->sg_counter = 0;
+ }
+ tsc->sg_counter++; //SG hit counter.
}
- if (skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0) > 0
- && tsc) //Increase freeze counter if attack connects.
- tsc->data[SC_FREEZE].val3++; //SG hit counter.
+ if (skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0) <= 0 && tsc)
+ tsc->sg_counter=0; //Attack absorbed.
break;
default:
skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
@@ -6822,7 +6823,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
int sec = skill_get_time2(sg->skill_id,sg->skill_lv);
if (status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8))
{
- struct TimerData* td = get_timer(tsc->data[type].timer);
+ struct TimerData* td = tsc->data[type]?get_timer(tsc->data[type]->timer):NULL;
if (td) sec = DIFF_TICK(td->tick, tick);
map_moveblock(bl, src->bl.x, src->bl.y, tick);
clif_fixpos(bl);
@@ -6837,7 +6838,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
break;
case UNT_VENOMDUST:
- if(tsc && tsc->data[type].timer==-1 )
+ if(tsc && !tsc->data[type])
status_change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),8);
break;
@@ -6887,8 +6888,8 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if (sg->src_id == bl->id)
break;
heal = sg->val2;
- if(tsc && tsc->data[SC_CRITICALWOUND].timer!=-1)
- heal -= heal * tsc->data[SC_CRITICALWOUND].val2 / 100;
+ if(tsc && tsc->data[SC_CRITICALWOUND])
+ heal -= heal * tsc->data[SC_CRITICALWOUND]->val2 / 100;
clif_skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
status_heal(bl, heal, 0, 0);
break;
@@ -7022,10 +7023,10 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
break;
}
- if (sg->state.magic_power && sc && sc->data[SC_MAGICPOWER].timer == -1)
+ if (sg->state.magic_power && sc && !sc->data[SC_MAGICPOWER])
{ //Unset magic power.
- sstatus->matk_min = matk_min;
- sstatus->matk_max = matk_max;
+ swap(sstatus->matk_min, sc->mp_matk_min);
+ swap(sstatus->matk_max, sc->mp_matk_max);
}
if (bl->type == BL_MOB && ss != bl)
@@ -7040,6 +7041,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
{
struct skill_unit_group *sg;
struct status_change *sc;
+ struct status_change_entry *sce;
int type;
nullpo_retr(0, src);
@@ -7047,6 +7049,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
nullpo_retr(0, sg=src->group);
sc = status_get_sc(bl);
type = SkillStatusChangeTable(sg->skill_id);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
if (bl->prev==NULL || !src->alive || //Need to delete the trap if the source died.
(status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB))
@@ -7054,11 +7057,11 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
switch(sg->unit_id){
case UNT_SAFETYWALL:
- if (sc && sc->data[type].timer!=-1)
+ if (sce)
status_change_end(bl,type,-1);
break;
case UNT_HERMODE: //Clear Hermode if the owner moved.
- if (sc && sc->data[type].timer!=-1 && sc->data[type].val3 == BCT_SELF && sc->data[type].val4 == sg->group_id)
+ if (sce && sce->val3 == BCT_SELF && sce->val4 == sg->group_id)
status_change_end(bl,type,-1);
break;
@@ -7067,7 +7070,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
struct block_list *target = map_id2bl(sg->val2);
if (target && target==bl)
{
- if (sc && sc->data[type].timer!=-1 && sc->data[type].val2 == sg->group_id)
+ if (sce && sce->val2 == sg->group_id)
status_change_end(bl,type,-1);
sg->limit = DIFF_TICK(tick,sg->tick)+1000;
}
@@ -7083,6 +7086,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int tick)
{
struct status_change *sc;
+ struct status_change_entry *sce;
int type;
sc = status_get_sc(bl);
@@ -7090,13 +7094,14 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
sc = NULL;
type = SkillStatusChangeTable(skill_id);
+ sce = (sc && type != -1)?sc->data[type]:NULL;
switch (skill_id)
{
case WZ_QUAGMIRE:
if (bl->type==BL_MOB)
break;
- if (sc && sc->data[type].timer != -1)
+ if (sce)
status_change_end(bl, type, -1);
break;
@@ -7108,7 +7113,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
case BD_ROKISWEIL:
case BD_INTOABYSS:
case BD_SIEGFRIED:
- if(sc && sc->data[SC_DANCING].timer != -1 && (sc->data[SC_DANCING].val1&0xFFFF) == skill_id)
+ if(sc && sc->data[SC_DANCING] && (sc->data[SC_DANCING]->val1&0xFFFF) == skill_id)
{ //Check if you just stepped out of your ensemble skill to cancel dancing. [Skotlex]
//We don't check for SC_LONGING because someone could always have knocked you back and out of the song/dance.
//FIXME: This code is not perfect, it doesn't checks for the real ensemble's owner,
@@ -7125,7 +7130,7 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
case CG_HERMODE:
case HW_GRAVITATION:
case NJ_SUITON:
- if (sc && sc->data[type].timer != -1)
+ if (sce)
status_change_end(bl, type, -1);
break;
@@ -7137,26 +7142,26 @@ static int skill_unit_onleft (int skill_id, struct block_list *bl, unsigned int
case DC_DONTFORGETME:
case DC_FORTUNEKISS:
case DC_SERVICEFORYOU:
- if (sc && sc->data[type].timer != -1)
+ if (sce)
{
- delete_timer(sc->data[type].timer, status_change_timer);
+ delete_timer(sce->timer, status_change_timer);
//NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas...
//not possible on our current implementation.
- sc->data[type].val4 = 1; //Store the fact that this is a "reduced" duration effect.
- sc->data[type].timer = add_timer(tick+skill_get_time2(skill_id,1), status_change_timer, bl->id, type);
+ sce->val4 = 1; //Store the fact that this is a "reduced" duration effect.
+ sce->timer = add_timer(tick+skill_get_time2(skill_id,1), status_change_timer, bl->id, type);
}
break;
case PF_FOGWALL:
- if (sc && sc->data[type].timer != -1)
+ if (sce)
{
status_change_end(bl,type,-1);
- if (sc->data[SC_BLIND].timer!=-1)
+ if ((sce=sc->data[SC_BLIND]))
{
if (bl->type == BL_PC) //Players get blind ended inmediately, others have it still for 30 secs. [Skotlex]
status_change_end(bl, SC_BLIND, -1);
else {
- delete_timer(sc->data[SC_BLIND].timer, status_change_timer);
- sc->data[SC_BLIND].timer = add_timer(30000+tick, status_change_timer, bl->id, SC_BLIND);
+ delete_timer(sce->timer, status_change_timer);
+ sce->timer = add_timer(30000+tick, status_change_timer, bl->id, SC_BLIND);
}
}
}
@@ -7298,7 +7303,7 @@ static int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
if(pc_isdead(tsd))
return 0;
- if (tsd->sc.count && (tsd->sc.data[SC_SILENCE].timer != -1 || tsd->sc.opt1))
+ if (tsd->sc.data[SC_SILENCE] || tsd->sc.opt1)
return 0;
switch(skillid)
@@ -7323,7 +7328,7 @@ static int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
(tsd->weapontype1==W_MUSICAL || tsd->weapontype1==W_WHIP) &&
sd->status.party_id && tsd->status.party_id &&
sd->status.party_id == tsd->status.party_id &&
- tsd->sc.data[SC_DANCING].timer == -1)
+ tsd->sc.data[SC_DANCING])
{
p_sd[(*c)++]=tsd->bl.id;
return skilllv;
@@ -7333,7 +7338,7 @@ static int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
}
break;
}
- //return 0;
+ return 0;
}
/*==========================================
@@ -7362,10 +7367,10 @@ int skill_check_pc_partner (struct map_session_data *sd, short skill_id, short*
}
return c;
default: //Warning: Assuming Ensemble skills here (for speed)
- if (c > 0 && (tsd = map_id2sd(p_sd[0])) != NULL)
+ if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map_id2sd(p_sd[0])) != NULL)
{
- sd->sc.data[SC_DANCING].val4= tsd->bl.id;
- sc_start4(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING].val2,*skill_lv,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000);
+ sd->sc.data[SC_DANCING]->val4 = tsd->bl.id;
+ sc_start4(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill_get_time(skill_id,*skill_lv)+1000);
clif_skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1);
tsd->skillid_dance = skill_id;
tsd->skilllv_dance = *skill_lv;
@@ -7503,7 +7508,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
//Consume
sd->itemid = sd->itemindex = -1;
if(skill == WZ_EARTHSPIKE && sc &&
- sc->data[SC_TKREST].timer != -1 && rand()%100 > sc->data[SC_TKREST].val2) // [marquis007]
+ sc->data[SC_TKREST] && rand()%100 > sc->data[SC_TKREST]->val2) // [marquis007]
; //Do not consume item.
else
pc_delitem(sd,i,1,0);
@@ -7569,7 +7574,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
zeny -= zeny*10/100;
break;
case AL_HOLYLIGHT:
- if(sc && sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_PRIEST)
+ if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_PRIEST)
sp *= 5;
break;
case SL_SMA:
@@ -7593,7 +7598,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
case MO_COMBOFINISH:
case CH_TIGERFIST:
case CH_CHAINCRUSH:
- if(sc && sc->data[SC_SPIRIT].timer!=-1 && sc->data[SC_SPIRIT].val2 == SL_MONK)
+ if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
sp -= sp*25/100; //FIXME: Need real data. this is a custom value.
break;
}
@@ -7619,7 +7624,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
case CR_SHRINK:
case TK_RUN:
case GS_GATLINGFEVER:
- if(sc && sc->data[SkillStatusChangeTable(skill)].timer!=-1)
+ if(sc && sc->data[SkillStatusChangeTable(skill)])
return 1; //Allow turning off.
break;
@@ -7646,38 +7651,38 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
else sd->spiritball_old = spiritball;
break;
case MO_BODYRELOCATION:
- if (sc && sc->data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ if (sc && sc->data[SC_EXPLOSIONSPIRITS])
spiritball = 0;
break;
case MO_CHAINCOMBO:
if(!sc)
return 0;
- if(sc->data[SC_BLADESTOP].timer!=-1)
+ if(sc->data[SC_BLADESTOP])
break;
- if(sc->data[SC_COMBO].timer != -1 && sc->data[SC_COMBO].val1 == MO_TRIPLEATTACK)
+ if(sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_TRIPLEATTACK)
break;
return 0;
- case MO_COMBOFINISH: //迪幃セ肴教
- if(!sc || sc->data[SC_COMBO].timer == -1 || sc->data[SC_COMBO].val1 != MO_CHAINCOMBO)
+ case MO_COMBOFINISH:
+ if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_CHAINCOMBO))
return 0;
break;
- case CH_TIGERFIST: //莨剰剋諡ウ
- if(!sc || sc->data[SC_COMBO].timer == -1 || sc->data[SC_COMBO].val1 != MO_COMBOFINISH)
+ case CH_TIGERFIST:
+ if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_COMBOFINISH))
return 0;
break;
- case CH_CHAINCRUSH: //騾」譟ア蟠ゥ謦
- if(!sc || sc->data[SC_COMBO].timer == -1)
+ case CH_CHAINCRUSH:
+ if(!(sc && sc->data[SC_COMBO]))
return 0;
- if(sc->data[SC_COMBO].val1 != MO_COMBOFINISH && sc->data[SC_COMBO].val1 != CH_TIGERFIST)
+ if(sc->data[SC_COMBO]->val1 != MO_COMBOFINISH && sc->data[SC_COMBO]->val1 != CH_TIGERFIST)
return 0;
break;
case MO_EXTREMITYFIST:
-// if(sc && sc->data[SC_EXTREMITYFIST].timer != -1) //To disable Asura during the 5 min skill block uncomment this...
+// if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this...
// return 0;
- if(sc && sc->data[SC_BLADESTOP].timer!=-1)
+ if(sc && sc->data[SC_BLADESTOP])
spiritball--;
- else if (sc && sc->data[SC_COMBO].timer != -1) {
- switch(sc->data[SC_COMBO].val1) {
+ else if (sc && sc->data[SC_COMBO]) {
+ switch(sc->data[SC_COMBO]->val1) {
case MO_COMBOFINISH:
spiritball = 4;
break;
@@ -7708,7 +7713,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
case TK_READYDOWN:
case TK_READYSTORM:
case TK_READYTURN:
- if(sc && sc->data[SkillStatusChangeTable(skill)].timer!=-1)
+ if(sc && sc->data[SkillStatusChangeTable(skill)])
return 1; //Enable disabling them regardless of who you are.
case TK_JUMPKICK:
if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) {
@@ -7724,7 +7729,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
case TK_COUNTER:
if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
- if(!sc || sc->data[SC_COMBO].timer == -1)
+ if(!(sc && sc->data[SC_COMBO]))
return 0; //Combo needs to be ready
if (pc_famerank(sd->status.char_id,MAPID_TAEKWON))
{ //Unlimited Combo
@@ -7735,23 +7740,23 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
}
break;
} else
- if(sc->data[SC_COMBO].val1 == skill)
+ if(sc->data[SC_COMBO]->val1 == skill)
break; //Combo ready.
//Cancel combo wait.
unit_cancel_combo(&sd->bl);
return 0;
- case BD_ADAPTATION: /* 繧「繝峨Μ繝 */
+ case BD_ADAPTATION:
{
int time;
- if(!sc || sc->data[SC_DANCING].timer==-1)
+ if(!(sc && sc->data[SC_DANCING]))
{
clif_skill_fail(sd,skill,0,0);
return 0;
}
- time = 1000*(sc->data[SC_DANCING].val3>>16);
+ time = 1000*(sc->data[SC_DANCING]->val3>>16);
if (skill_get_time(
- (sc->data[SC_DANCING].val1&0xFFFF), //Dance Skill ID
- (sc->data[SC_DANCING].val1>>16)) //Dance Skill LV
+ (sc->data[SC_DANCING]->val1&0xFFFF), //Dance Skill ID
+ (sc->data[SC_DANCING]->val1>>16)) //Dance Skill LV
- time <= skill_get_time2(skill,lv))
{
clif_skill_fail(sd,skill,0,0);
@@ -7800,12 +7805,12 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
break;
case SL_SMA:
if(type) break; //Only do the combo check when the target is selected (type == 0)
- if(!sc || sc->data[SC_SMA].timer == -1)
+ if(!(sc && sc->data[SC_SMA]))
return 0;
break;
case HT_POWER:
- if(!sc || sc->data[SC_COMBO].timer == -1 || sc->data[SC_COMBO].val1 != skill)
+ if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill))
return 0;
break;
case SA_DELUGE:
@@ -7870,30 +7875,30 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
case SG_SUN_WARM:
case SG_MOON_WARM:
case SG_STAR_WARM:
- if ((sd->bl.m == sd->feel_map[skill-SG_SUN_WARM].m) || (sc && sc->data[SC_MIRACLE].timer!=-1))
+ if ((sd->bl.m == sd->feel_map[skill-SG_SUN_WARM].m) || (sc && sc->data[SC_MIRACLE]))
break;
clif_skill_fail(sd,skill,0,0);
return 0;
break;
case SG_SUN_COMFORT:
- if ((sd->bl.m == sd->feel_map[0].m && (battle_config.allow_skill_without_day || is_day_of_sun())) || (sc && sc->data[SC_MIRACLE].timer!=-1))
+ if ((sd->bl.m == sd->feel_map[0].m && (battle_config.allow_skill_without_day || is_day_of_sun())) || (sc && sc->data[SC_MIRACLE]))
break;
clif_skill_fail(sd,skill,0,0);
return 0;
case SG_MOON_COMFORT:
- if ((sd->bl.m == sd->feel_map[1].m && (battle_config.allow_skill_without_day || is_day_of_moon())) || (sc && sc->data[SC_MIRACLE].timer!=-1))
+ if ((sd->bl.m == sd->feel_map[1].m && (battle_config.allow_skill_without_day || is_day_of_moon())) || (sc && sc->data[SC_MIRACLE]))
break;
clif_skill_fail(sd,skill,0,0);
return 0;
case SG_STAR_COMFORT:
- if ((sd->bl.m == sd->feel_map[2].m && (battle_config.allow_skill_without_day || is_day_of_star())) || (sc && sc->data[SC_MIRACLE].timer!=-1))
+ if ((sd->bl.m == sd->feel_map[2].m && (battle_config.allow_skill_without_day || is_day_of_star())) || (sc && sc->data[SC_MIRACLE]))
break;
clif_skill_fail(sd,skill,0,0);
return 0;
case SG_FUSION:
- if (sc && sc->data[SC_FUSION].timer!=-1)
+ if (sc && sc->data[SC_FUSION])
return 1;
- if (sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_STAR)
+ if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_STAR)
break;
//Auron insists we should implement SP consumption when you are not Soul Linked. [Skotlex]
if(sp>0 && type&1)
@@ -7930,7 +7935,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
return 0;
}
case NJ_BUNSINJYUTSU:
- if (!sc || sc->data[SC_NEN].timer==-1) {
+ if (!(sc && sc->data[SC_NEN])) {
clif_skill_fail(sd,skill,0,0);
return 0;
}
@@ -8035,6 +8040,11 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
return 0;
}
break;
+ case ST_CARTBOOST:
+ if(!(sc && sc->data[SC_CARTBOOST])) {
+ clif_skill_fail(sd,skill,0,0);
+ return 0;
+ }
case ST_CART:
if(!pc_iscarton(sd)) {
clif_skill_fail(sd,skill,0,0);
@@ -8048,19 +8058,13 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
}
break;
case ST_SIGHT:
- if(!sc || sc->data[SC_SIGHT].timer == -1) {
+ if(!(sc && sc->data[SC_SIGHT])) {
clif_skill_fail(sd,skill,0,0);
return 0;
}
break;
case ST_EXPLOSIONSPIRITS:
- if(!sc || sc->data[SC_EXPLOSIONSPIRITS].timer == -1) {
- clif_skill_fail(sd,skill,0,0);
- return 0;
- }
- break;
- case ST_CARTBOOST:
- if(!pc_iscarton(sd) || !sc || sc->data[SC_CARTBOOST].timer == -1) {
+ if(!(sc && sc->data[SC_EXPLOSIONSPIRITS])) {
clif_skill_fail(sd,skill,0,0);
return 0;
}
@@ -8072,7 +8076,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
}
break;
case ST_MOVE_ENABLE:
- if (sc && sc->data[SC_COMBO].timer != -1 && sc->data[SC_COMBO].val1 == skill)
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill)
sd->ud.canmove_tick = gettick(); //When using a combo, cancel the can't move delay to enable the skill. [Skotlex]
if (!unit_can_move(&sd->bl)) {
@@ -8081,7 +8085,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
}
break;
case ST_WATER:
- if (sc && (sc->data[SC_DELUGE].timer != -1 || sc->data[SC_SUITON].timer != -1))
+ if (sc && (sc->data[SC_DELUGE] || sc->data[SC_SUITON]))
break;
if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))
break;
@@ -8109,7 +8113,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
if (--amount[i] < 1)
continue;
}
- if(sc && sc->data[SC_INTOABYSS].timer != -1)
+ if(sc && sc->data[SC_INTOABYSS])
continue;
}
@@ -8129,7 +8133,7 @@ int skill_check_condition(struct map_session_data* sd, short skill, short lv, in
return 0;
}
if( itemid_isgemstone(itemid[i]) && skill != HW_GANBANTEIN &&
- sc && sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_WIZARD)
+ sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD)
index[i] = -1; //Gemstones are checked, but not substracted from inventory.
}
@@ -8204,21 +8208,21 @@ int skill_castfix_sc (struct block_list *bl, int time)
struct status_change *sc = status_get_sc(bl);
if (sc && sc->count) {
- if (sc->data[SC_SLOWCAST].timer != -1)
- time += time * sc->data[SC_SLOWCAST].val2 / 100;
- if (sc->data[SC_FASTCAST].timer != -1)
- time -= time * sc->data[SC_FASTCAST].val1 / 100;
- if (sc->data[SC_SUFFRAGIUM].timer != -1) {
- time -= time * sc->data[SC_SUFFRAGIUM].val2 / 100;
+ if (sc->data[SC_SLOWCAST])
+ time += time * sc->data[SC_SLOWCAST]->val2 / 100;
+ if (sc->data[SC_FASTCAST])
+ time -= time * sc->data[SC_FASTCAST]->val1 / 100;
+ if (sc->data[SC_SUFFRAGIUM]) {
+ time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
status_change_end(bl, SC_SUFFRAGIUM, -1);
}
- if (sc->data[SC_MEMORIZE].timer != -1) {
+ if (sc->data[SC_MEMORIZE]) {
time>>=1;
- if ((--sc->data[SC_MEMORIZE].val2) <= 0)
+ if ((--sc->data[SC_MEMORIZE]->val2) <= 0)
status_change_end(bl, SC_MEMORIZE, -1);
}
- if (sc->data[SC_POEMBRAGI].timer != -1)
- time -= time * sc->data[SC_POEMBRAGI].val2 / 100;
+ if (sc->data[SC_POEMBRAGI])
+ time -= time * sc->data[SC_POEMBRAGI]->val2 / 100;
}
return (time > 0) ? time : 0;
}
@@ -8273,16 +8277,16 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
struct status_change *sc;
sc= status_get_sc(bl);
if (sc && sc->count) {
- if (sc->data[SC_POEMBRAGI].timer != -1)
- time -= time * sc->data[SC_POEMBRAGI].val3 / 100;
- if (sc->data[SC_SPIRIT].timer != -1)
+ if (sc->data[SC_POEMBRAGI])
+ time -= time * sc->data[SC_POEMBRAGI]->val3 / 100;
+ if (sc->data[SC_SPIRIT])
switch (skill_id) {
case CR_SHIELDBOOMERANG:
- if (sc->data[SC_SPIRIT].val2 == SL_CRUSADER)
+ if (sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
time /=2;
break;
case AS_SONICBLOW:
- if (!map_flag_gvg(bl->m) && sc->data[SC_SPIRIT].val2 == SL_ASSASIN)
+ if (!map_flag_gvg(bl->m) && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
time /= 2;
break;
}
@@ -8584,7 +8588,7 @@ int skill_autospell (struct map_session_data *sd, int skillid)
if(skillid==MG_NAPALMBEAT) maxlv=3;
else if(skillid==MG_COLDBOLT || skillid==MG_FIREBOLT || skillid==MG_LIGHTNINGBOLT){
- if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_SAGE)
+ if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SAGE)
maxlv =10; //Soul Linker bonus. [Skotlex]
else if(skilllv==2) maxlv=1;
else if(skilllv==3) maxlv=2;
@@ -9098,34 +9102,21 @@ int skill_trap_splash (struct block_list *bl, va_list ap)
int skill_enchant_elemental_end (struct block_list *bl, int type)
{
struct status_change *sc;
-
+ const enum sc_type scs[] = { SC_ENCPOISON, SC_ASPERSIO, SC_FIREWEAPON, SC_WATERWEAPON, SC_WINDWEAPON, SC_EARTHWEAPON, SC_SHADOWWEAPON, SC_GHOSTWEAPON, SC_ENCHANTARMS };
+ int i;
nullpo_retr(0, bl);
nullpo_retr(0, sc= status_get_sc(bl));
if (!sc->count) return 0;
-
- if (type != SC_ENCPOISON && sc->data[SC_ENCPOISON].timer != -1)
- status_change_end(bl, SC_ENCPOISON, -1);
- if (type != SC_ASPERSIO && sc->data[SC_ASPERSIO].timer != -1)
- status_change_end(bl, SC_ASPERSIO, -1);
- if (type != SC_FIREWEAPON && sc->data[SC_FIREWEAPON].timer != -1)
- status_change_end(bl, SC_FIREWEAPON, -1);
- if (type != SC_WATERWEAPON && sc->data[SC_WATERWEAPON].timer != -1)
- status_change_end(bl, SC_WATERWEAPON, -1);
- if (type != SC_WINDWEAPON && sc->data[SC_WINDWEAPON].timer != -1)
- status_change_end(bl, SC_WINDWEAPON, -1);
- if (type != SC_EARTHWEAPON && sc->data[SC_EARTHWEAPON].timer != -1)
- status_change_end(bl, SC_EARTHWEAPON, -1);
- if (type != SC_SHADOWWEAPON && sc->data[SC_SHADOWWEAPON].timer != -1)
- status_change_end(bl, SC_SHADOWWEAPON, -1);
- if (type != SC_GHOSTWEAPON && sc->data[SC_GHOSTWEAPON].timer != -1)
- status_change_end(bl, SC_GHOSTWEAPON, -1);
- if (type != SC_ENCHANTARMS && sc->data[SC_ENCHANTARMS].timer != -1)
- status_change_end(bl, SC_ENCHANTARMS, -1);
+
+ for (i = 0; i < ARRAYLENGTH(scs); i++)
+ if (type != scs[i] && sc->data[scs[i]])
+ status_change_end(bl, scs[i], -1);
+
return 0;
}
-int skill_check_cloaking(struct block_list *bl, struct status_change *sc)
+int skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce)
{
static int dx[] = { 0, 1, 0, -1, -1, 1, 1, -1}; //optimized by Lupus
static int dy[] = {-1, 0, 1, 0, -1, -1, 1, 1};
@@ -9142,21 +9133,21 @@ int skill_check_cloaking(struct block_list *bl, struct status_change *sc)
}
} else
end = 0; //No wall check.
-
+
+ if(!sce) return end; //Just report.
+
if(end){
- if (sc->data[SC_CLOAKING].timer != -1) {
- if (sc->data[SC_CLOAKING].val1 < 3) //End cloaking.
- status_change_end(bl, SC_CLOAKING, -1);
- else if(sc->data[SC_CLOAKING].val4&1)
- { //Remove wall bonus
- sc->data[SC_CLOAKING].val4&=~1;
- status_calc_bl(bl,SCB_SPEED);
- }
- }
+ if (sce->val1 < 3) //End cloaking.
+ status_change_end(bl, SC_CLOAKING, -1);
+ else if(sce->val4&1)
+ { //Remove wall bonus
+ sce->val4&=~1;
+ status_calc_bl(bl,SCB_SPEED);
+ }
}
- else if(sc->data[SC_CLOAKING].timer != -1 && !(sc->data[SC_CLOAKING].val4&1))
+ else if(!(sce->val4&1))
{ //Add wall speed bonus
- sc->data[SC_CLOAKING].val4|=1;
+ sce->val4|=1;
status_calc_bl(bl,SCB_SPEED);
}
@@ -9170,30 +9161,31 @@ int skill_check_cloaking(struct block_list *bl, struct status_change *sc)
void skill_stop_dancing (struct block_list *src)
{
struct status_change* sc;
+ struct status_change_entry *sce;
struct skill_unit_group* group;
struct map_session_data* dsd = NULL;
nullpo_retv(src);
nullpo_retv(sc = status_get_sc(src));
- if(!sc->count || sc->data[SC_DANCING].timer == -1)
+ if(!sc->count || !(sce=sc->data[SC_DANCING]))
return;
- group = (struct skill_unit_group *)sc->data[SC_DANCING].val2;
- sc->data[SC_DANCING].val2 = 0;
+ group = (struct skill_unit_group *)sce->val2;
+ sce->val2 = 0;
- if (sc->data[SC_DANCING].val4)
+ if (sce->val4)
{
- if (sc->data[SC_DANCING].val4 != BCT_SELF)
- dsd = map_id2sd(sc->data[SC_DANCING].val4);
- sc->data[SC_DANCING].val4 = 0;
+ if (sce->val4 != BCT_SELF)
+ dsd = map_id2sd(sce->val4);
+ sce->val4 = 0;
}
status_change_end(src, SC_DANCING, -1);
- if (dsd)
+ if (dsd && (sce=dsd->sc.data[SC_DANCING]))
{
- dsd->sc.data[SC_DANCING].val4 = dsd->sc.data[SC_DANCING].val2 = 0;
+ sce->val4 = sce->val2 = 0;
status_change_end(&dsd->bl, SC_DANCING, -1);
}
@@ -9385,9 +9377,9 @@ int skill_delunitgroup (struct block_list *src, struct skill_unit_group *group)
if (skill_get_unit_flag(group->skill_id)&(UF_DANCE|UF_SONG|UF_ENSEMBLE))
{
struct status_change* sc = status_get_sc(src);
- if (sc && sc->data[SC_DANCING].timer != -1)
+ if (sc && sc->data[SC_DANCING])
{
- sc->data[SC_DANCING].val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex]
+ sc->data[SC_DANCING]->val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex]
status_change_end(src,SC_DANCING,-1);
}
}
@@ -9396,8 +9388,8 @@ int skill_delunitgroup (struct block_list *src, struct skill_unit_group *group)
// (needs to be done when the group is deleted by other means than skill deactivation)
if (group->unit_id == UNT_GOSPEL) {
struct status_change *sc = status_get_sc(src);
- if(sc && sc->data[SC_GOSPEL].timer != -1) {
- sc->data[SC_GOSPEL].val3 = 0; //Remove reference to this group. [Skotlex]
+ if(sc && sc->data[SC_GOSPEL]) {
+ sc->data[SC_GOSPEL]->val3 = 0; //Remove reference to this group. [Skotlex]
status_change_end(src,SC_GOSPEL,-1);
}
}
@@ -9406,8 +9398,8 @@ int skill_delunitgroup (struct block_list *src, struct skill_unit_group *group)
group->skill_id == SG_MOON_WARM ||
group->skill_id == SG_STAR_WARM) {
struct status_change *sc = status_get_sc(src);
- if(sc && sc->data[SC_WARM].timer != -1) {
- sc->data[SC_WARM].val4 = 0;
+ if(sc && sc->data[SC_WARM]) {
+ sc->data[SC_WARM]->val4 = 0;
status_change_end(src,SC_WARM,-1);
}
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 5ddd5b27c..9bff96961 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -246,7 +246,7 @@ int skill_autospell(struct map_session_data *md,int skillid);
int skill_calc_heal(struct block_list *src, struct block_list *target, int skill_lv);
-int skill_check_cloaking(struct block_list *bl, struct status_change *sc);
+int skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce);
// ステ?タス異常
int skill_enchant_elemental_end(struct block_list *bl, int type);
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);
+}
diff --git a/src/map/status.h b/src/map/status.h
index 71f84e93d..f1932ae32 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -272,10 +272,10 @@ enum sc_type {
SC_MAGICMIRROR,
SC_SLOWCAST,
SC_SUMMER,
- SC_EXPBOOST, // Field Guide
- SC_ITEMBOOST, // Bubble Gum
- SC_BOSSMAPINFO, // Convex Mirror
- SC_LIFEINSURANCE, // Life Insurance
+ SC_EXPBOOST,
+ SC_ITEMBOOST,
+ SC_BOSSMAPINFO,
+ SC_LIFEINSURANCE, //260
SC_INCCRI,
SC_INCDEF,
SC_INCBASEATK,
@@ -692,5 +692,6 @@ int status_check_visibility(struct block_list *src, struct block_list *target);
int status_readdb(void);
int do_init_status(void);
+void do_final_status(void);
#endif /* _STATUS_H_ */
diff --git a/src/map/unit.c b/src/map/unit.c
index 0dd464a67..0e01517dc 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -299,7 +299,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
ud->to_y = y;
sc = status_get_sc(bl);
- if (sc && sc->count && sc->data[SC_CONFUSION].timer != -1) //Randomize the target position
+ if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != -1) {
@@ -367,7 +367,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
ud->state.attack_continue = flag&2?1:0; //Chase to attack.
sc = status_get_sc(bl);
- if (sc && sc->count && sc->data[SC_CONFUSION].timer != -1) //Randomize the target position
+ if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
map_random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != -1) {
@@ -404,19 +404,18 @@ int unit_run(struct block_list *bl)
short to_x,to_y,dir_x,dir_y;
int i;
- if (!sc || !sc->count || sc->data[SC_RUN].timer == -1)
+ if (!(sc && sc->data[SC_RUN]))
return 0;
if (!unit_can_move(bl)) {
- if(sc->data[SC_RUN].timer!=-1)
- status_change_end(bl,SC_RUN,-1);
+ status_change_end(bl,SC_RUN,-1);
return 0;
}
to_x = bl->x;
to_y = bl->y;
- dir_x = dirx[sc->data[SC_RUN].val2];
- dir_y = diry[sc->data[SC_RUN].val2];
+ dir_x = dirx[sc->data[SC_RUN]->val2];
+ dir_y = diry[sc->data[SC_RUN]->val2];
for(i=0;i<AREA_SIZE;i++)
{
@@ -430,7 +429,7 @@ int unit_run(struct block_list *bl)
//If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
clif_status_change(bl, SI_BUMP, 1);
status_change_end(bl,SC_RUN,-1);
- skill_blown(bl,bl,skill_get_blewcount(TK_RUN,sc->data[SC_RUN].val1),unit_getdir(bl),0);
+ skill_blown(bl,bl,skill_get_blewcount(TK_RUN,sc->data[SC_RUN]->val1),unit_getdir(bl),0);
clif_fixpos(bl); //Why is a clif_slide (skill_blown) AND a fixpos needed? Ask Aegis.
clif_status_change(bl, SI_BUMP, 0);
return 0;
@@ -446,7 +445,7 @@ int unit_run(struct block_list *bl)
// copy-paste from above
clif_status_change(bl, SI_BUMP, 1);
status_change_end(bl,SC_RUN,-1);
- skill_blown(bl,bl,skill_get_blewcount(TK_RUN,sc->data[SC_RUN].val1),unit_getdir(bl),0);
+ skill_blown(bl,bl,skill_get_blewcount(TK_RUN,sc->data[SC_RUN]->val1),unit_getdir(bl),0);
clif_fixpos(bl);
clif_status_change(bl, SI_BUMP, 0);
return 0;
@@ -722,25 +721,25 @@ int unit_can_move(struct block_list *bl)
return 0;
if (sc->count && (
- sc->data[SC_ANKLE].timer != -1
- || sc->data[SC_AUTOCOUNTER].timer !=-1
- || sc->data[SC_TRICKDEAD].timer !=-1
- || sc->data[SC_BLADESTOP].timer !=-1
- || sc->data[SC_BLADESTOP_WAIT].timer !=-1
- || sc->data[SC_SPIDERWEB].timer !=-1
- || (sc->data[SC_DANCING].timer !=-1 && sc->data[SC_DANCING].val4 && (
- sc->data[SC_LONGING].timer == -1 ||
- (sc->data[SC_DANCING].val1&0xFFFF) == CG_MOONLIT ||
- (sc->data[SC_DANCING].val1&0xFFFF) == CG_HERMODE
+ sc->data[SC_ANKLE]
+ || sc->data[SC_AUTOCOUNTER]
+ || sc->data[SC_TRICKDEAD]
+ || sc->data[SC_BLADESTOP]
+ || sc->data[SC_BLADESTOP_WAIT]
+ || sc->data[SC_SPIDERWEB]
+ || (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
+ sc->data[SC_LONGING] ||
+ (sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
+ (sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
))
- || (sc->data[SC_GOSPEL].timer !=-1 && sc->data[SC_GOSPEL].val4 == BCT_SELF) // cannot move while gospel is in effect
- || sc->data[SC_STOP].timer != -1
- || sc->data[SC_CLOSECONFINE].timer != -1
- || sc->data[SC_CLOSECONFINE2].timer != -1
- || (sc->data[SC_CLOAKING].timer != -1 && //Need wall at level 1-2
- sc->data[SC_CLOAKING].val1 < 3 && !(sc->data[SC_CLOAKING].val4&1))
- || sc->data[SC_MADNESSCANCEL].timer != -1
- || (sc->data[SC_GRAVITATION].timer != -1 && sc->data[SC_GRAVITATION].val3 == BCT_SELF)
+ || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
+ || sc->data[SC_STOP]
+ || sc->data[SC_CLOSECONFINE]
+ || sc->data[SC_CLOSECONFINE2]
+ || (sc->data[SC_CLOAKING] && //Need wall at level 1-2
+ sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
+ || sc->data[SC_MADNESSCANCEL]
+ || (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
))
return 0;
}
@@ -817,16 +816,16 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
switch(skill_num)
{ //Check for skills that auto-select target
case MO_CHAINCOMBO:
- if (sc && sc->data[SC_BLADESTOP].timer != -1){
- if ((target=(struct block_list *)sc->data[SC_BLADESTOP].val4) == NULL)
+ if (sc && sc->data[SC_BLADESTOP]){
+ if ((target=(struct block_list *)sc->data[SC_BLADESTOP]->val4) == NULL)
return 0;
}
break;
case TK_JUMPKICK:
case TK_COUNTER:
case HT_POWER:
- if (sc && sc->data[SC_COMBO].timer != -1 && sc->data[SC_COMBO].val1 == skill_num)
- target_id = sc->data[SC_COMBO].val2;
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_num)
+ target_id = sc->data[SC_COMBO]->val2;
break;
case WE_MALE:
case WE_FEMALE:
@@ -958,10 +957,10 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
casttime += casttime * min(skill_lv, sd->spiritball);
break;
case MO_EXTREMITYFIST:
- if (sc && sc->data[SC_COMBO].timer != -1 &&
- (sc->data[SC_COMBO].val1 == MO_COMBOFINISH ||
- sc->data[SC_COMBO].val1 == CH_TIGERFIST ||
- sc->data[SC_COMBO].val1 == CH_CHAINCRUSH))
+ if (sc && sc->data[SC_COMBO] &&
+ (sc->data[SC_COMBO]->val1 == MO_COMBOFINISH ||
+ sc->data[SC_COMBO]->val1 == CH_TIGERFIST ||
+ sc->data[SC_COMBO]->val1 == CH_CHAINCRUSH))
casttime = 0;
temp = 1;
break;
@@ -969,11 +968,11 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
temp = 1;
break;
case ST_CHASEWALK:
- if (sc && sc->data[SC_CHASEWALK].timer != -1)
+ if (sc && sc->data[SC_CHASEWALK])
casttime = 0;
break;
case TK_RUN:
- if (sc && sc->data[SC_RUN].timer != -1)
+ if (sc && sc->data[SC_RUN])
casttime = 0;
break;
case KN_CHARGEATK:
@@ -1033,8 +1032,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
ud->skillid = skill_num;
ud->skilllv = skill_lv;
- if(sc && sc->data[SC_CLOAKING].timer != -1 &&
- !(sc->data[SC_CLOAKING].val4&4) && skill_num != AS_CLOAKING)
+ if(sc && sc->data[SC_CLOAKING] &&
+ !(sc->data[SC_CLOAKING]->val4&4) && skill_num != AS_CLOAKING)
{
status_change_end(src,SC_CLOAKING,-1);
if (!src->prev) return 0; //Warped away!
@@ -1137,8 +1136,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, sh
ud->skilly = skill_y;
ud->skilltarget = 0;
- if (sc && sc->data[SC_CLOAKING].timer != -1 &&
- !(sc->data[SC_CLOAKING].val4&4))
+ if (sc && sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4))
{
status_change_end(src,SC_CLOAKING,-1);
if (!src->prev) return 0; //Warped away!
@@ -1621,43 +1619,43 @@ int unit_remove_map(struct block_list *bl, int clrtype)
ud->attackabletime = ud->canmove_tick /*= ud->canact_tick*/ = gettick();
if(sc && sc->count ) { //map-change/warp dispells.
- if(sc->data[SC_BLADESTOP].timer!=-1)
+ if(sc->data[SC_BLADESTOP])
status_change_end(bl,SC_BLADESTOP,-1);
- if(sc->data[SC_BASILICA].timer!=-1)
+ if(sc->data[SC_BASILICA])
status_change_end(bl,SC_BASILICA,-1);
- if(sc->data[SC_ANKLE].timer != -1)
+ if(sc->data[SC_ANKLE])
status_change_end(bl, SC_ANKLE, -1);
- if (sc->data[SC_TRICKDEAD].timer != -1)
+ if (sc->data[SC_TRICKDEAD])
status_change_end(bl, SC_TRICKDEAD, -1);
- if (sc->data[SC_BLADESTOP].timer!=-1)
+ if (sc->data[SC_BLADESTOP])
status_change_end(bl,SC_BLADESTOP,-1);
- if (sc->data[SC_RUN].timer!=-1)
+ if (sc->data[SC_RUN])
status_change_end(bl,SC_RUN,-1);
- if (sc->data[SC_DANCING].timer!=-1) // clear dance effect when warping [Valaris]
+ if (sc->data[SC_DANCING]) // clear dance effect when warping [Valaris]
skill_stop_dancing(bl);
- if (sc->data[SC_WARM].timer!=-1)
+ if (sc->data[SC_WARM])
status_change_end(bl, SC_WARM, -1);
- if (sc->data[SC_DEVOTION].timer!=-1)
+ if (sc->data[SC_DEVOTION])
status_change_end(bl,SC_DEVOTION,-1);
- if (sc->data[SC_MARIONETTE].timer!=-1)
+ if (sc->data[SC_MARIONETTE])
status_change_end(bl,SC_MARIONETTE,-1);
- if (sc->data[SC_MARIONETTE2].timer!=-1)
+ if (sc->data[SC_MARIONETTE2])
status_change_end(bl,SC_MARIONETTE2,-1);
- 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);
- if (sc->data[SC_HIDING].timer!=-1)
+ if (sc->data[SC_HIDING])
status_change_end(bl, SC_HIDING, -1);
- if (sc->data[SC_CLOAKING].timer!=-1)
+ if (sc->data[SC_CLOAKING])
status_change_end(bl, SC_CLOAKING, -1);
- if (sc->data[SC_CHASEWALK].timer!=-1)
+ if (sc->data[SC_CHASEWALK])
status_change_end(bl, SC_CHASEWALK, -1);
- 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);
- if (sc->data[SC_CHANGE].timer!=-1)
+ if (sc->data[SC_CHANGE])
status_change_end(bl, SC_CHANGE, -1);
- if (sc->data[SC_MIRACLE].timer!=-1)
+ if (sc->data[SC_MIRACLE])
status_change_end(bl, SC_MIRACLE, -1);
}
@@ -1764,39 +1762,39 @@ int unit_free(struct block_list *bl, int clrtype)
//Status that are not saved...
if(sd->sc.count) {
- if(sd->sc.data[SC_SPURT].timer!=-1)
+ if(sd->sc.data[SC_SPURT])
status_change_end(bl,SC_SPURT,-1);
- if(sd->sc.data[SC_BERSERK].timer!=-1)
+ if(sd->sc.data[SC_BERSERK])
status_change_end(bl,SC_BERSERK,-1);
- if(sd->sc.data[SC_TRICKDEAD].timer!=-1)
+ if(sd->sc.data[SC_TRICKDEAD])
status_change_end(bl,SC_TRICKDEAD,-1);
- if(sd->sc.data[SC_GUILDAURA].timer!=-1)
+ if(sd->sc.data[SC_GUILDAURA])
status_change_end(bl,SC_GUILDAURA,-1);
if (battle_config.debuff_on_logout&1) {
- if(sd->sc.data[SC_ORCISH].timer!=-1)
+ if(sd->sc.data[SC_ORCISH])
status_change_end(bl,SC_ORCISH,-1);
- if(sd->sc.data[SC_STRIPWEAPON].timer!=-1)
+ if(sd->sc.data[SC_STRIPWEAPON])
status_change_end(bl,SC_STRIPWEAPON,-1);
- if(sd->sc.data[SC_STRIPARMOR].timer!=-1)
+ if(sd->sc.data[SC_STRIPARMOR])
status_change_end(bl,SC_STRIPARMOR,-1);
- if(sd->sc.data[SC_STRIPSHIELD].timer!=-1)
+ if(sd->sc.data[SC_STRIPSHIELD])
status_change_end(bl,SC_STRIPSHIELD,-1);
- if(sd->sc.data[SC_STRIPHELM].timer!=-1)
+ if(sd->sc.data[SC_STRIPHELM])
status_change_end(bl,SC_STRIPHELM,-1);
- if(sd->sc.data[SC_EXTREMITYFIST].timer!=-1)
+ if(sd->sc.data[SC_EXTREMITYFIST])
status_change_end(bl,SC_EXTREMITYFIST,-1);
- if(sd->sc.data[SC_EXPLOSIONSPIRITS].timer!=-1)
+ if(sd->sc.data[SC_EXPLOSIONSPIRITS])
status_change_end(bl,SC_EXPLOSIONSPIRITS,-1);
- if(sd->sc.data[SC_REGENERATION].timer!=-1 && sd->sc.data[SC_REGENERATION].val4)
+ if(sd->sc.data[SC_REGENERATION] && sd->sc.data[SC_REGENERATION]->val4)
status_change_end(bl,SC_REGENERATION,-1);
}
if (battle_config.debuff_on_logout&2)
{
- if(sd->sc.data[SC_MAXIMIZEPOWER].timer!=-1)
+ if(sd->sc.data[SC_MAXIMIZEPOWER])
status_change_end(bl,SC_MAXIMIZEPOWER,-1);
- if(sd->sc.data[SC_MAXOVERTHRUST].timer!=-1)
+ if(sd->sc.data[SC_MAXOVERTHRUST])
status_change_end(bl,SC_MAXOVERTHRUST,-1);
- if(sd->sc.data[SC_STEELBODY].timer!=-1)
+ if(sd->sc.data[SC_STEELBODY])
status_change_end(bl,SC_STEELBODY,-1);
}
}