diff options
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 3 | ||||
-rw-r--r-- | src/map/chrif.c | 3 | ||||
-rw-r--r-- | src/map/mercenary.c | 2 | ||||
-rw-r--r-- | src/map/mob.c | 3 | ||||
-rw-r--r-- | src/map/script.c | 19 | ||||
-rw-r--r-- | src/map/skill.c | 73 | ||||
-rw-r--r-- | src/map/status.c | 92 | ||||
-rw-r--r-- | src/map/status.h | 20 |
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__)) |