summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c3
-rw-r--r--src/map/chrif.c3
-rw-r--r--src/map/mercenary.c2
-rw-r--r--src/map/mob.c3
-rw-r--r--src/map/script.c19
-rw-r--r--src/map/skill.c73
-rw-r--r--src/map/status.c92
-rw-r--r--src/map/status.h20
8 files changed, 119 insertions, 96 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index b788c6c37..299ee321a 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -5469,7 +5469,8 @@ ACMD(autotrade) {
sd->state.autotrade = 1;
if( battle_config.at_timeout ) {
int timeout = atoi(message);
- status->change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
+ status->change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0,
+ ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, SCFLAG_NONE);
}
/* currently standalone is not supporting buyingstores, so we rely on the previous method */
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 4c8cd747b..34e92bee0 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -1178,7 +1178,8 @@ bool 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));
- status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
+ status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4,
+ data->tick, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE);
}
pc->scdata_received(sd);
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 80bcfdf05..a1503e97a 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -362,7 +362,7 @@ int mercenary_killbonus(struct mercenary_data *md)
const enum sc_type scs[] = { SC_MER_FLEE, SC_MER_ATK, SC_MER_HP, SC_MER_SP, SC_MER_HIT };
int index = rnd() % ARRAYLENGTH(scs);
- sc_start(NULL,&md->bl, scs[index], 100, rnd() % 5, 600000);
+ sc_start(NULL,&md->bl, scs[index], 100, rnd() % 5, 600000);
return 0;
}
diff --git a/src/map/mob.c b/src/map/mob.c
index fd2c4213f..ffab804a6 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -418,7 +418,8 @@ bool mob_ksprotected(struct block_list *src, struct block_list *target) {
return true;
} while(0);
- status->change_start(NULL, target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0);
+ status->change_start(NULL, target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks,
+ sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, SCFLAG_NONE);
return false;
}
diff --git a/src/map/script.c b/src/map/script.c
index dee678b4c..3b5264de9 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -10087,14 +10087,9 @@ BUILDIN(hideonnpc)
* sc_start <effect_id>,<duration>,<val1>{,<rate>,<flag>,{<unit_id>}};
* sc_start2 <effect_id>,<duration>,<val1>,<val2>{,<rate,<flag>,{<unit_id>}};
* sc_start4 <effect_id>,<duration>,<val1>,<val2>,<val3>,<val4>{,<rate,<flag>,{<unit_id>}};
- * <flag>
- * &1: Cannot be avoided (it has to start)
- * &2: Tick should not be reduced (by vit, luk, lv, etc)
- * &4: sc_data loaded, no value has to be altered.
- * &8: rate should not be reduced
+ * <flag>: @see enum scstart_flag
*/
-BUILDIN(sc_start)
-{
+BUILDIN(sc_start) {
TBL_NPC * nd = map->id2nd(st->oid);
struct block_list* bl;
enum sc_type type;
@@ -10113,11 +10108,11 @@ BUILDIN(sc_start)
tick = script_getnum(st,3);
val1 = script_getnum(st,4);
- //If from NPC we make default flag 1 to be unavoidable
+ //If from NPC we make default flag SCFLAG_NOAVOID to be unavoidable
if(nd && nd->bl.id == npc->fake_nd->bl.id)
- flag = script_hasdata(st,5+start_type)?script_getnum(st,5+start_type):2;
+ flag = script_hasdata(st,5+start_type) ? script_getnum(st,5+start_type) : SCFLAG_FIXEDTICK;
else
- flag = script_hasdata(st,5+start_type)?script_getnum(st,5+start_type):1;
+ flag = script_hasdata(st,5+start_type) ? script_getnum(st,5+start_type) : SCFLAG_NOAVOID;
rate = script_hasdata(st,4+start_type)?min(script_getnum(st,4+start_type),10000):10000;
@@ -10220,7 +10215,7 @@ BUILDIN(getscrate) {
bl = map->id2bl(st->rid);
if (bl)
- rate = status->get_sc_def(bl, bl, (sc_type)type, 10000, 10000, 0);
+ rate = status->get_sc_def(bl, bl, (sc_type)type, 10000, 10000, SCFLAG_NONE);
script_pushint(st,rate);
return true;
@@ -16063,7 +16058,7 @@ BUILDIN(mercenary_sc_start) {
tick = script_getnum(st,3);
val1 = script_getnum(st,4);
- status->change_start(NULL, &sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2);
+ status->change_start(NULL, &sd->md->bl, type, 10000, val1, 0, 0, 0, tick, SCFLAG_FIXEDTICK);
return true;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index d159c3e2c..393c88df2 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -691,10 +691,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
temp = skill->get_time2(status->sc2skill(type),7);
if (sd->addeff[i].flag&ATF_TARGET)
- status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0);
+ status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,SCFLAG_NONE);
if (sd->addeff[i].flag&ATF_SELF)
- status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0);
+ status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,SCFLAG_NONE);
}
}
@@ -709,9 +709,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
temp = skill->get_time2(status->sc2skill(type),7);
if( sd->addeff3[i].target&ATF_TARGET )
- status->change_start(src,bl,type,sd->addeff3[i].rate,7,0,0,0,temp,0);
+ status->change_start(src,bl,type,sd->addeff3[i].rate,7,0,0,0,temp,SCFLAG_NONE);
if( sd->addeff3[i].target&ATF_SELF )
- status->change_start(src,src,type,sd->addeff3[i].rate,7,0,0,0,temp,0);
+ status->change_start(src,src,type,sd->addeff3[i].rate,7,0,0,0,temp,SCFLAG_NONE);
}
}
}
@@ -778,7 +778,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
// Enchant Poison gives a chance to poison attacked enemies
if((sce=sc->data[SC_ENCHANTPOISON])) //Don't use sc_start since chance comes in 1/10000 rate.
status->change_start(src,bl,SC_POISON,sce->val2, sce->val1,src->id,0,0,
- skill->get_time2(AS_ENCHANTPOISON,sce->val1),0);
+ skill->get_time2(AS_ENCHANTPOISON,sce->val1),SCFLAG_NONE);
// Enchant Deadly Poison gives a chance to deadly poison attacked enemies
if((sce=sc->data[SC_EDP]))
sc_start4(src,bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0,
@@ -790,7 +790,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case SM_BASH:
if( sd && skill_lv > 5 && pc->checkskill(sd,SM_FATALBLOW)>0 )
status->change_start(src,bl,SC_STUN,500*(skill_lv-5)*sd->status.base_level/50,
- skill_lv,0,0,0,skill->get_time2(SM_FATALBLOW,skill_lv),0);
+ skill_lv,0,0,0,skill->get_time2(SM_FATALBLOW,skill_lv),SCFLAG_NONE);
break;
case MER_CRASH:
@@ -1079,7 +1079,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case GS_BULLSEYE: //0.1% coma rate.
if(tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
- status->change_start(src,bl,SC_COMA,10,skill_lv,0,src->id,0,0,0);
+ status->change_start(src,bl,SC_COMA,10,skill_lv,0,src->id,0,0,SCFLAG_NONE);
break;
case GS_PIERCINGSHOT:
sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
@@ -1189,7 +1189,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case NC_POWERSWING:
// Use flag=2, the stun duration is not vit-reduced.
- status->change_start(src, bl, SC_STUN, 5*skill_lv*100, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 2);
+ status->change_start(src, bl, SC_STUN, 5*skill_lv*100, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), SCFLAG_FIXEDTICK);
if( rnd()%100 < 5*skill_lv )
skill->castend_damage_id(src, bl, NC_AXEBOOMERANG, pc->checkskill(sd, NC_AXEBOOMERANG), tick, 1);
break;
@@ -1210,7 +1210,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case LG_HESPERUSLIT:
if ( sc && sc->data[SC_BANDING] ) {
if ( sc->data[SC_BANDING]->val2 == 4 ) // 4 banding RGs: Targets will be stunned at 100% chance for 4 ~ 8 seconds, irreducible by STAT.
- status->change_start(src, bl, SC_STUN, 10000, skill_lv, 0, 0, 0, 1000*(4+rand()%4), 2);
+ status->change_start(src, bl, SC_STUN, 10000, skill_lv, 0, 0, 0, 1000*(4+rand()%4), SCFLAG_FIXEDTICK);
else if ( sc->data[SC_BANDING]->val2 == 6 ) // 6 banding RGs: activate Pinpoint Attack Lv1-5
skill->castend_damage_id(src,bl,LG_PINPOINTATTACK,1+rand()%5,tick,0);
}
@@ -1356,7 +1356,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
rate += sd->weapon_coma_race[tstatus->race];
rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
if (rate)
- status->change_start(src, bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0);
+ status->change_start(src, bl, SC_COMA, rate, 0, 0, src->id, 0, 0, SCFLAG_NONE);
}
if( sd && battle_config.equip_self_break_rate )
{ // Self weapon breaking
@@ -1396,10 +1396,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if (sd && !skill_id && bl->type == BL_PC) { // This effect does not work with skills.
if (sd->def_set_race[tstatus->race].rate)
status->change_start(src,bl, SC_DEFSET, sd->def_set_race[tstatus->race].rate, sd->def_set_race[tstatus->race].value,
- 0, 0, 0, sd->def_set_race[tstatus->race].tick, 2);
+ 0, 0, 0, sd->def_set_race[tstatus->race].tick, SCFLAG_FIXEDTICK);
if (sd->def_set_race[tstatus->race].rate)
status->change_start(src,bl, SC_MDEFSET, sd->mdef_set_race[tstatus->race].rate, sd->mdef_set_race[tstatus->race].value,
- 0, 0, 0, sd->mdef_set_race[tstatus->race].tick, 2);
+ 0, 0, 0, sd->mdef_set_race[tstatus->race].tick, SCFLAG_FIXEDTICK);
}
}
@@ -1703,10 +1703,10 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
time = skill->get_time2(status->sc2skill(type),7);
if (dstsd->addeff2[i].flag&ATF_TARGET)
- status->change_start(bl,src,type,rate,7,0,0,0,time,0);
+ status->change_start(bl,src,type,rate,7,0,0,0,time,SCFLAG_NONE);
if (dstsd->addeff2[i].flag&ATF_SELF && !status->isdead(bl))
- status->change_start(bl,bl,type,rate,7,0,0,0,time,0);
+ status->change_start(bl,bl,type,rate,7,0,0,0,time,SCFLAG_NONE);
}
}
@@ -4079,7 +4079,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case SL_STIN:
case SL_STUN:
if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
- status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,10);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
@@ -4518,7 +4518,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
tsc->data[SC_MELODYOFSINK] || tsc->data[SC_BEYOND_OF_WARCRY] || tsc->data[SC_UNLIMITED_HUMMING_VOICE] ) &&
rnd()%100 < 4 * skill_lv + 2 * (sd ? pc->checkskill(sd,WM_LESSON) : 10) + 10 * battle->calc_chorusbonus(sd)) {
skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
- status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),8);
+ status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),SCFLAG_FIXEDRATE);
status_change_end(bl, SC_SWING, INVALID_TIMER);
status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
@@ -5195,7 +5195,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case RK_FIGHTINGSPIRIT:
case RK_ABUNDANCE:
if( sd && !pc->checkskill(sd, RK_RUNEMASTERY) ){
- if( status->change_start(src,&sd->bl, (sc_type)(rnd()%SC_CONFUSION), 1000, 1, 0, 0, 0, skill->get_time2(skill_id,skill_lv),8) ){
+ if( status->change_start(src,&sd->bl, (sc_type)(rnd()%SC_CONFUSION), 1000, 1, 0, 0, 0, skill->get_time2(skill_id,skill_lv),SCFLAG_FIXEDRATE) ){
skill->consume_requirement(sd,skill_id,skill_lv,2);
map->freeblock_unlock();
return 0;
@@ -6224,7 +6224,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
|| dstsd->status.char_id == sd->status.child
)
) {
- status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,8);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,SCFLAG_FIXEDRATE);
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
@@ -6427,7 +6427,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( battle->check_undead(tstatus->race,tstatus->def_ele) ) {
status->change_start(src, bl, SC_BLIND,
100*(100-(tstatus->int_/2+tstatus->vit/3+tstatus->luk/10)), 1,0,0,0,
- skill->get_time2(skill_id, skill_lv) * (100-(tstatus->int_+tstatus->vit)/2)/100,0);
+ skill->get_time2(skill_id, skill_lv) * (100-(tstatus->int_+tstatus->vit)/2)/100,SCFLAG_NONE);
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
if(dstmd)
@@ -7282,7 +7282,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
return 0;
}
else
- status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8);
+ status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),SCFLAG_FIXEDRATE);
}
break;
@@ -7688,7 +7688,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if (tsce) {
if(sd)
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,10000,8);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,10000,SCFLAG_FIXEDRATE);
status_change_end(bl, SC_SWOO, INVALID_TIMER);
break;
}
@@ -7696,7 +7696,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case SL_SKE:
if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,10);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
@@ -8427,7 +8427,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( tsc && tsc->data[SC_STONE] )
status_change_end(bl,SC_STONE,INVALID_TIMER);
else
- status->change_start(src,bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),2);
+ status->change_start(src,bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),SCFLAG_FIXEDTICK);
} else {
int rate = 45 + 5 * skill_lv;
if( rnd()%100 < rate ){
@@ -8663,13 +8663,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
//If the target was successfully inflected with the Unlucky status, give 1 of 3 random status's.
switch(rnd()%3) {//Targets in the Unlucky status will be affected by one of the 3 random status's regardless of resistance.
case 0:
- status->change_start(src,bl,SC_POISON,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10);
+ status->change_start(src,bl,SC_POISON,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
break;
case 1:
- status->change_start(src,bl,SC_SILENCE,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10);
+ status->change_start(src,bl,SC_SILENCE,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
break;
case 2:
- status->change_start(src,bl,SC_BLIND,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10);
+ status->change_start(src,bl,SC_BLIND,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
}
}
} else if( sd )
@@ -9462,10 +9462,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
&& rand()%100 < (10 * (5 * skill_lv - status_get_int(bl) / 2 + 45 + 5 * skill_lv))
) {
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- status->change_start(src, bl, type, 10000, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 1));
+ status->change_start(src, bl, type, 10000, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), SCFLAG_NOAVOID));
status_zap(bl, tstatus->max_hp * skill_lv * 5 / 100 , 0);
if( status->get_lv(bl) <= status->get_lv(src) )
- status->change_start(src, bl, SC_COMA, skill_lv, skill_lv, 0, src->id, 0, 0, 0);
+ status->change_start(src, bl, SC_COMA, skill_lv, skill_lv, 0, src->id, 0, 0, SCFLAG_NONE);
} else if( sd )
clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
@@ -9564,8 +9564,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
heal = 5 * status->get_lv(&hd->bl) + status->base_matk(&hd->battle_status, status->get_lv(&hd->bl));
status->heal(bl, heal, 0, 0);
clif->skill_nodamage(src, src, skill_id, skill_lv, clif->skill_nodamage(src, bl, AL_HEAL, heal, 1));
- status->change_start(src, src, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), 1|2|8);
- status->change_start(src, bl, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), 1|2|8);
+ status->change_start(src, src, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
+ status->change_start(src, bl, type, 1000, skill_lv, 0, 0, 0, skill->get_time(skill_id,skill_lv), SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
}
break;
@@ -11371,7 +11371,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
break;
} else if( sc && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) {
int sec = skill->get_time2(sg->skill_id,sg->skill_lv);
- if( status->change_start(ss, bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) {
+ if( status->change_start(ss, bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,SCFLAG_FIXEDRATE) ) {
const struct TimerData* td = sc->data[type]?timer->get(sc->data[type]->timer):NULL;
if( td )
sec = DIFF_TICK32(td->tick, tick);
@@ -11753,7 +11753,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_MANHOLE:
if( sg->val2 == 0 && tsc && (sg->unit_id == UNT_ANKLESNARE || bl->id != sg->src_id) ) {
int sec = skill->get_time2(sg->skill_id,sg->skill_lv);
- if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) {
+ if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, SCFLAG_FIXEDRATE) ) {
const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL;
if( td )
sec = DIFF_TICK32(td->tick, tick);
@@ -11783,7 +11783,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
if( bl->id != ss->id ) {
if( status_get_mode(bl)&MD_BOSS )
break;
- if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id, sg->skill_lv), 8) ) {
+ if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id, sg->skill_lv), SCFLAG_FIXEDRATE) ) {
map->moveblock(bl, src->bl.x, src->bl.y, tick);
clif->fixpos(bl);
@@ -11796,7 +11796,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_VENOMDUST:
if(tsc && !tsc->data[type])
- status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),0);
+ status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),SCFLAG_NONE);
break;
@@ -12143,7 +12143,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_CLOUD_KILL:
if(tsc && !tsc->data[type])
- status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),8);
+ status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),SCFLAG_FIXEDRATE);
skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
@@ -12242,7 +12242,8 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_POISON_MIST:
skill->attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- status->change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill->get_time2(sg->skill_id, sg->skill_lv), 2|8);
+ status->change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0,
+ skill->get_time2(sg->skill_id, sg->skill_lv), SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
break;
}
diff --git a/src/map/status.c b/src/map/status.c
index 5d1b92a51..746ca51e2 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6311,9 +6311,12 @@ void status_change_init(struct block_list *bl) {
memset(sc, 0, sizeof (struct status_change));
}
-//Applies SC defense to a given status change.
-//Returns the adjusted duration based on flag values.
-//the flag values are the same as in status->change_start.
+/**
+ * Applies SC defense to a given status change.
+ *
+ * @see status_change_start for the expected parameters.
+ * @return the adjusted duration based on flag values.
+ */
int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag) {
//Percentual resistance: 10000 = 100% Resist
//Example: 50% -> sc_def=5000 -> 25%; 5000ms -> tick_def=5000 -> 2500ms
@@ -6606,7 +6609,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
tick_def = sc_def;
//Natural resistance
- if (!(flag&8)) {
+ if (!(flag&SCFLAG_FIXEDRATE)) {
rate -= rate*sc_def/10000;
rate -= sc_def2;
@@ -6640,7 +6643,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
if (tick < 1) return 1;
//Rate reduction
- if (flag&2)
+ if (flag&SCFLAG_FIXEDTICK)
return tick;
tick -= tick*tick_def/10000;
@@ -6727,18 +6730,23 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) {
}
}
}
-/*==========================================
-* Starts a status change.
-* 'type' = type, 'val1~4' depend on the type.
-* 'rate' = base success rate. 10000 = 100%
-* 'tick' is base duration
-* 'flag':
-* &1 : Cannot be avoided (it has to start)
-* &2 : Tick should not be reduced (by vit, luk, lv, etc)
-* &4 : sc_data loaded, no value has to be altered.
-* &8 : rate should not be reduced (not evaluated here, but in some calls to other functions)
-* &16: Status icon (SI) should not be send
-*------------------------------------------*/
+/**
+ * Starts a status change.
+ *
+ * @param src Status change source bl.
+ * @param bl Status change target bl.
+ * @param type Status change type.
+ * @param rate Base success rate. 1 means 0.01%, 10000 means 100%.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ * @param tick Base duration (milliseconds).
+ * @param flag Special flags (@see enum scstart_flag).
+ *
+ * @retval 0 if no status change happened.
+ * @retval 1 if the status change was successfully applied.
+ */
int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) {
struct map_session_data *sd = NULL;
struct status_change* sc;
@@ -6841,7 +6849,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
sd = BL_CAST(BL_PC, bl);
//Adjust tick according to status resistances
- if( !(flag&(1|4)) ) {
+ if( !(flag&(SCFLAG_NOAVOID|SCFLAG_LOADED)) ) {
tick = status->get_sc_def(src, bl, type, rate, tick, flag);
if( !tick ) return 0;
}
@@ -6871,7 +6879,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
case SC_FREEZE:
//Undead are immune to Freeze/Stone
- if (undead_flag && !(flag&1))
+ if (undead_flag && !(flag&SCFLAG_NOAVOID))
return 0;
case SC_SLEEP:
case SC_STUN:
@@ -6980,7 +6988,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
//Strip skills, need to divest something or it fails.
case SC_NOEQUIPWEAPON:
- if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
+ if (sd && !(flag&SCFLAG_LOADED)) { //apply sc anyway if loading saved sc_data
int i;
opt_flag = 0; //Reuse to check success condition.
if(sd->bonus.unstripable_equip&EQP_WEAPON)
@@ -6998,7 +7006,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_NOEQUIPSHIELD:
if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
else
- if (sd && !(flag&4)) {
+ if (sd && !(flag&SCFLAG_LOADED)) {
int i;
if(sd->bonus.unstripable_equip&EQP_SHIELD)
return 0;
@@ -7010,7 +7018,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPARMOR:
- if (sd && !(flag&4)) {
+ if (sd && !(flag&SCFLAG_LOADED)) {
int i;
if(sd->bonus.unstripable_equip&EQP_ARMOR)
return 0;
@@ -7022,7 +7030,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_NOEQUIPHELM:
- if (sd && !(flag&4)) {
+ if (sd && !(flag&SCFLAG_LOADED)) {
int i;
if(sd->bonus.unstripable_equip&EQP_HELM)
return 0;
@@ -7135,7 +7143,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
//Check for BOSS resistances
- if(st->mode&MD_BOSS && !(flag&1)) {
+ if(st->mode&MD_BOSS && !(flag&SCFLAG_NOAVOID)) {
if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
return 0;
switch (type) {
@@ -7533,7 +7541,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
vd = status->get_viewdata(bl);
calc_flag = status->ChangeFlagTable[type];
- if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs
+ if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs
switch(type) {
case SC_ADORAMUS:
sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1));
@@ -7544,16 +7552,16 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_ENDURE:
val2 = 7; // Hit-count [Celest]
- if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !val4 ) {
+ if( !(flag&SCFLAG_NOAVOID) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !val4 ) {
struct map_session_data *tsd;
if( sd ) {
int i;
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, 17);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL);
}
} else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, 17);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL);
}
//val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
if( val4 )
@@ -7641,16 +7649,16 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_REFLECTSHIELD:
val2=10+val1*3; // %Dmg reflected
- if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) ) {
+ if( !(flag&SCFLAG_NOAVOID) && (bl->type&(BL_PC|BL_MER)) ) {
struct map_session_data *tsd;
if( sd ) {
int i;
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 17);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
}
} else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 17);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
}
break;
case SC_NOEQUIPWEAPON:
@@ -7893,7 +7901,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC_AUTOGUARD:
- if( !(flag&1) ) {
+ if( !(flag&SCFLAG_NOAVOID) ) {
struct map_session_data *tsd;
int i,t;
for( i = val2 = 0; i < val1; i++) {
@@ -7905,17 +7913,17 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if( sd ) {
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 17);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
}
}
else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 17);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL);
}
}
break;
case SC_DEFENDER:
- if (!(flag&1)) {
+ if (!(flag&SCFLAG_NOAVOID)) {
val2 = 5 + 15*val1; //Damage reduction
val3 = 0; // unused, previously speed adjustment
val4 = 250 - 50*val1; //Aspd adjustment
@@ -7926,7 +7934,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
for (i = 0; i < 5; i++) {
//See if there are devoted characters, and pass the status to them. [Skotlex]
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])))
- status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
+ status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID);
}
}
}
@@ -8053,7 +8061,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
while( i >= 0 ) {
type2 = types[i];
if( d_sc->data[type2] )
- status->change_start(bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, 0, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1), (type2 != SC_DEFENDER) ? 16 : 0);
+ status->change_start(bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, 0,
+ skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1),
+ (type2 != SC_DEFENDER) ? SCFLAG_NOICON : SCFLAG_NONE);
i--;
}
}
@@ -8452,7 +8462,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
tick_time = 4000; // [GodLesZ] tick time
break;
case SC_PYREXIA:
- status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
+ status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE); // Blind status that last for 30 seconds
val4 = tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
@@ -9050,7 +9060,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
}
- /* values that must be set regardless of flag&4 e.g. val_flag */
+ /* values that must be set regardless of SCFLAG_LOADED e.g. val_flag */
switch(type) {
case SC_FIGHTINGSPIRIT:
val_flag |= 1|2;
@@ -9462,7 +9472,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
calc_flag&=~SCB_DYE;
}
- if(!(flag&16) && !(flag&4 && status->DisplayType[type]))
+ if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->DisplayType[type]))
clif->status_change(bl,status->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
/**
@@ -11655,7 +11665,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
data.val2 = sc->data[i]->val2;
data.val3 = sc->data[i]->val3;
data.val4 = sc->data[i]->val4;
- status->change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
+ status->change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_FIXEDRATE);
flag = 1;
}
}
diff --git a/src/map/status.h b/src/map/status.h
index 568348d23..623ba7eb3 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -67,6 +67,20 @@ typedef enum sc_conf_type {
SC_NO_CLEAR = 0x80,
} sc_conf_type;
+/**
+ * Flags to be used with status->change_start
+ */
+enum scstart_flag {
+ // Note: When updating this enum, also update the documentation in doc/script_commands.txt and the constants in db/const.txt
+ SCFLAG_NONE = 0x00, ///< No special behavior.
+ SCFLAG_NOAVOID = 0x01, ///< Cannot be avoided (it has to start).
+ SCFLAG_FIXEDTICK = 0x02, ///< Tick should not be reduced (by vit, luk, lv, etc).
+ SCFLAG_LOADED = 0x04, ///< sc_data was loaded, no value has to be altered.
+ SCFLAG_FIXEDRATE = 0x08, ///< rate should not be reduced (not evaluated in status_change_start, but in some calls to other functions).
+ SCFLAG_NOICON = 0x10, ///< Status icon (SI) should not be sent.
+ SCFLAG_ALL = SCFLAG_NONE|SCFLAG_NOAVOID|SCFLAG_FIXEDTICK|SCFLAG_LOADED|SCFLAG_FIXEDRATE|SCFLAG_NOICON
+};
+
// Status changes listing. These code are for use by the server.
typedef enum sc_type {
SC_NONE = -1,
@@ -1921,9 +1935,9 @@ struct status_change {
#define status_get_mode(bl) (status->get_status_data(bl)->mode)
//Short version, receives rate in 1->100 range, and does not uses a flag setting.
-#define sc_start(src, bl, type, rate, val1, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),0,0,0,(tick),0))
-#define sc_start2(src, bl, type, rate, val1, val2, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),0,0,(tick),0))
-#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),(val3),(val4),(tick),0))
+#define sc_start(src, bl, type, rate, val1, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),0,0,0,(tick),SCFLAG_NONE))
+#define sc_start2(src, bl, type, rate, val1, val2, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),0,0,(tick),SCFLAG_NONE))
+#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),(val3),(val4),(tick),SCFLAG_NONE))
#define status_change_end(bl,type,tid) (status->change_end_((bl),(type),(tid),__FILE__,__LINE__))